From 2b13470421825e151851b5d91b0c72b3054fc27f Mon Sep 17 00:00:00 2001
From: V3n3RiX <venerix@redcorelinux.org>
Date: Sun, 8 Apr 2018 23:10:31 +0100
Subject: rewrite history

---
 src/backend/libsisyphus.py | 259 +++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 259 insertions(+)
 create mode 100755 src/backend/libsisyphus.py

(limited to 'src')

diff --git a/src/backend/libsisyphus.py b/src/backend/libsisyphus.py
new file mode 100755
index 0000000..36a2dce
--- /dev/null
+++ b/src/backend/libsisyphus.py
@@ -0,0 +1,259 @@
+#!/usr/bin/python3
+
+import animation
+import csv
+import os
+import shutil
+import sqlite3
+import subprocess
+import sys
+import urllib3
+import io
+from datetime import datetime
+
+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'
+sisyphusDB = '/var/lib/sisyphus/db/sisyphus.db'
+mirrorCfg = '/etc/sisyphus/mirrors.conf'
+
+def checkRoot():
+    if not os.getuid() == 0:
+        sys.exit("\nYou need root permissions to do this, exiting!\n")
+
+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'
+    portage_make_conf_symlink = '/etc/portage/make.conf'
+
+    if not os.path.islink(portage_make_conf_symlink):
+        print("\nmake.conf is not a symlink, refusing to run!\n")
+        sys.exit(1)
+    else:
+        if os.path.realpath(portage_make_conf_symlink) == portage_binmode_make_conf:
+            pass
+        elif os.path.realpath(portage_make_conf_symlink) == portage_mixedmode_make_conf:
+            pass
+        else:
+            print("\nThe system is not set to binmode or mixedmode, refusing to run!\n")
+            sys.exit(1)
+
+def fetchRemoteDatabaseCSV():
+    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')
+            rmtDscUrl = str(portageOutput.rstrip().split("=")[1].strip('\"').replace('packages', 'csv') + 'remoteDescriptionsPre.csv')
+
+    http = urllib3.PoolManager()
+
+    with http.request('GET', rmtCsvUrl, preload_content=False) as tmp_buffer, open(rmtPkgCsv, '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:
+        shutil.copyfileobj(tmp_buffer, output_file)
+
+def syncGitRepos():
+    subprocess.check_call(['emerge', '--sync', '--quiet'])
+
+def syncPortageCfg():
+    os.chdir(redcore_portage_config_path)
+    subprocess.call(['git', 'pull', '--quiet'])
+
+def syncRemoteDatabaseCSV():
+    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:
+        for row in csv.reader(rmtCsv):
+            sisyphusdb.cursor().execute("insert into remote_packages (category, name, version, slot) values (?, ?, ?, ?);", row)
+    sisyphusdb.commit()
+    sisyphusdb.close()
+
+    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:
+        for row in csv.reader(rmtCsv):
+            sisyphusdb.cursor().execute("insert into remote_descriptions (category, name, description) values (?, ?, ?);", row)
+    sisyphusdb.commit()
+    sisyphusdb.close()
+        
+def syncRemoteDatabaseTable():
+    fetchRemoteDatabaseCSV()
+    syncRemoteDatabaseCSV()
+
+@animation.wait('syncing remote database tables')
+def syncAll():
+    checkRoot()
+
+    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')
+            rmtDscUrl = str(portageOutput.rstrip().split("=")[1].strip('\"').replace('packages', 'csv') + 'remoteDescriptionsPre.csv')
+
+    http = urllib3.PoolManager()
+
+    reqRmtPkgTs = http.request('HEAD',rmtCsvUrl)
+    rmtPkgTs = int(datetime.strptime(reqRmtPkgTs.headers['last-modified'], '%a, %d %b %Y %H:%M:%S %Z').strftime("%s"))
+    lclPkgTs = int(datetime.utcnow().strftime("%s"))
+
+    reqRmtDscTs = http.request('HEAD',rmtDscUrl)
+    rmtDscTs = int(datetime.strptime(reqRmtDscTs.headers['last-modified'], '%a, %d %b %Y %H:%M:%S %Z').strftime("%s"))
+    lclDscTs = int(datetime.utcnow().strftime("%s"))
+
+    if rmtPkgTs > lclPkgTs or rmtDscTs > lclDscTs:
+        fetchRemoteDatabaseCSV()
+        syncGitRepos()
+        syncPortageCfg()
+        syncRemoteDatabaseTable()
+
+def makeLocalDatabaseCSV():
+    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 syncLocalDatabaseTable():
+    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:
+        for row in csv.reader(lclCsv):
+            sisyphusdb.cursor().execute("insert into local_packages (category, name, version, slot) values (?, ?, ?, ?);", row)
+    sisyphusdb.commit()
+    sisyphusdb.close()
+
+@animation.wait('syncing local database tables')
+def startSyncSPM():
+    makeLocalDatabaseCSV()
+    syncLocalDatabaseTable()
+
+def startInstall(pkgList):
+    syncAll()
+    portageExec = subprocess.Popen(['emerge', '-aq'] + pkgList)
+    portageExec.communicate()
+    makeLocalDatabaseCSV()
+    syncLocalDatabaseTable()
+
+def startUninstall(pkgList):
+    portageExec = subprocess.Popen(['emerge', '--depclean', '-aq'] + pkgList)
+    portageExec.communicate()
+    makeLocalDatabaseCSV()
+    syncLocalDatabaseTable()
+
+def startUninstallForce(pkgList):
+    portageExec = subprocess.Popen(['emerge', '--unmerge', '-aq'] + pkgList)
+    portageExec.communicate()
+    makeLocalDatabaseCSV()
+    syncLocalDatabaseTable()
+
+def removeOrphans():
+    portageExec = subprocess.Popen(['emerge', '--depclean', '-aq'])
+    portageExec.communicate()
+    makeLocalDatabaseCSV()
+    syncLocalDatabaseTable()
+
+def startUpgrade():
+    syncAll()
+    portageExec = subprocess.Popen(['emerge', '-uDaNq', '--backtrack=100', '--with-bdeps=y', '@world'])
+    portageExec.communicate()
+    makeLocalDatabaseCSV()
+    syncLocalDatabaseTable()
+
+def startSearch(pkgList):
+    subprocess.check_call(['emerge', '--search'] + pkgList)
+
+def startUpdate():
+    syncAll()
+
+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)
+
+    fetchRemoteDatabaseCSV()
+    syncRemoteDatabaseCSV()
+
+    makeLocalDatabaseCSV()
+    syncLocalDatabaseTable()
+
+def portageKill(portageCmd):
+        portageCmd.terminate()
+
+def getMirrors():
+    mirrorList = []
+    with open(mirrorCfg) as mirrorFile:
+        for line in mirrorFile.readlines():
+            if 'PORTAGE_BINHOST=' in line:
+                url = line.split("=")[1].replace('"', '').rstrip()
+                mirror = {'isActive':True,'Url':url}
+                if line.startswith('#'):
+                    mirror['isActive'] = False
+                mirrorList.append(mirror)
+    mirrorFile.close()
+    return mirrorList
+
+def setActiveMirror(mirrorList):
+    with open(mirrorCfg, 'w+') as mirrorFile:
+        mirrorFile.write("#######################################################\n")
+        mirrorFile.write("# Support for multiple mirrors is somewhat incomplete #\n")
+        mirrorFile.write("#    Uncomment only one mirror from the list bellow   #\n")
+        mirrorFile.write("#######################################################\n")
+        mirrorFile.write("\n")
+        for line in mirrorList :
+            mirror = 'PORTAGE_BINHOST=' + '"' + line['Url'] + '"'
+            if not line['isActive']:
+                mirror = '# ' + mirror
+            mirrorFile.write(mirror + "\n")
+            mirrorFile.write("\n")
+
+def listRepo():
+    mirrorList = getMirrors()
+    for i, line in enumerate(mirrorList):
+        if line['isActive']:
+            print(i+1,'*',line['Url'])
+        else:
+            print(i+1,' ',line['Url'])
+
+def setRepo(mirror):
+    mirror = int(mirror[0])
+    mirrorList = getMirrors()
+    if mirror not in range(1,len(mirrorList)+1):
+        print('mirror index is wrong, please check with "sisyphus mirror list"')
+    else:
+        for i in range(0,len(mirrorList)):
+            indx = i+1
+            if indx == mirror :
+                mirrorList[i]['isActive'] = True
+            else:
+                mirrorList[i]['isActive'] = False
+        setActiveMirror(mirrorList)
+
+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")
+    print("an apt-get/yum-alike interface to these commands, to assist newcomer people transitioning from")
+    print("Debian/RedHat-based systems to Gentoo.\n")
+    print("Commands :\n")
+    print("install - Install new packages")
+    print("uninstall - Uninstall packages *safely* (INFO : If reverse deps are found, package(s) will NOT be uninstalled)")
+    print("force-uninstall - Uninstall packages *unsafely* (WARNING : This option will ignore reverse deps, which may break your system)")
+    print("remove-orphans - Uninstall packages that are no longer needed")
+    print("update - Update the Portage tree, Overlay(s), Portage config files && Sisyphus database remote_packages table")
+    print("upgrade -  Upgrade the system")
+    print("search - Search for packages")
+    print("spmsync - Sync Sisyphus database with Portage database (if you install something with Portage, not Sisyphus)")
+    print("rescue - Rescue Sisyphus database if lost or corrupted")
+    print("mirror list - List available mirrors (the active one is marked with *)")
+    print("mirror set INDEX - Switch the repository to the selected mirror")
+    print("sysinfo - Display information about installed core packages and portage configuration")
-- 
cgit v1.2.3