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