Package Gnumed :: Package pycommon :: Module gmNetworkTools
[frames] | no frames]

Source Code for Module Gnumed.pycommon.gmNetworkTools

  1  # -*- coding: utf8 -*- 
  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  # std libs 
 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  # GNUmed libs 
 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  #=========================================================================== 
33 -def download_data_pack(url, filename=None):
34 if filename is None: 35 filename = gmTools.get_unique_filename(prefix = 'gm-dl-', suffix = 'zip') 36 _log.debug('downloading [%s] into [%s]', url, filename) 37 38 try: 39 dl_name, headers = urllib.urlretrieve(url, filename) 40 except (ValueError, OSError, IOError): 41 _log.exception('cannot download from [%s]', url) 42 gmLog2.log_stack_trace() 43 return None 44 45 _log.debug(u'%s' % headers) 46 return dl_name
47 #---------------------------------------------------------------------------
48 -def unzip_data_pack(filename=None):
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 #def md5(): 65 # 66 # if md5 is not None: 67 # _log.debug(' expected md5: %s', md5) 68 # try: 69 # file_md5 = gmTools.file2md5(filename = filename, return_hex = True) 70 # _log.info('[%s] exists', filename) 71 # _log.debug('calculated md5: %s', file_md5) 72 # except: 73 # _log.exception('cannot calculate md5 of [%s]', filename) 74 # file_md5 = '-1' 75 # if file_md5 == md5: 76 # _log.info('not downloading from [%s]', url) 77 # return filename 78 # 79 # file_md5 = gmTools.file2md5(filename = dl_name, return_hex = True) 80 # _log.debug('calculated md5: %s', file_md5) 81 # if md5 is not None: 82 # _log.error(' expected md5: %s', md5) 83 # if file_md5 != md5: 84 # _log.error('md5 mismatch, error downloading data pack') 85 # return None 86 #===========================================================================
87 -def download_data_pack_old(url, target_dir=None):
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 # FIXME: rewrite to use urllib.urlretrieve() and 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 # anything known ? 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 # up to date ? 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 # not up to date 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 # start with a text/plain part 279 part = writer.nextpart() 280 body = part.startbody('text/plain') 281 part.flushheaders() 282 body.write(message.encode(encoding)) 283 284 # now add the attachments 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 # main 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 #-----------------------------------------------------------------------
333 - def test_send_mail():
334 msg = u""" 335 To: %s 336 From: %s 337 Subject: gmTools test suite mail 338 339 This is a test mail from the gmTools.py module. 340 """ % (default_mail_receiver, default_mail_sender) 341 print "mail sending succeeded:", send_mail ( 342 receiver = [default_mail_receiver, u'karsten.hilbert@gmx.net'], 343 message = msg, 344 auth = {'user': default_mail_sender, 'password': u'gnumed-at-gmx-net'}, # u'gm/bugs/gmx' 345 debug = True, 346 attachments = [sys.argv[0]] 347 )
348 #-----------------------------------------------------------------------
349 - def test_check_for_update():
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 #-----------------------------------------------------------------------
366 - def test_dl_data_pack():
367 #url = 'file:./x-data_pack.zip' 368 #url = 'missing-file.zip' 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 #test_check_for_update() 376 #test_send_mail() 377 test_dl_data_pack() 378 379 #=========================================================================== 380