summaryrefslogtreecommitdiff
blob: 3a8e2dc899b75c6b31d3ca9c70b39d81a0175c1d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
#!/usr/bin/env python2.4

import os
import re
import portage
import portage_dep, portage_util, portage_versions

use_reduce = None

try:	use_reduce = portage_dep.use_reduce
except AttributeError:
	use_reduce = portage.use_reduce

paren_reduce = None
try:	paren_reduce = portage_dep.paren_reduce
except AttributeError:
	paren_reduce = portage.paren_reduce

flatten = None
try:	flatten = portage_util.flatten
except AttributeError:	
	flatten = portage.flatten

import md5
import sha
md5_cons = md5.new
sha1_cons = sha.new

porttree = "/usr/portage"

outdir = "ebuildindex"
if not os.path.exists(outdir):
    os.mkdir(outdir)
elif not os.path.isdir(outdir):
    import sys
    print "%s exists, but is not a directory." % (outdir)
    sys.exit(2)


def write_ebuild_stats(fd_out, cpv, dbapi):
    try:
        # find out the actual path to the ebuild
        path = dbapi.findname(cpv)
        filesize = os.path.getsize(path)
        mtime = os.path.getmtime(path)

        # hash it
        ebuild = open(path)
        (md5, sha1) = hash_file(ebuild, md5_cons(), sha1_cons())
        ebuild.seek(0)

        # Find $Header$ or $Id$ line
        matcher = re.compile("(\$(Header|Id):.*\$)")
        header = ""
        for line in ebuild:
            m = matcher.search(line)
            if m:
                header = m.group(1)
                break
        ebuild.close()
    except:
        filesize = 0
        mtime = 0
        md5 = 0
        sha1 = 0
        header = ""
        pass
    fd_out.write("Ebuild-PF: %s\n" % (cpv))
    fd_out.write("Ebuild-mtime: %s\n" % (mtime))
    fd_out.write("Ebuild-size: %s\n" % (filesize))
    fd_out.write("Ebuild-md5: %s\n" % (md5))
    fd_out.write("Ebuild-sha1: %s\n" % (sha1))
    fd_out.write("Ebuild-header: %s\n" % (header))
    
    # Reconstruct portage's CPV-related variables
    cpvlist = portage_versions.catpkgsplit(cpv)
    if len(cpvlist) == 4:
        cat = cpvlist[0]
        pac = cpvlist[1]
        ver = cpvlist[2]
        rev = cpvlist[3]
        fd_out.write("Ebuild-PN: %s\n"        % (pac))
        fd_out.write("Ebuild-PV: %s\n"        % (ver))
        fd_out.write("Ebuild-PR: %s\n"        % (rev))
        fd_out.write("Ebuild-CATEGORY: %s\n"  % (cat))
        fd_out.write("Ebuild-P: %s-%s\n"      % (pac, ver))
        fd_out.write("Ebuild-PVR: %s-%s-%s\n" % (pac, ver, rev))


def hash_file(fileobj, *hashobjects):
    """ RAM efficient hashing implementation for stream-based file objects. """
    data = fileobj.read(1024*1024)
    while data:
        for ho in hashobjects:
            ho.update(data)
        data = fileobj.read(1024*1024)

    return (ho.hexdigest() for ho in hashobjects)



config = portage.settings
config.unlock()
config["PORTDIR_OVERLAY"] = ''
config["PORTDIR"] = porttree

dbapi = portage.portdbapi(porttree, mysettings=config)


for cp in dbapi.cp_all():
    for cpv in dbapi.cp_list(cp):
        uris = ""
        try:
            uris, = dbapi.aux_get(cpv, ("SRC_URI",))
            uris = use_reduce(paren_reduce(uris), matchall=1)
            uris = flatten(uris)
        except Exception, e:
            print "Error with %s: %s" % (cpv, str(e))
            continue

        indexfile = "%s/%s.DIST" % (outdir, cpv.replace("/", "+"))
        fd_out = open(indexfile, "w")

        write_ebuild_stats(fd_out, cpv, dbapi)

        oldfiles = {}
        num = 0
        for uri in uris:
            filename = os.path.basename(uri)
            filenum = num
            if filename in oldfiles:
                # in case we have multiple uri's for one filename,
                # use the old filenum
                filenum = oldfiles[filename]
            else:
                oldfiles[filename] = num
                fd_out.write("Distfile-%05d-name: %s\n" % (num, filename))
                num += 1
            fd_out.write("Distfile-%05d-uri: %s\n"  % (filenum, uri))

        fd_out.close()