1
2 __doc__ = """GNUmed internetworking tools."""
3
4
5 __version__ = "$Revision: 1.98 $"
6 __author__ = "K. Hilbert <Karsten.Hilbert@gmx.net>"
7 __license__ = "GPL (details at http://www.gnu.org)"
8
9
10 import sys
11 import os.path
12 import logging
13 import urllib2 as wget
14 import urllib
15 import MimeWriter
16 import mimetypes
17 import mimetools
18 import StringIO
19 import zipfile
20
21
22
23 if __name__ == '__main__':
24 sys.path.insert(0, '../../')
25 from Gnumed.pycommon import gmLog2
26 from Gnumed.pycommon import gmTools
27 from Gnumed.pycommon import gmShellAPI
28 from Gnumed.pycommon import gmCfg2
29
30
31 _log = logging.getLogger('gm.net')
32
47
49
50 unzip_dir = os.path.splitext(filename)[0]
51 _log.debug('unzipping data pack into [%s]', unzip_dir)
52 gmTools.mkdir(unzip_dir)
53 try:
54 data_pack = zipfile.ZipFile(filename, 'r')
55 except (zipfile.BadZipfile):
56 _log.exception('cannot unzip data pack [%s]', filename)
57 gmLog2.log_stack_trace()
58 return None
59
60 data_pack.extractall(unzip_dir)
61
62 return unzip_dir
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
88
89 if target_dir is None:
90 target_dir = gmTools.get_unique_filename(prefix = 'gm-dl-')
91
92 _log.debug('downloading [%s]', url)
93 _log.debug('unpacking into [%s]', target_dir)
94
95 gmTools.mkdir(directory = target_dir)
96
97
98
99 paths = gmTools.gmPaths()
100 local_script = os.path.join(paths.local_base_dir, '..', 'external-tools', 'gm-download_data')
101
102 candidates = [u'gm-download_data', u'gm-download_data.bat', local_script, u'gm-download_data.bat']
103 args = u' %s %s' % (url, target_dir)
104
105 success = gmShellAPI.run_first_available_in_shell (
106 binaries = candidates,
107 args = args,
108 blocking = True,
109 run_last_one_anyway = True
110 )
111
112 if success:
113 return True, target_dir
114
115 _log.error('download failed')
116 return False, None
117
118 -def check_for_update(url=None, current_branch=None, current_version=None, consider_latest_branch=False):
119 """Check for new releases at <url>.
120
121 Returns (bool, text).
122 True: new release available
123 False: up to date
124 None: don't know
125 """
126 try:
127 remote_file = wget.urlopen(url)
128 except (wget.URLError, ValueError, OSError):
129 _log.exception("cannot retrieve version file from [%s]", url)
130 return (None, _('Cannot retrieve version information from:\n\n%s') % url)
131
132 _log.debug('retrieving version information from [%s]', url)
133
134 cfg = gmCfg2.gmCfgData()
135 try:
136 cfg.add_stream_source(source = 'gm-versions', stream = remote_file)
137 except (UnicodeDecodeError):
138 remote_file.close()
139 _log.exception("cannot read version file from [%s]", url)
140 return (None, _('Cannot read version information from:\n\n%s') % url)
141
142 remote_file.close()
143
144 latest_branch = cfg.get('latest branch', 'branch', source_order = [('gm-versions', 'return')])
145 latest_release_on_latest_branch = cfg.get('branch %s' % latest_branch, 'latest release', source_order = [('gm-versions', 'return')])
146 latest_release_on_current_branch = cfg.get('branch %s' % current_branch, 'latest release', source_order = [('gm-versions', 'return')])
147
148 cfg.remove_source('gm-versions')
149
150 _log.info('current release: %s', current_version)
151 _log.info('current branch: %s', current_branch)
152 _log.info('latest release on current branch: %s', latest_release_on_current_branch)
153 _log.info('latest branch: %s', latest_branch)
154 _log.info('latest release on latest branch: %s', latest_release_on_latest_branch)
155
156
157 no_release_information_available = (
158 (
159 (latest_release_on_current_branch is None) and
160 (latest_release_on_latest_branch is None)
161 ) or (
162 not consider_latest_branch and
163 (latest_release_on_current_branch is None)
164 )
165 )
166 if no_release_information_available:
167 _log.warning('no release information available')
168 msg = _('There is no version information available from:\n\n%s') % url
169 return (None, msg)
170
171
172 if consider_latest_branch:
173 _log.debug('latest branch taken into account')
174 if current_version >= latest_release_on_latest_branch:
175 _log.debug('up to date: current version >= latest version on latest branch')
176 return (False, None)
177 if latest_release_on_latest_branch is None:
178 if current_version >= latest_release_on_current_branch:
179 _log.debug('up to date: current version >= latest version on current branch and no latest branch available')
180 return (False, None)
181 else:
182 _log.debug('latest branch not taken into account')
183 if current_version >= latest_release_on_current_branch:
184 _log.debug('up to date: current version >= latest version on current branch')
185 return (False, None)
186
187 new_release_on_current_branch_available = (
188 (latest_release_on_current_branch is not None) and
189 (latest_release_on_current_branch > current_version)
190 )
191 _log.info('%snew release on current branch available', gmTools.bool2str(new_release_on_current_branch_available, '', 'no '))
192
193 new_release_on_latest_branch_available = (
194 (latest_branch is not None)
195 and
196 (
197 (latest_branch > current_branch) or (
198 (latest_branch == current_branch) and
199 (latest_release_on_latest_branch > current_version)
200 )
201 )
202 )
203 _log.info('%snew release on latest branch available', gmTools.bool2str(new_release_on_latest_branch_available, '', 'no '))
204
205 if not (new_release_on_current_branch_available or new_release_on_latest_branch_available):
206 _log.debug('up to date: no new releases available')
207 return (False, None)
208
209
210 msg = _('A new version of GNUmed is available.\n\n')
211 msg += _(' Your current version: "%s"\n') % current_version
212 if consider_latest_branch:
213 if new_release_on_current_branch_available:
214 msg += u'\n'
215 msg += _(' New version: "%s"') % latest_release_on_current_branch
216 msg += u'\n'
217 msg += _(' - bug fixes only\n')
218 msg += _(' - database fixups may be needed\n')
219 if new_release_on_latest_branch_available:
220 if current_branch != latest_branch:
221 msg += u'\n'
222 msg += _(' New version: "%s"') % latest_release_on_latest_branch
223 msg += u'\n'
224 msg += _(' - bug fixes and new features\n')
225 msg += _(' - database upgrade required\n')
226 else:
227 msg += u'\n'
228 msg += _(' New version: "%s"') % latest_release_on_current_branch
229 msg += u'\n'
230 msg += _(' - bug fixes only\n')
231 msg += _(' - database fixups may be needed\n')
232
233 msg += u'\n\n'
234 msg += _(
235 'Note, however, that this version may not yet\n'
236 'be available *pre-packaged* for your system.'
237 )
238
239 msg += u'\n\n'
240 msg += _('Details are found on <http://wiki.gnumed.de>.\n')
241 msg += u'\n'
242 msg += _('Version information loaded from:\n\n %s') % url
243
244 return (True, msg)
245
246 default_mail_sender = u'gnumed@gmx.net'
247 default_mail_receiver = u'gnumed-devel@gnu.org'
248 default_mail_server = u'mail.gmx.net'
249
250 -def send_mail(sender=None, receiver=None, message=None, server=None, auth=None, debug=False, subject=None, encoding='quoted-printable', attachments=None):
251
252 if message is None:
253 return False
254
255 message = message.lstrip().lstrip('\r\n').lstrip()
256
257 if sender is None:
258 sender = default_mail_sender
259
260 if receiver is None:
261 receiver = [default_mail_receiver]
262
263 if server is None:
264 server = default_mail_server
265
266 if subject is None:
267 subject = u'gmTools.py: send_mail() test'
268
269 msg = StringIO.StringIO()
270 writer = MimeWriter.MimeWriter(msg)
271 writer.addheader('To', u', '.join(receiver))
272 writer.addheader('From', sender)
273 writer.addheader('Subject', subject[:50].replace('\r', '/').replace('\n', '/'))
274 writer.addheader('MIME-Version', '1.0')
275
276 writer.startmultipartbody('mixed')
277
278
279 part = writer.nextpart()
280 body = part.startbody('text/plain')
281 part.flushheaders()
282 body.write(message.encode(encoding))
283
284
285 if attachments is not None:
286 for a in attachments:
287 filename = os.path.basename(a[0])
288 try:
289 mtype = a[1]
290 encoding = a[2]
291 except IndexError:
292 mtype, encoding = mimetypes.guess_type(a[0])
293 if mtype is None:
294 mtype = 'application/octet-stream'
295 encoding = 'base64'
296 elif mtype == 'text/plain':
297 encoding = 'quoted-printable'
298 else:
299 encoding = 'base64'
300
301 part = writer.nextpart()
302 part.addheader('Content-Transfer-Encoding', encoding)
303 body = part.startbody("%s; name=%s" % (mtype, filename))
304 mimetools.encode(open(a[0], 'rb'), body, encoding)
305
306 writer.lastpart()
307
308 import smtplib
309 session = smtplib.SMTP(server)
310 session.set_debuglevel(debug)
311 if auth is not None:
312 session.login(auth['user'], auth['password'])
313 refused = session.sendmail(sender, receiver, msg.getvalue())
314 session.quit()
315 msg.close()
316 if len(refused) != 0:
317 _log.error("refused recipients: %s" % refused)
318 return False
319
320 return True
321
322
323
324 if __name__ == '__main__':
325
326 if len(sys.argv) < 2:
327 sys.exit()
328
329 if sys.argv[1] != 'test':
330 sys.exit()
331
332
348
350
351 test_data = [
352 ('http://www.gnumed.de/downloads/gnumed-versions.txt', None, None, False),
353 ('file:///home/ncq/gm-versions.txt', None, None, False),
354 ('file:///home/ncq/gm-versions.txt', '0.2', '0.2.8.1', False),
355 ('file:///home/ncq/gm-versions.txt', '0.2', '0.2.8.1', True),
356 ('file:///home/ncq/gm-versions.txt', '0.2', '0.2.8.5', True)
357 ]
358
359 for test in test_data:
360 print "arguments:", test
361 found, msg = check_for_update(test[0], test[1], test[2], test[3])
362 print msg
363
364 return
365
367
368
369 url = 'gmTools.py'
370 dl_name = download_data_pack(url)
371 print url, "->", dl_name
372 unzip_dir = unzip_data_pack(dl_name)
373 print "unzipped into", unzip_dir
374
375
376
377 test_dl_data_pack()
378
379
380