dress up the website

Add base templates for css style and nav header
Replace item-based publisher listing with link-pased listing
add a link view and don't list the whole history on overview pages
limit link lists to 1000 items
add 'fixing' page to provide more technical help
main
eric 2023-08-21 14:51:42 -04:00
parent e70d580aea
commit db6c6d48cc
16 changed files with 759 additions and 115 deletions

1
.gitignore vendored
View File

@ -26,6 +26,7 @@ share/python-wheels/
*.egg *.egg
MANIFEST MANIFEST
keys/ keys/
private/
# PyInstaller # PyInstaller
# Usually these files are written by a python script from a template # Usually these files are written by a python script from a template

View File

@ -0,0 +1,387 @@
<style>
@import url("https://fonts.googleapis.com/css?family=Roboto|Roboto+Condensed:400&display=swap&subset=latin-ext");
@import url("https://fonts.googleapis.com/css?family=Lato|Roboto+Slab:300,400,500&display=swap");
/*! minireset.css v0.0.6 | MIT License | github.com/jgthms/minireset.css */
html,body,p,ol,ul,li,dl,dt,dd,blockquote,figure,fieldset,legend,textarea,pre,iframe,hr,h1,h2,h3,h4,h5,h6 {
margin: 0;
padding: 0
}
h1,h2,h3,h4,h5,h6 {
font-size: 100%;
font-weight: normal
}
ul {
list-style: none
}
button,input,select,textarea {
margin: 0
}
html {
box-sizing: border-box
}
*,*::before,*::after {
box-sizing: inherit
}
img,video {
height: auto;
max-width: 100%
}
iframe {
border: 0
}
table {
border-collapse: collapse;
border-spacing: 0
}
td,th {
padding: 0
}
td:not([align]),th:not([align]) {
text-align: left
}
html {
background-color: #fff;
font-size: 16px;
-moz-osx-font-smoothing: grayscale;
-webkit-font-smoothing: antialiased;
min-width: 300px;
overflow-x: hidden;
overflow-y: scroll;
text-rendering: optimizeLegibility;
text-size-adjust: 100%
}
article,aside,figure,footer,header,hgroup,section {
display: block
}
body,button,input,select,textarea {
font-family: "Roboto",sans-serif
}
code,pre {
-moz-osx-font-smoothing: auto;
-webkit-font-smoothing: auto;
font-family: monospace
}
body {
color: #4a4a4a;
font-size: 1em;
font-weight: 400;
line-height: 1.5
}
a {
color: #478ab7;
cursor: pointer;
text-decoration: none
}
a strong {
color: currentColor
}
a:hover {
color: #363636
}
code {
background-color: #f5f5f5;
color: #cc5252;
font-size: .875em;
font-weight: normal;
padding: .25em .5em .25em
}
hr {
background-color: #f5f5f5;
border: none;
display: block;
height: 2px;
margin: 1.5rem 0
}
img {
height: auto;
max-width: 100%
}
input[type="checkbox"],input[type="radio"] {
vertical-align: baseline
}
small {
font-size: .875em
}
span {
font-style: inherit;
font-weight: inherit
}
strong {
color: #363636;
font-weight: 700
}
fieldset {
border: none
}
pre {
-webkit-overflow-scrolling: touch;
background-color: #f5f5f5;
color: #4a4a4a;
font-size: .875em;
overflow-x: auto;
padding: 1.25rem 1.5rem;
white-space: pre;
word-wrap: normal
}
pre code {
background-color: transparent;
color: currentColor;
font-size: 1em;
padding: 0
}
table td,table th {
vertical-align: top
}
table th {
color: #363636
}
.container {
flex-grow: 1;
margin: 0 auto;
position: relative;
width: auto;
}
.content li+li {
margin-top: .25em
}
.content p:not(:last-child),.content dl:not(:last-child),.content ol:not(:last-child),.content ul:not(:last-child),.content blockquote:not(:last-child),.content pre:not(:last-child) {
margin-bottom: 1em
}
.content h1 {
font-size: 2em;
margin-bottom: .5em
}
.content h1:not(:first-child) {
margin-top: 1em
}
.content h2 {
font-size: 1.75em;
margin-bottom: .5714em
}
.content h2:not(:first-child) {
margin-top: 1.1428em
}
.content h3 {
font-size: 1.5em;
margin-bottom: .6666em
}
.content h3:not(:first-child) {
margin-top: 1.3333em
}
.content h4 {
font-size: 1.25em;
margin-bottom: .8em
}
.content h5 {
font-size: 1.125em;
margin-bottom: .8888em
}
.content h6 {
font-size: 1em;
margin-bottom: 1em
}
.content h1,.content h2,.content h3 {
font-family: Roboto Slab;
font-weight: 400;
line-height: 1.325;
color: #4a4a4a
}
.content h1 a,.content h2 a,.content h3 a {
word-break: break-word
}
.content h4,.content h5,.content h6 {
font-family: Roboto;
font-weight: 700;
line-height: 1.325;
color: #000000
}
.content h4 a,.content h5 a,.content h6 a {
word-break: break-word
}
.content blockquote {
background-color: #f5f5f5;
border-left: 5px solid #dbdbdb;
padding: 1.25em 1.5em
}
.content ol {
list-style-position: outside;
margin-left: 2em;
margin-top: 1em
}
.content ol:not([type]) {
list-style-type: decimal
}
.content ol:not([type]).is-lower-alpha {
list-style-type: lower-alpha
}
.content ol:not([type]).is-lower-roman {
list-style-type: lower-roman
}
.content ol:not([type]).is-upper-alpha {
list-style-type: upper-alpha
}
.content ol:not([type]).is-upper-roman {
list-style-type: upper-roman
}
.content ul {
list-style: disc outside;
margin-left: 2em;
margin-top: 1em
}
.content ul ul, .content dl ul {
list-style-type: circle;
margin-top: .5em
}
.content ul ul ul {
list-style-type: square
}
.content dt {
margin-top: .5em
}
.content dd {
margin-left: 2em
}
.content figure {
margin-left: 2em;
margin-right: 2em;
text-align: center
}
.content figure:not(:first-child) {
margin-top: 2em
}
.content figure:not(:last-child) {
margin-bottom: 2em
}
.content figure img {
display: inline-block
}
.content figure figcaption {
font-style: italic
}
.content pre {
-webkit-overflow-scrolling: touch;
overflow-x: auto;
padding: 1.25em 1.5em;
white-space: pre;
word-wrap: normal
}
.content sup,.content sub {
font-size: 75%
}
.content table td,.content table th {
border: 1px solid #dbdbdb;
border-width: 0 0 1px;
padding: .5em .75em;
vertical-align: top
}
.content table th {
color: #363636
}
.content table th:not([align]) {
text-align: left
}
.content table thead td,.content table thead th {
border-width: 0 0 2px;
color: #363636
}
.content table tfoot td,.content table tfoot th {
border-width: 2px 0 0;
color: #363636
}
.content table tbody tr:last-child td,.content table tbody tr:last-child th {
border-bottom-width: 0
}
.content .tabs li+li {
margin-top: 0
}
.content.is-small {
font-size: .75rem
}
.content.is-medium {
font-size: 1.25rem
}
.content.is-large {
font-size: 1.5rem
}
.section {
padding: 1.5rem;
}
header nav a {
padding: 1.5em;
font-size: medium;
font-weight: bold;
}
</style>

View File

@ -0,0 +1,72 @@
{% load static %}
<html>
<head>
<title>Fixing DOAB Links</title>
{% include "basestyle.html" %}
</head>
<body>
{% include "header.html" %}
<main class="section oapen-topic oapen-main">
<div class="container">
<div class="content">
<h1>
Fixing DOAB Links
</h1>
<p>
Keeping the links in DOAB working is a collaborative enterprise of the community. This site checks the links, but without participation from participating publishers, addressing the problems it exposes would be impossible.
</p>
<h3>Types of problems, and how to fix them</h3>
<p>
When a link is checked we record the status code and content type returned by the web server. This status code gives us hints about what sort of problem is present
</p>
<dl>
<dt id='code301'>"301" or "302" indicates a bad redirect.
<dd> Redirects are used to keep links working after they've changed addresses. CrossRef links, for example, are usually redirected to the publisher's website. But sometimes the redirecting server get it wrong, and there are problems with the resolutions. Another type of problem involves chains of redirects - there might be a loop, or there might be an insecure link in the middle of an other wise secure chain of links - That used to be OK, but now it's an error.
<dt id='code403'>"403" indicates a misconfigured server that is not allowing access to the promised resource.
<dd> Sometimes this happens when a website is trying to authenticate users, even thought the resource is open access. Check to make sure your server is not trying to authenticate users for open access resources Or perhaps a link for a closed resource has been mistakenly loaded to DOAB.
<dt id='code404'>"404" means the link is broken - the resource is not found.
<dd> The common causes for this error are:
<ul>
<li> The url loaded to DOAB is incorrect. Maybe there's a typo, or perhaps an encoding error (URLs can contain accented characters, whitespace, or symbols, so they need to be escaped or encoded).
<li> A resource that used to be available has disappeared or has changed addresses.
</ul>
In any case, the correct URL should be loaded to DOAB, or in the worst case, deleted.
<dt id='code408'>"408" means the website didn't respond in a reasonable time.
<dd> This might be an intermittent problem. Links get checked every month, so look at the the history of checks to see if that's so. Otherwise, you probably have a server problem.
<dt id='code500'>"500" means something has gone wrong at the website server.
<dd> you have a server problem.
<dt id='code502'>"502" is a gateway error.
<dd>Some websites use load balancers or content distribution networks; if these gateways have a problem connecting with the source website, they send a 502 response. The server needs checking.
<dt id='code503'>"503" means that a website couldnt be reached.
<dd>This could happen because the server was too busy, under maintenance, or something else. Amazon's robot blocker returns 503 codes, so these must be checked manually. It may be that your server is blocking users based on the user-agent sent with the request. To make sure that DOAB Check doesn't get blocked, add "doab_check_bot" to your server's allow list.
<dt id='code504'>"504" indicates that the server, while acting as a gateway or proxy did not get a response in time from an upstream server.
<dd>Some web server run in protected environments and only talk to the internet via a gateway or a proxy. This means that there is a problem with the communication between the web server and a server in-between.
<dt id='code511'>"511" indicates a problem with the security of the connection - most often an incomplete certificate.
<dd> The <a href="https://www.ssllabs.com/ssltest/">SSL Server Test</a> can help you diagnose this problem. But beware - current we browsers often ignore some security problems, so the link might work when you try to test it. But because the browser vendors are gradually clamping down on weak security, the next update to Firefox or Chrome might start issuing warnings that you website is unsafe. Better to fix it now.
<dt id='code0'>"None" or "0" means something has gone terribly wrong. Possibly a bug in the checker or a malformed url.
<dd>If your server admins can't find the problem, have them contact us!
<dt id='code200'>"200" means that the link operated correctly.
<dd> Unfortunately, this DOESN'T necessarily mean that the link is going to the right place. Checking THAT is beyond the scope of this project at present.
</dl>
</div>
</div>
</main>
</body>
</html>

View File

@ -0,0 +1,40 @@
<header>
<div class="container">
<nav role="navigation">
<div class="level topnav">
<a href="/">
DOAB Check
</a>
<a href="{% url 'fixing' %}">
Fixing links
</a>
<a href="https://doabooks.org"">
DOAB
</a>
<a href="https://oapen.org"">
OAPEN
</a>
<a href="https://ebookfoundation.org"">
Free Ebook Foundation
</a>
</div>
</div>
</div>
</nav>
</div>
</header>

View File

@ -2,12 +2,17 @@
<html> <html>
<head> <head>
<title>DOAB Check</title> <title>DOAB Check</title>
{% include "basestyle.html" %}
</head> </head>
<body> <body>
{% include "header.html" %}
<main class="section oapen-topic oapen-main">
<div class="container">
<div class="content">
<h1> <h1>
Welcome to DOAB Check! Welcome to DOAB Check!
</h1> </h1>
<p> <p style='box-sizing: content-box'>
<img style='height:5em; padding:1em; margin-bottom: 1em' src='{% static "fef_logo_large.png" %}' alt='FEF logo'> <img style='height:5em; padding:1em; margin-bottom: 1em' src='{% static "fef_logo_large.png" %}' alt='FEF logo'>
<img style='height:5em; padding:1em; margin-bottom: 1em' src='{% static "doab.png" %}' alt='DOAB logo'> <img style='height:5em; padding:1em; margin-bottom: 1em' src='{% static "doab.png" %}' alt='DOAB logo'>
</p </p
@ -36,16 +41,16 @@ View <a href="{% url 'publishers' %}">the list of publishers whose links we've c
When a link is checked we record the status code and content type returned by the web server. When a link is checked we record the status code and content type returned by the web server.
</p> </p>
<ul> <ul>
<li>"301" or "302" indicates a bad redirect. <li><a href="{% url 'fixing' %}#code302">"301" or "302"</a> indicates a bad redirect.
<li>"403" indicates a misconfigured server that is not allowing access to the promised resource. <li><a href="{% url 'fixing' %}#code403">"403"</a> indicates a misconfigured server that is not allowing access to the promised resource.
<li>"404" means the link is broken - the resource is not found. <li><a href="{% url 'fixing' %}#code404">"404"</a> means the link is broken - the resource is not found.
<li>"408" means the website didn't respond in a reasonable time. <li><a href="{% url 'fixing' %}#code408">"408"</a> means the website didn't respond in a reasonable time.
<li>"500" means something has gone wrong at the website server. <li><a href="{% url 'fixing' %}#code500">"500"</a> means something has gone wrong at the website server.
<li>"502" means is a gateway error. Some websites use load balancers or content distribution networks; if these gateways have a problem connecting with the source website, they send a 502 response. <li><a href="{% url 'fixing' %}#code502">"502"</a> means is a gateway error. Some websites use load balancers or content distribution networks; if these gateways have a problem connecting with the source website, they send a 502 response.
<li>"503" means that a website couldnt be reached. This could happen because the server was too busy, under maintenance, or something else. Amazon's robot blocker returns 503 codes, so these must be checked manually. <li><a href="{% url 'fixing' %}#code503">"503"</a> means that a website couldnt be reached. This could happen because the server was too busy, under maintenance, or something else. Amazon's robot blocker returns 503 codes, so these must be checked manually.
<li>"504" indicates that the server, while acting as a gateway or proxy did not get a response in time from an upstream server. <li><a href="{% url 'fixing' %}#code504">"504"</a> indicates that the server, while acting as a gateway or proxy did not get a response in time from an upstream server.
<li>"511" indicates a problem with the security of the connection - most often an incomplete certificate. <li><a href="{% url 'fixing' %}#code511">"511"</a> indicates a problem with the security of the connection - most often an incomplete certificate.
<li>"None" or "0" means something has gone terribly wrong. Possibly a bug in the checker or a malformed url. <li><a href="{% url 'fixing' %}#code0">"None" or "0"</a> means something has gone terribly wrong. Possibly a bug in the checker or a malformed url.
</ul> </ul>
<p> {{ num_checked }} links have been checked. <p> <p> {{ num_checked }} links have been checked. <p>
@ -64,6 +69,8 @@ When a link is checked we record the status code and content type returned by th
</tr> </tr>
{% endfor %} {% endfor %}
</table> </table>
</div>
</div>
</main>
</body> </body>
</html> </html>

View File

@ -0,0 +1,40 @@
<html>
<head>
<title>DOAB Link Details</title>
{% include "basestyle.html" %}
</head>
<body>
{% include "header.html" %}
<main class="section oapen-topic oapen-main">
<div class="container">
<div class="content">
<h2>
Link Checking Details
</h2>
<ul>
<li> URL: <a href="{{ link.url }}">{{ link.url }}</a>
{% for item in link.items.all %}
<li>Title: {{ item.title }}
<li>Publisher: {{ item.publisher_name }}
{% endfor %}
<li>Provider: <a href="{% url 'provider' link.provider %}">{{ link.provider }}</a>
{% if not link.live %}
<li>THIS LINK HAS BEEN REMOVED FROM DOAB
{% endif %}
</ul>
<h3>Link Checking History</h3>
<table>
{% for check in link.recent_checks %}
<tr>
<td>{{ check.created }}</td>
<td {% if check.return_code != 200 %} style="color:red"{% endif %}>{{ check.return_code }}</td>
<td>{{check.content_type}}</td>
</tr>
{% endfor %}
</div>
</div>
</main>
</body>
</html>

View File

@ -1,11 +1,17 @@
<html> <html>
<head> <head>
<title>DOAB Problem Links</title> <title>DOAB Problem Links</title>
{% include "basestyle.html" %}
</head> </head>
<body> <body>
{% include "header.html" %}
<main class="section oapen-topic oapen-main">
<div class="container">
<div class="content">
<h2> <h2>
DOAB links with Status code: {{ code | default:'0 or None' }} DOAB links with status code: {{ code | default:'0 or None' }}
</h2> </h2>
<p> Here's <a href="{% url 'fixing' %}#code{{ code | default:'0' }}">more information about status code {{ code | default:'0 or None' }}</a>
<ul> <ul>
{% for provider in providers %} {% for provider in providers %}
<li> <a href="#{{ provider.provider | urlencode }}">{{ provider.provider }}</a>: <li> <a href="#{{ provider.provider | urlencode }}">{{ provider.provider }}</a>:
@ -19,21 +25,27 @@ DOAB links with Status code: {{ code | default:'0 or None' }}
<dd> <dd>
<ul> <ul>
{% for link in provider.links %} {% for link in provider.links %}
<li> {% with title=link.items.all.0.title %}
<p><a href="{{link.url}}">{{link.url}}</a> ({{link.items.first.publisher_name | default:'*** no publisher name ***'}}) {% ifchanged title %}<div class='itemtitle'>{{ title }}</div>{% endifchanged %}
<table>
{% for check in link.recent_checks %} <div class='itemlink'><a href="{{ link.url }}">{{ link.url }}</a></div>
<tr> <a href="{% url 'link' link.id %}">[full info]</a>
<td>{{ check.created }}</td>
<td {% if check.return_code != 200 %} style="color:red"{% endif %}>{{ check.return_code }}</td> <table class="checked">
<td>{{check.content_type}}</td> <tr>
{% endfor %} <td>Last checked: {{ link.recent_check.created }}</td>
</table> <td {%if code != 200 %} style="color:red"{% endif %}>{{ code }}</td>
</li> <td>{{ link.recent_check.content_type }}</td>
</tr>
</table>
{% if forloop.counter == 1000 %} Can't display more than 1000 links {% endif %}
{% endwith %}
{% endfor %} {% endfor %}
</ul> </ul>
</dd> </dd>
{% endfor %} {% endfor %}
</dl> </dl>
</body> </div>
</div>
</main></body>
</html> </html>

View File

@ -1,8 +1,13 @@
<html> <html>
<head> <head>
<title>DOAB Link Checking Problems by Publisher</title> <title>DOAB Link Checking Problems by Publisher</title>
{% include "basestyle.html" %}
</head> </head>
<body> <body>
{% include "header.html" %}
<main class="section oapen-topic oapen-main">
<div class="container">
<div class="content">
<h2> <h2>
DOAB Link Checking Problems by Publisher DOAB Link Checking Problems by Publisher
</h2> </h2>
@ -22,5 +27,8 @@ DOAB Link Checking Problems by Publisher
</table> </table>
</ul> </ul>
</div>
</div>
</main>
</body> </body>
</html> </html>

View File

@ -1,8 +1,13 @@
<html> <html>
<head> <head>
<title>DOAB Hosts</title> <title>DOAB Hosts</title>
{% include "basestyle.html" %}
</head> </head>
<body> <body>
{% include "header.html" %}
<main class="section oapen-topic oapen-main">
<div class="container">
<div class="content">
<h2> <h2>
Link Checking for Link Checking for
{{provider.provider}} ({{provider.link_count}} links) {{provider.provider}} ({{provider.link_count}} links)
@ -12,33 +17,46 @@ Link Checking for
<tr> <tr>
<th>HTTP Code</th> <th>HTTP Code</th>
<th>number</th> <th>number</th>
<th></th>
</tr> </tr>
{% for code in codes %} {% for code in codes %}
<tr {% if code.recent_check__return_code != 200 %} style="color:red"{% endif %}> <tr {% if code.recent_check__return_code != 200 %} style="color:red"{% endif %}>
<td> {{ code.recent_check__return_code }} </td> <td> {{ code.recent_check__return_code }} </td>
<td> {{ code.count }} </td> <td> <a href="#code{{ code.recent_check__return_code }}">{{ code.count }}</a>
<td><a href="{% url 'fixing' %}#{{ code.recent_check__return_code }}">how to fix</a></td>
</tr> </tr>
{% empty %} {% empty %}
<tr><td colspan=2>None of the active links for {{ provider.provider }} have been checked.</td> <tr><td colspan=2>None of the active links for {{ provider.provider }} have been checked.</td>
{% endfor %} {% endfor %}
</table> </table>
<h3>Checked links</h3> <h3>Checked links by status</h3>
<ul> <ul>
{% for link in links %} {% for codeobj in codes %}
<li> {% with code=codeobj.recent_check__return_code %}
<a href="{{link.url}}">{{link.url}}</a> <h3{% if code != 200 %} style="color:red"{% endif %} id="code{{ code }}"> {{ code }}</h3>
<table> {% for link in codeobj.links %}
{% for check in link.recent_checks %} {% with title=link.items.all.0.title %}
<tr> {% ifchanged title %}<div class='itemtitle'>{{ title }}</div>{% endifchanged %}
<td>{{ check.created }}</td>
<td {% if check.return_code != 200 %} style="color:red"{% endif %}>{{ check.return_code }}</td> <div class='itemlink'><a href="{{ link.url }}">{{ link.url }}</a></div>
<td>{{check.content_type}}</td> <a href="{% url 'link' link.id %}">[full info]</a>
</tr>
<table class="checked">
<tr>
<td>Last checked: {{ link.recent_check.created }}</td>
<td {%if code != 200 %} style="color:red"{% endif %}>{{ code }}</td>
<td>{{ link.recent_check.content_type }}</td>
</tr>
</table>
{% if forloop.counter == 1000 %} Can't display more than 1000 links {% endif %}
{% endwith %}
{% endfor %} {% endfor %}
</table>
</li> {% endwith %}
{% endfor %} {% endfor %}
</ul> </div>
</div>
</main>
</body> </body>
</html> </html>

View File

@ -1,8 +1,13 @@
<html> <html>
<head> <head>
<title>DOAB Hostnames</title> <title>DOAB Hostnames</title>
{% include "basestyle.html" %}
</head> </head>
<body> <body>
{% include "header.html" %}
<main class="section oapen-topic oapen-main">
<div class="container">
<div class="content">
<h2> <h2>
DOAB Link Checking by Server Hostname DOAB Link Checking by Server Hostname
</h2> </h2>
@ -12,5 +17,8 @@ DOAB Link Checking by Server Hostname
<li><a href="{% url 'provider' provider.provider %}">{{provider.provider}}</a> ({{provider.link_count}})</li> <li><a href="{% url 'provider' provider.provider %}">{{provider.provider}}</a> ({{provider.link_count}})</li>
{% endfor %} {% endfor %}
</ul> </ul>
</div>
</div>
</main>
</body> </body>
</html> </html>

View File

@ -1,57 +0,0 @@
<html>
<head>
<title>DOAB Link Checking for {{ publisher.publisher }}</title>
</head>
<body>
<h2>
DOAB Linkchecking for
{{ publisher.publisher }} ({{ publisher.item_count|default:0 }} records)
</h2>
<h3>Link checking summary</h3>
<table>
<tr>
<th>HTTP Code</th>
<th>number</th>
</tr>
{% for code in codes %}
<tr {% if code.links__recent_check__return_code != 200 %} style="color:red"{% endif %}>
<td> {{ code.links__recent_check__return_code }} </td>
<td> {{ code.count }} </td>
</tr>
{% empty %}
<tr><td colspan=2>None of the active links for {{ publisher.publisher }} have been checked.</td>
{% endfor %}
</table>
<h3>Items with checked links</h3>
<ul>
{% for item in items %}
<li>
<a href="{{ item.url }}">{{ item.doab }}</a> - {{ item.title }}
{% for link in item.links.all %}
<table>
<tr>
<th>
<a href="{{ link.url }}">{{ link.url }}</a>
</th>
<tr>
<td>
<table>
{% for check in link.recent_checks %}
<tr {% if check.return_code != 200 %} style="color:red"{% endif %}>
<td>{{ check.created }}:</td>
<td>{{ check.return_code }}</td>
<td>{{ check.content_type }}</td>
</tr>
{% endfor %}
</table>
</td>
</tr>
{% endfor %}
</table>
</li>
{% endfor %}
</ul>
</body>
</html>

View File

@ -0,0 +1,81 @@
<!DOCTYPE html>
<html>
<head>
<title>DOAB Link Checking for {{ publisher }}</title>
{% include "basestyle.html" %}
<style>
.itemtitle {
padding-top: 1.5ex;
font-weight: bold;
}
.checked td {
padding-right: 2em
}
#summary th {
padding-right: 2em
}
</style>
</head>
<body>
{% include "header.html" %}
<main class="section oapen-topic oapen-main">
<div class="container">
<div class="content">
<h2>
DOAB Linkchecking for
{{ publisher }} ({{ count|default:0 }} links)
</h2>
<h3>Link checking summary</h3>
<table id="summary">
<tr>
<th>HTTP Status Code</th>
<th>number of links</th>
<th></th>
</tr>
{% for codeobj in codes %}
{% with code=codeobj.recent_check__return_code %}
<tr {% if code != 200 %} style="color:red"{% endif %}>
<td> {{ code }} </td>
<td> <a href="#code{{ code }}">{% if codeobj.count < 998 %}{{ codeobj.count }}
{% else %} more than 1000 {% endif %}</a> </td>
<td> <a href='{{ code }}'>?</a> </td>
</tr>
{% endwith %}
{% empty %}
<tr><td colspan=2>None of the active links for {{ publisher.publisher }} have been checked.</td>
{% endfor %}
</table>
<h3>Checked links by status</h3>
<ul>
{% for codeobj in codes %}
{% with code=codeobj.recent_check__return_code %}
<h3{% if code != 200 %} style="color:red"{% endif %} id="code{{ code }}"> {{ code }}</h3>
{% for link in codeobj.links %}
{% with title=link.items.all.0.title %}
{% ifchanged title %}<div class='itemtitle'>{{ title }}</div>{% endifchanged %}
<div class='itemlink'><a href="{{ link.url }}">{{ link.url }}</a></div>
<a href="{% url 'link' link.id %}">[full info]</a>
<table class="checked">
<tr>
<td>Last checked: {{ link.recent_check.created }}</td>
<td {%if code != 200 %} style="color:red"{% endif %}>{{ code }}</td>
<td>{{ link.recent_check.content_type }}</td>
</tr>
</table>
{% if forloop.counter == 1000 %} Can't display more than 1000 links {% endif %}
{% endwith %}
{% endfor %}
{% endwith %}
{% endfor %}
</ul>
</div>
</div>
</body>
</html>

View File

@ -1,8 +1,13 @@
<html> <html>
<head> <head>
<title>DOAB Publishers</title> <title>DOAB Publishers</title>
{% include "basestyle.html" %}
</head> </head>
<body> <body>
{% include "header.html" %}
<main class="section oapen-topic oapen-main">
<div class="container">
<div class="content">
<h2> <h2>
DOAB Linkchecking by Publisher DOAB Linkchecking by Publisher
</h2> </h2>
@ -15,5 +20,8 @@ DOAB Linkchecking by Publisher
</a> ({{publisher.item_count}})</li> </a> ({{publisher.item_count}})</li>
{% endfor %} {% endfor %}
</ul> </ul>
</div>
</div>
</main>
</body> </body>
</html> </html>

View File

@ -25,6 +25,10 @@ class PageTests(TestCase):
self.assertEqual(r.status_code, 200) self.assertEqual(r.status_code, 200)
r = self.client.get("/problems/publishers/") r = self.client.get("/problems/publishers/")
self.assertEqual(r.status_code, 200) self.assertEqual(r.status_code, 200)
r = self.client.get("/link/10")
self.assertEqual(r.status_code, 200)
r = self.client.get("/fixing/")
self.assertEqual(r.status_code, 200)
sample_doab = 'oai:doab-books:20.500.12854/25850' sample_doab = 'oai:doab-books:20.500.12854/25850'

View File

@ -9,10 +9,13 @@ from . import views
urlpatterns = [ urlpatterns = [
path('', views.HomepageView.as_view(), name='home'), path('', views.HomepageView.as_view(), name='home'),
path('admin/', admin.site.urls), path('admin/', admin.site.urls),
path('fixing/', TemplateView.as_view(template_name='fixing.html'), name='fixing'),
path('problems/publishers/', views.ProblemPublishersView.as_view(), name='probpubs'), path('problems/publishers/', views.ProblemPublishersView.as_view(), name='probpubs'),
path('problems/<str:code>/', views.ProblemsView.as_view(), name='problems'), path('problems/<str:code>/', views.ProblemsView.as_view(), name='problems'),
path('providers/', views.ProvidersView.as_view(), name='providers'), path('providers/', views.ProvidersView.as_view(), name='providers'),
path('providers/<str:provider>/', views.ProviderView.as_view(), name='provider'), path('providers/<str:provider>/', views.ProviderView.as_view(), name='provider'),
path('publishers/', views.PublishersView.as_view(), name='publishers'), path('publishers/', views.PublishersView.as_view(), name='publishers'),
re_path(r'publishers/(?P<publisher>.*)', views.PublisherView.as_view(), name='publisher'), re_path(r'publishers/(?P<publisher>.*)', views.PublisherView.as_view(), name='publisher'),
re_path(r'link/(?P<link_id>\d*)', views.LinkView.as_view(), name='link'),
] ]

View File

@ -63,11 +63,24 @@ class ProviderView(generic.TemplateView):
codes = provider_links.order_by('-recent_check__return_code').values( codes = provider_links.order_by('-recent_check__return_code').values(
'recent_check__return_code').distinct() 'recent_check__return_code').distinct()
for code in codes: for code in codes:
code['count'] = provider_links.filter( code['links'] = provider_links.filter(live=True,
recent_check__return_code=code['recent_check__return_code'], recent_check__return_code=code['recent_check__return_code'],
).distinct().count() ).order_by('items__title')
code['count'] = code['links'].count()
code['links'] = code['links'][:1000]
return {'provider': provider, 'links': provider_links, 'codes': codes} return {'provider': provider,
'links': provider_links.order_by('-recent_check__return_code'),
'codes': codes}
class LinkView(generic.TemplateView):
template_name = 'link.html'
def get_context_data(self, **kwargs):
link_id = int(kwargs['link_id'])
link = get_object_or_404(Link, id=link_id)
return {'link': link}
class PublishersView(generic.TemplateView): class PublishersView(generic.TemplateView):
@ -100,28 +113,27 @@ class ProblemPublishersView(generic.TemplateView):
yield (NOPUBNAME if not k else k), v yield (NOPUBNAME if not k else k), v
return {'pubs': fixempty(pubs)} return {'pubs': fixempty(pubs)}
class PublisherView(generic.TemplateView): class PublisherView(generic.TemplateView):
template_name = 'publisher.html' template_name = 'publisherlinks.html'
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
pub = kwargs['publisher'] pub = kwargs['publisher']
publisher = {'publisher': pub} publisher = {'publisher': pub}
if pub == NOPUBNAME: if pub == NOPUBNAME:
pub = '' pub = ''
publisher_items = Item.objects.filter( publisher_links = Link.objects.filter(
publisher_name=pub, status=1, items__publisher_name=pub, items__status=1, recent_check__isnull=False
) )
publisher['item_count'] = publisher_items.count() link_count = publisher_links.distinct().count()
publisher_items = publisher_items.filter(links__recent_check__isnull=False).distinct()
codes = publisher_links.order_by('-recent_check__return_code').values(
codes = publisher_items.order_by('-links__recent_check__return_code').values( 'recent_check__return_code').distinct()
'links__recent_check__return_code').distinct()
for code in codes: for code in codes:
code['count'] = Link.objects.filter(live=True, code['links'] = publisher_links.filter(live=True,
recent_check__return_code=code['links__recent_check__return_code'], recent_check__return_code=code['recent_check__return_code'],
items__publisher_name=pub).distinct().count() ).order_by('items__title')
code['count'] = code['links'].count()
return {'codes': codes, 'publisher': pub, 'count': link_count}
return {'publisher': publisher, 'items': publisher_items, 'codes': codes}