mirror of
https://github.com/spalencsar/bearhub.git
synced 2026-07-09 06:24:15 +02:00
[appimage] database lock implemented
This commit is contained in:
@@ -17,7 +17,7 @@ from bauh.api.abstract.view import MessageType
|
|||||||
from bauh.api.constants import HOME_PATH
|
from bauh.api.constants import HOME_PATH
|
||||||
from bauh.commons.html import bold
|
from bauh.commons.html import bold
|
||||||
from bauh.commons.system import SystemProcess, new_subprocess, ProcessHandler, run_cmd
|
from bauh.commons.system import SystemProcess, new_subprocess, ProcessHandler, run_cmd
|
||||||
from bauh.gems.appimage import query, INSTALLATION_PATH, suggestions
|
from bauh.gems.appimage import query, INSTALLATION_PATH, suggestions, db
|
||||||
from bauh.gems.appimage.model import AppImage
|
from bauh.gems.appimage.model import AppImage
|
||||||
from bauh.gems.appimage.worker import DatabaseUpdater
|
from bauh.gems.appimage.worker import DatabaseUpdater
|
||||||
|
|
||||||
@@ -46,10 +46,15 @@ class AppImageManager(SoftwareManager):
|
|||||||
|
|
||||||
def _get_db_connection(self, db_path: str) -> sqlite3.Connection:
|
def _get_db_connection(self, db_path: str) -> sqlite3.Connection:
|
||||||
if os.path.exists(db_path):
|
if os.path.exists(db_path):
|
||||||
|
db.acquire_lock(db_path)
|
||||||
return sqlite3.connect(db_path)
|
return sqlite3.connect(db_path)
|
||||||
else:
|
else:
|
||||||
self.logger.warning("Could not get a database connection. File '{}' not found".format(db_path))
|
self.logger.warning("Could not get a database connection. File '{}' not found".format(db_path))
|
||||||
|
|
||||||
|
def _close_connection(self, db_path: str, con: sqlite3.Connection):
|
||||||
|
con.close()
|
||||||
|
db.release_lock(db_path)
|
||||||
|
|
||||||
def _gen_app_key(self, app: AppImage):
|
def _gen_app_key(self, app: AppImage):
|
||||||
return '{}{}'.format(app.name.lower(), app.github.lower() if app.github else '')
|
return '{}{}'.format(app.name.lower(), app.github.lower() if app.github else '')
|
||||||
|
|
||||||
@@ -84,7 +89,7 @@ class AppImageManager(SoftwareManager):
|
|||||||
res.installed.append(iapp)
|
res.installed.append(iapp)
|
||||||
|
|
||||||
finally:
|
finally:
|
||||||
connection.close()
|
self._close_connection(DB_APPS_PATH, connection)
|
||||||
else:
|
else:
|
||||||
self.logger.warning('Could not get a connection from the local database at {}'.format(DB_APPS_PATH))
|
self.logger.warning('Could not get a connection from the local database at {}'.format(DB_APPS_PATH))
|
||||||
|
|
||||||
@@ -127,7 +132,7 @@ class AppImageManager(SoftwareManager):
|
|||||||
|
|
||||||
break
|
break
|
||||||
finally:
|
finally:
|
||||||
con.close()
|
self._close_connection(DB_APPS_PATH, con)
|
||||||
|
|
||||||
res.total = len(res.installed)
|
res.total = len(res.installed)
|
||||||
return res
|
return res
|
||||||
@@ -220,27 +225,34 @@ class AppImageManager(SoftwareManager):
|
|||||||
connection = self._get_db_connection(DB_APPS_PATH)
|
connection = self._get_db_connection(DB_APPS_PATH)
|
||||||
|
|
||||||
if connection:
|
if connection:
|
||||||
cursor = connection.cursor()
|
try:
|
||||||
|
cursor = connection.cursor()
|
||||||
|
|
||||||
cursor.execute(query.FIND_APP_ID_BY_NAME_AND_GITHUB.format(pkg.name.lower(), pkg.github.lower() if pkg.github else ''))
|
cursor.execute(query.FIND_APP_ID_BY_NAME_AND_GITHUB.format(pkg.name.lower(), pkg.github.lower() if pkg.github else ''))
|
||||||
app_tuple = cursor.fetchone()
|
app_tuple = cursor.fetchone()
|
||||||
|
|
||||||
if not app_tuple:
|
if not app_tuple:
|
||||||
raise Exception("Could not retrieve {} from the database {}".format(pkg, DB_APPS_PATH))
|
raise Exception("Could not retrieve {} from the database {}".format(pkg, DB_APPS_PATH))
|
||||||
|
finally:
|
||||||
connection.close()
|
self._close_connection(DB_APPS_PATH, connection)
|
||||||
|
|
||||||
connection = self._get_db_connection(DB_RELEASES_PATH)
|
connection = self._get_db_connection(DB_RELEASES_PATH)
|
||||||
cursor = connection.cursor()
|
|
||||||
|
|
||||||
releases = cursor.execute(query.FIND_RELEASES_BY_APP_ID.format(app_tuple[0]))
|
if connection:
|
||||||
|
try:
|
||||||
|
cursor = connection.cursor()
|
||||||
|
|
||||||
if releases:
|
releases = cursor.execute(query.FIND_RELEASES_BY_APP_ID.format(app_tuple[0]))
|
||||||
for idx, tup in enumerate(releases):
|
|
||||||
history.append({'0_version': tup[0], '1_published_at': datetime.strptime(tup[2], '%Y-%m-%dT%H:%M:%SZ') if tup[2] else '', '2_url_download': tup[1]})
|
|
||||||
|
|
||||||
if res.pkg_status_idx == -1 and pkg.version == tup[0]:
|
if releases:
|
||||||
res.pkg_status_idx = idx
|
for idx, tup in enumerate(releases):
|
||||||
|
history.append({'0_version': tup[0], '1_published_at': datetime.strptime(tup[2], '%Y-%m-%dT%H:%M:%SZ') if tup[2] else '', '2_url_download': tup[1]})
|
||||||
|
|
||||||
|
if res.pkg_status_idx == -1 and pkg.version == tup[0]:
|
||||||
|
res.pkg_status_idx = idx
|
||||||
|
|
||||||
|
finally:
|
||||||
|
self._close_connection(DB_RELEASES_PATH, connection)
|
||||||
|
|
||||||
return res
|
return res
|
||||||
|
|
||||||
@@ -350,6 +362,9 @@ class AppImageManager(SoftwareManager):
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
def prepare(self):
|
def prepare(self):
|
||||||
|
for path in (DB_APPS_PATH, DB_RELEASES_PATH):
|
||||||
|
db.release_lock(path)
|
||||||
|
|
||||||
self.dbs_updater.start()
|
self.dbs_updater.start()
|
||||||
|
|
||||||
def list_updates(self, internet_available: bool) -> List[PackageUpdate]:
|
def list_updates(self, internet_available: bool) -> List[PackageUpdate]:
|
||||||
@@ -386,7 +401,7 @@ class AppImageManager(SoftwareManager):
|
|||||||
app = AppImage(*t)
|
app = AppImage(*t)
|
||||||
res.append(PackageSuggestion(app, suggestions.ALL.get(app.name.lower())))
|
res.append(PackageSuggestion(app, suggestions.ALL.get(app.name.lower())))
|
||||||
finally:
|
finally:
|
||||||
connection.close()
|
self._close_connection(DB_APPS_PATH, connection)
|
||||||
|
|
||||||
return res
|
return res
|
||||||
|
|
||||||
|
|||||||
18
bauh/gems/appimage/db.py
Normal file
18
bauh/gems/appimage/db.py
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
import os
|
||||||
|
import time
|
||||||
|
|
||||||
|
|
||||||
|
def acquire_lock(db_path: str):
|
||||||
|
lock_path = db_path + '.lock'
|
||||||
|
while True:
|
||||||
|
if not os.path.exists(lock_path):
|
||||||
|
open(lock_path, 'a').close()
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
time.sleep(0.0005)
|
||||||
|
|
||||||
|
|
||||||
|
def release_lock(db_path: str):
|
||||||
|
lock_path = db_path + '.lock'
|
||||||
|
if os.path.exists(lock_path):
|
||||||
|
os.remove(lock_path)
|
||||||
@@ -9,7 +9,7 @@ from pathlib import Path
|
|||||||
from threading import Thread
|
from threading import Thread
|
||||||
|
|
||||||
from bauh.api.http import HttpClient
|
from bauh.api.http import HttpClient
|
||||||
from bauh.gems.appimage import LOCAL_PATH
|
from bauh.gems.appimage import LOCAL_PATH, db
|
||||||
|
|
||||||
|
|
||||||
class DatabaseUpdater(Thread if bool(int(os.getenv('BAUH_DEBUG', 0))) else Process):
|
class DatabaseUpdater(Thread if bool(int(os.getenv('BAUH_DEBUG', 0))) else Process):
|
||||||
@@ -42,7 +42,10 @@ class DatabaseUpdater(Thread if bool(int(os.getenv('BAUH_DEBUG', 0))) else Proce
|
|||||||
if old_db_files:
|
if old_db_files:
|
||||||
self.logger.info('Deleting old database files')
|
self.logger.info('Deleting old database files')
|
||||||
for f in old_db_files:
|
for f in old_db_files:
|
||||||
|
db.acquire_lock(f)
|
||||||
os.remove(f)
|
os.remove(f)
|
||||||
|
db.release_lock(f)
|
||||||
|
|
||||||
self.logger.info('Old database files deleted')
|
self.logger.info('Old database files deleted')
|
||||||
|
|
||||||
self.logger.info('Uncompressing {}'.format(self.COMPRESS_FILE_PATH))
|
self.logger.info('Uncompressing {}'.format(self.COMPRESS_FILE_PATH))
|
||||||
|
|||||||
Reference in New Issue
Block a user