new details page design

This commit is contained in:
Nick Sweeting 2019-03-27 03:49:39 -04:00
parent c9c5b04df0
commit 2ed91fe429
9 changed files with 419 additions and 251 deletions

View file

@ -40,6 +40,7 @@ from config import (
CHROME_VERSION, CHROME_VERSION,
GIT_VERSION, GIT_VERSION,
YOUTUBEDL_VERSION, YOUTUBEDL_VERSION,
ONLY_NEW,
) )
from util import ( from util import (
enforce_types, enforce_types,
@ -87,33 +88,40 @@ def archive_link(link: Link, page=None) -> Link:
link = load_json_link_index(link.link_dir, link) link = load_json_link_index(link.link_dir, link)
log_link_archiving_started(link.link_dir, link, is_new) log_link_archiving_started(link.link_dir, link, is_new)
link = link.overwrite(updated=datetime.now())
stats = {'skipped': 0, 'succeeded': 0, 'failed': 0} stats = {'skipped': 0, 'succeeded': 0, 'failed': 0}
for method_name, should_run, method_function in ARCHIVE_METHODS: for method_name, should_run, method_function in ARCHIVE_METHODS:
if method_name not in link.history: try:
link.history[method_name] = [] if method_name not in link.history:
link.history[method_name] = []
if should_run(link.link_dir, link):
log_archive_method_started(method_name) if should_run(link.link_dir, link):
log_archive_method_started(method_name)
result = method_function(link.link_dir, link) result = method_function(link.link_dir, link)
link.history[method_name].append(result) link.history[method_name].append(result)
stats[result.status] += 1 stats[result.status] += 1
log_archive_method_finished(result) log_archive_method_finished(result)
else: else:
stats['skipped'] += 1 stats['skipped'] += 1
except Exception as e:
raise Exception('Exception in archive_methods.fetch_{}(Link(url={}))'.format(
method_name,
link.url,
)) from e
# print(' ', stats) # print(' ', stats)
link = Link(**{ # If any changes were made, update the link index json and html
**link._asdict(),
'updated': datetime.now(),
})
write_link_index(link.link_dir, link) write_link_index(link.link_dir, link)
patch_links_index(link)
was_changed = stats['succeeded'] or stats['failed']
if was_changed:
patch_links_index(link)
log_link_archiving_finished(link.link_dir, link, is_new, stats) log_link_archiving_finished(link.link_dir, link, is_new, stats)
except KeyboardInterrupt: except KeyboardInterrupt:

View file

@ -154,7 +154,7 @@ def write_html_links_index(out_dir: str, links: List[Link], finished: bool=False
link.title link.title
or (link.base_url if link.is_archived else TITLE_LOADING_MSG) or (link.base_url if link.is_archived else TITLE_LOADING_MSG)
), ),
'tags': link.tags or '', 'tags': (link.tags or '') + (' {}'.format(link.extension) if link.is_static else ''),
'favicon_url': ( 'favicon_url': (
os.path.join('archive', link.timestamp, 'favicon.ico') os.path.join('archive', link.timestamp, 'favicon.ico')
# if link['is_archived'] else 'data:image/gif;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs=' # if link['is_archived'] else 'data:image/gif;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs='
@ -196,12 +196,11 @@ def patch_links_index(link: Link, out_dir: str=OUTPUT_DIR) -> None:
patched_links = [] patched_links = []
for saved_link in json_file_links: for saved_link in json_file_links:
if saved_link.url == link.url: if saved_link.url == link.url:
patched_links.append(Link(**{ patched_links.append(saved_link.overwrite(
**saved_link._asdict(), title=title,
'title': title, history=link.history,
'history': link.history, updated=link.updated,
'updated': link.updated, ))
}))
else: else:
patched_links.append(saved_link) patched_links.append(saved_link)
@ -283,7 +282,7 @@ def write_html_link_index(out_dir: str, link: Link) -> None:
), ),
'extension': link.extension or 'html', 'extension': link.extension or 'html',
'tags': link.tags or 'untagged', 'tags': link.tags or 'untagged',
'status': 'Archived' if link.is_archived else 'Not yet archived', 'status': 'archived' if link.is_archived else 'not yet archived',
'status_color': 'success' if link.is_archived else 'danger', 'status_color': 'success' if link.is_archived else 'danger',
})) }))

View file

@ -131,7 +131,7 @@ def log_link_archiving_started(link_dir: str, link: Link, is_new: bool):
print('\n[{symbol_color}{symbol}{reset}] [{symbol_color}{now}{reset}] "{title}"'.format( print('\n[{symbol_color}{symbol}{reset}] [{symbol_color}{now}{reset}] "{title}"'.format(
symbol_color=ANSI['green' if is_new else 'black'], symbol_color=ANSI['green' if is_new else 'black'],
symbol='+' if is_new else '*', symbol='+' if is_new else '',
now=datetime.now().strftime('%Y-%m-%d %H:%M:%S'), now=datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
title=link.title or link.base_url, title=link.title or link.base_url,
**ANSI, **ANSI,

View file

@ -59,6 +59,10 @@ class Link:
object.__setattr__(self, 'history', cast_history) object.__setattr__(self, 'history', cast_history)
def overwrite(self, **kwargs):
"""pure functional version of dict.update that returns a new instance"""
return Link(**{**self._asdict(), **kwargs})
def __eq__(self, other): def __eq__(self, other):
if not isinstance(other, Link): if not isinstance(other, Link):
return NotImplemented return NotImplemented
@ -96,6 +100,9 @@ class Link:
'is_static': self.is_static, 'is_static': self.is_static,
'is_archived': self.is_archived, 'is_archived': self.is_archived,
'num_outputs': self.num_outputs, 'num_outputs': self.num_outputs,
'num_failures': self.num_failures,
'oldest_archive_date': self.oldest_archive_date,
'newest_archive_date': self.newest_archive_date,
}) })
return info return info
@ -152,11 +159,42 @@ class Link:
from util import ts_to_date from util import ts_to_date
return ts_to_date(self.updated) if self.updated else None return ts_to_date(self.updated) if self.updated else None
@property
def oldest_archive_date(self) -> Optional[datetime]:
from util import ts_to_date
most_recent = min(
(result.start_ts
for method in self.history.keys()
for result in self.history[method]),
default=None,
)
return ts_to_date(most_recent) if most_recent else None
@property
def newest_archive_date(self) -> Optional[datetime]:
from util import ts_to_date
most_recent = max(
(result.start_ts
for method in self.history.keys()
for result in self.history[method]),
default=None,
)
return ts_to_date(most_recent) if most_recent else None
### Archive Status Helpers ### Archive Status Helpers
@property @property
def num_outputs(self) -> int: def num_outputs(self) -> int:
return len(tuple(filter(None, self.latest_outputs().values()))) return len(tuple(filter(None, self.latest_outputs().values())))
@property
def num_failures(self) -> int:
return sum(1
for method in self.history.keys()
for result in self.history[method]
if result.status == 'failed')
@property @property
def is_static(self) -> bool: def is_static(self) -> bool:
from util import is_static_file from util import is_static_file

View file

@ -13,51 +13,64 @@
padding: 0px; padding: 0px;
font-family: "Gill Sans", Helvetica, sans-serif; font-family: "Gill Sans", Helvetica, sans-serif;
} }
header { .header-top small {
background-color: #aa1e55; font-weight: 200;
color: #1a1a1a; color: #efefef;
padding: 10px;
padding-top: 0px;
padding-bottom: 15px;
/*height: 40px;*/
} }
header h1 {
margin: 7px 0px; .header-top {
font-size: 35px; width: 100%;
font-weight: 300; height: auto;
color: #1a1a1a; min-height: 40px;
} margin: 0px;
header h1 img {
height: 44px;
vertical-align: bottom;
}
header a {
text-decoration: none !important;
color: #1a1a1a;
}
.header-center {
margin: auto;
float: none;
text-align: center; text-align: center;
padding-top: 6px; color: white;
font-size: calc(11px + 0.86vw);
font-weight: 200;
padding: 4px 4px;
border-bottom: 3px solid #aa1e55;
background-color: #aa1e55;
} }
.header-center small { input[type=search] {
color: #eaeaea; width: 22vw;
opacity: 0.7; border-radius: 4px;
border: 1px solid #aeaeae;
padding: 3px 5px;
} }
.header-left { .nav > div {
float: left; min-height: 30px;
} }
.header-right { .header-top a {
float: right; text-decoration: none;
padding-top: 17px; color: rgba(0,0,0,0.6);
padding-right: 10px;
} }
header + div { .header-top a:hover {
margin-top: 10px; text-decoration: none;
color: rgba(0,0,0,0.9);
} }
.header-top .col-lg-4 {
text-align: center;
padding-top: 4px;
padding-bottom: 4px;
}
.header-archivebox img {
display: inline-block;
margin-right: 3px;
height: 30px;
margin-left: 12px;
margin-top: -4px;
margin-bottom: 2px;
}
.header-archivebox img:hover {
opacity: 0.5;
}
#table-bookmarks_length, #table-bookmarks_filter { #table-bookmarks_length, #table-bookmarks_filter {
padding: 0px 15px; padding-top: 12px;
opacity: 0.8;
padding-left: 24px;
padding-right: 22px;
margin-bottom: -16px;
} }
table { table {
padding: 6px; padding: 6px;
@ -98,6 +111,9 @@
overflow-y: scroll; overflow-y: scroll;
table-layout: fixed; table-layout: fixed;
} }
.dataTables_wrapper {
background-color: #fafafa;
}
table tr a span[data-archived~=False] { table tr a span[data-archived~=False] {
opacity: 0.4; opacity: 0.4;
} }
@ -131,7 +147,11 @@
border-radius: 4px; border-radius: 4px;
float:right float:right
} }
input[type=search]::-webkit-search-cancel-button {
-webkit-appearance: searchfield-cancel-button;
}
</style> </style>
<link rel="stylesheet" href="static/bootstrap.min.css">
<link rel="stylesheet" href="static/jquery.dataTables.min.css"/> <link rel="stylesheet" href="static/jquery.dataTables.min.css"/>
<script src="static/jquery.min.js"></script> <script src="static/jquery.min.js"></script>
<script src="static/jquery.dataTables.min.js"></script> <script src="static/jquery.dataTables.min.js"></script>
@ -151,21 +171,20 @@
</head> </head>
<body data-status="$status"> <body data-status="$status">
<header> <header>
<div class="header-right"> <div class="header-top container-fluid">
<a href="https://github.com/pirate/ArchiveBox/wiki">Documentation</a> &nbsp; | &nbsp; <div class="row nav">
<a href="https://github.com/pirate/ArchiveBox">Source</a> &nbsp; | &nbsp; <div class="col-lg-6">
<a href="https://archivebox.io">Website</a> <a href="?" class="header-archivebox" title="Last updated: $time_updated">
</div> <img src="static/archive.png" alt="Logo"/>
<div class="header-left"> ArchiveBox: Index
<a href="?" title="Reload..."> </a>
<h1><img src="static/archive.png"/> ArchiveBox: Index</h1> </div>
</a> <div class="col-lg-6">
</div> <a href="https://github.com/pirate/ArchiveBox/wiki">Documentation</a> &nbsp; | &nbsp;
<div class="header-center"> <a href="https://github.com/pirate/ArchiveBox">Source</a> &nbsp; | &nbsp;
Archived Sites <a href="https://archivebox.io">Website</a>
<!--<span class="in-progress">(Currently Updating)</span>--> </div>
<br/> </div>
<small>Last updated $time_updated</small>
</div> </div>
</header> </header>
<table id="table-bookmarks"> <table id="table-bookmarks">

View file

@ -4,7 +4,7 @@
<a href="$archive_path/$index_url"><img src="$favicon_url" class="link-favicon" decoding="async"></a> <a href="$archive_path/$index_url"><img src="$favicon_url" class="link-favicon" decoding="async"></a>
<a href="$archive_path/$archive_url" title="$title"> <a href="$archive_path/$archive_url" title="$title">
<span data-title-for="$url" data-archived="$is_archived">$title</span> <span data-title-for="$url" data-archived="$is_archived">$title</span>
<small>$tags</small> <small style="float:right">$tags</small>
</a> </a>
</td> </td>
<td> <td>

View file

@ -6,69 +6,72 @@
html, body { html, body {
width: 100%; width: 100%;
height: 100%; height: 100%;
}
body {
background-color: #ddd; background-color: #ddd;
} }
header { header {
width: 100%;
height: 90px;
background-color: #aa1e55; background-color: #aa1e55;
padding-bottom: 12px;
}
small {
font-weight: 200;
}
.header-top {
width: 100%;
height: auto;
min-height: 40px;
margin: 0px; margin: 0px;
text-align: center; text-align: center;
color: white; color: white;
} font-size: calc(11px + 0.86vw);
header h1 {
padding-top: 5px;
padding-bottom: 5px;
margin: 0px;
font-weight: 200; font-weight: 200;
font-family: "Gill Sans", Helvetica, sans-serif; padding: 4px 4px;
font-size: calc(16px + 1vw); background-color: #aa1e55;
} }
.collapse-icon { .nav > div {
float: right; min-height: 30px;
color: black; margin: 8px 0px;
width: 126px;
font-size: 0.8em;
margin-top: 20px;
margin-right: 0px;
margin-left: -35px;
} }
.nav-icon img { .header-top a {
float: left; text-decoration: none;
display: block; color: rgba(0,0,0,0.6);
margin-right: 13px;
color: black;
height: 53px;
margin-top: 12px;
margin-left: 10px;
} }
.nav-icon img:hover { .header-top a:hover {
text-decoration: none;
color: rgba(0,0,0,0.9);
}
.header-top .col-lg-4 {
text-align: center;
padding-top: 4px;
padding-bottom: 4px;
}
.header-archivebox img {
display: inline-block;
margin-right: 3px;
height: 30px;
margin-left: 12px;
margin-top: -4px;
margin-bottom: 2px;
}
.header-archivebox img:hover {
opacity: 0.5; opacity: 0.5;
} }
.title-url { .header-url small {
color: black;
display: block;
width: 75%;
white-space: nowrap; white-space: nowrap;
overflow: hidden; font-weight: 200;
margin: auto;
} }
.archive-page-header { .header-url img {
margin-top: 5px; height: 20px;
vertical-align: -2px;
margin-right: 4px;
}
.info-row {
margin-top: 2px;
margin-bottom: 5px; margin-bottom: 5px;
} }
.archive-page-header .alert { .info-row .alert {
margin-bottom: 0px; margin-bottom: 0px;
} }
h1 small {
opacity: 0.4;
font-size: 0.6em;
}
h1 small:hover {
opacity: 0.8;
}
.card { .card {
overflow: hidden; overflow: hidden;
box-shadow: 2px 3px 14px 0px rgba(0,0,0,0.02); box-shadow: 2px 3px 14px 0px rgba(0,0,0,0.02);
@ -87,18 +90,24 @@
max-height: 102px; max-height: 102px;
overflow: hidden; overflow: hidden;
} }
.card-title {
margin-bottom: 4px;
}
.card-img-top { .card-img-top {
border: 0px; border: 0px;
padding: 0px; padding: 0px;
margin: 0px; margin: 0px;
overflow: hidden; overflow: hidden;
opacity: 0.8; opacity: 0.8;
border-top: 1px solid gray; border-top: 1px solid rgba(0,0,0,0);
border-radius: 3px; border-radius: 4px;
border-bottom: 1px solid #ddd; border-bottom: 1px solid rgba(0,0,0,0);
height: 430px; height: 430px;
width: 400%; width: 405%;
margin-bottom: -330px; margin-bottom: -330px;
background-color: #333;
margin-left: -1%;
margin-right: -1%;
transform: scale(0.25); transform: scale(0.25);
transform-origin: 0 0; transform-origin: 0 0;
@ -116,8 +125,7 @@
box-shadow: 0px -6px 13px 1px rgba(0,0,0,0.05); box-shadow: 0px -6px 13px 1px rgba(0,0,0,0.05);
} }
.iframe-large { .iframe-large {
height: 93%; height: calc(100% - 40px);
margin-top: -10px;
} }
.pdf-frame { .pdf-frame {
transform: none; transform: none;
@ -125,6 +133,9 @@
height: 160px; height: 160px;
margin-top: -60px; margin-top: -60px;
margin-bottom: 0px; margin-bottom: 0px;
transform: scale(1.1);
width: 100%;
margin-left: -10%;
} }
img.external { img.external {
height: 30px; height: 30px;
@ -138,13 +149,61 @@
border: 4px solid green; border: 4px solid green;
} }
.screenshot { .screenshot {
background-color: #333;
transform: none; transform: none;
width: 100%; width: 100%;
height: auto; min-height: 100px;
max-height: 100px; max-height: 100px;
margin-bottom: 0px; margin-bottom: 0px;
object-fit: cover; object-fit: cover;
object-position: top; object-position: top center;
}
.header-bottom {
border-top: 1px solid rgba(170, 30, 85, 0.9);
padding-bottom: 12px;
border-bottom: 5px solid rgb(170, 30, 85);
margin-bottom: -1px;
border-radius: 4px;
background-color: rgba(23, 22, 22, 0.88);
width: 98%;
border: 1px solid rgba(0,0,0,0.2);
box-shadow: 4px 4px 4px rgba(0,0,0,0.2);
margin-top: 5px;
}
.header-bottom-info {
color: #6f6f6f;
padding-top: 8px;
padding-bottom: 13px;
}
.header-bottom-info > div {
text-align: center;
}
.header-bottom-info h5 {
font-size: 1.1em;
font-weight: 200;
margin-top: 3px;
margin-bottom: 3px;
color: rgba(255, 255, 255, 0.74);
}
.info-chunk {
width: auto;
display:inline-block;
text-align: center;
margin: 10px 10px;
vertical-align: top;
}
.info-chunk .badge {
margin-top: 5px;
}
.header-bottom-frames .card-title {
padding-bottom: 0px;
font-size: 1.2vw;
margin-bottom: 5px;
}
.header-bottom-frames .card-text {
font-size: 0.9em;
} }
@media(max-width: 1092px) { @media(max-width: 1092px) {
@ -164,131 +223,170 @@
.card { .card {
margin-bottom: 5px; margin-bottom: 5px;
} }
header > h1 > a.collapse-icon, header > h1 > a.nav-icon { header > h1 > a.header-url, header > h1 > a.header-archivebox {
display: none; display: none;
} }
} }
</style> </style>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/css/bootstrap.min.css" integrity="sha384-rwoIResjU2yc3z8GV/NPeZWAv56rSmLldC3R/AZzGRnGxQQKnKkoFVhFQhNUwEyJ" crossorigin="anonymous"> <link rel="stylesheet" href="../../static/bootstrap.min.css">
</head> </head>
<body> <body>
<header> <header>
<h1 class="page-title"> <div class="header-top container-fluid">
<a href="../../index.html" class="nav-icon" title="Go to Main Index..."> <div class="row nav">
<img src="../../static/archive.png" alt="Archive Icon"> <div class="col-lg-6">
</a> <a href="../../index.html" class="header-archivebox" title="Go to Main Index...">
<a href="#" class="collapse-icon" style="text-decoration: none" title="Toggle info panel..."> <img src="../../static/archive.png" alt="Archive Icon">
ArchiveBox:
</a>
<img src="$favicon_url" height="20px"> $title<br/>
<a href="$url" class="title-url">
<small>$base_url</small>
</a>
</h1>
</header>
<div class="site-header container-fluid">
<div class="row archive-page-header">
<div class="col-lg-4 alert well">
Bookmarked: <small title="Timestamp: $timestamp">$bookmarked_date</small>
&nbsp; | &nbsp;
Last updated: <small title="Timestamp: $updated">$updated_date</small>
&nbsp; | &nbsp;
Total files: <small title="Archive methods">🗃 $num_outputs</small>
</div>
<div class="col-lg-4 alert well">
Type:
<span class="badge badge-default">$extension</span>
&nbsp; | &nbsp;
Tags:
<span class="badge badge-warning">$tags</span>
&nbsp; | &nbsp;
Status:
<span class="badge badge-$status_color">$status</span>
</div>
<div class="col-lg-4 alert well">
Archive Methods:
<a href="index.json" title="JSON summary of archived link.">JSON</a> |
<a href="warc/" title="Any WARC archives for the page">WARC</a> |
<a href="media/" title="Audio, Video, and Subtitle files.">Media</a> |
<a href="git/" title="Any git repos at the url">Git Repos</a> |
<a href="favicon.ico" title="Any git repos at the url">Favicon</a> |
<a href="." title="Webserver-provided index of files directory.">See all files...</a>
</div>
<hr/>
<div class="col-lg-2">
<div class="card selected-card">
<iframe class="card-img-top" src="$archive_url" sandbox="allow-same-origin allow-scripts allow-forms" scrolling="no"></iframe>
<div class="card-body">
<a href="$archive_url" style="float:right" title="Open in new tab..." target="_blank" rel="noopener">
<img src="../../static/external.png" class="external"/>
</a> </a>
<a href="$archive_url" target="preview"><h4 class="card-title">Local Archive</h4></a> <a href="#">Page Details</a><br/>
<p class="card-text">archive/$domain</p> <small style="margin-top: 5px; display: block">
</div> <a href="../../index.html">Home</a> &nbsp; | &nbsp;
<a href="https://github.com/pirate/ArchiveBox">Github</a> &nbsp; | &nbsp;
<a href="https://github.com/pirate/ArchiveBox/wiki">Documentation</a>
</small>
</div> </div>
</div> <div class="col-lg-6">
<div class="col-lg-2"> <img src="$link_dir/$favicon_url" alt="Favicon">
<div class="card"> &nbsp; &nbsp;
<iframe class="card-img-top" src="$dom_url" sandbox="allow-same-origin allow-scripts allow-forms" scrolling="no"></iframe> $title
<div class="card-body"> &nbsp; &nbsp;
<a href="$dom_url" style="float:right" title="Open in new tab..." target="_blank" rel="noopener"> <small>
<img src="../../static/external.png" class="external"/> <a href="$url" title="Toggle info panel..." class="header-url" title="$url">
</a> $base_url
<a href="$dom_url" target="preview"><h4 class="card-title">HTML</h4></a> </a>
<p class="card-text">archive/output.html</p> </small>
</div> &nbsp; &nbsp;
</div> <a href="#" class="header-toggle"></a>
</div>
<div class="col-lg-2">
<div class="card">
<iframe class="card-img-top pdf-frame" src="$pdf_url" scrolling="no"></iframe>
<div class="card-body">
<a href="$pdf_url" style="float:right" title="Open in new tab..." target="_blank" rel="noopener">
<img src="../../static/external.png" class="external"/>
</a>
<a href="$pdf_url" target="preview" id="pdf-btn"><h4 class="card-title">PDF</h4></a>
<p class="card-text">archive/output.pdf</p>
</div>
</div>
</div>
<div class="col-lg-2">
<div class="card">
<img class="card-img-top screenshot" src="$screenshot_url"></iframe>
<div class="card-body">
<a href="$screenshot_url" style="float:right" title="Open in new tab..." target="_blank" rel="noopener">
<img src="../../static/external.png" class="external"/>
</a>
<a href="$screenshot_url" target="preview"><h4 class="card-title">Screenshot</h4></a>
<p class="card-text">archive/screenshot.png</p>
</div>
</div>
</div>
<div class="col-lg-2">
<div class="card">
<iframe class="card-img-top" src="$url" sandbox="allow-same-origin allow-scripts allow-forms" scrolling="no"></iframe>
<div class="card-body">
<a href="$url" style="float:right" title="Open in new tab..." target="_blank" rel="noopener">
<img src="../../static/external.png" class="external"/>
</a>
<a href="$url" target="preview"><h4 class="card-title">Original</h4></a>
<p class="card-text">$domain</p>
</div>
</div>
</div>
<div class="col-lg-2">
<div class="card">
<iframe class="card-img-top" src="$archive_org_url" sandbox="allow-same-origin allow-scripts allow-forms" scrolling="no"></iframe>
<div class="card-body">
<a href="$archive_org_url" style="float:right" title="Open in new tab..." target="_blank" rel="noopener">
<img src="../../static/external.png" class="external"/>
</a>
<a href="$archive_org_url" target="preview"><h4 class="card-title">Archive.Org</h4></a>
<p class="card-text">web.archive.org/web/...</p>
</div>
</div> </div>
</div> </div>
</div> </div>
</div> <div class="header-bottom container-fluid">
<div class="row header-bottom-info">
<div class="col-lg-4">
<div title="Date bookmarked or imported" class="info-chunk">
<h5>Added</h5>
$bookmarked_date
</div>
<div title="Date first archived" class="info-chunk">
<h5>First Archived</h5>
$oldest_archive_date
</div>
<div title="Date last checked" class="info-chunk">
<h5>Last Checked</h5>
$updated_date
</div>
</div>
<div class="col-lg-4">
<div class="info-chunk">
<h5>Type</h5>
<div class="badge badge-default">$extension</div>
</div>
<div class="info-chunk">
<h5>Tags</h5>
<div class="badge badge-warning">$tags</div>
</div>
<div class="info-chunk">
<h5>Status</h5>
<div class="badge badge-$status_color">$status</div>
</div>
<div class="info-chunk">
<h5>Saved</h5>
✅ $num_outputs
</div>
<div class="info-chunk">
<h5>Errors</h5>
❌ $num_failures
</div>
</div>
<div class="col-lg-4">
<div class="info-chunk">
<h5>🗃 Files</h5>
<a href="index.json" title="JSON summary of archived link.">JSON</a> |
<a href="warc/" title="Any WARC archives for the page">WARC</a> |
<a href="media/" title="Audio, Video, and Subtitle files.">Media</a> |
<a href="git/" title="Any git repos at the url">Git</a> |
<a href="favicon.ico" title="Any git repos at the url">Favicon</a> |
<a href="." title="Webserver-provided index of files directory.">See all...</a>
</div>
</div>
</div>
<div class="row header-bottom-frames">
<div class="col-lg-2">
<div class="card selected-card">
<iframe class="card-img-top" src="$archive_url" sandbox="allow-same-origin allow-scripts allow-forms" scrolling="no"></iframe>
<div class="card-body">
<a href="$archive_url" style="float:right" title="Open in new tab..." target="_blank" rel="noopener">
<img src="../../static/external.png" class="external"/>
</a>
<a href="$archive_url" target="preview"><h4 class="card-title">Local Archive</h4></a>
<p class="card-text">archive/$domain</p>
</div>
</div>
</div>
<div class="col-lg-2">
<div class="card">
<iframe class="card-img-top" src="$dom_url" sandbox="allow-same-origin allow-scripts allow-forms" scrolling="no"></iframe>
<div class="card-body">
<a href="$dom_url" style="float:right" title="Open in new tab..." target="_blank" rel="noopener">
<img src="../../static/external.png" class="external"/>
</a>
<a href="$dom_url" target="preview"><h4 class="card-title">HTML</h4></a>
<p class="card-text">archive/output.html</p>
</div>
</div>
</div>
<div class="col-lg-2">
<div class="card">
<iframe class="card-img-top pdf-frame" src="$pdf_url" scrolling="no"></iframe>
<div class="card-body">
<a href="$pdf_url" style="float:right" title="Open in new tab..." target="_blank" rel="noopener">
<img src="../../static/external.png" class="external"/>
</a>
<a href="$pdf_url" target="preview" id="pdf-btn"><h4 class="card-title">PDF</h4></a>
<p class="card-text">archive/output.pdf</p>
</div>
</div>
</div>
<div class="col-lg-2">
<div class="card">
<img class="card-img-top screenshot" src="$screenshot_url"></iframe>
<div class="card-body">
<a href="$screenshot_url" style="float:right" title="Open in new tab..." target="_blank" rel="noopener">
<img src="../../static/external.png" class="external"/>
</a>
<a href="$screenshot_url" target="preview"><h4 class="card-title">Screenshot</h4></a>
<p class="card-text">archive/screenshot.png</p>
</div>
</div>
</div>
<div class="col-lg-2">
<div class="card">
<iframe class="card-img-top" src="$url" sandbox="allow-same-origin allow-scripts allow-forms" scrolling="no"></iframe>
<div class="card-body">
<a href="$url" style="float:right" title="Open in new tab..." target="_blank" rel="noopener">
<img src="../../static/external.png" class="external"/>
</a>
<a href="$url" target="preview"><h4 class="card-title">Original</h4></a>
<p class="card-text">$domain</p>
</div>
</div>
</div>
<div class="col-lg-2">
<div class="card">
<iframe class="card-img-top" src="$archive_org_url" sandbox="allow-same-origin allow-scripts allow-forms" scrolling="no"></iframe>
<div class="card-body">
<a href="$archive_org_url" style="float:right" title="Open in new tab..." target="_blank" rel="noopener">
<img src="../../static/external.png" class="external"/>
</a>
<a href="$archive_org_url" target="preview"><h4 class="card-title">Archive.Org</h4></a>
<p class="card-text">web.archive.org/web/...</p>
</div>
</div>
</div>
</div>
</div>
</header>
<iframe sandbox="allow-same-origin allow-scripts allow-forms" class="full-page-iframe" src="$archive_url" name="preview"></iframe> <iframe sandbox="allow-same-origin allow-scripts allow-forms" class="full-page-iframe" src="$archive_url" name="preview"></iframe>
<script <script
@ -321,14 +419,14 @@
}) })
// hide header when collapse icon is clicked // hide header when collapse icon is clicked
jQuery('.collapse-icon').on('click', function() { jQuery('.header-toggle').on('click', function() {
if (jQuery('.collapse-icon').text().includes('▾')) { if (jQuery('.header-toggle').text().includes('▾')) {
jQuery('.collapse-icon').text('▸') jQuery('.header-toggle').text('▸')
jQuery('.site-header').hide() jQuery('.header-bottom').hide()
jQuery('.full-page-iframe').addClass('iframe-large') jQuery('.full-page-iframe').addClass('iframe-large')
} else { } else {
jQuery('.collapse-icon').text('▾') jQuery('.header-toggle').text('▾')
jQuery('.site-header').show() jQuery('.header-bottom').show()
jQuery('.full-page-iframe').removeClass('iframe-large') jQuery('.full-page-iframe').removeClass('iframe-large')
} }
return true return true

File diff suppressed because one or more lines are too long

View file

@ -528,10 +528,10 @@ class TimedProgress:
# return # return
if self.p is not None: if self.p is not None:
self.p.terminate() self.p.terminate()
self.p = None self.p = None
sys.stdout.write('\r{}{}\r'.format((' ' * TERM_WIDTH()), ANSI['reset'])) # clear whole terminal line sys.stdout.write('\r{}{}\r'.format((' ' * TERM_WIDTH()), ANSI['reset'])) # clear whole terminal line
sys.stdout.flush()
@enforce_types @enforce_types