summaryrefslogtreecommitdiff
blob: 5fdd6908487321f9b01bb45446004187a18c5a13 (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
#!/usr/bin/python
# -*- coding: utf8 -*-

# Fever - by MichaƂ Bentkowski 2007
# licensed under GPL

# first, let's do some koji things
import koji
session=koji.ClientSession("http://koji.fedoraproject.org/kojihub")

# now, import the other things we need

from commons import download, rpmvercmp, vercmpsort
import re
from xml.sax.saxutils import unescape

#set timeout TODO: should be set in config file
import socket
socket.setdefaulttimeout(45)

import sys

class Fever:
	def __init__(self, debug=0, 
			listformat="\* (?P<name>.*?) (?P<regex>.*) (?P<url>.*?)\n",
			listlocation="http://fedoraproject.org/wiki/PackageMaintainers/FEver"):
		self.debug=debug
		#self.listformat=listformat
		#self.lislocation=listlocation
		# it's sane to download a site with a list of packages at once
		site=download(listlocation, debug)
		# and let's parse it!
		self.pkglist={} # this var will keep all info of packages
		for package in re.finditer(listformat, site):
			dict=package.groupdict() #retrieve dictionary with name regex and url
			name=dict['name']
			del dict['name'] # we don't need name in dict anymore
			# sometimes there are escaped chars like &lt; in regex 
			# so we need to unescape them first
			dict['regex']=unescape(dict['regex'])
			self.pkglist[name]=dict
			self.pkglist[name]['checked']=False
			if debug >= 2:
				print "%s parsed. Data: %s" % (name,dict)
				
	def getPkgSiteVersion(self,pkgname):
		# download a proper site and get a package version
		site=download(self.pkglist[pkgname]['url'], self.debug)
		regex=self.pkglist[pkgname]['regex']
		versions=vercmpsort( re.findall(regex, site) ) # find all versions and sort'em
		return versions[0] # we need only the newest one
	
	def getPkgKojiVersion(self, pkgname):
		# first, we need koji's package id
		pkgid=session.getPackageID(pkgname)
		# now, list all builds
		builds=session.listBuilds(pkgid)
		# extract all versions and sort'em
		versions=vercmpsort( [x['version'] for x in session.listBuilds(pkgid)])
		return versions[0] # return the newest one
	
	def getPkgList(self):
		return self.pkglist
	
	def getPkgInfo(self, pkgname):
		return self.pkglist[pkgname]
	
	def checkPackage(self, pkgname):
		# this is probably the most important function,
		# it checks if repo version is newer than the available one.
		# Returns 0 if versions match or koji version is newer than site version
		# (it may happen if there's something wrong with regex) and 1 if a package's
		# owner need to update his package, -1 - if error.
		if self.debug >= 1:
			print 'Checking %s...' % pkgname
		try:
			sitever=self.getPkgSiteVersion(pkgname)
			kojiver=self.getPkgKojiVersion(pkgname)
		except:
			# if no version were found, we don't need this package anymore
			if self.debug >= 1:
				print "%s won't be checked. Error. %s" % (pkgname, str(sys.exc_info()))
			self.pkglist[pkgname]['checked']=False
			return -1
		if self.debug >= 2:
			print '%s: koji: %s; site: %s' % (pkgname, kojiver, sitever)
		compare=rpmvercmp(kojiver, sitever)
		self.pkglist[pkgname]['kojiver']=kojiver
		self.pkglist[pkgname]['sitever']=sitever
		self.pkglist[pkgname]['checked']=True
		if compare == -1: #if a newer version's available
			self.pkglist[pkgname]['uptodate']=False
			return 1
		else: # if isn't
			self.pkglist[pkgname]['uptodate']=True
			return 0
		
	def checkAllPackages(self):
		# simple loop to check all packages at once.
		for package in self.pkglist.keys():
			result=self.checkPackage(package)
				
	def isPackageUpToDate(self,pkgname):
		# just check if a given package is up to date
		return self.pkglist[pkgname]['uptodate']
	
	def listUpToDate(self):
		# list all up-to-date packages
		return [dict([(k,v)]) for k,v in self.pkglist.iteritems() if v['checked']==True and v['uptodate']==True]
	
	def listNotUpToDate(self):
		# list all not-up-to-date packages
		return [dict([(k,v)]) for k,v in self.pkglist.iteritems() if v['checked']==True and v['uptodate']==False]