/[gentoo]/src/packages/gentoo.py
Gentoo

Diff of /src/packages/gentoo.py

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

Revision 1.4 Revision 1.16.2.1
1#!/usr/bin/python -OO 1#!/usr/bin/python -O
2"""These functions mainly take ebuild info (grabbed from the database and 2"""These functions mainly take ebuild info (grabbed from the database and
3 convert it to HTML. See the "main" function at the bottom.""" 3 convert it to HTML. See the "main" function at the bottom."""
4 4
5__revision__ = "$Revision: 1.4 $" 5__revision__ = "$Revision: 1.16.2.1 $"
6# $Source: /var/cvsroot/gentoo/src/packages/gentoo.py,v $ 6# $Source: /var/cvsroot/gentoo/src/packages/gentoo.py,v $
7 7
8import config 8import config
9import os 9import os
10import time 10import time
11import string
11import sys 12import sys
12import ebuilddb 13import ebuilddb
13import bugs 14import bugs
14import changelogs 15import changelogs
15from cgi import escape 16from cgi import escape
16from urllib import quote 17from urllib import quote
17 18
18# import portage, but temporarily redirect stderr 19endversion={"pre":-2,"p":0,"alpha":-4,"beta":-3,"rc":-1}
19if 'portage' not in dir(): 20# as there's no reliable way to set {}.keys() order
20 null = open('/dev/null', 'w') 21# netversion_keys will be used instead of endversion.keys
21 tmp = sys.stderr 22# to have fixed search order, so that "pre" is checked
22 sys.stderr = null 23# before "p"
23 sys.path = ["/usr/lib/portage/pym"]+sys.path 24endversion_keys = ["pre", "p", "alpha", "beta", "rc"]
24 import portage
25 sys.stderr = tmp
26 sys.path = sys.path[1:]
27 25
28tree = portage.portdbapi('/usr/portage')
29
30def is_masked(ebuild):
31 """Return true if ebuild is masked"""
32
33 return (not tree.visible(['%(category)s/%(name)s-%(version)s' % ebuild]))
34
35def is_new(db, ebuild): 26def is_new(db, ebuild):
36 """Check for newness. An ebuild is considered new if it is the 27 """Check for newness."""
37 only ebuild with that category/name in ebuild and it has no prevarch""" 28
38
39 c = db.cursor() 29 c = db.cursor()
40 query = ('SELECT prevarch FROM ebuild WHERE category="%s" AND name="%s"' 30 query = ('SELECT new FROM package WHERE category="%s" AND name="%s"'
41 % (ebuild['category'], ebuild['name'])) 31 % (ebuild['category'], ebuild['name']))
42 c.execute(query) 32 c.execute(query)
43 results = c.fetchall() 33 results = c.fetchall()
44 if len(results) == 1 and results[0][0] is None: 34 if len(results) == 1 and results[0][0]:
45 return 1 35 return 1
46 return 0 36 return 0
47 37
48def changelog_to_html(changelog): 38changelog_to_html = changelogs.bugs_to_html
49 """HTML-ize a changelog entry"""
50 html = ""
51 for char in changelog:
52 if char == '\n':
53 html = "%s<br>" % html
54 else:
55 html = "%s%s" % (html, escape(char))
56 html = changelogs.bugs_to_html(html)
57 return html
58 39
59def homepage_to_html(homepage): 40def homepage_to_html(homepage):
60 """convert HOMEPAGE entry to HTML""" 41 """convert HOMEPAGE entry to HTML"""
61 if not homepage.strip(): 42 if not homepage.strip():
62 return "?" 43 return "?"
63 homepage = homepage.replace('|',' ') 44 homepage = homepage.replace('|',' ')
64 pieces = homepage.split() 45 pieces = homepage.split()
65 count = len(pieces) 46 count = len(pieces)
66 if count == 1: 47 if count == 1:
67 return ('<a class="homepage" href="%s">' 48 return ('<a class="homepage" href="%s">'
68 'Homepage</a>' % pieces[0]) 49 'Homepage</a>' % pieces[0])
69 50
70 html = ['[<a href="%s">%s</a>]' % (page, index + 1) for index, 51 html = ['[<a href="%s">%s</a>]' % (page, index + 1) for index,
71 page in enumerate(pieces)] 52 page in enumerate(pieces)]
72 return " ".join(['<span class="homepage">Homepages'] + html + 53 return " ".join(['<span class="homepage">Homepages'] + html +
73 ['</span>']) 54 ['</span>'])
74 55
75def license_to_html(license): 56def license_to_html(license):
76 """Create link to license[s]""" 57 """Create link to license[s]"""
77 if not license.strip(): return "?" 58 if not license.strip(): return "?"
78 license = license.replace('|',' ') 59 license = license.replace('|',' ')
60 license = license.replace('(', '')
61 license = license.replace(')', '')
79 pieces = license.split() 62 pieces = license.split()
80 html = ['<a href="http://www.gentoo.org/cgi-bin/viewcvs.cgi/*checkout*/' 63 html = ['<a href="http://www.gentoo.org/cgi-bin/viewcvs.cgi/*checkout*/'
81 'licenses/%s">%s</a>' % (piece, piece) for piece in pieces] 64 'licenses/%s">%s</a>' % (piece, piece) for piece in pieces]
82 return '<br>\n'.join(html) 65 return '<br>\n'.join(html)
83 66
84def package_to_html(pkginfo, db): 67def package_to_html(pkginfo, db, full=False):
85 """This function needs a database (db) connection because it performs a 68 """This function needs a database (db) connection because it performs a
86 query_to_dict on the package""" 69 query_to_dict on the package"""
87 70
88 table_begin = '<table class="ebuild">' 71 table_begin = '<table class="ebuild">'
89 name = '<tr><td class="fields">%s</td></tr>' % pkginfo['name'] 72 name = '<tr><td class="fields">%s</td></tr>' % pkginfo['name']
73 if full:
74 image = ('<img class="pkgimg"alt="" src="%s/%s/%s.jpg" align="right">' %
75 (config.ICONS, pkginfo['category'], pkginfo['name'])
76 )
77 else:
78 image = ''
90 description = ('<tr><td class="item">' 79 description = ('<tr><td class="item">'
91 '<img align="right" alt="" src="%s/%s.png">'
92 '<b>Description: </b>%s</td></tr>' % (config.ICONS, 80 '%s<b>Description: </b>%s</td></tr>'
93 pkginfo['category'], escape(pkginfo['description']))) 81 % (image, escape(pkginfo['description']))
82 )
94 ebuilds = get_recent_releases(pkginfo, db) 83 ebuilds = get_recent_releases(pkginfo, db)
95 releases = '<tr><td>%s</td></tr>' % archs_to_html(ebuilds, 'Releases') 84 releases = '<tr><td>%s</td></tr>' % archs_to_html(ebuilds, 'Releases')
96 #bug_string = ('<br><h3>Related bugs:</h3>\n%s' 85 #bug_string = ('<br><h3>Related bugs:</h3>\n%s'
97 # % bugs_to_html(pkginfo['name'])) 86 # % bugs_to_html(pkginfo['name']))
98 general = '<tr><td>%s</td></tr>' % general_info_to_html(pkginfo) 87 general = '<tr><td>%s</td></tr>' % general_info_to_html(pkginfo)
88 #similar = '<tr><td>%s</td></tr>' % create_similar_pkgs_link(pkginfo)
99 table_end = '</table>' 89 table_end = '</table>'
100 rows = '\n\t'.join([name, description, releases, general]) 90 rows = '\n\t'.join([name, description, releases, general])
101 return '\n\t'.join([table_begin, rows, table_end]) 91 return '\n\t'.join([table_begin, rows, table_end])
102 92
103def archs_to_html(ebuilds, heading = None): 93def archs_to_html(ebuilds, heading = None):
104 """Create table for availability on each architecture""" 94 """Create table for availability on each architecture"""
105 heading = heading or '&nbsp;' 95 heading = heading or '&nbsp;'
106 table_begin = '<table class="releases">' 96 table_begin = '<table class="releases">'
107 header_row = ''.join(['<tr><td><b>%s</b></td>' % heading] + 97 header_row = ''.join(['<tr><td><b>%s</b></td>' % heading] +
108 ['<th class="arch">%s</th>' % i for i in config.ARCHLIST] + 98 ['<th class="arch">%s</th>' % i.replace('-',' ') for i in config.ARCHLIST] +
109 ['</tr>'] 99 ['</tr>']
110 ) 100 )
111 rows = [] 101 rows = []
102 ebuilds.sort(cmp_ebuilds)
103 ebuilds.reverse()
112 for ebuild in ebuilds: 104 for ebuild in ebuilds:
113 masked = is_masked(ebuild)
114 archs = ebuild['arch'].split() 105 archs = ebuild['arch'].split(',')
115 row_start = ('<tr>\n\t<th class="releases"><a href="%sebuilds/?%s-%s"' 106 row_start = ('<tr>\n\t<th class="releases"><a href="%sebuilds/?%s-%s"'
116 ' title="%s">%s</a></th>\n' % (config.FEHOME, 107 ' title="%s">%s</a></th>\n' % (config.FEHOME,
117 ebuild['name'], ebuild['version'], ebuild['time'], 108 ebuild['name'], ebuild['version'], ebuild['time'],
118 ebuild['version'])) 109 ebuild['version']))
119 row_data = [] 110 row_data = []
120 for arch in config.ARCHLIST: 111 for arch in config.ARCHLIST:
121 if arch in archs: 112 if arch in archs:
122 arch_string = '+' 113 arch_string = '+'
123 elif '~%s' % arch in archs: 114 elif '~%s' % arch in archs:
124 arch_string = '~' 115 arch_string = '~'
125 else: 116 else:
126 arch_string = '-' 117 arch_string = '-'
127 if arch_string != '-' and masked: 118 if arch_string != '-' and ebuild['masked']:
128 arch_string = 'M' + arch_string 119 arch_string = 'M' + arch_string
129 row_data.append('\t<td class="archcell" arch="%s">%s</td>' 120 row_data.append('\t<td class="archcell" arch="%s">%s</td>'
130 % (arch_string, arch_string)) 121 % (arch_string, arch_string))
131 row_end = '</tr>' 122 row_end = '</tr>'
132 rows.append('\n\t'.join([row_start] + row_data + [row_end])) 123 rows.append('\n\t'.join([row_start] + row_data + [row_end]))
133 table_end = '</table>' 124 table_end = '</table>'
134 return '\n\t'.join([table_begin] + [header_row] + rows + [table_end]) 125 return '\n\t'.join([table_begin] + [header_row] + rows + [table_end])
135 126
136def ebuild_to_html(ebinfo, new=0, show_bugs=0): 127def ebuild_to_html(ebinfo, new=0, show_bugs=0, full = False):
137 """Convert ebuild (dict) to html, if new, print out a "this is new" notice 128 """Convert ebuild (dict) to html, if new, print out a "this is new" notice
138 if show_bugs, show bugs for this particular ebuild (requires access to 129 if show_bugs, show bugs for this particular ebuild (requires access to
139 bugzilla""" 130 bugzilla"""
140 if new: 131 if new:
141 new_string = """ &nbsp;&nbsp;<span class="new">new!</span> """ 132 new_string = """ &nbsp;&nbsp;<span class="new">new!</span> """
142 else: 133 else:
143 new_string = "" 134 new_string = ""
144 135
145 table_begin = '<table class="ebuild">' 136 table_begin = '<table class="ebuild">'
146 name_and_date = ('<tr><td class="fields">' 137 name_and_date = ('<tr><td class="fields">'
147 '<a href="%spackages/?category=%s;name=%s">%s</a> %s%s<br>' 138 '<a href="%spackages/?category=%s;name=%s">%s</a> %s%s<br>'
148 '<span class="time">%s</span>' 139 '<span class="time">%s</span>'
149 '</td></tr>' % (config.FEHOME, quote(ebinfo['category']), 140 '</td></tr>' % (config.FEHOME, quote(ebinfo['category']),
150 quote(ebinfo['name']), 141 quote(ebinfo['name']),
151 ebinfo['name'], 142 ebinfo['name'],
152 ebinfo['version'], 143 ebinfo['version'],
153 new_string, 144 new_string,
154 ebinfo['time'].localtime().strftime("%c %Z"))) 145 ebinfo['time'].strftime("%c %Z")))
146
147 if full:
148 image = ('<img class="pkgimg" alt="" src="%s/%s/%s.jpg" align="right">' %
149 (config.ICONS, ebinfo['category'], ebinfo['name'])
155 150 )
151 else:
152 image = ''
156 desc_and_changes = ('<tr><td class="item" valign="top">' 153 desc_and_changes = ('<tr><td class="item" valign="top">'
157 '<img alt="" align="right" src="%simages/%s.png">'
158 '<p><b>Description:</b> %s</p>' 154 '<p><b>Description:</b> %s %s</p>'
159 '<p><b>Changes:</b><br>' 155 '<p><b>Changes:</b><br>'
160 '%s</p></td></tr>' % ( 156 '%s</p></td></tr>' % (
161 config.FEHOME,
162 ebinfo['category'],
163 escape(ebinfo['description']), 157 escape(ebinfo['description']),
158 image,
164 changelog_to_html(ebinfo['changelog']))) 159 changelog_to_html(ebinfo['changelog'])))
165 160
166 archs = '<tr><td>%s</td></tr>' % archs_to_html([ebinfo]) 161 archs = '<tr><td>%s</td></tr>' % archs_to_html([ebinfo])
167 general = '<tr><td>%s</td></tr>' % general_info_to_html(ebinfo) 162 general = '<tr><td>%s</td></tr>' % general_info_to_html(ebinfo)
168 table_end = '</table>' 163 table_end = '</table>'
169 164
170 if 1 == 1:
171 bug_string = '' 165 bug_string = ''
172 else: 166 if show_bugs:
167 bug_string = bugs_to_html(ebinfo['name'])
168 if bug_string:
173 bug_string = '<br><h3>Related bugs:</h3>%s' \ 169 bug_string = '<br><h3 class="bugs">Related bugs:</h3>%s' \
174 % bugs_to_html(ebinfo['name']) 170 % bug_string
175 171
176 return '\n\t'.join([table_begin, 172 return '\n\t'.join([table_begin,
177 name_and_date, 173 name_and_date,
178 desc_and_changes, 174 desc_and_changes,
179 archs, 175 archs,
180 general, 176 general,
181 table_end, 177 table_end,
182 bug_string]) 178 bug_string])
183 179
184def general_info_to_html(pkg): 180def general_info_to_html(pkg):
185 """This actually will (should) take either a package or ebuild dict 181 """This actually will (should) take either a package or ebuild dict
186 as an argument""" 182 as an argument"""
187 183
184 import forums
185
188 changelogurl = ('http://www.gentoo.org/cgi-bin/viewcvs.cgi/*checkout*/' 186 changelogurl = ('http://www.gentoo.org/cgi-bin/viewcvs.cgi/*checkout*/'
189 '%s/%s/ChangeLog' % (pkg['category'],pkg['name'])) 187 '%s/%s/ChangeLog' % (pkg['category'],pkg['name']))
190 cat_header = '<th class="category">Category</th>' 188 cat_header = '<th class="category">Category</th>'
191 license_header = '<th class="license">License</th>' 189 license_header = '<th class="license">License</th>'
192 category = ('<td class="category">' 190 category = ('<td class="category">'
193 '<a href="%spackages/?category=%s">%s</a></td>' % (config.FEHOME, 191 '<a href="%spackages/?category=%s">%s</a></td>' % (config.FEHOME,
194 pkg['category'], pkg['category'])) 192 pkg['category'], pkg['category']))
195 homepage = ('<td class="homepage" rowspan="2">%s</td>' 193 homepage = ('<td class="homepage" rowspan="2">%s</td>'
196 % homepage_to_html(pkg['homepage'])) 194 % homepage_to_html(pkg['homepage']))
197 license = ('<td class="license">%s</td>' 195 license = ('<td class="license">%s</td>'
198 % license_to_html(pkg['license'])) 196 % license_to_html(pkg['license']))
199 changelog = ('<td class="changelog" rowspan="2">' 197 changelog = ('<td class="changelog" rowspan="2">'
200 '<a href="%s">ChangeLog</a><td>' % changelogurl) 198 '<a href="%s">ChangeLog</a></td>' % changelogurl)
201 199 similar = ('<td class="similar" rowspan="2">'
200 '%s</td>' % create_similar_pkgs_link(pkg))
201 related_bugs = ('<td class="related_bugs" rowspan="2">'
202 '%s</td>' % create_related_bugs_link(pkg))
203 forums = ('<td class="forums" rowspan="2">'
204 '%s</td>' % forums.create_forums_link(pkg))
205
202 return '\n\t'.join(['<table class="general_info">', 206 return '\n\t'.join(['<table class="general_info">',
203 '<tr>', 207 '<tr>',
204 cat_header, 208 cat_header,
205 homepage, 209 homepage,
206 license_header, 210 license_header,
207 changelog, 211 changelog,
212 similar,
213 related_bugs,
214 forums,
208 '</tr>', 215 '</tr>',
209 '<tr>', 216 '<tr>',
210 category, 217 category,
211 license, 218 license,
212 '</tr>', 219 '</tr>',
213 '</table>']) 220 '</table>'])
214 221
222def create_similar_pkgs_link(pkg):
223 """Create a link to similar packages"""
224
225 return '<a href="/similar/?package=%(category)s/%(name)s">Similar</a>' % pkg
226
227def create_related_bugs_link(pkg):
228 """Create a link to related bugs"""
229
230 url = ('http://bugs.gentoo.org/buglist.cgi?query_format='
231 '&amp;short_desc_type=allwords'
232 '&amp;short_desc=%s'
233 '&amp;bug_status=UNCONFIRMED'
234 '&amp;bug_status=NEW'
235 '&amp;bug_status=ASSIGNED'
236 '&amp;bug_status=REOPENED'
237 % escape(pkg['name']))
238
239 return '<a title="bugs.gentoo.org" href="%s">Bugs</a>' % url
240
215def bugs_to_html(package): 241def bugs_to_html(package):
216 """Given package name (no version #s), return html text of bugs as 242 """Given package name (no version #s), return html text of bugs as
217 reported by bugzilla""" 243 reported by bugzilla"""
218 # Right now we have an issue with the bugzilla site. New interface 244 # Right now we have an issue with the bugzilla site. New interface
219 # needs to be written, Bail out. 245 # needs to be written, Bail out.
220 return "" 246 #return ""
221 import urllib2 247 import urllib2
222 url = ('http://bugs.gentoo.org/buglist.cgi?query_format=' 248 url = ('http://bugs.gentoo.org/buglist.cgi?query_format='
223 '&short_desc_type=allwords&short_desc=%s' 249 '&amp;short_desc_type=allwords'
224 '&bug_status=UNCONFIRMED&bug_status=NEW&bug_status=ASSIGNED' 250 '&amp;short_desc=%s'
251 '&amp;bug_status=UNCONFIRMED'
252 '&amp;bug_status=NEW'
253 '&amp;bug_status=ASSIGNED'
225 '&bug_status=REOPENED' 254 '&amp;bug_status=REOPENED'
255 '&amp;ctype=csv'
226 '&ctype=csv' % package) 256 % package)
227 fp = urllib2.urlopen(url) 257 fp = urllib2.urlopen(url)
228 factory = bugs.BugFactory() 258 factory = bugs.BugFactory()
229 package_bugs = factory.fromCSV(fp) 259 package_bugs = factory.fromCSV(fp)
230 if package_bugs: 260 if package_bugs:
231 writer = bugs.HTMLWriter(package_bugs, 'bugs.gentoo.org') 261 writer = bugs.HTMLWriter(package_bugs, 'bugs.gentoo.org')
232 return str(writer) 262 return str(writer)
233 else: 263 else:
234 return "None" 264 return ""
235 265
236def get_most_recent(db, max=config.MAXPERPAGE, arch="", branch=""): 266def get_most_recent(db, max=config.MAXPERPAGE, arch="", branch="", new = False):
237 c = db.cursor() 267 c = db.cursor()
238 extra = '' 268 extra = ''
239 if arch: 269 if arch:
240 stable_extra = ('ebuild.arch REGEXP "^%s| %s" ' 270 stable_extra = ('FIND_IN_SET("%s", ebuild.arch) > 0 AND '
241 ' AND ebuild.prevarch NOT REGEXP"^%s| %s"' 271 'FIND_IN_SET("%s", ebuild.prevarch) = 0 ' % (arch, arch))
242 % (arch,arch,arch,arch)) 272 testing_extra = ('FIND_IN_SET("~%s", ebuild.arch) > 0 AND '
243 testing_extra = ('ebuild.arch REGEXP "^~%s| ~%s" ' 273 'FIND_IN_SET("~%s", ebuild.prevarch) = 0 ' % (arch, arch))
244 ' AND ebuild.prevarch NOT REGEXP "^~%s| ~%s"'
245 % (arch,arch,arch,arch))
246 if branch == 'stable': 274 if branch == 'stable':
247 extra = ' AND (%s) ' % stable_extra 275 extra = ' AND (%s) ' % stable_extra
248 elif branch == 'testing': 276 elif branch == 'testing':
249 extra = ' AND (%s) ' % testing_extra 277 extra = ' AND (%s) ' % testing_extra
250 else: 278 else:
251 extra = ' AND ((%s) OR (%s)) ' % (stable_extra, testing_extra) 279 extra = ' AND ((%s) OR (%s)) ' % (stable_extra, testing_extra)
280
281 if new:
282 extra = ('%s AND package.new=1 ' % extra)
283
252 query = """SELECT ebuild.category,ebuild.name,version,when_found,description, 284 query = """SELECT ebuild.category,ebuild.name,version,ebuild.when_found,description,
253 changelog,arch,homepage,license FROM ebuild,package WHERE ebuild.name=\ 285 changelog,arch,homepage,license,is_masked FROM ebuild,package WHERE ebuild.name=\
254 package.name AND ebuild.category=package.category %s ORDER by when_found DESC \ 286 package.name AND ebuild.category=package.category %s ORDER by ebuild.when_found DESC \
255 LIMIT %s""" % (extra,max) 287 LIMIT %s""" % (extra,max)
256 c.execute(query) 288 c.execute(query)
257 results = c.fetchall() 289 results = c.fetchall()
258 return results 290 return results
259 291
292def get_most_recent_bumps(db, max=config.MAXPERPAGE):
293 """Return most recent version bumps (pkgs with no prevarch)"""
294 c = db.cursor()
295 query = ('SELECT ebuild.category, ebuild.name, version, when_found, '
296 'description, changelog, arch, homepage, license,is_masked FROM ebuild, package '
297 'WHERE ebuild.name=package.name AND ebuild.category=package.category '
298 'AND prevarch="" AND version NOT LIKE "%%-r_" AND version NOT LIKE '
299 '"%%-r__" AND NOT new ORDER by when_found '
300 'DESC LIMIT %s' % max)
301
302 c.execute(query)
303 results = c.fetchall()
304 return results
305
260def query_to_dict(d): 306def query_to_dict(d):
261 """Convert a SQL query to a dict""" 307 """Convert a SQL query to a dict"""
262 einfo = {} 308 einfo = {}
263 keys = ('category', 'name', 'version', 'time', 'description', 'changelog', 309 keys = ('category', 'name', 'version', 'time', 'description', 'changelog',
264 'arch', 'homepage', 'license') 310 'arch', 'homepage', 'license', 'masked')
265 for i in range(len(keys)): 311 for i in range(len(keys)):
266 try: 312 try:
267 einfo[keys[i]] = d[i] 313 einfo[keys[i]] = d[i]
268 except IndexError: 314 except IndexError:
269 continue 315 continue
272def get_recent_releases(pkg, db, max=config.MAX_RECENT_RELEASES): 318def get_recent_releases(pkg, db, max=config.MAX_RECENT_RELEASES):
273 """Return MAX_RECENT_RELEASES most recent releases for pkg. Returns and 319 """Return MAX_RECENT_RELEASES most recent releases for pkg. Returns and
274 ebuild-type dict""" 320 ebuild-type dict"""
275 c = db.cursor() 321 c = db.cursor()
276 query = ('SELECT category,name,version,when_found,NULL,changelog,arch ,' 322 query = ('SELECT category,name,version,when_found,NULL,changelog,arch ,'
277 'NULL,NULL FROM ebuild WHERE name="%s" AND category="%s" ORDER BY ' 323 'NULL,NULL,is_masked FROM ebuild WHERE name="%s" AND category="%s" ORDER BY '
278 'version DESC LIMIT %s' % (pkg['name'],pkg['category'],max)) 324 'version DESC LIMIT %s' % (pkg['name'],pkg['category'],max))
279 c.execute(query) 325 c.execute(query)
280 results = c.fetchall() 326 results = c.fetchall()
281 #print results 327 #print results
282 return [ query_to_dict(i) for i in results ] 328 return [ query_to_dict(i) for i in results ]
283 329
330def cmp_ebuilds(a, b):
331 """Compare two ebuilds"""
332 fields_a = pkgsplit('%s-%s' % (a['name'], a['version']))
333 fields_b = pkgsplit('%s-%s' % (b['name'], b['version']))
334 return pkgcmp(fields_a, fields_b)
335
336pkgcache={}
337
338def pkgsplit(mypkg,silent=1):
339 try:
340 if not pkgcache[mypkg]:
341 return None
342 return pkgcache[mypkg][:]
343 except KeyError:
344 pass
345 myparts=string.split(mypkg,'-')
346 if len(myparts)<2:
347 if not silent:
348 print "!!! Name error in",mypkg+": missing a version or name part."
349 pkgcache[mypkg]=None
350 return None
351 for x in myparts:
352 if len(x)==0:
353 if not silent:
354 print "!!! Name error in",mypkg+": empty \"-\" part."
355 pkgcache[mypkg]=None
356 return None
357 #verify rev
358 revok=0
359 myrev=myparts[-1]
360 if len(myrev) and myrev[0]=="r":
361 try:
362 int(myrev[1:])
363 revok=1
364 except SystemExit, e:
365 raise
366 except:
367 pass
368 if revok:
369 if ververify(myparts[-2]):
370 if len(myparts)==2:
371 pkgcache[mypkg]=None
372 return None
373 else:
374 for x in myparts[:-2]:
375 if ververify(x):
376 pkgcache[mypkg]=None
377 return None
378 #names can't have versiony looking parts
379 myval=[string.join(myparts[:-2],"-"),myparts[-2],myparts[-1]]
380 pkgcache[mypkg]=myval
381 return myval
382 else:
383 pkgcache[mypkg]=None
384 return None
385
386 elif ververify(myparts[-1],silent=silent):
387 if len(myparts)==1:
388 if not silent:
389 print "!!! Name error in",mypkg+": missing name part."
390 pkgcache[mypkg]=None
391 return None
392 else:
393 for x in myparts[:-1]:
394 if ververify(x):
395 if not silent:
396 print "!!! Name error in",mypkg+": multiple version parts."
397 pkgcache[mypkg]=None
398 return None
399 myval=[string.join(myparts[:-1],"-"),myparts[-1],"r0"]
400 pkgcache[mypkg]=myval[:]
401 return myval
402 else:
403 pkgcache[mypkg]=None
404 return None
405
406vercache={}
407def ververify(myorigval,silent=1):
408 try:
409 return vercache[myorigval]
410 except KeyError:
411 pass
412 if len(myorigval)==0:
413 if not silent:
414 print "!!! Name error: package contains empty \"-\" part."
415 return 0
416 myval=string.split(myorigval,'.')
417 if len(myval)==0:
418 if not silent:
419 print "!!! Name error: empty version string."
420 vercache[myorigval]=0
421 return 0
422 #all but the last version must be a numeric
423 for x in myval[:-1]:
424 if not len(x):
425 if not silent:
426 print "!!! Name error in",myorigval+": two decimal points in a row"
427 vercache[myorigval]=0
428 return 0
429 try:
430 foo=int(x)
431 except SystemExit, e:
432 raise
433 except:
434 if not silent:
435 print "!!! Name error in",myorigval+": \""+x+"\" is not a valid version component."
436 vercache[myorigval]=0
437 return 0
438 if not len(myval[-1]):
439 if not silent:
440 print "!!! Name error in",myorigval+": two decimal points in a row"
441 vercache[myorigval]=0
442 return 0
443 try:
444 foo=int(myval[-1])
445 vercache[myorigval]=1
446 return 1
447 except SystemExit, e:
448 raise
449 except:
450 pass
451 #ok, our last component is not a plain number or blank, let's continue
452 if myval[-1][-1] in string.lowercase:
453 try:
454 foo=int(myval[-1][:-1])
455 vercache[myorigval]=1
456 return 1
457 # 1a, 2.0b, etc.
458 except SystemExit, e:
459 raise
460 except:
461 pass
462 #ok, maybe we have a 1_alpha or 1_beta2; let's see
463 #ep="endpart"
464 ep=string.split(myval[-1],"_")
465 if len(ep)!=2:
466 if not silent:
467 print "!!! Name error in",myorigval
468 vercache[myorigval]=0
469 return 0
470 try:
471 foo=int(ep[0][-1])
472 chk=ep[0]
473 except SystemExit, e:
474 raise
475 except:
476 # because it's ok last char is not numeric. example: foo-1.0.0a_pre1
477 chk=ep[0][:-1]
478
479 try:
480 foo=int(chk)
481 except SystemExit, e:
482 raise
483 except:
484 #this needs to be numeric or numeric+single letter,
485 #i.e. the "1" in "1_alpha" or "1a_alpha"
486 if not silent:
487 print "!!! Name error in",myorigval+": characters before _ must be numeric or numeric+single letter"
488 vercache[myorigval]=0
489 return 0
490 for mye in endversion_keys:
491 if ep[1][0:len(mye)]==mye:
492 if len(mye)==len(ep[1]):
493 #no trailing numeric; ok
494 vercache[myorigval]=1
495 return 1
496 else:
497 try:
498 foo=int(ep[1][len(mye):])
499 vercache[myorigval]=1
500 return 1
501 except SystemExit, e:
502 raise
503 except:
504 #if no endversions work, *then* we return 0
505 pass
506 if not silent:
507 print "!!! Name error in",myorigval
508 vercache[myorigval]=0
509 return 0
510
511def relparse(myver):
512 "converts last version part into three components"
513 number=0
514 suffix=0
515 endtype=0
516 endnumber=0
517
518 mynewver=string.split(myver,"_")
519 myver=mynewver[0]
520
521 #normal number or number with letter at end
522 divider=len(myver)-1
523 if myver[divider:] not in "1234567890":
524 #letter at end
525 suffix=ord(myver[divider:])
526 number=string.atof(myver[0:divider])
527 else:
528 number=string.atof(myver)
529
530 if len(mynewver)==2:
531 #an endversion
532 for x in endversion_keys:
533 elen=len(x)
534 if mynewver[1][:elen] == x:
535 endtype=endversion[x]
536 try:
537 endnumber=string.atof(mynewver[1][elen:])
538 except:
539 endnumber=0
540 break
541 return [number,suffix,endtype,endnumber]
542
543# vercmp:
544# ripped from portage.py to prevent having to import
545vcmpcache={}
546def vercmp(val1,val2):
547 if val1==val2:
548 #quick short-circuit
549 return 0
550 valkey=val1+" "+val2
551 try:
552 return vcmpcache[valkey]
553 try:
554 return -vcmpcache[val2+" "+val1]
555 except KeyError:
556 pass
557 except KeyError:
558 pass
559
560 # consider 1_p2 vc 1.1
561 # after expansion will become (1_p2,0) vc (1,1)
562 # then 1_p2 is compared with 1 before 0 is compared with 1
563 # to solve the bug we need to convert it to (1,0_p2)
564 # by splitting _prepart part and adding it back _after_expansion
565 val1_prepart = val2_prepart = ''
566 if val1.count('_'):
567 val1, val1_prepart = val1.split('_', 1)
568 if val2.count('_'):
569 val2, val2_prepart = val2.split('_', 1)
570
571 # replace '-' by '.'
572 # FIXME: Is it needed? can val1/2 contain '-'?
573 val1=string.split(val1,'-')
574 if len(val1)==2:
575 val1[0]=val1[0]+"."+val1[1]
576 val2=string.split(val2,'-')
577 if len(val2)==2:
578 val2[0]=val2[0]+"."+val2[1]
579
580 val1=string.split(val1[0],'.')
581 val2=string.split(val2[0],'.')
582
583 #add back decimal point so that .03 does not become "3" !
584 for x in range(1,len(val1)):
585 if val1[x][0] == '0' :
586 val1[x]='.' + val1[x]
587 for x in range(1,len(val2)):
588 if val2[x][0] == '0' :
589 val2[x]='.' + val2[x]
590
591 # extend version numbers
592 if len(val2)<len(val1):
593 val2.extend(["0"]*(len(val1)-len(val2)))
594 elif len(val1)<len(val2):
595 val1.extend(["0"]*(len(val2)-len(val1)))
596
597 # add back _prepart tails
598 if val1_prepart:
599 val1[-1] += '_' + val1_prepart
600 if val2_prepart:
601 val2[-1] += '_' + val2_prepart
602 #The above code will extend version numbers out so they
603 #have the same number of digits.
604 for x in range(0,len(val1)):
605 cmp1=relparse(val1[x])
606 cmp2=relparse(val2[x])
607 for y in range(0,4):
608 myret=cmp1[y]-cmp2[y]
609 if myret != 0:
610 vcmpcache[valkey]=myret
611 return myret
612 vcmpcache[valkey]=0
613 return 0
614
615# pkgcmp:
616# ripped from portage.py to prevent having to import
617def pkgcmp(pkg1,pkg2):
618 """if returnval is less than zero, then pkg2 is newer than pkg1, zero if equal and positive if older."""
619 if pkg1[0] != pkg2[0]:
620 return None
621 mycmp=vercmp(pkg1[1],pkg2[1])
622 if mycmp>0:
623 return 1
624 if mycmp<0:
625 return -1
626 r1=int(pkg1[2][1:])
627 r2=int(pkg2[2][1:])
628 if r1>r2:
629 return 1
630 if r2>r1:
631 return -1
632 return 0
633
284def ebuilds_to_rss(fp, ebuilds, simple=False, subtitle=""): 634def ebuilds_to_rss(fp, ebuilds, simple=False, subtitle=""):
285 """write out ebuild info to RSS file (fp)""" 635 """write out ebuild info to RSS file (fp)"""
636
637 # web link for RSS feed
638 if subtitle:
639 link = '%s/%s' % (config.FEHOME, subtitle.replace(' ','/',1))
640 else:
641 link = config.FEHOME
642
643 pubDate = time.strftime("%a, %d %b %Y %H:%M:%S +0000", time.gmtime())
286 fp.write("""<?xml version="1.0" encoding="iso-8859-1"?> 644 fp.write("""<?xml version="1.0" encoding="UTF-8"?>
287 <rss version="0.92"> 645 <rss version="2.0">
288 <channel> 646 <channel>
289 <title>Fresh ebuilds %s</title> 647 <title>packages.gentoo.org [ %s ]</title>
290 <link>%s</link> 648 <link>%s</link>
291 <description>Latest ebuilds from the Gentoo Linux portage tree</description> 649 <description>Latest ebuilds from the Gentoo Linux portage tree</description>
292 <![CDATA[<link rel="stylesheet" href="%s" type="text/css" title="styled" />]]>
293 <webMaster>www@gentoo.org</webMaster> 650 <webMaster>www@gentoo.org</webMaster>
651
652 <image>
653 <title>Online Package Database</title>
654 <url>%s</url>
655 <link>%s</link>
656 </image>
657
294 <managingEditor>marduk@gentoo.org</managingEditor> 658 <managingEditor>marduk@gentoo.org</managingEditor>
295 <pubDate>%s</pubDate>""" % (subtitle,config.FEHOME, config.STYLESHEET, 659 <pubDate>%s</pubDate>""" % (subtitle, link, config.RSS_IMAGE,
296 time.strftime("%a, %d %b %Y %H:%M:%S +0000", time.gmtime()))) 660 config.FEHOME, pubDate))
297 661
298 for ebuild in ebuilds: 662 for ebuild in ebuilds:
299 if simple: 663 if simple:
300 description = escape(ebuild['description']) 664 description = escape(ebuild['description'])
301 else: 665 else:
302 description = '\n<![CDATA[\n%s\n]]>' % ebuild_to_html(ebuild) 666 description = ('\n'
667 '<![CDATA[\n'
668 '<link rel="stylesheet" type="text/css" href="%s"></link>\n'
669 '%s\n]]>' % (config.STYLESHEET, ebuild_to_html(ebuild, full=True))
670 )
303 671
304 fp.write("""<item> 672 fp.write("""<item>
305 <title>%s %s</title> 673 <title>%s/%s %s</title>
306 <link>%sebuilds/?%s-%s</link> 674 <link>%sebuilds/?%s-%s</link>
307 <description> 675 <description>
308 %s 676 %s
309 </description> 677 </description>
310 <pubDate>%s</pubDate> 678 <pubDate>%s</pubDate>
311 </item> 679 </item>
312 """ % (ebuild['name'], 680 """ % (ebuild['category'],
681 ebuild['name'],
313 ebuild['version'], 682 ebuild['version'],
314 config.FEHOME, 683 config.FEHOME,
315 ebuild['name'], 684 ebuild['name'],
316 ebuild['version'], 685 ebuild['version'],
317 description, 686 description,
318 ebuild['time'].gmtime().strftime("%a, %d %b %Y %H:%M:%S +0000")) 687 ebuild['time'].strftime("%a, %d %b %Y %H:%M:%S +0000"))
319 ) 688 )
320 689
321 fp.write("</channel>\n</rss>\n") 690 fp.write("\n\
322 691 <textInput>\n\
323if __name__ == '__main__': 692 <title>Search the Online Package Database</title>\n\
693 <link>%s/search/</link>\n\
694 <description>emerge -Ss</description>\n\
695 <name>sstring</name>\n\
696 </textInput>\n\
697 </channel>\n\
698 </rss>\n" % config.FEHOME)
699
700def main(argv=None):
701 if argv is None:
702 argv = sys.argv
324 try: 703 try:
325 if sys.argv[1] == '-g': 704 if argv[1] == '-g':
326 ebuilddb.main() 705 ebuilddb.main()
327 except IndexError: 706 except IndexError:
328 pass 707 pass
329 708
330 db = ebuilddb.db_connect() 709 db = ebuilddb.db_connect()
331 branches = ('', 'stable', 'testing') 710 branches = ('', 'stable', 'testing')
332 for arch in [''] + config.ARCHLIST: 711 for arch in [''] + config.ARCHLIST:
333 for branch in branches: 712 for branch in branches:
334 fullpath = os.path.join(config.LOCALHOME, "archs", arch, branch, 713 fullpath = os.path.join(config.LOCALHOME, "archs", arch, branch,
335 config.INDEX) 714 config.INDEX)
336 index = open(fullpath,'w') 715 index = open(fullpath,'w')
337 if arch: 716
338 sarch = arch
339 else:
340 sarch = 'all'
341 if branch:
342 sbranch = branch
343 else:
344 sbranch = 'all'
345
346 index.write("""<table border="0" cellpadding="0" cellspacing="5" 717 index.write("""<table border="0" cellpadding="0" cellspacing="5"
347 width="100%">\n""") 718 width="100%">\n""")
348 index.write("""<tr><td valign="top">\n""") 719 index.write("""<tr><td valign="top">\n""")
349 index.write('<!--#include file="archnav.html" -->\n\n</td></tr>\n' 720 index.write('<!--#include file="archnav.html" -->\n\n</td></tr>\n'
350 '<tr><td>') 721 '<tr><td>')
351 results = get_most_recent(db, arch=arch, branch=branch) 722 results = get_most_recent(db, arch=arch, branch=branch)
352 ebuilds = [ query_to_dict(i) for i in results ] 723 ebuilds = [ query_to_dict(i) for i in results ]
353 for ebuild in ebuilds: 724 for ebuild in ebuilds:
354 new = is_new(db, ebuild) 725 new = is_new(db, ebuild)
355 pkgfilename = "%s/%s-%s.html" % ( 726 pkgfilename = "%s/%s-%s.html" % (
356 config.EBUILD_FILES,ebuild['name'],ebuild['version']) 727 config.EBUILD_FILES,ebuild['name'],ebuild['version'])
357 ebuild_html = ebuild_to_html(ebuild, new) 728 ebuild_html = ebuild_to_html(ebuild, new, show_bugs = False)
358 if arch == '' and branch == '': 729 if arch == '' and branch == '':
359 pkgfile = open(pkgfilename,'w') 730 pkgfile = open(pkgfilename,'w')
360 pkgfile.write(ebuild_html) 731 pkgfile.write(ebuild_html)
361 pkgfile.close() 732 pkgfile.close()
362 ebuildfilename = "%s/%s/%s/%s-%s.ebuild" \ 733 ebuildfilename = "%s/%s/%s/%s-%s.ebuild" \
363 % (ebuilddb.config.PORTAGE_DIR, 734 % (ebuilddb.config.PORTAGE_DIR,
364 ebuild['category'],ebuild['name'],ebuild['name'], 735 ebuild['category'],ebuild['name'],ebuild['name'],
365 ebuild['version']) 736 ebuild['version'])
366 os.system('touch -r %s %s || touch -d "today -1 year" %s' 737 os.system('touch -r %s %s || touch -d "today -1 year" %s'
367 % (ebuildfilename,pkgfilename,pkgfilename)) 738 % (ebuildfilename,pkgfilename,pkgfilename))
368 739
369 try: 740 try:
370 index.write('%s\n\n' % (ebuild_html)) 741 index.write('%s\n\n' % (ebuild_html))
371 except IOError: 742 except IOError:
372 continue 743 continue
373 index.write("""</table>\n""") 744 index.write("""</table>\n""")
374 index.close() 745 index.close()
375 746
376 subtitle = ' %s %s' % (arch, branch) 747 subtitle = ' %s %s' % (arch, branch)
377 rss = open(os.path.join(config.LOCALHOME, "archs", arch, branch, 748 rss = open(os.path.join(config.LOCALHOME, "archs", arch, branch,
378 config.RSS), 'w') 749 config.RSS), 'w')
379 ebuilds_to_rss(rss, ebuilds, simple=False, subtitle=subtitle) 750 ebuilds_to_rss(rss, ebuilds, simple=False, subtitle=subtitle)
380 rss.close() 751 rss.close()
381 752
382 rss2 = open(os.path.join(config.LOCALHOME, "archs", arch, branch, 753 rss2 = open(os.path.join(config.LOCALHOME, "archs", arch, branch,
383 config.RSS2), 'w') 754 config.RSS2), 'w')
384 ebuilds_to_rss(rss2, ebuilds, simple=True, subtitle=subtitle) 755 ebuilds_to_rss(rss2, ebuilds, simple=True, subtitle=subtitle)
385 rss.close() 756 rss.close()
757
758if __name__ == '__main__':
759 sys.exit(main())

Legend:
Removed from v.1.4  
changed lines
  Added in v.1.16.2.1

  ViewVC Help
Powered by ViewVC 1.1.20