def gettree(tree, config): emsg("Importing " + tree + " portage tree", config) if '.pyc' in config['esearchdbfile']: ext = ".pyc" else: ext = ".py" try: target = tmp_prefix + tree + "tree" + ext if os.path.exists(target): os.unlink(target) os.symlink(os.path.join(config['esearchdbdir'], config['esearchdbfile']), target) except OSError as e: if e.errno != 17: error(str(e), fatal=True) try: if tree == "old": from esyncoldtree import db try: from esyncoldtree import dbversion if dbversion < config['needdbversion']: outofdateerror() except ImportError: outofdateerror() else: from esyncnewtree import db except ImportError: error("Could not find " + tree + "esearch-index. Please run " + green("eupdatedb") + " as root first", fatal=True) os.unlink(target) return db
def main(): try: opts = getopt(sys.argv[1:], "hvqd:n", ["help", "verbose", "quiet", "directory=", "nocolor"]) except GetoptError as error: error(error + "(see" + darkgreen("--help") + "for all options)" + '\n') config = parseopts(opts) success = updatedb(config) # sys.exit() values are opposite T/F sys.exit(not success)
def main(): try: opts = getopt(sys.argv[1:], "hwdlmnqvs", ["help", "webrsync", "delta-webrsync", "layman-sync", "nocolor", "verbose", "metadata", "nospinner", "quiet"]) except GetoptError as error: error(str(error) + " (see" + darkgreen("--help") + " for all options)") config = parseopts(opts) success = sync(config) # sys.exit() values are opposite T/F sys.exit(not success)
def main(): try: opts = getopt(sys.argv[1:], "hvqd:n", ["help", "verbose", "quiet", "directory=", "nocolor"] ) except GetoptError as error: error(error + "(see" + darkgreen("--help") + "for all options)" + '\n') config = parseopts(opts) success = updatedb(config) # sys.exit() values are opposite T/F sys.exit(not success)
def loaddb(config): """Loads the esearchdb""" try: sys.path.append(config['esearchdbdir']) from esearchdb import db except (ImportError, SyntaxError): error("Could not find esearch-index. Please run " + green("eupdatedb") + " as root first", stderr=config['stderr']) try: from esearchdb import dbversion if dbversion < config['needdbversion']: outofdateerror(config['stderr']) except ImportError: outofdateerror(config['stderr']) return db
def create_regex(config, pattern): """Creates a regular expression from a pattern string""" # Hacks for people who aren't regular expression gurus if pattern == "*": pattern = ".*" else: pattern = pattern.replace("++", r"\+\+") try: regex = re.compile(pattern, re.IGNORECASE) except re.error: error("Invalid regular expression.", stderr=config['stderr']) fullname = (config['fullname'] or '/' in pattern) and not config['searchdesc'] return pattern, regex, fullname
def parseopts(opts, config=None): if config is None: config = CONFIG if len(opts[1]) == 0: usage() for a in opts[0]: arg = a[0] if arg in ("-h", "--help"): usage() if arg in ("-S", "--searchdesc"): config['searchdesc'] = True elif arg in ("-F", "--fullname"): config['fullname'] = True elif arg in ("-I", "--instonly"): config['instonly'] = True elif arg in ("-N", "--notinst"): config['notinst'] = True elif arg in ("-c", "--compact"): config['outputm'] = COMPACT elif arg in ("-v", "--verbose"): config['outputm'] = VERBOSE elif arg in ("-e", "--ebuild"): config['portdir'] = settings["PORTDIR"] config['overlay'] = settings["PORTDIR_OVERLAY"] config['outputm'] = EBUILDS elif arg in ("-x", "--exclude"): config['exclude'].append(a[1]) elif arg in ("-o", "--own"): config['outputm'] = OWN config['outputf'] = a[1] elif arg in ("-d", "--directory"): config['esearchdbdir'] = a[1] if not exists(config['esearchdbdir']): error("directory '" + darkgreen(config['esearchdbdir']) + "' does not exist.", stderr=config['stderr']) elif arg in ("-n", "--nocolor"): nocolor() if config['fullname'] and config['searchdesc']: error("Please use either " + darkgreen("--fullname") + " or " + darkgreen("--searchdesc"), stderr=config['stderr']) return config
def main(): try: opts = getopt(sys.argv[1:], "hSFINcveo:d:n", ["help", "searchdesc", "fullname", "instonly", "notinst", "compact", "verbose", "ebuild", "own=", "directory=", "nocolor" ]) except GetoptError as errmsg: error(str(errmsg) + " (see " + darkgreen("--help") + " for all options)") config = parseopts(opts) db = loaddb(config) regexlist = create_regexp(config, opts[1]) found = search_list(config, regexlist, db) success = output_results(config, regexlist, found) # sys.exit() values are opposite T/F sys.exit(not success)
def create_regexp(config, patterns): """Creates a list of regular expressions and other data for use in db searches for each pattern in the list of patterns""" regexlist = [] # Hacks for people who aren't regular expression gurus for pattern in patterns: if pattern == "*": pattern = ".*" else: pattern = re.sub("\+\+", "\+\+", pattern) try: regexlist.append([re.compile(pattern, re.IGNORECASE), pattern, "", 0, (config['fullname'] or '/' in pattern) and not config['searchdesc']]) except re.error: error("Invalid regular expression.", stderr=config['stderr']) return regexlist
def create_regex(config, pattern): """Creates a regular expression from a pattern string""" # Hacks for people who aren't regular expression gurus if pattern == "*": pattern = ".*" else: pattern = re.sub("\+\+", "\+\+", pattern) try: regex = re.compile(pattern, re.IGNORECASE) except re.error: error("Invalid regular expression.", stderr=config['stderr']) fullname = (config['fullname'] or '/' in pattern) and not config['searchdesc'] return pattern, regex, fullname
def main(): try: opts = getopt(sys.argv[1:], "hSFINcveo:d:n", [ "help", "searchdesc", "fullname", "instonly", "notinst", "compact", "verbose", "ebuild", "own=", "directory=", "nocolor" ]) except GetoptError as errmsg: error( str(errmsg) + " (see " + darkgreen("--help") + " for all options)") config = parseopts(opts) db = loaddb(config) regexlist = create_regexp(config, opts[1]) found = search_list(config, regexlist, db) success = output_results(config, regexlist, found) # sys.exit() values are opposite T/F sys.exit(not success)
def create_regexp(config, patterns): """Creates a list of regular expressions and other data for use in db searches for each pattern in the list of patterns""" regexlist = [] # Hacks for people who aren't regular expression gurus for pattern in patterns: if pattern == "*": pattern = ".*" else: pattern = re.sub("\+\+", "\+\+", pattern) try: regexlist.append([ re.compile(pattern, re.IGNORECASE), pattern, "", 0, (config['fullname'] or '/' in pattern) and not config['searchdesc'] ]) except re.error: error("Invalid regular expression.", stderr=config['stderr']) return regexlist
def parseopts(opts, config=None): if config is None: config = CONFIG config['verbose'] = 0 for a in opts[0]: arg = a[0] if arg in ("-h", "--help"): usage() elif arg in ("-v", "--verbose"): config['verbose'] = 1 elif arg in ("-q", "--quiet"): config['verbose'] = -1 elif arg in ("-d", "--directory"): config['esearchdbdir'] = a[1] if not exists(config['esearchdbdir']): error("directory '" + darkgreen(config['esearchdbdir']) + "'", "does not exist.", stderr=config['stderr']) elif arg in ("-n", "--nocolor"): nocolor() return config
def layman_sync(config): # check for an available layman api try: from layman import Layman except ImportError: # run it in a subprocess if config['verbose'] >= 0: emsg("Doing " + config['layman-cmd'] + " now", config) if config['verbose'] == 1: errorcode = os.system(config['layman-cmd'] + " | tee " + laymanlog_sync + " 2>&1") else: errorcode = os.system(config['layman-cmd'] + " > " + laymanlog_sync + " 2>&1") if errorcode != 0: error("'" + config['layman-cmd'] + "' failed, see " + laymanlog_sync + " for errors", fatal=False) print("") return False, [] return True, [] # run the api to sync emsg("Running the Layman API", config) if config['verbose'] < 1: quietness = 0 else: quietness = 4 _layman = Layman(stdout=config['stdout'], stderr=config['stderr'], quiet=config['verbose'] < 1, quietness=quietness, verbose=config['verbose'] > 0, nocolor=config['nocolor']) repos = _layman.get_installed() success = _layman.sync(repos, output_results=config['verbose'] > 0) warnings = _layman.sync_results[1] if not success: error("Syncing with the layman api "\ "failed.\n Failures were:", fatal=False) fatals = _layman.sync_results[2] for ovl, result in fatals: error(result, fatal=False) return success, warnings
def layman_sync(config): # check for an available layman api try: from layman import Layman except ImportError: # run it in a subprocess if config['verbose'] >= 0: emsg("Doing " + config['layman-cmd'] +" now", config) if config['verbose'] == 1: errorcode = os.system(config['layman-cmd'] + " | tee " + laymanlog_sync + " 2>&1") else: errorcode = os.system(config['layman-cmd'] + " > " + laymanlog_sync + " 2>&1") if errorcode != 0: error("'" + config['layman-cmd'] + "' failed, see " + laymanlog_sync + " for errors", fatal=False) print("") return False, [] return True, [] # run the api to sync emsg("Running the Layman API", config) if config['verbose']<1: quietness=0 else: quietness=4 _layman = Layman(stdout=config['stdout'], stderr=config['stderr'], quiet=config['verbose']<1, quietness=quietness, verbose=config['verbose']>0, nocolor=config['nocolor']) repos = _layman.get_installed() success = _layman.sync(repos, output_results=config['verbose']>0) warnings = _layman.sync_results[1] if not success: error("Syncing with the layman api "\ "failed.\n Failures were:", fatal=False) fatals = _layman.sync_results[2] for ovl, result in fatals: error(result, fatal=False) return success, warnings
def output_results(config, regexlist, found): data = {} data['ebuilds'] = [] data['defebuild'] = (0, 0) data['output'] = [] count = 0 for pkg in found: if config['outputm'] in (NORMAL, VERBOSE): data['output'] += do_normal(pkg, config['outputm'] == VERBOSE) elif config['outputm'] in (COMPACT, EBUILDS): data['output'].append(do_compact(pkg)) elif config['outputm'] == OWN: data['output'].append(do_own(pkg, config['outputf'])) if config['outputm'] == EBUILDS: if count == 0: searchdef = pkg[0] + "-" + pkg[3] else: searchdef = "" search_ebuilds("%s/%s/" % (config['portdir'], pkg[1]), True, searchdef, "", config, data) if config['overlay']: repo_num=1 for repo in config['overlay'].split(): search_ebuilds("%s/%s/" % ( repo, pkg[1]), False, searchdef,repo_num, config, data) repo_num += 1 count += 1 data['count'] = len(found) data['output'] = '\n'.join(data['output']) if config['outputm'] in (NORMAL, VERBOSE): #print("[ Results for search key :", bold(pattern), "]") print("[ Applications found :", bold(str(count)), "]\n") try: print(data['output'], end=' ') print("") except IOError: pass else: print(data['output']) if config['outputm'] == EBUILDS: if config['overlay'] and config['found_in_overlay']: repo_num=1 for repo in config['overlay'].split(): print(red("Overlay "+str(repo_num)+" : "+repo)) repo_num += 1 if count != 0: if count > 1: data['defebuild'] = (0, 0) if len(data['ebuilds']) == 1: nr = 1 else: if data['defebuild'][0] != 0: print(bold("\nShow Ebuild"), " (" + darkgreen(data['defebuild'][0]) + "): ", end=' ') else: print(bold("\nShow Ebuild: "), end=' ') try: nr = sys.stdin.readline() except KeyboardInterrupt: return False try: editor = getenv("EDITOR") if editor: system(editor + " " + data['ebuilds'][int(nr) - 1]) else: print("") error("Please set EDITOR", False, stderr=config['stderr']) except IndexError: print("", file=config['stderr']) error("No such ebuild", False, stderr=config['stderr']) except ValueError: if data['defebuild'][0] != 0: system(editor + " " + data['defebuild'][1]) else: print("", file=config['stderr']) error("Please enter a valid number", False, stderr=config['stderr']) return True
def updatedb(config=None): if not os.access(config['esearchdbdir'], os.W_OK): print(yellow("Warning:"), "You do not have sufficient permissions to save the index file in:", green(config['esearchdbdir']), file=config['stderr']) return False if config['verbose'] != -1 and "ACCEPT_KEYWORDS" in environ: print(yellow("Warning:"), "You have set ACCEPT_KEYWORDS in environment, this will result", file=config['stdout']) print(" in a modified index file", file=config['stdout']) ebuilds = portage.portdb.cp_all() numebuilds = len(ebuilds) if exists(config['tmpfile']): error("there is probably another eupdatedb running already.\n" + " If you're sure there is no other process, remove", config['tmpfile'], fatal=False) return False try: dbfd = open(config['tmpfile'], O_CREAT | O_EXCL | O_WRONLY, 0o600) except OSError: error("Failed to open temporary file.", fatal=False) return False dbfile = fdopen(dbfd, "w") dbfile.write("dbversion = " + str(config['needdbversion']) + "\n") dbfile.write("db = (\n") if not config['verbose']: config['stdout'].write(green(" * ") + "indexing: ") config['stdout'].flush() nr = 0 nrchars = 0 elif config['verbose'] == 1: lastcat = False cattime = time() try: for pkg in ebuilds: masked = False if not config['verbose']: nr += 1 s = str(numebuilds - nr) + " ebuilds to go" config['stdout'].write((nrchars * "\b \b") + s) config['stdout'].flush() nrchars = len(s) pkgv = portage.portdb.xmatch("bestmatch-visible", pkg) if not pkgv: pkgv = portage.best(portage.portdb.xmatch("match-all", pkg)) if not pkgv: continue masked = True if len(pkgv) > 1: try: homepage, description, _license = portage.portdb.aux_get( pkgv, ["HOMEPAGE", "DESCRIPTION", "LICENSE"]) except KeyError: homepage, description, _license = "", "", "" pass if len(pkgv) > 1: filesize = getfetchsize(pkgv) else: filesize = '0' (curcat, pkgname) = pkg.split("/") if config['verbose'] == 1 and curcat != lastcat: if lastcat != False: print(duration(cattime), file=config['stdout']) print(bold(" * " + curcat) + ":", end=' ', file=config['stdout']) cattime = time() lastcat = curcat installed = pkg_version(VARTREE.dep_bestmatch(pkg)) if installed: installed = str(installed) dbfile.write(repr((str(pkgname), str(pkg), masked, str(pkg_version(pkgv)), installed, str(filesize), str(homepage), str(description), str(_license))) + str(",\n")) except KeyboardInterrupt: dbfile.close() unlink(config['tmpfile']) print("", file=config['stdout']) return False print("", file=config['stdout']) dbfile.write(")") dbfile.close() copyfile(config['tmpfile'], os.path.join(config['esearchdbdir'], config['esearchdbfile'])) unlink(config['tmpfile']) sys.path.insert(0, config['esearchdbdir']) import esearchdb # import the file, to generate pyc if exists( os.path.join(config['esearchdbdir'], config['esearchdbfile']) + "c"): config['esearchdbfile'] += "c" print(green(" *"), "esearch-index generated in", duration(start), file=config['stdout']) print(green(" *"), "indexed", bold(str(numebuilds)), "ebuilds", file=config['stdout']) print(green(" *"), "size of esearch-index:", bold(str(int(stat( os.path.join(config['esearchdbdir'], config['esearchdbfile']) )[6]/1024)) + " kB"), file=config['stdout']) return True
def updatedb(config=None): if not os.access(config['esearchdbdir'], os.W_OK): print( yellow("Warning:"), "You do not have sufficient permissions to save the index file in:", green(config['esearchdbdir']), file=config['stderr']) return False if config['verbose'] != -1 and "ACCEPT_KEYWORDS" in environ: print(yellow("Warning:"), "You have set ACCEPT_KEYWORDS in environment, this will result", file=config['stdout']) print(" in a modified index file", file=config['stdout']) ebuilds = portage.portdb.cp_all() numebuilds = len(ebuilds) if exists(config['tmpfile']): error("there is probably another eupdatedb running already.\n" + " If you're sure there is no other process, remove", config['tmpfile'], fatal=False) return False try: dbfd = open(config['tmpfile'], O_CREAT | O_EXCL | O_WRONLY, 0o600) except OSError: error("Failed to open temporary file.", fatal=False) return False dbfile = fdopen(dbfd, "w") dbfile.write("dbversion = " + str(config['needdbversion']) + "\n") dbfile.write("db = (\n") if not config['verbose']: config['stdout'].write(green(" * ") + "indexing: ") config['stdout'].flush() nr = 0 nrchars = 0 elif config['verbose'] == 1: lastcat = False cattime = time() try: for pkg in ebuilds: masked = False if not config['verbose']: nr += 1 s = str(numebuilds - nr) + " ebuilds to go" config['stdout'].write((nrchars * "\b \b") + s) config['stdout'].flush() nrchars = len(s) pkgv = portage.portdb.xmatch("bestmatch-visible", pkg) if not pkgv: pkgv = portage.best(portage.portdb.xmatch("match-all", pkg)) if not pkgv: continue masked = True if len(pkgv) > 1: try: homepage, description, _license = portage.portdb.aux_get( pkgv, ["HOMEPAGE", "DESCRIPTION", "LICENSE"]) except KeyError: homepage, description, _license = "", "", "" pass if len(pkgv) > 1: filesize = getfetchsize(pkgv) else: filesize = '0' (curcat, pkgname) = pkg.split("/") if config['verbose'] == 1 and curcat != lastcat: if lastcat != False: print(duration(cattime), file=config['stdout']) print(bold(" * " + curcat) + ":", end=' ', file=config['stdout']) cattime = time() lastcat = curcat installed = pkg_version(VARTREE.dep_bestmatch(pkg)) if installed: installed = str(installed) dbfile.write( repr((str(pkgname), str(pkg), masked, str(pkg_version(pkgv)), installed, str(filesize), str(homepage), str(description), str(_license))) + str(",\n")) except KeyboardInterrupt: dbfile.close() unlink(config['tmpfile']) print("", file=config['stdout']) return False print("", file=config['stdout']) dbfile.write(")") dbfile.close() copyfile(config['tmpfile'], os.path.join(config['esearchdbdir'], config['esearchdbfile'])) unlink(config['tmpfile']) sys.path.insert(0, config['esearchdbdir']) import esearchdb # import the file, to generate pyc if exists( os.path.join(config['esearchdbdir'], config['esearchdbfile']) + "c"): config['esearchdbfile'] += "c" print(green(" *"), "esearch-index generated in", duration(start), file=config['stdout']) print(green(" *"), "indexed", bold(str(numebuilds)), "ebuilds", file=config['stdout']) print(green(" *"), "size of esearch-index:", bold( str( int( stat( os.path.join(config['esearchdbdir'], config['esearchdbfile']))[6] / 1024)) + " kB"), file=config['stdout']) return True
def output_results(config, regexlist, found): data = {} data['ebuilds'] = [] data['defebuild'] = (0, 0) i = 0 for regex, pattern, foo, foo, fullname in regexlist: count = 0 data['output'] = [] for pkg in found[pattern]: if config['outputm'] in (NORMAL, VERBOSE): newdata, _continue = do_normal(pkg, config['outputm'] == VERBOSE) data['output'] += newdata if _continue: continue elif config['outputm'] in (COMPACT, EBUILDS): data['output'].append(do_compact(pkg)) elif config['outputm'] == OWN: data['output'].append(do_own(pkg, config['outputf'])) if config['outputm'] == EBUILDS: if count == 0: searchdef = pkg[0] + "-" + pkg[3] else: searchdef = "" searchEbuilds("%s/%s/" % (config['portdir'], pkg[1]), True, searchdef, "", config, data) if config['overlay']: repo_num = 1 for repo in config['overlay'].split(): searchEbuilds("%s/%s/" % (repo, pkg[1]), False, searchdef, repo_num, config, data) repo_num += 1 count += 1 regexlist[i][2] = "\n".join(data['output']) regexlist[i][3] = count i += 1 for regex, pattern, output, count, foo in regexlist: if config['outputm'] in (NORMAL, VERBOSE): print("[ Results for search key :", bold(pattern), "]") print("[ Applications found :", bold(str(count)), "]\n") try: print(output, end=' ') print("") except IOError: pass else: print(output) if config['outputm'] == EBUILDS: if config['overlay'] and config['found_in_overlay']: repo_num = 1 for repo in config['overlay'].split(): print(red("Overlay " + str(repo_num) + " : " + repo)) repo_num += 1 if count != 0: if count > 1: data['defebuild'] = (0, 0) if len(data['ebuilds']) == 1: nr = 1 else: if data['defebuild'][0] != 0: print(bold("\nShow Ebuild"), " (" + darkgreen(data['defebuild'][0]) + "): ", end=' ') else: print(bold("\nShow Ebuild: "), end=' ') try: nr = sys.stdin.readline() except KeyboardInterrupt: return False try: editor = getenv("EDITOR") if editor: system(editor + " " + data['ebuilds'][int(nr) - 1]) else: print("") error("Please set EDITOR", False, stderr=config['stderr']) except IndexError: print("", file=config['stderr']) error("No such ebuild", False, stderr=config['stderr']) except ValueError: if data['defebuild'][0] != 0: system(editor + " " + data['defebuild'][1]) else: print("", file=config['stderr']) error("Please enter a valid number", False, stderr=config['stderr']) return True
def sync(config): tree_old = gettree("old", config) if config['layman-sync']: if not layman_sync(config): return False if config['verbose'] >= 0: emsg("Doing '" + config['syncprogram'] + "' now", config) if config['verbose'] == 1: errorcode = os.system(config['syncprogram'] + " | tee " + logfile_sync + " 2>&1") else: errorcode = os.system(config['syncprogram'] + " > " + logfile_sync + " 2>&1") if errorcode != 0: error("'" + config['syncprogram'] + "' failed, see " + logfile_sync + " for errors", fatal=False) return False if config['verbose'] >= 0: print("") emsg("Doing 'eupdatedb' now", config) print("") # run eupdatedb natively success = updatedb(config) if not success: print("") error("running updatedb failed", fatal=False) return False if config['verbose'] >= 0: print("") # uncomment the sys.path line below if you comment out the # emerge sync code section for testing #sys.path.insert(0, config['esearchdbdir']) from esearchdb import db as tree_new emsg("Preparing databases", config) new = {} for pkg in tree_new: new[pkg[1]] = pkg[3] old = {} for pkg in tree_old: old[pkg[1]] = pkg[3] emsg("Searching for changes", config) print("") # alphabetic sort items = list(new.items()) items.sort(lambda x, y: cmp(x[0], y[0])) old_keys = list(old.keys()) # update our config to run searchdb config['outputm'] = COMPACT config['fullname'] = True #individual pkgname search method haspkgs = False for (pkg, version) in items: if (pkg not in old_keys) or (old[pkg] != new[pkg]): success = searchdb(config, ["^" + pkg + "$"], tree_new) haspkgs = True if not haspkgs: emsg("No updates found", config) success = True # multiple pkgname search method # build our re search list #pkg_patterns = [] #for (pkg, version) in items: #if (pkg not in old_keys) or (old[pkg] != new[pkg]): #pkg_patterns.append("^" + pkg + "$") #if pkg_patterns == []: #emsg("No updates found", config) #success = True #else: #success = searchdb(config, pkg_patterns, tree_new) return success