Explorar o código

new details page design

Nick Sweeting %!s(int64=6) %!d(string=hai) anos
pai
achega
2ed91fe429

+ 28 - 20
archivebox/archive_methods.py

@@ -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:
-                link.history[method_name] = []
-            
-            if should_run(link.link_dir, link):
-                log_archive_method_started(method_name)
-
-                result = method_function(link.link_dir, link)
-
-                link.history[method_name].append(result)
-
-                stats[result.status] += 1
-                log_archive_method_finished(result)
-            else:
-                stats['skipped'] += 1
+            try:
+                if method_name not in link.history:
+                    link.history[method_name] = []
+                
+                if should_run(link.link_dir, link):
+                    log_archive_method_started(method_name)
+
+                    result = method_function(link.link_dir, link)
+
+                    link.history[method_name].append(result)
+
+                    stats[result.status] += 1
+                    log_archive_method_finished(result)
+                else:
+                    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(**{
-            **link._asdict(),
-            'updated': datetime.now(),
-        })
-
+        # If any changes were made, update the link index json and html
         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:

+ 7 - 8
archivebox/index.py

@@ -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(**{
-                **saved_link._asdict(),
-                'title': title,
-                'history': link.history,
-                'updated': link.updated,
-            }))
+            patched_links.append(saved_link.overwrite(
+                title=title,
+                history=link.history,
+                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',
         }))
         }))
 
 

+ 1 - 1
archivebox/logs.py

@@ -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,

+ 38 - 0
archivebox/schema.py

@@ -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

+ 72 - 53
archivebox/templates/index.html

@@ -13,51 +13,64 @@
                 padding: 0px;
                 padding: 0px;
                 font-family: "Gill Sans", Helvetica, sans-serif;
                 font-family: "Gill Sans", Helvetica, sans-serif;
             }
             }
-            header {
-                background-color: #aa1e55;
-                color: #1a1a1a;
-                padding: 10px;
-                padding-top: 0px;
-                padding-bottom: 15px;
-                /*height: 40px;*/
-            }
-            header h1 {
-                margin: 7px 0px;
-                font-size: 35px;
-                font-weight: 300;
-                color: #1a1a1a;
-            }
-            header h1 img {
-                height: 44px;
-                vertical-align: bottom;
-            }
-            header a {
-                text-decoration: none !important;
-                color: #1a1a1a;
-            }
-            .header-center {
-                margin: auto;
-                float: none;
+            .header-top small {
+                font-weight: 200;
+                color: #efefef;
+            }
+            
+            .header-top {
+                width: 100%;
+                height: auto;
+                min-height: 40px;
+                margin: 0px;
                 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 {
-                color: #eaeaea;
-                opacity: 0.7;
+            input[type=search] {
+                width: 22vw;
+                border-radius: 4px;
+                border: 1px solid #aeaeae;
+                padding: 3px 5px;
             }
             }
-            .header-left {
-                float: left;
+            .nav > div {
+                min-height: 30px;
             }
             }
-            .header-right {
-                float: right;
-                padding-top: 17px;
-                padding-right: 10px;
+            .header-top a {
+                text-decoration: none;
+                color: rgba(0,0,0,0.6);
             }
             }
-            header + div {
-                margin-top: 10px;
+            .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;
+            }
+
             #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">
-                <a href="https://github.com/pirate/ArchiveBox/wiki">Documentation</a> &nbsp; | &nbsp; 
-                <a href="https://github.com/pirate/ArchiveBox">Source</a> &nbsp; | &nbsp; 
-                <a href="https://archivebox.io">Website</a>
-            </div>
-            <div class="header-left">
-                <a href="?" title="Reload...">
-                    <h1><img src="static/archive.png"/> ArchiveBox: Index</h1>
-                </a>
-            </div>
-            <div class="header-center">
-                Archived Sites
-                <!--<span class="in-progress">(Currently Updating)</span>-->
-                <br/>
-                <small>Last updated $time_updated</small>
+            <div class="header-top container-fluid">
+                <div class="row nav">
+                    <div class="col-lg-6">
+                        <a href="?" class="header-archivebox" title="Last updated: $time_updated">
+                            <img src="static/archive.png" alt="Logo"/>
+                            ArchiveBox: Index
+                        </a>
+                    </div>
+                    <div class="col-lg-6">
+                        <a href="https://github.com/pirate/ArchiveBox/wiki">Documentation</a> &nbsp; | &nbsp; 
+                        <a href="https://github.com/pirate/ArchiveBox">Source</a> &nbsp; | &nbsp; 
+                        <a href="https://archivebox.io">Website</a>
+                    </div>
+                </div>
             </div>
             </div>
         </header>
         </header>
         <table id="table-bookmarks">
         <table id="table-bookmarks">

+ 1 - 1
archivebox/templates/index_row.html

@@ -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>

+ 266 - 168
archivebox/templates/link_index.html

@@ -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;
-            }
-            header h1 {
-                padding-top: 5px;
-                padding-bottom: 5px;
-                margin: 0px;
+                font-size: calc(11px + 0.86vw);
                 font-weight: 200;
                 font-weight: 200;
-                font-family: "Gill Sans", Helvetica, sans-serif;
-                font-size: calc(16px + 1vw);
-            }
-            .collapse-icon {
-                float: right;
-                color: black;
-                width: 126px;
-                font-size: 0.8em;
-                margin-top: 20px;
-                margin-right: 0px;
-                margin-left: -35px;
-            }
-            .nav-icon img {
-                float: left;
-                display: block;
-                margin-right: 13px;
-                color: black;
-                height: 53px;
-                margin-top: 12px;
-                margin-left: 10px;
-            }
-            .nav-icon img:hover {
+                padding: 4px 4px;
+                background-color: #aa1e55;
+            }
+            .nav > div {
+                min-height: 30px;
+                margin: 8px 0px;
+            }
+            .header-top a {
+                text-decoration: none;
+                color: rgba(0,0,0,0.6);
+            }
+            .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 {
-                color: black;
-                display: block;
-                width: 75%;
+            .header-url small {
                 white-space: nowrap;
                 white-space: nowrap;
-                overflow: hidden;
-                margin: auto;
+                font-weight: 200;
             }
             }
-            .archive-page-header {
-                margin-top: 5px;
+            .header-url img {
+                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-radius: 3px;
-                border-bottom: 1px solid #ddd;
+                border-top: 1px solid rgba(0,0,0,0);
+                border-radius: 4px;
+                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%;
-                margin-top: -10px;
+                height: calc(100% - 40px);
             }
             }
             .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">
-                <a href="../../index.html" class="nav-icon" title="Go to Main Index...">
-                    <img src="../../static/archive.png" alt="Archive Icon">
-                </a>
-                <a href="#" class="collapse-icon" style="text-decoration: none" title="Toggle info panel...">
-                    ▾
-                </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"/>
+            <div class="header-top container-fluid">
+                <div class="row nav">
+                    <div class="col-lg-6">
+                        <a href="../../index.html" class="header-archivebox" title="Go to Main Index...">
+                            <img src="../../static/archive.png" alt="Archive Icon">
+                            ArchiveBox:
                         </a>
                         </a>
-                        <a href="$archive_url" target="preview"><h4 class="card-title">Local Archive</h4></a>
-                        <p class="card-text">archive/$domain</p>
-                      </div>
+                        <a href="#">Page Details</a><br/>
+                        <small style="margin-top: 5px; display: block">
+                            <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-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 class="col-lg-6">
+                        <img src="$link_dir/$favicon_url" alt="Favicon">
+                        &nbsp; &nbsp;
+                        $title
+                        &nbsp; &nbsp;
+                        <small>
+                            <a href="$url" title="Toggle info panel..." class="header-url" title="$url">
+                                $base_url
+                            </a>
+                        </small>
+                        &nbsp; &nbsp;
+                        <a href="#" class="header-toggle">▾</a>
                     </div>
                     </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 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>
-                </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 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>
-                </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 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>
                 </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 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>
                 </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() {
-                if (jQuery('.collapse-icon').text().includes('▾')) {
-                    jQuery('.collapse-icon').text('▸')
-                    jQuery('.site-header').hide()
+            jQuery('.header-toggle').on('click', function() {
+                if (jQuery('.header-toggle').text().includes('▾')) {
+                    jQuery('.header-toggle').text('▸')
+                    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('.site-header').show()
+                    jQuery('.header-toggle').text('▾')
+                    jQuery('.header-bottom').show()
                     jQuery('.full-page-iframe').removeClass('iframe-large')
                     jQuery('.full-page-iframe').removeClass('iframe-large')
                 }
                 }
                 return true
                 return true

A diferenza do arquivo foi suprimida porque é demasiado grande
+ 5 - 0
archivebox/templates/static/bootstrap.min.css


+ 1 - 1
archivebox/util.py

@@ -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

Algúns arquivos non se mostraron porque demasiados arquivos cambiaron neste cambio