import glob import logging import os import tarfile import time import traceback from pathlib import Path from threading import Thread import requests from bauh.api.http import HttpClient from bauh.gems.appimage import LOCAL_PATH class DatabaseUpdater(Thread): URL_DB = 'https://raw.githubusercontent.com/vinifmor/bauh-files/master/appimage/dbs.tar.gz' COMPRESS_FILE_PATH = LOCAL_PATH + '/db.tar.gz' def __init__(self, http_client: HttpClient, logger: logging.Logger, db_locks: dict): super(DatabaseUpdater, self).__init__(daemon=True) self.http_client = http_client self.logger = logger self.enabled = bool(int(os.getenv('BAUH_APPIMAGE_DB_UPDATER', 1))) self.db_locks = db_locks self.sleep = int(os.getenv('BAUH_APPIMAGE_DB_UPDATER_TIME', 60 * 20)) def _download_databases(self): self.logger.info('Retrieving AppImage databases') res = self.http_client.get(self.URL_DB) if res: Path(LOCAL_PATH).mkdir(parents=True, exist_ok=True) with open(self.COMPRESS_FILE_PATH, 'wb+') as f: f.write(res.content) self.logger.info("Database file saved at {}".format(self.COMPRESS_FILE_PATH)) old_db_files = glob.glob(LOCAL_PATH + '/*.db') if old_db_files: self.logger.info('Deleting old database files') for f in old_db_files: self.db_locks[f].acquire() try: os.remove(f) finally: self.db_locks[f].release() self.logger.info('Old database files deleted') self.logger.info('Uncompressing {}'.format(self.COMPRESS_FILE_PATH)) try: tf = tarfile.open(self.COMPRESS_FILE_PATH) tf.extractall(LOCAL_PATH) self.logger.info('Successfully uncompressed file {}'.format(self.COMPRESS_FILE_PATH)) except: self.logger.error('Could not extract file {}'.format(self.COMPRESS_FILE_PATH)) traceback.print_exc() finally: self.logger.info('Deleting {}'.format(self.COMPRESS_FILE_PATH)) os.remove(self.COMPRESS_FILE_PATH) self.logger.info('Successfully removed {}'.format(self.COMPRESS_FILE_PATH)) else: self.logger.warning('Could not download the database file {}'.format(self.URL_DB)) def run(self): if self.enabled: while True: try: self._download_databases() except requests.exceptions.ConnectionError: self.logger.warning('The internet connection seems to be off.') self.logger.info('Sleeping') time.sleep(self.sleep) else: self.logger.warning('AppImage database updater disabled')