ArchiveBox/archivebox/archive.py

137 lines
4.3 KiB
Python
Raw Normal View History

2017-05-05 09:00:30 +00:00
#!/usr/bin/env python3
2019-03-21 05:28:12 +00:00
"""
ArchiveBox command line application.
2017-05-05 09:00:30 +00:00
2019-03-21 05:28:12 +00:00
./archive and ./bin/archivebox both point to this file,
but you can also run it directly using `python3 archive.py`
2019-03-21 05:28:12 +00:00
Usage & Documentation:
https://github.com/pirate/ArchiveBox/Wiki
"""
2019-03-21 05:28:12 +00:00
import os
import sys
2019-03-21 05:28:12 +00:00
from links import links_after_timestamp
from index import write_links_index, load_links_index
from archive_methods import archive_link
from config import (
ARCHIVE_DIR,
ONLY_NEW,
OUTPUT_DIR,
2018-06-11 02:02:33 +00:00
GIT_SHA,
)
from util import (
2019-02-27 09:48:38 +00:00
save_remote_source,
2019-02-21 22:54:44 +00:00
save_stdin_source,
2019-03-21 05:28:12 +00:00
)
from logs import (
log_archiving_started,
log_archiving_paused,
log_archiving_finished,
)
2017-06-15 22:33:01 +00:00
2018-06-11 02:02:33 +00:00
__AUTHOR__ = 'Nick Sweeting <git@nicksweeting.com>'
__VERSION__ = GIT_SHA[:9]
2019-03-21 05:28:12 +00:00
__DESCRIPTION__ = 'ArchiveBox: The self-hosted internet archive.'
2019-01-14 23:11:48 +00:00
__DOCUMENTATION__ = 'https://github.com/pirate/ArchiveBox/wiki'
2017-05-05 11:27:05 +00:00
2017-10-30 11:09:33 +00:00
def print_help():
2019-03-21 05:28:12 +00:00
print('ArchiveBox: The self-hosted internet archive.\n')
print("Documentation:")
print(" https://github.com/pirate/ArchiveBox/wiki\n")
print("UI Usage:")
print(" Open output/index.html to view your archive.\n")
print("CLI Usage:")
print(" echo 'https://example.com' | ./archive\n")
print(" ./archive ~/Downloads/bookmarks_export.html\n")
print(" ./archive https://example.com/feed.rss\n")
print(" ./archive 15109948213.123\n")
2017-06-30 08:23:19 +00:00
2017-10-30 11:09:33 +00:00
2019-03-21 05:28:12 +00:00
def main(*args):
if set(args).intersection(('-h', '--help', 'help')) or len(args) > 2:
print_help()
raise SystemExit(0)
if set(args).intersection(('--version', 'version')):
print('ArchiveBox version {}'.format(__VERSION__))
raise SystemExit(0)
2019-03-21 05:28:12 +00:00
### Handle CLI arguments
# ./archive bookmarks.html
# ./archive 1523422111.234
import_path, resume = None, None
if len(args) == 2:
# if the argument is a string, it's a import_path file to import
# if it's a number, it's a timestamp to resume archiving from
if args[1].replace('.', '').isdigit():
import_path, resume = None, args[1]
else:
import_path, resume = args[1], None
2017-10-30 11:09:33 +00:00
2019-03-21 05:28:12 +00:00
### Set up output folder
if not os.path.exists(OUTPUT_DIR):
os.makedirs(OUTPUT_DIR)
2019-03-21 05:28:12 +00:00
### Handle ingesting urls piped in through stdin
# (.e.g if user does cat example_urls.txt | ./archive)
if not sys.stdin.isatty():
stdin_raw_text = sys.stdin.read()
if stdin_raw_text and import_path:
print(
'[X] You should pass either a path as an argument, '
'or pass a list of links via stdin, but not both.\n'
)
print_help()
raise SystemExit(1)
2017-10-30 11:09:33 +00:00
2019-03-21 05:28:12 +00:00
import_path = save_stdin_source(stdin_raw_text)
2017-10-30 11:09:33 +00:00
2019-03-21 05:28:12 +00:00
### Handle ingesting urls from a remote file/feed
# (e.g. if an RSS feed URL is used as the import path)
if import_path and any(import_path.startswith(s) for s in ('http://', 'https://', 'ftp://')):
import_path = save_remote_source(import_path)
2019-03-21 05:28:12 +00:00
### Run the main archive update process
update_archive_data(import_path=import_path, resume=resume)
2017-06-30 08:23:19 +00:00
2019-03-21 05:28:12 +00:00
def update_archive_data(import_path=None, resume=None):
2019-03-22 19:09:39 +00:00
"""The main ArchiveBox entrancepoint. Everything starts here."""
2018-04-17 11:30:06 +00:00
2019-03-21 05:28:12 +00:00
# Step 1: Load list of links from the existing index
# merge in and dedupe new links from import_path
all_links, new_links = load_links_index(out_dir=OUTPUT_DIR, import_path=import_path)
2019-03-21 05:28:12 +00:00
# Step 2: Write updated index with deduped old and new links back to disk
write_links_index(out_dir=OUTPUT_DIR, links=all_links)
2019-03-21 05:28:12 +00:00
# Step 3: Run the archive methods for each link
links = new_links if ONLY_NEW else all_links
log_archiving_started(len(links), resume)
idx, link = 0, 0
try:
2019-03-21 05:28:12 +00:00
for idx, link in enumerate(links_after_timestamp(links, resume)):
link_dir = os.path.join(ARCHIVE_DIR, link['timestamp'])
archive_link(link_dir, link)
2019-03-21 05:28:12 +00:00
except KeyboardInterrupt:
log_archiving_paused(len(links), idx, link and link['timestamp'])
2017-06-30 08:23:19 +00:00
raise SystemExit(0)
2019-03-21 05:28:12 +00:00
except:
print()
raise
2019-03-21 05:28:12 +00:00
log_archiving_finished(len(links))
2019-03-21 05:28:12 +00:00
# Step 4: Re-write links index with updated titles, icons, and resources
all_links, _ = load_links_index(out_dir=OUTPUT_DIR)
write_links_index(out_dir=OUTPUT_DIR, links=all_links, finished=True)
2017-10-30 11:09:33 +00:00
2019-03-21 05:28:12 +00:00
if __name__ == '__main__':
main(*sys.argv)