You are not logged in.

#26 2007-11-04 23:53:11

kanpio
Member
From: Poland/Wrocław
Registered: 2006-01-25
Posts: 49

Re: psearch - Gentoo's esearch Arch style [revision]

How about making psearch more colorful? I think this is more readable:

2_2.png

Here is psearch file:

#!/usr/bin/env python
import sys
from psearch import *
from getopt import *

def usage():
    """ displays the help message then exits """
    print bold + "psearch v1.1 " + neutral + "- written by Justin Cameron (wrythe@gmail.com)\n"
    print "Usage: " + bold + "psearch " + neutral + "[ options ] <string>"
    print bold + "Options:"
    print "  --aur, -a"
    print neutral + "    Include the Arch User Repository in the search\n"
    print bold + "  --allpackages=<repository>, -A <repository>"
    print neutral + "    List all packages in <repository>\n"
    print bold + "  --compact, -c"
    print neutral + "    Use compact output (displays less information)\n"
    print bold + "  --depends=<package>, -d <package>"
    print neutral + "    Display packages that depend on <package>\n"
    print bold + "  --format, -f"
    print neutral + "    Use custom output format (see man page for details)\n"
    print bold + "  --group=<group>, -g <group>"
    print neutral + "    Display all packages that are members of <group>\n"
    print bold + "  --help, -h"
    print neutral + "    Display this help dialog\n"
    print bold + "  --info, -I"
    print neutral + "    Display pacman and repository information\n"
    print bold + "  --instonly, -i"
    print neutral + "    Only display packages that are installed\n"
    print bold + "  --listfiles=<package>, -l <package>"
    print neutral + "    List files owned by <package>\n"
    print bold + "  --noinstonly, -n"
    print neutral + "    Only display packages that are not installed\n"
    print bold + "  --upgradeonly, -u"
    print neutral + "    Only display packages that are installed and have a newer version available\n"
    print bold + "  --omit=<string>, -o <string>"
    print neutral + "    Omit a string from the results (helpful to narrow searches)\n"
    print bold + "  --owns=<file>, -O <file>"
    print neutral + "    Display information for the package that owns <file>\n"
    print bold + "  --pkginfo=<package>, -p <package>"
    print neutral + "    Display information for <package>\n"
    print bold + "  --rep=<repository>, -r <repository>"
    print neutral + "    Only search in <repository>\n"
    print bold + "  --strict, -s"
    print neutral + "    Match package name only, not name and description\n"
    print bold + "  --reverse, -v"
    print neutral + "    Reverse output (display from Z-A instead of A-Z)\n"
    print bold + "  --nocolor, -x"
    print neutral + "    Suppress all color from output\n"
    print bold + "  --boldonly, -X"
    print neutral + "    Suppress all color from output, but keep bolded text\n"
    print "  Try " + bold + "man psearch" + neutral + " for more details"

def help():
    print ""
    print bold + "Usage: psearch " + neutral + "[options] <string>"
    print bold + "Options: " + neutral + "[aAdfghiIlnucrsoOpvxX]"
    print neutral + "For more help try " + bold + "psearch --help" + neutral,
    print "or consult the man page"
    print ""

def kill_color(keepbold):
    global blue
    global white
    global cyan
    global red
    global grey
    global neutral
    global bold

    blue = ""
    cyan = ""
    grey = ""
    white = ""
    red = ""
    
    if not keepbold:
        neutral = ""
        bold = ""

def convert_size(x):
    x = int(x)
    x = x / 1024

    if x < 999:
        x = str(x)
    elif x < 999999:
        x = str(x)
        x = x[:-3] + "," + x[-3:]
    elif x < 999999999:
        x = str(x)
        x = x[:-3] + "," + x[-3:]
        x = x[:-7] + "," + x[-7:]
    else:
        x = str(x)

    return x + " kB"

# formats long strings to wrap nicely given a
# string and space buffer
def format_text(s, b):
    width = int(os.popen("stty size").read().split()[1])
    if len(s) <= width - b:
        return s

    result = ""
    n = width - b
    s += " "
    while len(s) > 0:
        result += b*" " + s[:n]
        while not result.endswith(" ") and not result.endswith(".") and not result.endswith(","):
            s = result[-1] + s
            result = result[:-1]
        s = s[n:]            
        result += "\n"

    return result[b:].strip()

# like format_text, but specifically for compact output
def format_compact_text(s, b):
    width = int(os.popen("stty size").read().split()[1])
    if len(s) <= width - (b + 10):
        return s

    s += " "    
    result = s[:width - (b + 10)]
    s = s[width - (b + 10):]
    n = width - 4
    
    while len(s) > 0:
        while not result.endswith(" ") and not result.endswith(".") and not result.endswith("-") and not result.endswith(","):
            s = result[-1] + s
            result = result[:-1]
            
        result += "\n    " + s[:n].strip()
        s = s[n:].strip()
        
                
    return result

# print error message and exit
def error(msg):
    print red + "Error:" + neutral, msg, neutral
    sys.exit(-1)

# print error then list valid repositories
def rep_error(rep):
    print red + "Error: " + bold + rep + neutral + " is not a valid repository"
    print "Available repositories are:"
    print blue + "  :: " + bold + "aur"
    print blue + "  :: " + bold + "local"
    for i in rep_list():
        print blue + "  :: " + bold + i
    
    print neutral
    sys.exit(-1)
    
# package information    
def show_pkg_info(pkg):
    try:
        if pkg_version_installed(pkg) != None:
            installed = True
        else:
            installed = False
            
        data = pkg_info(pkg, installed)
        o = [blue + " > " + bold + pkg + neutral + " information:"]
        if installed:
            if data[11]:
                reason = "Explicitly installed"
            else:
                reason = "Installed as a dependency"
            
            if len(data[13]) == 0:
                deps = "None  "
            else:
                deps = ""
                for i in data[13]:
                    deps += i + ", "

            if len(data[14]) == 0:
                req = "None  "
            else:
                req = ""
                for i in data[14]:
                    req += i + ", "
                                
            if len(data[15]) == 0:
                conflicts = "None  "
            else:
                conflicts = ""
                for i in data[15]:
                    conflicts += i + ", "
            
            # some casting must be done since some values may be None
            o.append(grey + "   Package name      : " + neutral + pkg)
            o.append(grey + "   Package version   : " + neutral + data[0])
            o.append(grey + "   Packaged by       : " + neutral + data[6])
            o.append(grey + "   Homepage          : " + neutral + str(data[5]))
            o.append(grey + "   License           : " + neutral + str(data[7]))
            o.append(grey + "   Group             : " + neutral + str(data[3]))
            o.append(grey + "   Architecture      : " + neutral + data[8])
            o.append(grey + "   Installed size    : " + neutral 
                + convert_size(data[2]))
            o.append(grey + "   Build date        : " + neutral + data[9])
            o.append(grey + "   Install date      : " + neutral + data[10])
            o.append(grey + "   Reason installed  : " + neutral + reason)
            o.append(grey + "   Dependencies      : " + neutral 
                + format_text(deps[:-2], 23))
            o.append(grey + "   Required by       : " + neutral 
                + format_text(req[:-2], 23))
            o.append(grey + "   Conflicts with    : " + neutral 
                + format_text(conflicts[:-2], 23))
            o.append(grey + "   Description       : " + neutral 
                + format_text(data[1], 23))
        else:
            if len(data[6]) == 0:
                deps = "None  "
            else:
                deps = ""
                for i in data[6]:
                    deps += i + ", "

            if len(data[7]) == 0:
                replaces = "None  "
            else:
                replaces = ""
                for i in data[7]:
                    replaces += i + ", "
                                
            if len(data[8]) == 0:
                conflicts = "None  "
            else:
                conflicts = ""
                for i in data[8]:
                    conflicts += i + ", "

            # some casting must be done since some values may be None
            o.append(grey + "   Repository        : " + neutral + data[4])
            o.append(grey + "   Package name      : " + neutral + pkg)
            o.append(grey + "   Package version   : " + neutral + data[0])
            o.append(grey + "   Group             : " + neutral + str(data[3]))
            o.append(grey + "   Download size     : " + neutral 
                + convert_size(data[2]))
            o.append(grey + "   Dependencies      : " + neutral 
                + format_text(deps[:-2], 23))
            o.append(grey + "   Conflicts with    : " + neutral 
                + format_text(conflicts[:-2], 23))
            o.append(grey + "   Replaces          : " + neutral 
                + format_text(replaces[:-2], 23))
            o.append(grey + "   Description       : " + neutral 
                + format_text(data[1], 23))
            o.append(grey + "   MD5 sum           : " + neutral + data[5])

        for i in o:
            print i
            
        print ""
    except:
        error(bold + pkg + neutral + " was not found.")

# file owner
def owns(filename):
    try:
        pkg = file_owner(filename)
        
        if pkg != None:
            print blue + " > " + bold + pkg + neutral + " owns " + bold + filename + neutral
            show_pkg_info(pkg)
        else:
            print blue + "> " + neutral + "No package owns " + bold + filename + neutral
            
    except Exception, msg:
        error(bold + filename + ": " + neutral + str(msg))

# pacman and repository information
def show_info():
    pacman_version = pkg_info("pacman", True)[0]
    pacman_cache = str(cache_total_packages()) + " packages, "
    pacman_cache += "(" + convert_size(cache_size()) + ")"
    reps = rep_list()
    
    print blue + " > " + bold + "Pacman version: " + neutral + pacman_version
    print blue + " > " + bold + "Pacman cache: " + neutral + pacman_cache
    print blue + " > " + bold + "Repositories:" + neutral
    
    for i in reps:
        print blue + "   :: " + bold + i + neutral
        print "      Last update: " + rep_last_update(i)
        print "      " + str(rep_number_of_packages(i)) + " packages available"

# list files owned by a package
def list_files(pkg):
    try:
        files = pkg_files(pkg)
        print blue + "> " + neutral + "Contents of " + bold + pkg + neutral
        for f in files:
            s = "/" + f
            
            if s.endswith("/"):
                s = bold + s[:-1] + neutral

            print s
    except:
        error("package " + bold + pkg + neutral + " was not found")

# list dependencies
def depends(pkg):
    try:
        info = pkg_info(pkg, True)
        if len(info[14]) == 0:
            print "No package requires " + bold + pkg + neutral
        else:
            print bold + pkg + neutral + " is required by: "
            for i in info[14]:
                print blue + " > " + bold + i + neutral
    except:
        error(bold + pkg + neutral + " was not found.")

# similar to portage's --pretend; list packages that would
# be upgraded or installed should an upgrad be performed
def pretend():
    dump = os.popen("pacman -Qu").read().split()
    print dump

# populate the results
def populate(style):
    global final_results

    if style == "search":
        if aur or use == "aur":
            print blue + " > " + bold + " Resolving " + cyan + "aur.archlinux.org",
            print bold + "... " + neutral,

            try:
                final_results = aur_search(regex, strict)
                print ""
            except:
                print "failed!"

            if use != "aur":
                final_results.extend(pkg_search(regex, use, strict))
        else:
            try:
                final_results = pkg_search(regex, use, strict)
            except:
                rep_error(use)
    elif style == "all":
        try:
            final_results = rep_packages(all_packages)
        except:
            rep_error(all_packages)
    elif style == "group":
        final_results = pkg_group_packages(group)
            
# find the ultimate results
def find_results():
    if use == "all" or use == "local":
        # first, find local packages to try to find any package
        # that doesn't belong to a repository
        tmp_pkgs = pkg_search(regex, "local", strict)
        local_pkgs = []
        local_pkgs.extend(tmp_pkgs)
        for i in tmp_pkgs:
            for j in final_results:
                if i[1] == j[1]:
                    local_pkgs.remove(i)
                    break

        final_results.extend(local_pkgs)    
    omitlist = []
    ver = None
    
    for i in final_results:
        # find stat the package
        pkg_stat = grey + "N"
        ver = pkg_version_installed(i[1])

        if ver != None:
            if i[2] == ver:
                pkg_stat = bold + "I"
            else:
                pkg_stat = cyan + "U"
        i.append(pkg_stat)

        # find results to omit, if any
        if omit != None and (omit in i[1] or omit in i[3].lower()):
            omitlist.append(i)
        
        if stat != None:
            if stat != pkg_stat[-1]:
                omitlist.append(i)
                
    if len(omitlist) > 0:
        for i in omitlist:
            final_results.remove(i)

    n = len(final_results)
    es = ""
    s = ""
    if n != 1:
        es = "es"

    # don't display a header if a custom format
    # is specified or output is compact
    if not compact and format == None:
        print blue + " > " + bold + str(n) + " match" + es,
        if len(header) == 0:
            if len(regex) != 1:
                s = "s"
                key_terms = ""
                for i in regex:
                    key_terms += i + ", "
                key_terms = key_terms[:-2]
            else:
                key_terms = regex[0]
            
            print "for key term" + s + blue + " [ " + cyan + key_terms + blue + " ]"
        else:
            print header[0] + blue + " [ " + cyan + header[1] + blue + " ]"
    
        print neutral
    
    # reverse results if necessary
    if reverse:
        final_results.reverse()
    
    o = []
    for i in final_results:
        inst_ver = pkg_version_installed(i[1])
        if inst_ver == None:
            inst_ver = ""
            
        if format != None:
            s = format
            s = s.replace("\\n", "\n")
            s = s.replace("\\t", "\t")
            s = s.replace("%r", i[0])
            s = s.replace("%n", i[1])
            s = s.replace("%p", i[0] + "/" + i[1])
            s = s.replace("%vl", i[2])
            s = s.replace("%vi", inst_ver)
            if i[0] == "aur":
                s = s.replace("%s", i[4])
            else:
                s = s.replace("%s", convert_size(i[4]))
            s = s.replace("%d", i[3])
            s = s.replace("%ccyan", cyan)
            s = s.replace("%cdcyan", darkcyan)
            s = s.replace("%cwhite", white)
            s = s.replace("%cgrey", grey)
            s = s.replace("%cdgrey", darkgrey)
            s = s.replace("%cblack", black)
            s = s.replace("%cred", red)
            s = s.replace("%cdred", darkred)
            s = s.replace("%cgreen", green)
            s = s.replace("%cdgreen", darkgreen)
            s = s.replace("%cpurple", purple)
            s = s.replace("%cdpurple", darkpurple)
            s = s.replace("%cyellow", yellow)
            s = s.replace("%cbrown", brown)
            s = s.replace("%coff", neutral)
            s = s.replace("%cbold", bold)
            o.append(s + neutral)
        else:
            if compact:
                s = blue + "[" + i[-1] + blue + "] " + bold + i[0] + "/" + i[1] + " "
                n = len(i[0]) + len(i[1]) + len(i[2])
                s += neutral + "(" + i[2] + "): " + format_compact_text(i[3], n)
                if i[-1][-1] == "U":
                    s += " " + blue + "[" + inst_ver + "]" + neutral
                
                o.append(s)
            else:
                if i[-1][-1] == "U":
                    iv = red + inst_ver
                elif i[-1][-1] == "I":
                    iv = green + inst_ver
                else:
                    iv = blue + "[" + cyan + " Not installed " + blue + "]"
                    
                o.append(blue + ":: " + bold + i[0] + "/" + i[1])
                o.append(grey + "     Latest version    : " + yellow + i[2])
                o.append(grey + "     Version installed : " + neutral + iv)
                if i[0] != "aur":
                    o.append(grey + "     Download size     : " + purple 
                        + convert_size(i[4]))
                else:
                    o.append(grey + "     Number of votes   : " + purple + i[4])
                if iv != blue + "[" + cyan + " Not installed " + blue + "]":
                    o.append(grey + "     URL               : " + blue + pkg_url(i[1]))

                o.append(grey + "     Description       : " + white 
                    + format_text(i[3], 25) + "\n")

    for i in o:
        print i

            
if __name__ == "__main__":
    done = False
    aur = False
    all_packages = None
    reverse = False
    strict = False
    compact = False
    populated = False
    group = None
    stat = None
    omit = None
    format = None
    use = "all"
    header = []
    regex = []
    final_results = []
    
    # Possible colors to use in output. Not all of these are used by default, 
    # but may be used if the user defines their own format
    darkgrey = "\033[1m\033[30m"
    black = "\033[0m\033[30m"
    darkgreen = "\033[0m\033[32m"
    green = "\033[1m\033[32m"
    darkpurple = "\033[0m\033[35m"
    purple = "\033[1m\033[35m"
    brown = "\033[0m\033[33m"
    yellow = "\033[1m\033[33m"
    darkblue = "\033[0m\033[34m"
    blue = "\033[1m\033[34m"
    darkcyan = "\033[0m\033[36m"
    cyan = "\033[1m\033[36m"
    grey = "\033[0m\033[37m"
    white = "\033[1m\033[37m"
    darkred = "\033[0m\033[31m"
    red = "\033[1m\033[31m"
    neutral = "\033[0m"
    bold = neutral + "\033[01m"


    # Get options
    try:
        opts = getopt(sys.argv[1:], "aA:d:f:g:hiIl:nuUcr:so:O:p:vxX", ["aur", "allpackages=", "depends=", "format=", "group=", "help", "instonly", "info", "listfiles=", "noinstonly", "upgradeonly", "pretend", "compact", "rep=", "strict", "omit=", "owns=", "pkginfo=", "reverse", "nocolor", "boldonly"])
    except GetoptError, errmsg:
        error( neutral + "Invalid option or usage. Try " + bold + "psearch --help " + neutral + "or " + bold + "man psearch" + neutral + " for options.")

    for i in opts[0]:
        arg = i[0]

        if arg in ("-a", "--aur"):
            aur = True
        elif arg in ("-A", "--allpackages"):
            all_packages = i[1]
            populate("all")
            populated = True
            header = ["in", i[1]]
            break
        elif arg in ("-d", "--depends"):
            depends(i[1])
            done = True
        elif arg in ("-f", "--format"):
            format = i[1]
        elif arg in ("-h", "--help"):
            usage()
            done = True
        elif arg in ("-i", "--instonly"):
            stat = "I"
        elif arg in ("-n", "--noinstonly"):
            stat = "N"
        elif arg in ("-u", "--upgradeonly"):
            stat = "U"
        elif arg in ("-c", "--compact"):
            compact = True
        elif arg in ("-r", "--rep"):
            use = i[1]
        elif arg in ("-s", "--strict"):
            strict = True
        elif arg in ("-o", "--omit"):
            omit = i[1]
        elif arg in ("-O", "--owns"):
            owns(i[1])
            done = True
        elif arg in ("-p", "--pkginfo"):
            show_pkg_info(i[1])
            done = True
        elif arg in ("-x", "--nocolor"):
            kill_color(False)
        elif arg in ("-X", "--boldonly"):
            kill_color(True)
        elif arg in ("-I", "--info"):
            show_info()
            done = True
        elif arg in ("-v", "--reverse"):
            reverse = True
        elif arg in ("-l", "--listfiles"):
            list_files(i[1])
            done = True
        elif arg in ("-g", "--group"):
            group = i[1]
            populate("group")
            populated = True
            header = ["in group", i[1]]
#            break
        elif arg in ("-U", "--pretend"):
            pretend()
            done = True

    if not done:
        if len(opts[1]) == 0 and not populated:
            help()
            sys.exit(0)
        elif len(opts[-1]) > 1:
            regex = opts[-1]
        else:
            regex = (opts[1])

        if not populated:
            populate("search")
            populated = True

        try:
            find_results()
        except KeyboardInterrupt:
            print neutral + "... aborting!"

Offline

#27 2008-01-12 23:09:59

zenix
Member
From: Earth - Save it!
Registered: 2007-08-05
Posts: 104
Website

Re: psearch - Gentoo's esearch Arch style [revision]

For those who want to get psearch compatiable with pacman 3.1:

NOTE: This is slightly hackish, not for new users though the entire process isn't too hard
* Goto the AUR page for psearch and download the PKGBUILD (http://aur.archlinux.org/packages.php?d … =1&ID=7821)
* Enter the download directory with the PKGBUILD and run makepkg (no parameters). This should download the source and compile it.
* Open src/psearch-1.7-7/psearch.py in your favorite editor
* Modify line 4 from

pacman_lib = "/var/lib/pacman"

to

pacman_lib = "/var/lib/pacman/sync"

* Save and exit the editor
* Now run makepkg -ie in the dir with the PKGBUILD. Don't forget the -e! Otherwise makepkg will redownload the original source code again and you'll have to make the changes again.
* After install the updated psearch, in your terminal goto /var/lib/pacman/sync
* Run

ln -s ../local local

to create a symbolic link to the local cache for psearch to look through

Enjoy!

Last edited by zenix (2008-01-12 23:11:27)


I made an AUR helper once.
I also go by evaryont and nogweii elsewhere on the internet.
Check out my projects and packages.

Offline

#28 2008-01-13 00:31:30

dir
Member
From: dotph
Registered: 2007-10-10
Posts: 20

Re: psearch - Gentoo's esearch Arch style [revision]

Or simply add this to the build part of the PKGBUILD:

sed -e "s|/var/lib/pacman/|/var/lib/pacman/sync/|g" -i psearch.py
mkdir -p $startdir/pkg/var/lib/pacman/sync
ln -s /var/lib/pacman/local $startdir/pkg/var/lib/pacman/sync/local

Offline

#29 2008-01-13 01:10:53

shining
Pacman Developer
Registered: 2006-05-10
Posts: 2,043

Re: psearch - Gentoo's esearch Arch style [revision]

That symlink is a really ugly hack big_smile


pacman roulette : pacman -S $(pacman -Slq | LANG=C sort -R | head -n $((RANDOM % 10)))

Offline

#30 2008-01-13 16:28:06

zenix
Member
From: Earth - Save it!
Registered: 2007-08-05
Posts: 104
Website

Re: psearch - Gentoo's esearch Arch style [revision]

shining - I know, but it's the only way psearch will work with pacman 3.1 sad Ah well, ugly, but it works!

dir - Lol much cleaner than my way. Hopefully wrythe will be able to update psearch big_smile


I made an AUR helper once.
I also go by evaryont and nogweii elsewhere on the internet.
Check out my projects and packages.

Offline

#31 2008-01-13 19:42:06

ibendiben
Member
Registered: 2007-10-10
Posts: 519

Re: psearch - Gentoo's esearch Arch style [revision]

psearch -a pacman
 >  Resolving aur.archlinux.org ...  
Traceback (most recent call last):
  File "/usr/bin/psearch", line 615, in <module>
    populate("search")
  File "/usr/bin/psearch", line 341, in populate
    final_results.extend(pkg_search(regex, use, strict))
  File "/usr/lib/python2.5/site-packages/psearch.py", line 485, in pkg_search
    pkgs = rep_packages(r)
  File "/usr/lib/python2.5/site-packages/psearch.py", line 92, in rep_packages
    x = os.listdir(pacman_lib + rep)
OSError: [Errno 2] No such file or directory: '/var/lib/pacman/core'

hmm
Tried both solutions... what could I've done wrong, any ideas?

Offline

#32 2008-01-14 09:57:17

byte
Member
From: Düsseldorf (DE)
Registered: 2006-05-01
Posts: 2,046

Re: psearch - Gentoo's esearch Arch style [revision]

Yes, you didn't wait for a psearch update.


1000

Offline

#33 2008-01-14 10:35:24

ibendiben
Member
Registered: 2007-10-10
Posts: 519

Re: psearch - Gentoo's esearch Arch style [revision]

lol

Offline

#34 2008-01-14 17:39:43

sen
Member
From: .de
Registered: 2007-02-18
Posts: 153
Website

Re: psearch - Gentoo's esearch Arch style [revision]

Wow, that's exactly what I missed when switching from gentoo to arch... it's a shame I didn't learn about psearch earlier!
Keep up the good work. smile

Offline

#35 2008-01-14 18:07:55

patroclo7
Member
From: Bassano del Grappa, ITALY
Registered: 2006-01-11
Posts: 915

Re: psearch - Gentoo's esearch Arch style [revision]

Yes, may be that psearch could be accepted in a repo. It should not be assimilated to dangerous stuff such as yaourt, because it does not install anything, but only performs searches (also in the AUR, but after that you still have to go in the AUR, look at the comments, download the tarball and all this safe routine smile ).


Mortuus in anima, curam gero cutis

Offline

#36 2008-02-16 22:46:40

varl
Member
Registered: 2007-06-07
Posts: 51

Re: psearch - Gentoo's esearch Arch style [revision]

It is flagged as out of date, and the last comments are a month old, is this still working? smile

Offline

#37 2008-03-07 07:05:40

Purch
Member
From: Finland
Registered: 2006-02-23
Posts: 229

Re: psearch - Gentoo's esearch Arch style [revision]

Has anyone fixed the AUR problem after AUR upgrade?

Offline

Board footer

Powered by FluxBB