Do not load avatar from cache if token is empty. Fixes bug #517098.
[empathy.git] / release.py
1 #!/usr/bin/env python
2
3 import os
4 import re
5 import urllib
6 import csv
7 import datetime
8 from string import Template
9
10 username = 'xclaesse'
11 upload_server = 'master.gnome.org'
12 template = '''\
13 $name $version is now available for download from:
14 $download
15
16 $md5sums
17
18 What is it?
19 ===========
20 $about
21
22 You can visit the project web site:
23 $website
24
25 What's New?
26 ===========
27 $news
28
29 $footer'''
30
31 class Bug:
32         number = ''
33         author = ''
34
35 class Project:
36         def __init__(self):
37                 f = open('config.h', 'r')
38                 s = f.read()
39                 f.close()
40
41                 key = {}
42                 key['package'] = '#define PACKAGE_NAME "'
43                 key['version'] = '#define PACKAGE_VERSION "'
44                 key['bugreport'] = '#define PACKAGE_BUGREPORT "'
45
46                 for line in s.splitlines(1):
47                         if line.startswith(key['package']):
48                                 p1 = len(key['package'])
49                                 p2 = line.rfind('"')
50                                 self.package_name = line[p1:p2]                 
51                         elif line.startswith(key['version']):
52                                 p1 = len(key['version'])
53                                 p2 = line.rfind('"')
54                                 self.package_version = line[p1:p2]              
55                         elif line.startswith(key['bugreport']):
56                                 p2 = line.rfind('"')
57                                 p1 = line.rfind('=') + 1
58                                 self.package_module = line[p1:p2]               
59
60                 first = self.package_version.find('.')
61                 second = self.package_version.find('.', first + 1)
62                 if first == -1 or second == -1 or first == second:
63                         version_dir = self.package_version
64                 else:
65                         version_dir = self.package_version[:second]
66                 self.package_dl_url = 'http://download.gnome.org/sources/%s/%s/' % (self.package_name.lower(), 
67                                                                                     version_dir)
68         def exec_cmd(self,cmd):
69                 return os.popen(cmd).read()
70
71         def get_news(self):
72                 f = open ('NEWS', 'r')
73                 s = f.read()
74                 f.close()
75                 start = s.find ('NEW in '+ self.package_version)
76                 if start != -1:
77                         start = s.find ('\n', start) + 1
78                         start = s.find ('\n', start) + 1
79                         end = s.find ('NEW in', start) - 1
80                         return s[start:end].strip()
81
82         def get_md5sums(self):
83                 md5sums = ''
84
85                 cmd = 'md5sum %s-%s.tar.gz' % (self.package_name.lower(), self.package_version)
86                 md5sums += self.exec_cmd(cmd)
87
88                 cmd = 'md5sum %s-%s.tar.bz2' % (self.package_name.lower(), self.package_version)
89                 md5sums += self.exec_cmd(cmd).strip()
90
91                 return md5sums
92
93         def get_bugzilla_info(self):
94                 query = 'http://bugzilla.gnome.org/browse.cgi?product=%s' % (self.package_module)
95                 f = urllib.urlopen(query)
96                 s = f.read()
97                 f.close()
98
99                 s1 = '<p><i>'
100                 i = s.find(s1)
101                 start = i + len(s1)
102                 s2 = '</i></p>'
103                 end = s.find(s2, i + 1)
104                 description = s[start:end]
105
106                 s1 = "GNOME SVN"
107                 i = s.find(s1)
108                 s1 = "href"
109                 i = s.find(s1, i)        
110                 start = i + 6
111                 s2 = '">'
112                 end = s.find(s2, start)
113                 project_url = s[start:end]
114
115                 return (description, project_url)
116
117         def get_release_notes(self):
118                 name = self.package_name
119                 version = self.package_version
120                 download = self.package_dl_url
121                 md5sums = self.get_md5sums()
122                 (about, website) = self.get_bugzilla_info()
123                 news = self.get_news()
124                 footer = '%s\n%s team' % (datetime.date.today().strftime('%d %B %Y'),\
125                                           self.package_name)
126
127                 t = Template(template)
128                 return t.substitute(locals())
129         
130         def get_last_tag(self):
131                 tags_str = self.exec_cmd('git-tag')
132                 tags = tags_str.splitlines()
133
134                 return tags[len(tags)-1]
135
136         def parse_commit(self, ref, author, date, message):
137                 p1 = message.rfind('(')
138                 p2 = message.rfind (')')
139                 if len(message) - p2 <= 2:
140                         author = message[p1+1:p2]
141                         message = message[:p1]
142
143                 msg = message.lower()
144                 if msg.find('translation') != -1 and\
145                    msg.find('updated') != -1:
146                         self.translations += ' - ' + message + ' (' + author + ').\n' 
147                 elif message.find('#') != -1:
148                         p1 = message.find('#')
149                         while p1 != -1:
150                                 bug = Bug()
151                                 p2 = message.find(' ', p1)
152                                 bug.number = message[p1+1:p2]
153                                 bug.author = author
154                                 self.bug_commits.append(bug)
155                                 p1 = message.find('#', p2)
156                 else:
157                         self.commits += ' - ' + message + ' (' + author + ').\n'
158
159         def query_bug_commits(self):
160                 bugs = ''
161                 for bug in self.bug_commits:
162                         bugs += bug.number + ','
163
164                 # Bugzilla query to use
165                 query = 'http://bugzilla.gnome.org/buglist.cgi?ctype=csv' \
166                         '&bug_status=RESOLVED,CLOSED,VERIFIED' \
167                         '&resolution=FIXED' \
168                         '&bug_id=' + bugs.replace(',', '%2c')
169
170                 f = urllib.urlopen(query)
171                 s = f.read()
172                 f.close()
173
174                 col_bug_id = -1
175                 col_description = -1
176
177                 reader = csv.reader(s.splitlines(1))
178                 header = reader.next()
179                 i = 0
180
181                 for col in header:
182                         if col == 'bug_id':
183                                 col_bug_id = i
184                         if col == 'short_short_desc':
185                                 col_description = i
186                         i = i + 1
187
188                 for row in reader:
189                         bug_number = row[col_bug_id]
190                         description = row[col_description]
191
192                         for bug in self.bug_commits:
193                                 if bug.number == bug_number:
194                                         self.bugs += ' - Fixed #%s, %s (%s)\n' % (bug.number, description, bug.author)
195                                         break
196
197         def get_commits(self):
198                 self.commits = ''
199                 self.translations = ''
200                 self.bugs = ''
201                 self.bug_commits = []
202                 last_tag = self.get_last_tag()
203                 ref = None
204
205                 changes = self.exec_cmd ("git-log " + last_tag + "..")
206                 for line in changes.splitlines(1):
207                         if line.startswith('commit'):
208                                 if ref != None:
209                                         self.parse_commit (ref, author, date, message)
210                                 p1 = line.find(' ')
211                                 ref = line[p1:].strip()
212                                 author = ''
213                                 date = ''
214                                 message = ''
215                         elif line.startswith('Author:'):
216                                 p1 = line.find(' ')
217                                 p2 = line.find('<')
218                                 author = line[p1:p2].strip()
219                         elif line.startswith('Date:'):
220                                 p1 = line.find(' ')
221                                 date = line[p1:].strip()
222                         elif line.startswith('    git-svn-id:'):
223                                 continue
224                         elif line.startswith('Merge:'):
225                                 continue
226                         else:
227                                 msg = line.strip()
228                                 if msg == '':
229                                         continue
230                                 if message != '':
231                                         message += '\n'
232                                 message += msg
233
234                 self.query_bug_commits ()
235
236         def make_tag(self):
237                 new_tag = self.package_name.upper() + '_' +\
238                           self.package_version.replace('.', '_')
239
240                 url1 = self.exec_cmd('git-config svn-remote.svn.url').strip()
241                 url2 = url1[:url1.rfind('/')] + '/tags/' + new_tag
242                 self.exec_cmd('svn copy %s %s -m "Tagged for release %s."' % (url1, url2, self.package_version))
243
244                 self.exec_cmd('git-tag -m "Tagged for release %s." %s' % ( self.package_version, new_tag))
245
246         def generate_news(self):
247                 self.get_commits()
248                 news = 'NEW in '+ self.package_version + '\n==============\n' 
249                 news += self.commits + '\nBugs fixed:\n' + self.bugs + '\nTranslations:\n' + self.translations + '\n'
250
251                 return news
252
253         def write_news(self):
254                 news = self.generate_news()
255
256                 f = open ('/tmp/NEWS', 'w')
257                 s = f.write(news)
258                 f.close()
259
260                 self.exec_cmd('cat NEWS >> /tmp/NEWS')
261                 self.exec_cmd('mv /tmp/NEWS .')
262
263         def upload_tarball(self):
264                 tarball = '%s-%s.tar.gz' % (self.package_name.lower(), self.package_version)
265
266                 cmd = 'scp %s %s@%s:' % (tarball, username, upload_server)
267                 self.exec_cmd(cmd)
268
269                 cmd = 'ssh %s@%s install-module -u %s' % (username, upload_server, tarball)
270                 self.exec_cmd(cmd)
271
272         def release(self):
273                 self.make_tag()
274                 self.upload_tarball()
275                 print self.get_release_notes()
276
277 p = Project()
278 #print p.generate_news()
279 #p.write_news()
280 #p.release()