mirror of
https://github.com/ArchiveBox/ArchiveBox.git
synced 2025-05-13 14:44:29 -04:00
new details page design
This commit is contained in:
parent
c9c5b04df0
commit
2ed91fe429
9 changed files with 419 additions and 251 deletions
|
@ -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:
|
||||||
|
|
|
@ -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',
|
||||||
}))
|
}))
|
||||||
|
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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> |
|
<div class="row nav">
|
||||||
<a href="https://github.com/pirate/ArchiveBox">Source</a> |
|
<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> |
|
||||||
<div class="header-center">
|
<a href="https://github.com/pirate/ArchiveBox">Source</a> |
|
||||||
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">
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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>
|
|
||||||
|
|
|
||||||
Last updated: <small title="Timestamp: $updated">$updated_date</small>
|
|
||||||
|
|
|
||||||
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>
|
|
||||||
|
|
|
||||||
Tags:
|
|
||||||
<span class="badge badge-warning">$tags</span>
|
|
||||||
|
|
|
||||||
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> |
|
||||||
|
<a href="https://github.com/pirate/ArchiveBox">Github</a> |
|
||||||
|
<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">
|
|
||||||
<iframe class="card-img-top" src="$dom_url" sandbox="allow-same-origin allow-scripts allow-forms" scrolling="no"></iframe>
|
$title
|
||||||
<div class="card-body">
|
|
||||||
<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>
|
|
||||||
</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
|
||||||
|
|
6
archivebox/templates/static/bootstrap.min.css
vendored
Normal file
6
archivebox/templates/static/bootstrap.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
|
@ -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
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue