pywaybackup 1.0.3__tar.gz → 1.2.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {pywaybackup-1.0.3 → pywaybackup-1.2.0}/PKG-INFO +43 -22
- {pywaybackup-1.0.3 → pywaybackup-1.2.0}/README.md +42 -22
- pywaybackup-1.2.0/pywaybackup/Exception.py +73 -0
- {pywaybackup-1.0.3 → pywaybackup-1.2.0}/pywaybackup/SnapshotCollection.py +12 -63
- {pywaybackup-1.0.3 → pywaybackup-1.2.0}/pywaybackup/Verbosity.py +15 -13
- pywaybackup-1.2.0/pywaybackup/__version__.py +1 -0
- pywaybackup-1.2.0/pywaybackup/archive.py +442 -0
- pywaybackup-1.2.0/pywaybackup/arguments.py +42 -0
- pywaybackup-1.2.0/pywaybackup/helper.py +83 -0
- pywaybackup-1.2.0/pywaybackup/main.py +54 -0
- {pywaybackup-1.0.3 → pywaybackup-1.2.0}/pywaybackup.egg-info/PKG-INFO +43 -22
- {pywaybackup-1.0.3 → pywaybackup-1.2.0}/pywaybackup.egg-info/SOURCES.txt +2 -0
- {pywaybackup-1.0.3 → pywaybackup-1.2.0}/pywaybackup.egg-info/requires.txt +1 -0
- pywaybackup-1.0.3/pywaybackup/__version__.py +0 -1
- pywaybackup-1.0.3/pywaybackup/archive.py +0 -306
- pywaybackup-1.0.3/pywaybackup/arguments.py +0 -34
- pywaybackup-1.0.3/pywaybackup/main.py +0 -34
- {pywaybackup-1.0.3 → pywaybackup-1.2.0}/LICENSE +0 -0
- {pywaybackup-1.0.3 → pywaybackup-1.2.0}/pywaybackup/__init__.py +0 -0
- {pywaybackup-1.0.3 → pywaybackup-1.2.0}/pywaybackup.egg-info/dependency_links.txt +0 -0
- {pywaybackup-1.0.3 → pywaybackup-1.2.0}/pywaybackup.egg-info/entry_points.txt +0 -0
- {pywaybackup-1.0.3 → pywaybackup-1.2.0}/pywaybackup.egg-info/top_level.txt +0 -0
- {pywaybackup-1.0.3 → pywaybackup-1.2.0}/setup.cfg +0 -0
- {pywaybackup-1.0.3 → pywaybackup-1.2.0}/setup.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: pywaybackup
|
|
3
|
-
Version: 1.0
|
|
3
|
+
Version: 1.2.0
|
|
4
4
|
Summary: Download snapshots from the Wayback Machine
|
|
5
5
|
Home-page: https://github.com/bitdruid/python-wayback-machine-downloader
|
|
6
6
|
Author: bitdruid
|
|
@@ -11,8 +11,9 @@ Description-Content-Type: text/markdown
|
|
|
11
11
|
License-File: LICENSE
|
|
12
12
|
Requires-Dist: requests==2.31.0
|
|
13
13
|
Requires-Dist: tqdm==4.66.2
|
|
14
|
+
Requires-Dist: python-magic==0.4.27
|
|
14
15
|
|
|
15
|
-
#
|
|
16
|
+
# python wayback machine downloader
|
|
16
17
|
|
|
17
18
|
[](https://pypi.org/project/pywaybackup/)
|
|
18
19
|
[](https://pypi.org/project/pywaybackup/)
|
|
@@ -21,7 +22,9 @@ Requires-Dist: tqdm==4.66.2
|
|
|
21
22
|
|
|
22
23
|
Downloading archived web pages from the [Wayback Machine](https://archive.org/web/).
|
|
23
24
|
|
|
24
|
-
Internet-archive is a nice source for several OSINT-information. This
|
|
25
|
+
Internet-archive is a nice source for several OSINT-information. This tool is a work in progress to query and fetch archived web pages.
|
|
26
|
+
|
|
27
|
+
This tool allows you to download content from the Wayback Machine (archive.org). You can use it to download either the latest version or all versions of web page snapshots within a specified range.
|
|
25
28
|
|
|
26
29
|
## Installation
|
|
27
30
|
|
|
@@ -29,7 +32,7 @@ Internet-archive is a nice source for several OSINT-information. This script is
|
|
|
29
32
|
|
|
30
33
|
1. Install the package <br>
|
|
31
34
|
```pip install pywaybackup```
|
|
32
|
-
2. Run the
|
|
35
|
+
2. Run the tool <br>
|
|
33
36
|
```waybackup -h```
|
|
34
37
|
|
|
35
38
|
### Manual
|
|
@@ -40,30 +43,25 @@ Internet-archive is a nice source for several OSINT-information. This script is
|
|
|
40
43
|
```pip install .```
|
|
41
44
|
- in a virtual env or use `--break-system-package`
|
|
42
45
|
|
|
43
|
-
##
|
|
44
|
-
|
|
45
|
-
This script allows you to download content from the Wayback Machine (archive.org). You can use it to download either the latest version or all versions of web page snapshots within a specified range.
|
|
46
|
-
|
|
47
|
-
### Arguments
|
|
46
|
+
## Arguments
|
|
48
47
|
|
|
49
48
|
- `-h`, `--help`: Show the help message and exit.
|
|
50
|
-
- `-a`, `--about`: Show information about the
|
|
49
|
+
- `-a`, `--about`: Show information about the tool and exit.
|
|
51
50
|
|
|
52
|
-
|
|
51
|
+
### Required
|
|
53
52
|
|
|
54
53
|
- `-u`, `--url`: The URL of the web page to download. This argument is required.
|
|
55
54
|
|
|
56
55
|
#### Mode Selection (Choose One)
|
|
57
|
-
|
|
58
56
|
- `-c`, `--current`: Download the latest version of each file snapshot. You will get a rebuild of the current website with all available files (but not any original state because new and old versions are mixed).
|
|
59
57
|
- `-f`, `--full`: Download snapshots of all timestamps. You will get a folder per timestamp with the files available at that time.
|
|
60
58
|
- `-s`, `--save`: Save a page to the Wayback Machine. (beta)
|
|
61
59
|
|
|
62
|
-
|
|
60
|
+
### Optional query parameters
|
|
63
61
|
|
|
64
62
|
- `-l`, `--list`: Only print the snapshots available within the specified range. Does not download the snapshots.
|
|
65
63
|
- `-e`, `--explicit`: Only download the explicit given url. No wildcard subdomains or paths. Use e.g. to get root-only snapshots.
|
|
66
|
-
- `-o`, `--output`: The folder where downloaded files will be saved.
|
|
64
|
+
- `-o`, `--output`: Defaults to `waybackup_snapshots` in the current directory. The folder where downloaded files will be saved.
|
|
67
65
|
|
|
68
66
|
- **Range Selection:**<br>
|
|
69
67
|
Specify the range in years or a specific timestamp either start, end or both. If you specify the `range` argument, the `start` and `end` arguments will be ignored. Format for timestamps: YYYYMMDDhhmmss. You can only give a year or increase specificity by going through the timestamp starting on the left.<br>
|
|
@@ -72,13 +70,36 @@ Specify the range in years or a specific timestamp either start, end or both. If
|
|
|
72
70
|
- `--start`: Timestamp to start searching.
|
|
73
71
|
- `--end`: Timestamp to end searching.
|
|
74
72
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
-
|
|
81
|
-
-
|
|
73
|
+
### Additional behavior manipulation
|
|
74
|
+
|
|
75
|
+
- **`--csv`** `<path>`:<br>
|
|
76
|
+
Path defaults to output-dir. Saves a CSV file with the json-response for successfull downloads. If `--list` is set, the CSV contains the CDX list of snapshots. If `--current` or `--full` is set, CSV contains downloaded files. Named as `waybackup_<sanitized_url>.csv`.
|
|
77
|
+
|
|
78
|
+
- **`--skip`** `<path>`:<br>
|
|
79
|
+
Path defaults to output-dir. Checks for an existing `waybackup_<domain>.csv` for URLs to skip downloading. Useful for interrupted downloads. Files are checked by their root-domain, ensuring consistency across queries. This means that if you download `http://example.com/subdir1/` and later `http://example.com`, the second query will skip the first path.
|
|
80
|
+
|
|
81
|
+
- **`--no-redirect`**:<br>
|
|
82
|
+
Disables following redirects of snapshots. Useful for preventing timestamp-folder mismatches caused by Archive.org redirects.
|
|
83
|
+
|
|
84
|
+
- **`--verbosity`** `<level>`:<br>
|
|
85
|
+
Sets verbosity level. Options are `json` (prints JSON response) or `progress` (shows progress bar).
|
|
86
|
+
|
|
87
|
+
- **`--retry`** `<attempts>`:<br>
|
|
88
|
+
Specifies number of retry attempts for failed downloads.
|
|
89
|
+
|
|
90
|
+
- **`--workers`** `<count>`:<br>
|
|
91
|
+
Sets the number of simultaneous download workers. Default is 1, safe range is about 10. Be cautious as too many workers may lead to refused connections from the Wayback Machine.
|
|
92
|
+
|
|
93
|
+
**CDX Query Handling:**
|
|
94
|
+
- **`--cdxbackup`** `<path>`:<br>
|
|
95
|
+
Path defaults to output-dir. Saves the result of CDX query as a file. Useful for later downloading snapshots and overcoming refused connections by CDX server due to too many queries. Named as `waybackup_<sanitized_url>.cdx`.
|
|
96
|
+
|
|
97
|
+
- **`--cdxinject`** `<filepath>`:<br>
|
|
98
|
+
Injects a CDX query file to download snapshots. Ensure the query matches the previous `--url` for correct folder structure.
|
|
99
|
+
|
|
100
|
+
### Debug
|
|
101
|
+
|
|
102
|
+
- `--debug`: If set, full traceback will be printed in case of an error. The full exception will be written into `waybackup_error.log`.
|
|
82
103
|
|
|
83
104
|
### Examples
|
|
84
105
|
|
|
@@ -183,5 +204,5 @@ The csv contains the json response in a table format.
|
|
|
183
204
|
|
|
184
205
|
## Contributing
|
|
185
206
|
|
|
186
|
-
I'm always happy for some feature requests to improve the usability of this
|
|
207
|
+
I'm always happy for some feature requests to improve the usability of this tool.
|
|
187
208
|
Feel free to give suggestions and report issues. Project is still far from being perfect.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
#
|
|
1
|
+
# python wayback machine downloader
|
|
2
2
|
|
|
3
3
|
[](https://pypi.org/project/pywaybackup/)
|
|
4
4
|
[](https://pypi.org/project/pywaybackup/)
|
|
@@ -7,7 +7,9 @@
|
|
|
7
7
|
|
|
8
8
|
Downloading archived web pages from the [Wayback Machine](https://archive.org/web/).
|
|
9
9
|
|
|
10
|
-
Internet-archive is a nice source for several OSINT-information. This
|
|
10
|
+
Internet-archive is a nice source for several OSINT-information. This tool is a work in progress to query and fetch archived web pages.
|
|
11
|
+
|
|
12
|
+
This tool allows you to download content from the Wayback Machine (archive.org). You can use it to download either the latest version or all versions of web page snapshots within a specified range.
|
|
11
13
|
|
|
12
14
|
## Installation
|
|
13
15
|
|
|
@@ -15,7 +17,7 @@ Internet-archive is a nice source for several OSINT-information. This script is
|
|
|
15
17
|
|
|
16
18
|
1. Install the package <br>
|
|
17
19
|
```pip install pywaybackup```
|
|
18
|
-
2. Run the
|
|
20
|
+
2. Run the tool <br>
|
|
19
21
|
```waybackup -h```
|
|
20
22
|
|
|
21
23
|
### Manual
|
|
@@ -26,30 +28,25 @@ Internet-archive is a nice source for several OSINT-information. This script is
|
|
|
26
28
|
```pip install .```
|
|
27
29
|
- in a virtual env or use `--break-system-package`
|
|
28
30
|
|
|
29
|
-
##
|
|
30
|
-
|
|
31
|
-
This script allows you to download content from the Wayback Machine (archive.org). You can use it to download either the latest version or all versions of web page snapshots within a specified range.
|
|
32
|
-
|
|
33
|
-
### Arguments
|
|
31
|
+
## Arguments
|
|
34
32
|
|
|
35
33
|
- `-h`, `--help`: Show the help message and exit.
|
|
36
|
-
- `-a`, `--about`: Show information about the
|
|
34
|
+
- `-a`, `--about`: Show information about the tool and exit.
|
|
37
35
|
|
|
38
|
-
|
|
36
|
+
### Required
|
|
39
37
|
|
|
40
38
|
- `-u`, `--url`: The URL of the web page to download. This argument is required.
|
|
41
39
|
|
|
42
40
|
#### Mode Selection (Choose One)
|
|
43
|
-
|
|
44
41
|
- `-c`, `--current`: Download the latest version of each file snapshot. You will get a rebuild of the current website with all available files (but not any original state because new and old versions are mixed).
|
|
45
42
|
- `-f`, `--full`: Download snapshots of all timestamps. You will get a folder per timestamp with the files available at that time.
|
|
46
43
|
- `-s`, `--save`: Save a page to the Wayback Machine. (beta)
|
|
47
44
|
|
|
48
|
-
|
|
45
|
+
### Optional query parameters
|
|
49
46
|
|
|
50
47
|
- `-l`, `--list`: Only print the snapshots available within the specified range. Does not download the snapshots.
|
|
51
48
|
- `-e`, `--explicit`: Only download the explicit given url. No wildcard subdomains or paths. Use e.g. to get root-only snapshots.
|
|
52
|
-
- `-o`, `--output`: The folder where downloaded files will be saved.
|
|
49
|
+
- `-o`, `--output`: Defaults to `waybackup_snapshots` in the current directory. The folder where downloaded files will be saved.
|
|
53
50
|
|
|
54
51
|
- **Range Selection:**<br>
|
|
55
52
|
Specify the range in years or a specific timestamp either start, end or both. If you specify the `range` argument, the `start` and `end` arguments will be ignored. Format for timestamps: YYYYMMDDhhmmss. You can only give a year or increase specificity by going through the timestamp starting on the left.<br>
|
|
@@ -58,13 +55,36 @@ Specify the range in years or a specific timestamp either start, end or both. If
|
|
|
58
55
|
- `--start`: Timestamp to start searching.
|
|
59
56
|
- `--end`: Timestamp to end searching.
|
|
60
57
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
-
|
|
67
|
-
-
|
|
58
|
+
### Additional behavior manipulation
|
|
59
|
+
|
|
60
|
+
- **`--csv`** `<path>`:<br>
|
|
61
|
+
Path defaults to output-dir. Saves a CSV file with the json-response for successfull downloads. If `--list` is set, the CSV contains the CDX list of snapshots. If `--current` or `--full` is set, CSV contains downloaded files. Named as `waybackup_<sanitized_url>.csv`.
|
|
62
|
+
|
|
63
|
+
- **`--skip`** `<path>`:<br>
|
|
64
|
+
Path defaults to output-dir. Checks for an existing `waybackup_<domain>.csv` for URLs to skip downloading. Useful for interrupted downloads. Files are checked by their root-domain, ensuring consistency across queries. This means that if you download `http://example.com/subdir1/` and later `http://example.com`, the second query will skip the first path.
|
|
65
|
+
|
|
66
|
+
- **`--no-redirect`**:<br>
|
|
67
|
+
Disables following redirects of snapshots. Useful for preventing timestamp-folder mismatches caused by Archive.org redirects.
|
|
68
|
+
|
|
69
|
+
- **`--verbosity`** `<level>`:<br>
|
|
70
|
+
Sets verbosity level. Options are `json` (prints JSON response) or `progress` (shows progress bar).
|
|
71
|
+
|
|
72
|
+
- **`--retry`** `<attempts>`:<br>
|
|
73
|
+
Specifies number of retry attempts for failed downloads.
|
|
74
|
+
|
|
75
|
+
- **`--workers`** `<count>`:<br>
|
|
76
|
+
Sets the number of simultaneous download workers. Default is 1, safe range is about 10. Be cautious as too many workers may lead to refused connections from the Wayback Machine.
|
|
77
|
+
|
|
78
|
+
**CDX Query Handling:**
|
|
79
|
+
- **`--cdxbackup`** `<path>`:<br>
|
|
80
|
+
Path defaults to output-dir. Saves the result of CDX query as a file. Useful for later downloading snapshots and overcoming refused connections by CDX server due to too many queries. Named as `waybackup_<sanitized_url>.cdx`.
|
|
81
|
+
|
|
82
|
+
- **`--cdxinject`** `<filepath>`:<br>
|
|
83
|
+
Injects a CDX query file to download snapshots. Ensure the query matches the previous `--url` for correct folder structure.
|
|
84
|
+
|
|
85
|
+
### Debug
|
|
86
|
+
|
|
87
|
+
- `--debug`: If set, full traceback will be printed in case of an error. The full exception will be written into `waybackup_error.log`.
|
|
68
88
|
|
|
69
89
|
### Examples
|
|
70
90
|
|
|
@@ -169,5 +189,5 @@ The csv contains the json response in a table format.
|
|
|
169
189
|
|
|
170
190
|
## Contributing
|
|
171
191
|
|
|
172
|
-
I'm always happy for some feature requests to improve the usability of this
|
|
173
|
-
Feel free to give suggestions and report issues. Project is still far from being perfect.
|
|
192
|
+
I'm always happy for some feature requests to improve the usability of this tool.
|
|
193
|
+
Feel free to give suggestions and report issues. Project is still far from being perfect.
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
|
|
2
|
+
import sys
|
|
3
|
+
import os
|
|
4
|
+
from datetime import datetime
|
|
5
|
+
import linecache
|
|
6
|
+
import traceback
|
|
7
|
+
|
|
8
|
+
class Exception:
|
|
9
|
+
|
|
10
|
+
new_debug = True
|
|
11
|
+
debug = False
|
|
12
|
+
output = None
|
|
13
|
+
command = None
|
|
14
|
+
|
|
15
|
+
@classmethod
|
|
16
|
+
def init(cls, debug=False, output=None, command=None):
|
|
17
|
+
sys.excepthook = cls.exception_handler # set custom exception handler (uncaught exceptions)
|
|
18
|
+
cls.output = output
|
|
19
|
+
cls.command = command
|
|
20
|
+
cls.debug = True if debug else False
|
|
21
|
+
|
|
22
|
+
@classmethod
|
|
23
|
+
def exception(cls, message: str, e: Exception, tb=None):
|
|
24
|
+
custom_tb = sys.exc_info()[-1] if tb is None else tb
|
|
25
|
+
original_tb = "".join(traceback.format_exception(type(e), e, e.__traceback__))
|
|
26
|
+
exception_message = (
|
|
27
|
+
"-------------------------\n"
|
|
28
|
+
f"!-- Exception: {message}\n"
|
|
29
|
+
)
|
|
30
|
+
if custom_tb is not None:
|
|
31
|
+
while custom_tb.tb_next: # loop to last traceback frame
|
|
32
|
+
custom_tb = custom_tb.tb_next
|
|
33
|
+
tb_frame = custom_tb.tb_frame
|
|
34
|
+
tb_line = custom_tb.tb_lineno
|
|
35
|
+
func_name = tb_frame.f_code.co_name
|
|
36
|
+
filename = tb_frame.f_code.co_filename
|
|
37
|
+
codeline = linecache.getline(filename, tb_line).strip()
|
|
38
|
+
exception_message += (
|
|
39
|
+
f"!-- File: {filename}\n"
|
|
40
|
+
f"!-- Function: {func_name}\n"
|
|
41
|
+
f"!-- Line: {tb_line}\n"
|
|
42
|
+
f"!-- Segment: {codeline}\n"
|
|
43
|
+
)
|
|
44
|
+
else:
|
|
45
|
+
exception_message += "!-- Traceback is None\n"
|
|
46
|
+
exception_message += (
|
|
47
|
+
f"!-- Description: {e}\n"
|
|
48
|
+
"-------------------------")
|
|
49
|
+
print(exception_message)
|
|
50
|
+
if cls.debug:
|
|
51
|
+
debug_file = os.path.join(cls.output, "waybackup_error.log")
|
|
52
|
+
print(f"Exception log: {debug_file}")
|
|
53
|
+
print("-------------------------")
|
|
54
|
+
print(f"Full traceback:\n{original_tb}")
|
|
55
|
+
if cls.new_debug: # new run, overwrite file
|
|
56
|
+
cls.new_debug = False
|
|
57
|
+
f = open(debug_file, "w")
|
|
58
|
+
f.write("-------------------------\n")
|
|
59
|
+
f.write(f"Command: {cls.command}\n")
|
|
60
|
+
f.write("-------------------------\n\n")
|
|
61
|
+
else: # current run, append to file
|
|
62
|
+
f = open(debug_file, "a")
|
|
63
|
+
f.write(datetime.now().strftime("%Y-%m-%d %H:%M:%S") + "\n")
|
|
64
|
+
f.write(exception_message + "\n")
|
|
65
|
+
f.write(original_tb + "\n")
|
|
66
|
+
|
|
67
|
+
@staticmethod
|
|
68
|
+
def exception_handler(exception_type, exception, traceback):
|
|
69
|
+
if issubclass(exception_type, KeyboardInterrupt):
|
|
70
|
+
sys.__excepthook__(exception_type, exception, traceback)
|
|
71
|
+
return
|
|
72
|
+
Exception.exception("UNCAUGHT EXCEPTION", exception, traceback) # uncaught exceptions also with custom scheme
|
|
73
|
+
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
from
|
|
1
|
+
from pywaybackup.helper import url_split
|
|
2
2
|
import os
|
|
3
3
|
|
|
4
4
|
class SnapshotCollection:
|
|
5
5
|
|
|
6
6
|
SNAPSHOT_COLLECTION = []
|
|
7
|
-
MODE_CURRENT = 0
|
|
7
|
+
MODE_CURRENT = 0
|
|
8
8
|
|
|
9
9
|
@classmethod
|
|
10
10
|
def create_list(cls, cdxResult, mode):
|
|
@@ -15,7 +15,7 @@ class SnapshotCollection:
|
|
|
15
15
|
- mode `current`: Only the latest snapshot of each file is included.
|
|
16
16
|
"""
|
|
17
17
|
# creates a list of dictionaries for each snapshot entry
|
|
18
|
-
cls.SNAPSHOT_COLLECTION = sorted([{"timestamp": snapshot[0], "digest": snapshot[1], "mimetype": snapshot[2], "status": snapshot[3], "url": snapshot[4]} for snapshot in cdxResult
|
|
18
|
+
cls.SNAPSHOT_COLLECTION = sorted([{"timestamp": snapshot[0], "digest": snapshot[1], "mimetype": snapshot[2], "status": snapshot[3], "url": snapshot[4]} for snapshot in cdxResult[1:]], key=lambda k: k['timestamp'], reverse=True)
|
|
19
19
|
if mode == "current":
|
|
20
20
|
cls.MODE_CURRENT = 1
|
|
21
21
|
cdxResult_list_filtered = []
|
|
@@ -29,21 +29,23 @@ class SnapshotCollection:
|
|
|
29
29
|
# writes the index for each snapshot entry
|
|
30
30
|
cls.SNAPSHOT_COLLECTION = [{"id": idx, **entry} for idx, entry in enumerate(cls.SNAPSHOT_COLLECTION)]
|
|
31
31
|
|
|
32
|
+
|
|
32
33
|
@classmethod
|
|
33
34
|
def count_list(cls):
|
|
34
35
|
return len(cls.SNAPSHOT_COLLECTION)
|
|
35
36
|
|
|
37
|
+
|
|
36
38
|
@classmethod
|
|
37
39
|
def create_collection(cls):
|
|
38
40
|
new_collection = []
|
|
39
41
|
for idx, cdx_entry in enumerate(cls.SNAPSHOT_COLLECTION):
|
|
40
|
-
timestamp,
|
|
41
|
-
url_archive = f"
|
|
42
|
+
timestamp, url_origin = cdx_entry["timestamp"], cdx_entry["url"]
|
|
43
|
+
url_archive = f"https://web.archive.org/web/{timestamp}id_/{url_origin}"
|
|
42
44
|
collection_entry = {
|
|
43
45
|
"id": idx,
|
|
44
46
|
"timestamp": timestamp,
|
|
45
47
|
"url_archive": url_archive,
|
|
46
|
-
"url_origin":
|
|
48
|
+
"url_origin": url_origin,
|
|
47
49
|
"redirect_url": False,
|
|
48
50
|
"redirect_timestamp": False,
|
|
49
51
|
"response": False,
|
|
@@ -52,20 +54,10 @@ class SnapshotCollection:
|
|
|
52
54
|
new_collection.append(collection_entry)
|
|
53
55
|
cls.SNAPSHOT_COLLECTION = new_collection
|
|
54
56
|
|
|
55
|
-
@classmethod
|
|
56
|
-
def snapshot_entry_create_output(cls, collection_entry: dict, output: str) -> str:
|
|
57
|
-
"""
|
|
58
|
-
Create the output path for a snapshot entry of the collection according to the mode.
|
|
59
|
-
|
|
60
|
-
Input:
|
|
61
|
-
- collection_entry: A single snapshot entry of the collection (dict).
|
|
62
|
-
- output: The output directory (str).
|
|
63
57
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
""
|
|
67
|
-
timestamp, url = collection_entry["timestamp"], collection_entry["url_origin"]
|
|
68
|
-
domain, subdir, filename = cls.url_split(url, index=True)
|
|
58
|
+
@classmethod
|
|
59
|
+
def create_output(cls, url: str, timestamp: str, output: str):
|
|
60
|
+
domain, subdir, filename = url_split(url.split("id_/")[1], index=True)
|
|
69
61
|
if cls.MODE_CURRENT:
|
|
70
62
|
download_dir = os.path.join(output, domain, subdir)
|
|
71
63
|
else:
|
|
@@ -73,6 +65,7 @@ class SnapshotCollection:
|
|
|
73
65
|
download_file = os.path.abspath(os.path.join(download_dir, filename))
|
|
74
66
|
return download_file
|
|
75
67
|
|
|
68
|
+
|
|
76
69
|
@classmethod
|
|
77
70
|
def snapshot_entry_modify(cls, collection_entry: dict, key: str, value: str):
|
|
78
71
|
"""
|
|
@@ -82,47 +75,3 @@ class SnapshotCollection:
|
|
|
82
75
|
- Modify an existing key-value pair if the key exists.
|
|
83
76
|
"""
|
|
84
77
|
collection_entry[key] = value
|
|
85
|
-
|
|
86
|
-
@classmethod
|
|
87
|
-
def url_get_timestamp(cls, url):
|
|
88
|
-
"""
|
|
89
|
-
Extract the timestamp from a wayback machine URL.
|
|
90
|
-
"""
|
|
91
|
-
timestamp = url.split("web.archive.org/web/")[1].split("/")[0]
|
|
92
|
-
timestamp = ''.join([char for char in timestamp if char.isdigit()])
|
|
93
|
-
return timestamp
|
|
94
|
-
|
|
95
|
-
@classmethod
|
|
96
|
-
def _url_get_filetype(cls, url):
|
|
97
|
-
file_extension = os.path.splitext(url)[1][1:]
|
|
98
|
-
urltype_mapping = {
|
|
99
|
-
"jpg": "im_",
|
|
100
|
-
"jpeg": "im_",
|
|
101
|
-
"png": "im_",
|
|
102
|
-
"gif": "im_",
|
|
103
|
-
"svg": "im_",
|
|
104
|
-
"ico": "im_",
|
|
105
|
-
"css": "cs_"
|
|
106
|
-
#"js": "js_"
|
|
107
|
-
}
|
|
108
|
-
urltype = urltype_mapping.get(file_extension, "id_")
|
|
109
|
-
return urltype
|
|
110
|
-
|
|
111
|
-
@classmethod
|
|
112
|
-
def url_split(cls, url, index=False):
|
|
113
|
-
"""
|
|
114
|
-
Split a URL into domain, subdir and filename.
|
|
115
|
-
"""
|
|
116
|
-
if not urlparse(url).scheme:
|
|
117
|
-
url = "http://" + url
|
|
118
|
-
parsed_url = urlparse(url)
|
|
119
|
-
domain = parsed_url.netloc.split("@")[-1].split(":")[0] # split mailto: and port
|
|
120
|
-
path_parts = parsed_url.path.split("/")
|
|
121
|
-
if not url.endswith("/") or "." in path_parts[-1]:
|
|
122
|
-
filename = path_parts[-1]
|
|
123
|
-
subdir = "/".join(path_parts[:-1]).strip("/")
|
|
124
|
-
else:
|
|
125
|
-
filename = "index.html" if index else ""
|
|
126
|
-
subdir = "/".join(path_parts).strip("/")
|
|
127
|
-
filename = filename.replace("%20", " ") # replace url encoded spaces
|
|
128
|
-
return domain, subdir, filename
|
|
@@ -2,44 +2,46 @@ import tqdm
|
|
|
2
2
|
import json
|
|
3
3
|
from pywaybackup.SnapshotCollection import SnapshotCollection as sc
|
|
4
4
|
|
|
5
|
+
|
|
5
6
|
class Verbosity:
|
|
6
7
|
|
|
7
8
|
mode = None
|
|
8
9
|
args = None
|
|
9
10
|
pbar = None
|
|
10
11
|
|
|
12
|
+
new_debug = True
|
|
13
|
+
debug = False
|
|
14
|
+
output = None
|
|
15
|
+
command = None
|
|
16
|
+
|
|
11
17
|
@classmethod
|
|
12
|
-
def
|
|
13
|
-
cls.args =
|
|
18
|
+
def init(cls, v_args: list, debug=False, output=None, command=None):
|
|
19
|
+
cls.args = v_args
|
|
20
|
+
cls.output = output
|
|
21
|
+
cls.command = command
|
|
14
22
|
if cls.args == "progress":
|
|
15
23
|
cls.mode = "progress"
|
|
16
24
|
elif cls.args == "json":
|
|
17
25
|
cls.mode = "json"
|
|
18
26
|
else:
|
|
19
27
|
cls.mode = "standard"
|
|
28
|
+
cls.debug = True if debug else False
|
|
20
29
|
|
|
21
30
|
@classmethod
|
|
22
|
-
def
|
|
31
|
+
def fini(cls):
|
|
23
32
|
if cls.mode == "progress":
|
|
24
33
|
if cls.pbar is not None: cls.pbar.close()
|
|
25
|
-
if cls.mode == "progress" or cls.mode == "standard":
|
|
26
|
-
successed = len([snapshot for snapshot in sc.SNAPSHOT_COLLECTION if "file" in snapshot and snapshot["file"]])
|
|
27
|
-
failed = len([snapshot for snapshot in sc.SNAPSHOT_COLLECTION if "file" in snapshot and not snapshot["file"]])
|
|
28
|
-
print(f"\nFiles downloaded: {successed}")
|
|
29
|
-
print(f"Files missing: {failed}")
|
|
30
|
-
print("")
|
|
31
34
|
if cls.mode == "json":
|
|
32
35
|
print(json.dumps(sc.SNAPSHOT_COLLECTION, indent=4, sort_keys=True))
|
|
33
36
|
|
|
34
37
|
@classmethod
|
|
35
38
|
def write(cls, message: str = None, progress: int = None):
|
|
36
39
|
if cls.mode == "progress":
|
|
37
|
-
if progress == 0:
|
|
38
|
-
print("")
|
|
40
|
+
if cls.pbar is None and progress == 0:
|
|
39
41
|
maxval = sc.count_list()
|
|
40
42
|
cls.pbar = tqdm.tqdm(total=maxval, desc="Downloading", unit=" snapshot", ascii="░▒█")
|
|
41
|
-
|
|
42
|
-
cls.pbar.update(
|
|
43
|
+
if cls.pbar is not None and progress is not None and progress > 0 :
|
|
44
|
+
cls.pbar.update(progress)
|
|
43
45
|
cls.pbar.refresh()
|
|
44
46
|
elif cls.mode == "json":
|
|
45
47
|
pass
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "1.2.0"
|