summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xsrc/backend/libsisyphus.py187
-rwxr-xr-xsrc/frontend/gui/sisyphus-gui.py8
2 files changed, 127 insertions, 68 deletions
diff --git a/src/backend/libsisyphus.py b/src/backend/libsisyphus.py
index f166dd7..cfd93a8 100755
--- a/src/backend/libsisyphus.py
+++ b/src/backend/libsisyphus.py
@@ -9,21 +9,23 @@ import subprocess
import sys
import urllib3
import io
-
from dateutil import parser
redcore_portage_config_path = '/opt/redcore-build'
-
-rmtPkgCsv = '/var/lib/sisyphus/csv/remotePackagesPre.csv'
-rmtDscCsv = '/var/lib/sisyphus/csv/remoteDescriptionsPre.csv'
-lclPkgCsv = '/var/lib/sisyphus/csv/localPackagesPre.csv'
+remotePkgsDB = '/var/lib/sisyphus/csv/remotePackagesPre.csv'
+remoteDscsDB = '/var/lib/sisyphus/csv/remoteDescriptionsPre.csv'
+localPkgsDB = '/var/lib/sisyphus/csv/localPackagesPre.csv'
sisyphusDB = '/var/lib/sisyphus/db/sisyphus.db'
mirrorCfg = '/etc/sisyphus/mirrors.conf'
+# only run as root (CLI + GUI frontend)
+
def checkRoot():
if not os.getuid() == 0:
sys.exit("\nYou need root permissions to do this, exiting!\n")
+# only run in binary mode (binmode) or hybrid mode (mixedmode) (CLI + GUI frontend)
+
def checkSystemMode():
portage_binmode_make_conf = '/opt/redcore-build/conf/intel/portage/make.conf.amd64-binmode'
portage_mixedmode_make_conf = '/opt/redcore-build/conf/intel/portage/make.conf.amd64-mixedmode'
@@ -41,44 +43,51 @@ def checkSystemMode():
print("\nThe system is not set to binmode or mixedmode, refusing to run!\n")
sys.exit(1)
-def getRmtCsvUrl():
- rmtCsvUrl = []
+# get current mirror information, so we know where we download from (CLI + GUI frontend)
+
+def getRemotePkgsURL():
+ remotePkgsURL = []
portageExec = subprocess.Popen(['emerge', '--info', '--verbose'], stdout=subprocess.PIPE)
for portageOutput in io.TextIOWrapper(portageExec.stdout, encoding="utf-8"):
if "PORTAGE_BINHOST" in portageOutput.rstrip():
- rmtCsvUrl = str(portageOutput.rstrip().split("=")[1].strip('\"').replace('packages', 'csv') + 'remotePackagesPre.csv')
- return rmtCsvUrl
+ remotePkgsURL = str(portageOutput.rstrip().split("=")[1].strip('\"').replace('packages', 'csv') + 'remotePackagesPre.csv')
+ return remotePkgsURL
-def getRmtDscUrl():
- rmtDscUrl = []
+def getRemoteDscsURL():
+ remoteDscsURL = []
portageExec = subprocess.Popen(['emerge', '--info', '--verbose'], stdout=subprocess.PIPE)
for portageOutput in io.TextIOWrapper(portageExec.stdout, encoding="utf-8"):
if "PORTAGE_BINHOST" in portageOutput.rstrip():
- rmtDscUrl = str(portageOutput.rstrip().split("=")[1].strip('\"').replace('packages', 'csv') + 'remoteDescriptionsPre.csv')
- return rmtDscUrl
+ remoteDscsURL = str(portageOutput.rstrip().split("=")[1].strip('\"').replace('packages', 'csv') + 'remoteDescriptionsPre.csv')
+ return remoteDscsURL
-def fetchRemoteDatabaseCSV():
- rmtCsvUrl = getRmtCsvUrl()
- rmtDscUrl = getRmtDscUrl()
+# download remote CSV's to be imported into the database (CLI + GUI frontend)
+def fetchRemoteDatabase():
+ remotePkgsURL = getRemotePkgsURL()
+ remoteDscsURL = getRemoteDscsURL()
http = urllib3.PoolManager()
- with http.request('GET', rmtCsvUrl, preload_content=False) as tmp_buffer, open(rmtPkgCsv, 'wb') as output_file:
+ with http.request('GET', remotePkgsURL, preload_content=False) as tmp_buffer, open(remotePkgsDB, 'wb') as output_file:
shutil.copyfileobj(tmp_buffer, output_file)
- with http.request('GET', rmtDscUrl, preload_content=False) as tmp_buffer, open(rmtDscCsv, 'wb') as output_file:
+ with http.request('GET', remoteDscsURL, preload_content=False) as tmp_buffer, open(remoteDscsDB, 'wb') as output_file:
shutil.copyfileobj(tmp_buffer, output_file)
-def makeLocalDatabaseCSV():
+# generate local CSV's to be imported into the database (CLI + GUI frontend)
+
+def makeLocalDatabase():
subprocess.check_call(['/usr/share/sisyphus/helpers/make_local_csv']) # this is really hard to do in python, so we cheat with a bash helper script
-def syncRemoteDatabaseTable():
- fetchRemoteDatabaseCSV()
+# download and import remote CSV's into the database (CLI + GUI frontend)
+
+def syncRemoteDatabase():
+ fetchRemoteDatabase()
sisyphusdb = sqlite3.connect(sisyphusDB)
sisyphusdb.cursor().execute('''drop table if exists remote_packages''')
sisyphusdb.cursor().execute('''create table remote_packages (category TEXT,name TEXT,version TEXT,slot TEXT)''')
- with open(rmtPkgCsv) as rmtCsv:
+ with open(remotePkgsDB) as rmtCsv:
for row in csv.reader(rmtCsv):
sisyphusdb.cursor().execute("insert into remote_packages (category, name, version, slot) values (?, ?, ?, ?);", row)
sisyphusdb.commit()
@@ -87,114 +96,156 @@ def syncRemoteDatabaseTable():
sisyphusdb = sqlite3.connect(sisyphusDB)
sisyphusdb.cursor().execute('''drop table if exists remote_descriptions''')
sisyphusdb.cursor().execute('''create table remote_descriptions (category TEXT,name TEXT,description TEXT)''')
- with open(rmtDscCsv) as rmtCsv:
+ with open(remoteDscsDB) as rmtCsv:
for row in csv.reader(rmtCsv):
sisyphusdb.cursor().execute("insert into remote_descriptions (category, name, description) values (?, ?, ?);", row)
sisyphusdb.commit()
sisyphusdb.close()
-def syncLocalDatabaseTable():
- makeLocalDatabaseCSV()
+# generate and import local CSV's into the database (CLI + GUI frontend)
+
+def syncLocalDatabase():
+ makeLocalDatabase()
sisyphusdb = sqlite3.connect(sisyphusDB)
sisyphusdb.cursor().execute('''drop table if exists local_packages''')
sisyphusdb.cursor().execute('''create table local_packages (category TEXT,name TEXT,version TEXT,slot TEXT)''')
- with open(lclPkgCsv) as lclCsv:
+ with open(localPkgsDB) as lclCsv:
for row in csv.reader(lclCsv):
sisyphusdb.cursor().execute("insert into local_packages (category, name, version, slot) values (?, ?, ?, ?);", row)
sisyphusdb.commit()
sisyphusdb.close()
-def syncGitRepos():
- subprocess.check_call(['emerge', '--sync', '--quiet'])
+# sync portage tree (CLI + GUI frontend)
+
+def syncPortageTree():
+ subprocess.call(['emerge', '--sync', '--quiet'])
+
+# sync portage configuration files (CLI + GUI frontend)
def syncPortageCfg():
os.chdir(redcore_portage_config_path)
subprocess.call(['git', 'pull', '--quiet'])
-@animation.wait('syncing remote database tables')
+# check remote timestamps...if newer than local timestamps, sync everything (CLI + GUI frontend)
+
+@animation.wait('syncing remote database')
def syncAll():
checkRoot()
- rmtCsvUrl = getRmtCsvUrl()
- rmtDscUrl = getRmtDscUrl()
+ remotePkgsURL = getRemotePkgsURL()
+ remoteDscsURL = getRemoteDscsURL()
http = urllib3.PoolManager()
- reqRmtPkgTs = http.request('HEAD',rmtCsvUrl)
- rmtPkgTs = int(parser.parse(reqRmtPkgTs.headers['last-modified']).strftime("%s"))
- lclPkgTs = int(os.path.getctime(rmtPkgCsv))
+ reqRemotePkgsTS = http.request('HEAD',remotePkgsURL)
+ remotePkgsTS = int(parser.parse(reqRemotePkgsTS.headers['last-modified']).strftime("%s"))
+ localPkgsTS = int(os.path.getctime(remotePkgsDB))
- reqRmtDscTs = http.request('HEAD',rmtDscUrl)
- rmtDscTs = int(parser.parse(reqRmtDscTs.headers['last-modified']).strftime("%s"))
- lclDscTs = int(os.path.getctime(rmtDscCsv))
+ reqRemoteDscsTS = http.request('HEAD',remoteDscsURL)
+ remoteDscsTS = int(parser.parse(reqRemoteDscsTS.headers['last-modified']).strftime("%s"))
+ localDscsTS = int(os.path.getctime(remoteDscsDB))
- if rmtPkgTs > lclPkgTs or rmtDscTs > lclDscTs:
- syncGitRepos()
+ if remotePkgsTs < localPkgsTs:
+ pass
+ elif remoteDscsTs < localDscsTs:
+ pass
+ else:
+ syncPortageTree()
syncPortageCfg()
- syncRemoteDatabaseTable()
+ syncRemoteDatabase()
+
+# regenerate local CSV's and import them into the database (CLI frontend)
+# if something is installed with portage directly using emerge, sisyphus won't be aware of it
+# this will parse local portage database and import the changes into sisyphus database
-@animation.wait('syncing local database tables')
+@animation.wait('syncing local database')
def startSyncSPM():
- syncLocalDatabaseTable()
+ syncLocalDatabase()
+
+# sync portage tree and portage configuration files (CLI frontend)
+
+@animation.wait('syncing portage')
+def startSync():
+ syncPortageTree()
+ syncPortageCfg()
+
+# regenerate sisyphus database (CLI frontend)
+# if for some reason sisyphus database gets corrupted or deleted, we can still regenerate it from portage database
+# this will fetch remote information from mirrors, parse local portage database and regenerate sisyphus database
+
+@animation.wait('resurrecting database')
+def rescueDB():
+ if os.path.exists(remotePkgsDB):
+ os.remove(remotePkgsDB)
+ if os.path.exists(remoteDscsDB):
+ os.remove(remoteDscsDB)
+ if os.path.exists(localPkgsDB):
+ os.remove(localPkgsDB)
+ if os.path.exists(sisyphusDB):
+ os.remove(sisyphusDB)
+
+ syncRemoteDatabase()
+ syncLocalDatabase()
+
+# call portage to install the package(s) (CLI frontend)
def startInstall(pkgList):
syncAll()
portageExec = subprocess.Popen(['emerge', '-aq'] + pkgList)
portageExec.communicate()
- syncLocalDatabaseTable()
+ syncLocalDatabase()
+
+# call portage to uninstall the package(s) (CLI frontend)
def startUninstall(pkgList):
portageExec = subprocess.Popen(['emerge', '--depclean', '-aq'] + pkgList)
portageExec.communicate()
- syncLocalDatabaseTable()
+ syncLocalDatabase()
+
+# call portage to force-uninstall the package(s) (CLI frontend)
def startUninstallForce(pkgList):
portageExec = subprocess.Popen(['emerge', '--unmerge', '-aq'] + pkgList)
portageExec.communicate()
- syncLocalDatabaseTable()
+ syncLocalDatabase()
+
+# call portage to remove orphan package(s) (CLI frontend)
def removeOrphans():
portageExec = subprocess.Popen(['emerge', '--depclean', '-aq'])
portageExec.communicate()
- syncLocalDatabaseTable()
+ syncLocalDatabase()
+
+# call portage to perform a system upgrade (CLI frontend)
def startUpgrade():
syncAll()
portageExec = subprocess.Popen(['emerge', '-uDaNq', '--backtrack=100', '--with-bdeps=y', '@world'])
portageExec.communicate()
- syncLocalDatabaseTable()
+ syncLocalDatabase()
+
+# call portage to search for package(s) (CLI frontend)
def startSearch(pkgList):
subprocess.check_call(['emerge', '--search'] + pkgList)
+# check remote timestamps...if newer than local timestamps, sync everything (CLI + GUI frontend)
+
def startUpdate():
syncAll()
-@animation.wait('syncing portage tree && portage config files')
-def startSync():
- syncGitRepos()
- syncPortageCfg()
+# display information about installed core packages and portage configuration (CLI frontend)
def sysInfo():
subprocess.check_call(['emerge', '--info'])
-@animation.wait('resurrecting database tables')
-def rescueDB():
- if os.path.exists(rmtPkgCsv):
- os.remove(rmtPkgCsv)
- if os.path.exists(rmtDscCsv):
- os.remove(rmtDscCsv)
- if os.path.exists(lclPkgCsv):
- os.remove(lclPkgCsv)
- if os.path.exists(sisyphusDB):
- os.remove(sisyphusDB)
-
- syncRemoteDatabaseTable()
- syncLocalDatabaseTable()
+# kill background portage process if sisyphus dies (CLI + GUI frontend)
def portageKill(portageCmd):
portageCmd.terminate()
+# get a list of mirrors (GUI frontend)
+
def getMirrors():
mirrorList = []
with open(mirrorCfg) as mirrorFile:
@@ -208,6 +259,8 @@ def getMirrors():
mirrorFile.close()
return mirrorList
+# set the active mirror (GUI frontend)
+
def setActiveMirror(mirrorList):
with open(mirrorCfg, 'w+') as mirrorFile:
mirrorFile.write("#######################################################\n")
@@ -222,6 +275,8 @@ def setActiveMirror(mirrorList):
mirrorFile.write(mirror + "\n")
mirrorFile.write("\n")
+# get a list of mirrors (CLI frontend)
+
def listRepo():
mirrorList = getMirrors()
for i, line in enumerate(mirrorList):
@@ -230,6 +285,8 @@ def listRepo():
else:
print(i+1,' ',line['Url'])
+# set the active mirror (CLI frontend)
+
def setRepo(mirror):
mirror = int(mirror[0])
mirrorList = getMirrors()
@@ -244,6 +301,8 @@ def setRepo(mirror):
mirrorList[i]['isActive'] = False
setActiveMirror(mirrorList)
+# display help menu (CLI frontend)
+
def showHelp():
print("\nUsage : sisyphus command [package(s)] || [file(s)]\n")
print("Sisyphus is a simple python wrapper around portage, gentoolkit, and portage-utils that provides")
diff --git a/src/frontend/gui/sisyphus-gui.py b/src/frontend/gui/sisyphus-gui.py
index 238e291..406ea7a 100755
--- a/src/frontend/gui/sisyphus-gui.py
+++ b/src/frontend/gui/sisyphus-gui.py
@@ -377,7 +377,7 @@ class MainWorker(QtCore.QObject):
atexit.register(portageKill, portageExec)
for portageOutput in io.TextIOWrapper(portageExec.stdout, encoding="utf-8"):
self.strReady.emit(portageOutput.rstrip())
- syncLocalDatabaseTable()
+ syncLocalDatabase()
self.finished.emit()
@QtCore.pyqtSlot()
@@ -389,7 +389,7 @@ class MainWorker(QtCore.QObject):
atexit.register(portageKill, portageExec)
for portageOutput in io.TextIOWrapper(portageExec.stdout, encoding="utf-8"):
self.strReady.emit(portageOutput.rstrip())
- syncLocalDatabaseTable()
+ syncLocalDatabase()
self.finished.emit()
@QtCore.pyqtSlot()
@@ -400,7 +400,7 @@ class MainWorker(QtCore.QObject):
atexit.register(portageKill, portageExec)
for portageOutput in io.TextIOWrapper(portageExec.stdout, encoding="utf-8"):
self.strReady.emit(portageOutput.rstrip())
- syncLocalDatabaseTable()
+ syncLocalDatabase()
self.finished.emit()
@QtCore.pyqtSlot()
@@ -411,7 +411,7 @@ class MainWorker(QtCore.QObject):
atexit.register(portageKill, portageExec)
for portageOutput in io.TextIOWrapper(portageExec.stdout, encoding="utf-8"):
self.strReady.emit(portageOutput.rstrip())
- syncLocalDatabaseTable()
+ syncLocalDatabase()
self.finished.emit()