Compare commits

...

15 Commits

Author SHA1 Message Date
msramalho
8624e9f177 version update 0.7.1 2023-11-13 11:58:43 +01:00
Galen Reich
381940f5a8 Fix Selenium headless invokation (#106)
Co-authored-by: msramalho <19508417+msramalho@users.noreply.github.com>
2023-11-13 11:56:35 +01:00
msramalho
1382f8b795 version bump and release without commit 2023-09-22 10:18:58 +01:00
Dave Mateer
fac8364762 Updated gd.py to work with shared folders (#102)
Co-authored-by: msramalho <19508417+msramalho@users.noreply.github.com>
2023-09-22 10:17:54 +01:00
msramalho
0feeb0bd24 Bump version to v0.6.12 for release 2023-09-20 10:18:44 +01:00
msramalho
ddb9dc87d7 unfortunately needed twitter->x 2023-09-20 10:17:31 +01:00
msramalho
e8935b9a80 Bump version to v0.6.11 for release 2023-09-15 19:53:07 +01:00
msramalho
b157f9a6b1 renaming variable 2023-09-15 19:52:47 +01:00
msramalho
ea38a604bb fixes #96 by not assigning to self.prop 2023-09-15 19:35:35 +01:00
msramalho
53494c961e Bump version to v0.6.10 for release 2023-09-14 17:50:08 +01:00
Kai
f7839a99cc Add configs for path to write and read wacz archives (#93)
Co-authored-by: msramalho <19508417+msramalho@users.noreply.github.com>
2023-09-14 17:49:37 +01:00
msramalho
7a2119e6e9 Bump version to v0.6.9 for release 2023-09-12 20:08:00 +01:00
Miguel Sozinho Ramalho
3ae25e51e7 adds flexibile setup for wacz in docker (#94) 2023-09-12 20:07:21 +01:00
msramalho
9584193d69 Bump version to v0.6.8 for release 2023-09-08 15:10:02 +01:00
msramalho
0dd45d90f1 fix: docker+wacz troubles 2023-09-08 15:09:50 +01:00
9 changed files with 840 additions and 805 deletions

View File

@@ -2,7 +2,7 @@ FROM webrecorder/browsertrix-crawler:latest
ENV RUNNING_IN_DOCKER=1 ENV RUNNING_IN_DOCKER=1
WORKDIR /app/auto-archiver WORKDIR /app
RUN pip install --upgrade pip && \ RUN pip install --upgrade pip && \
pip install pipenv && \ pip install pipenv && \
@@ -28,4 +28,4 @@ COPY ./src/ .
ENTRYPOINT ["pipenv", "run", "python3", "-m", "auto_archiver"] ENTRYPOINT ["pipenv", "run", "python3", "-m", "auto_archiver"]
# should be executed with 2 volumes (3 if local_storage is used) # should be executed with 2 volumes (3 if local_storage is used)
# docker run --rm -v $PWD/secrets:/app/secrets -v $PWD/local_archive:/app/local_archive aa pipenv run python3 -m auto_archiver --config secrets/orchestration.yaml # docker run --rm -v $PWD/secrets:/app/secrets -v $PWD/local_archive:/app/local_archive aa pipenv run python3 -m auto_archiver --config secrets/orchestration.yaml

1528
Pipfile.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -8,8 +8,8 @@ TAG=$(python -c 'from src.auto_archiver.version import __version__; print("v" +
read -p "Creating new release for $TAG. Do you want to continue? [Y/n] " prompt read -p "Creating new release for $TAG. Do you want to continue? [Y/n] " prompt
if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then if [[ $prompt == "y" || $prompt == "Y" || $prompt == "yes" || $prompt == "Yes" ]]; then
git add -A # git add -A
git commit -m "Bump version to $TAG for release" || true && git push # git commit -m "Bump version to $TAG for release" || true && git push
echo "Creating new git tag $TAG" echo "Creating new git tag $TAG"
git tag "$TAG" -m "$TAG" git tag "$TAG" -m "$TAG"
git push --tags git push --tags

View File

@@ -15,8 +15,8 @@ class TwitterArchiver(Archiver):
""" """
name = "twitter_archiver" name = "twitter_archiver"
link_pattern = re.compile(r"twitter.com\/(?:\#!\/)?(\w+)\/status(?:es)?\/(\d+)") link_pattern = re.compile(r"(?:twitter|x).com\/(?:\#!\/)?(\w+)\/status(?:es)?\/(\d+)")
link_clean_pattern = re.compile(r"(.+twitter\.com\/.+\/\d+)(\?)*.*") link_clean_pattern = re.compile(r"(.+(?:twitter|x)\.com\/.+\/\d+)(\?)*.*")
def __init__(self, config: dict) -> None: def __init__(self, config: dict) -> None:
super().__init__(config) super().__init__(config)

View File

@@ -27,6 +27,7 @@ class WaczArchiverEnricher(Enricher, Archiver):
def configs() -> dict: def configs() -> dict:
return { return {
"profile": {"default": None, "help": "browsertrix-profile (for profile generation see https://github.com/webrecorder/browsertrix-crawler#creating-and-using-browser-profiles)."}, "profile": {"default": None, "help": "browsertrix-profile (for profile generation see https://github.com/webrecorder/browsertrix-crawler#creating-and-using-browser-profiles)."},
"docker_commands": {"default": None, "help":"if a custom docker invocation is needed"},
"timeout": {"default": 120, "help": "timeout for WACZ generation in seconds"}, "timeout": {"default": 120, "help": "timeout for WACZ generation in seconds"},
"extract_media": {"default": True, "help": "If enabled all the images/videos/audio present in the WACZ archive will be extracted into separate Media. The .wacz file will be kept untouched."} "extract_media": {"default": True, "help": "If enabled all the images/videos/audio present in the WACZ archive will be extracted into separate Media. The .wacz file will be kept untouched."}
} }
@@ -46,51 +47,45 @@ class WaczArchiverEnricher(Enricher, Archiver):
url = to_enrich.get_url() url = to_enrich.get_url()
collection = str(uuid.uuid4())[0:8] collection = str(uuid.uuid4())[0:8]
browsertrix_home = os.path.abspath(ArchivingContext.get_tmp_dir()) browsertrix_home_host = os.environ.get('BROWSERTRIX_HOME_HOST') or os.path.abspath(ArchivingContext.get_tmp_dir())
browsertrix_home_container = os.environ.get('BROWSERTRIX_HOME_CONTAINER') or browsertrix_home_host
if os.getenv('RUNNING_IN_DOCKER'): cmd = [
"crawl",
"--url", url,
"--scopeType", "page",
"--generateWACZ",
"--text",
"--screenshot", "fullPage",
"--collection", collection,
"--id", collection,
"--saveState", "never",
"--behaviors", "autoscroll,autoplay,autofetch,siteSpecific",
"--behaviorTimeout", str(self.timeout),
"--timeout", str(self.timeout)]
# call docker if explicitly enabled or we are running on the host (not in docker)
use_docker = os.environ.get('WACZ_ENABLE_DOCKER') or not os.environ.get('RUNNING_IN_DOCKER')
if use_docker:
logger.debug(f"generating WACZ in Docker for {url=}")
logger.debug(f"{browsertrix_home_host=} {browsertrix_home_container=}")
if self.docker_commands:
cmd = self.docker_commands + cmd
else:
cmd = ["docker", "run", "--rm", "-v", f"{browsertrix_home_host}:/crawls/", "webrecorder/browsertrix-crawler"] + cmd
if self.profile:
profile_fn = os.path.join(browsertrix_home_container, "profile.tar.gz")
logger.debug(f"copying {self.profile} to {profile_fn}")
shutil.copyfile(self.profile, profile_fn)
cmd.extend(["--profile", os.path.join("/crawls", "profile.tar.gz")])
else:
logger.debug(f"generating WACZ without Docker for {url=}") logger.debug(f"generating WACZ without Docker for {url=}")
cmd = [
"crawl",
"--url", url,
"--scopeType", "page",
"--generateWACZ",
"--text",
"--screenshot", "fullPage",
"--collection", collection,
"--id", collection,
"--saveState", "never",
"--behaviors", "autoscroll,autoplay,autofetch,siteSpecific",
"--behaviorTimeout", str(self.timeout),
"--timeout", str(self.timeout)]
if self.profile: if self.profile:
cmd.extend(["--profile", os.path.join("/app", str(self.profile))]) cmd.extend(["--profile", os.path.join("/app", str(self.profile))])
else:
logger.debug(f"generating WACZ in Docker for {url=}")
cmd = [
"docker", "run",
"--rm", # delete container once it has completed running
"-v", f"{browsertrix_home}:/crawls/",
# "-it", # this leads to "the input device is not a TTY"
"webrecorder/browsertrix-crawler", "crawl",
"--url", url,
"--scopeType", "page",
"--generateWACZ",
"--text",
"--screenshot", "fullPage",
"--collection", collection,
"--behaviors", "autoscroll,autoplay,autofetch,siteSpecific",
"--behaviorTimeout", str(self.timeout),
"--timeout", str(self.timeout)
]
if self.profile:
profile_fn = os.path.join(browsertrix_home, "profile.tar.gz")
shutil.copyfile(self.profile, profile_fn)
cmd.extend(["--profile", os.path.join("/crawls", "profile.tar.gz")])
try: try:
logger.info(f"Running browsertrix-crawler: {' '.join(cmd)}") logger.info(f"Running browsertrix-crawler: {' '.join(cmd)}")
@@ -99,18 +94,18 @@ class WaczArchiverEnricher(Enricher, Archiver):
logger.error(f"WACZ generation failed: {e}") logger.error(f"WACZ generation failed: {e}")
return False return False
if os.getenv('RUNNING_IN_DOCKER'): if use_docker:
filename = os.path.join("collections", collection, f"{collection}.wacz") wacz_fn = os.path.join(browsertrix_home_container, "collections", collection, f"{collection}.wacz")
else: else:
filename = os.path.join(browsertrix_home, "collections", collection, f"{collection}.wacz") wacz_fn = os.path.join("collections", collection, f"{collection}.wacz")
if not os.path.exists(filename): if not os.path.exists(wacz_fn):
logger.warning(f"Unable to locate and upload WACZ {filename=}") logger.warning(f"Unable to locate and upload WACZ {wacz_fn=}")
return False return False
to_enrich.add_media(Media(filename), "browsertrix") to_enrich.add_media(Media(wacz_fn), "browsertrix")
if self.extract_media: if self.extract_media:
self.extract_media_from_wacz(to_enrich, filename) self.extract_media_from_wacz(to_enrich, wacz_fn)
return True return True
def extract_media_from_wacz(self, to_enrich: Metadata, wacz_filename: str) -> None: def extract_media_from_wacz(self, to_enrich: Metadata, wacz_filename: str) -> None:

View File

@@ -119,7 +119,7 @@ class GDriveStorage(Storage):
'parents': [upload_to] 'parents': [upload_to]
} }
media = MediaFileUpload(media.filename, resumable=True) media = MediaFileUpload(media.filename, resumable=True)
gd_file = self.service.files().create(body=file_metadata, media_body=media, fields='id').execute() gd_file = self.service.files().create(supportsAllDrives=True, body=file_metadata, media_body=media, fields='id').execute()
logger.debug(f'uploadf: uploaded file {gd_file["id"]} successfully in folder={upload_to}') logger.debug(f'uploadf: uploaded file {gd_file["id"]} successfully in folder={upload_to}')
# must be implemented even if unused # must be implemented even if unused
@@ -150,6 +150,9 @@ class GDriveStorage(Storage):
for attempt in range(retries): for attempt in range(retries):
results = self.service.files().list( results = self.service.files().list(
# both below for Google Shared Drives
supportsAllDrives=True,
includeItemsFromAllDrives=True,
q=query_string, q=query_string,
spaces='drive', # ie not appDataFolder or photos spaces='drive', # ie not appDataFolder or photos
fields='files(id, name)' fields='files(id, name)'
@@ -182,7 +185,7 @@ class GDriveStorage(Storage):
'mimeType': 'application/vnd.google-apps.folder', 'mimeType': 'application/vnd.google-apps.folder',
'parents': [parent_id] 'parents': [parent_id]
} }
gd_folder = self.service.files().create(body=file_metadata, fields='id').execute() gd_folder = self.service.files().create(supportsAllDrives=True, body=file_metadata, fields='id').execute()
return gd_folder.get('id') return gd_folder.get('id')
# def exists(self, key): # def exists(self, key):

View File

@@ -65,6 +65,9 @@ class UrlUtil:
if "vk.com/images/" in url: return False if "vk.com/images/" in url: return False
if "vk.com/images/reaction/" in url: return False if "vk.com/images/reaction/" in url: return False
# wikipedia
if "wikipedia.org/static" in url: return False
return True return True
@staticmethod @staticmethod

View File

@@ -15,7 +15,7 @@ class Webdriver:
def __enter__(self) -> webdriver: def __enter__(self) -> webdriver:
options = webdriver.FirefoxOptions() options = webdriver.FirefoxOptions()
options.headless = True options.add_argument("--headless")
options.set_preference('network.protocol-handler.external.tg', False) options.set_preference('network.protocol-handler.external.tg', False)
try: try:
self.driver = webdriver.Firefox(options=options) self.driver = webdriver.Firefox(options=options)

View File

@@ -1,9 +1,9 @@
_MAJOR = "0" _MAJOR = "0"
_MINOR = "6" _MINOR = "7"
# On main and in a nightly release the patch should be one ahead of the last # On main and in a nightly release the patch should be one ahead of the last
# released build. # released build.
_PATCH = "7" _PATCH = "1"
# This is mainly for nightly builds which have the suffix ".dev$DATE". See # This is mainly for nightly builds which have the suffix ".dev$DATE". See
# https://semver.org/#is-v123-a-semantic-version for the semantics. # https://semver.org/#is-v123-a-semantic-version for the semantics.
_SUFFIX = "" _SUFFIX = ""