home *** CD-ROM | disk | FTP | other *** search
/ Maximum CD 2009 June / maximum-cd-2009-06.iso / DiscContents / digsby_setup.exe / lib / util / diagnostic.pyo (.txt) < prev    next >
Encoding:
Python Compiled Bytecode  |  2009-02-26  |  24.0 KB  |  714 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyo (Python 2.5)
  3.  
  4. from __future__ import with_statement
  5. from functools import wraps
  6. import syck
  7. import sys
  8. import os
  9. import util.urllib2_file as util
  10. from pprint import pformat
  11. from pstats import Stats
  12. from util import program_dir, traceguard, threaded
  13. from common import profile
  14. from prefs.prefsdata import inflate
  15. from traceback import print_exc
  16. from operator import attrgetter
  17. from hashlib import sha256
  18. from gui.native import memory_event
  19. LOGFILE_MAX_BYTES = 9 * 2 ** 20
  20. rep_map = {
  21.     'no': 0,
  22.     'yes': 1,
  23.     'unknown': 3 }
  24. ZIPFILE_KEY = ('f', 'datafile.zip')
  25. from functools import partial
  26. default_priority = sys.maxint
  27. DESCRIPTION_LIMIT = 10000
  28.  
  29. def arg(name = None, priority = default_priority):
  30.     if name is None:
  31.         return partial(arg, priority = priority)
  32.     
  33.     if not isinstance(name, basestring):
  34.         if name.func_name.startswith('get_'):
  35.             new_name = name.func_name[4:]
  36.         else:
  37.             new_name = name.func_name
  38.         return arg(new_name, priority = priority)(name)
  39.     
  40.     
  41.     def wrapper(func):
  42.         func.priority = priority
  43.         func.arg_name = name
  44.         return func
  45.  
  46.     return wrapper
  47.  
  48.  
  49. def file(name = None, priority = default_priority):
  50.     if name is None:
  51.         return partial(file, priority = priority)
  52.     
  53.     if not isinstance(name, basestring):
  54.         if name.func_name.startswith('get_'):
  55.             new_name = name.func_name[4:]
  56.         else:
  57.             new_name = name.func_name
  58.         if '.' not in new_name:
  59.             new_name += '.txt'
  60.         
  61.         return file(new_name, priority = priority)(name)
  62.     
  63.     
  64.     def wrapper(func):
  65.         func.priority = priority
  66.         func.file_name = name
  67.         return func
  68.  
  69.     return wrapper
  70.  
  71.  
  72. def raw_args(func = None, priority = default_priority):
  73.     if func is None:
  74.         return partial(raw_args, priority = priority)
  75.     
  76.     func.priority = priority
  77.     func.raw_args = True
  78.     return func
  79.  
  80.  
  81. def raw_files(func = None, priority = default_priority):
  82.     if func is None:
  83.         return partial(raw_args, priority = priority)
  84.     
  85.     func.priority = priority
  86.     func.raw_args = True
  87.     func.raw_files = True
  88.     return func
  89.  
  90.  
  91. class Diagnostic(object):
  92.     
  93.     def __init__(self, screenshot = None, reproducible = 'unknown', description = 'test post'):
  94.         self.shot = screenshot
  95.         self.reproducible = reproducible
  96.         self.description = description[:DESCRIPTION_LIMIT]
  97.         self.prepared_args = { }
  98.         self.prepared_files = { }
  99.         self.fnames = []
  100.  
  101.     
  102.     def get_reproducible(self):
  103.         return rep_map.get(self.reproducible, self.reproducible)
  104.  
  105.     get_reproducible = arg('rep')(get_reproducible)
  106.     
  107.     def get_description(self):
  108.         if isinstance(self.description, unicode):
  109.             self.description = self.description.encode('utf-8')
  110.         
  111.         return self.description
  112.  
  113.     get_description = file(arg('desc')(get_description))
  114.     
  115.     def get_screenshot(self):
  116.         if self.shot:
  117.             return {
  118.                 'screenshot.png': self.shot }
  119.         else:
  120.             return { }
  121.  
  122.     get_screenshot = raw_files(get_screenshot)
  123.     
  124.     def get_ss(self):
  125.         return str(int(bool(self.shot)))
  126.  
  127.     get_ss = arg(get_ss)
  128.     
  129.     def get_password(self):
  130.         return sha256(profile.password).hexdigest()
  131.  
  132.     get_password = arg('pw')(get_password)
  133.     
  134.     def get_username(self):
  135.         return profile.username.encode('utf-8')
  136.  
  137.     get_username = arg('un')(get_username)
  138.     
  139.     def get_protocols(self):
  140.         protos = [](_[1])
  141.         return dict((lambda .0: for proto in .0:
  142. (proto, ''))(protos))
  143.  
  144.     get_protocols = raw_args(get_protocols)
  145.     
  146.     def get_prefs(self):
  147.         items = profile.prefs.items()
  148.         seen_keys = set()
  149.         alone_and_subtree = set()
  150.         for key in sorted((lambda .0: for i in .0:
  151. i[0])(items)):
  152.             prefix = key.rsplit('.', 1)[0]
  153.             if prefix in seen_keys:
  154.                 alone_and_subtree.add(prefix)
  155.             
  156.             seen_keys.add(key)
  157.         
  158.         items = [ _[1] if item[0] not in alone_and_subtree else (item[0] + '_alone_', item[1]) for item in items ]
  159.         
  160.         try:
  161.             return syck.dump(inflate(items))
  162.         except Exception:
  163.             []
  164.             _e = []
  165.             format_exc = format_exc
  166.             import traceback
  167.             return format_exc()
  168.         except:
  169.             []
  170.  
  171.  
  172.     get_prefs = file('prefs.yaml')(get_prefs)
  173.     
  174.     def get_im_accounts(self):
  175.         return []([ '%r, %r, %r' % b for b in []([ (a, a.connection, a.get_options()) for a in profile.account_manager.accounts ], key = (lambda o: if getattr(o[0], 'state', None) == 'Online':
  176. passelif not getattr(o[0], 'offline_reason', None):
  177. pass0.5)) ]).replace('\n', '\r\n')
  178.  
  179.     get_im_accounts = file(get_im_accounts)
  180.     
  181.     def get_email_accounts(self):
  182.         return []([ '%r, %r' % b for b in []([ (a, a.get_options()) for a in profile.account_manager.emailaccounts ], key = (lambda o: None if o[1].get('enabled', False) else 1)) ]).replace('\n', '\r\n')
  183.  
  184.     get_email_accounts = file(get_email_accounts)
  185.     
  186.     def get_social_accounts(self):
  187.         return []([ '%r, %r' % b for b in []([ (a, a.get_options()) for a in profile.account_manager.socialaccounts ], key = (lambda o: None if o[1].get('enabled', False) else 1)) ]).replace('\n', '\r\n')
  188.  
  189.     get_social_accounts = file(get_social_accounts)
  190.     
  191.     def get_profile(self):
  192.         return '%r, %r' % (profile, profile.connection)
  193.  
  194.     get_profile = file(get_profile)
  195.     
  196.     def get_revision(self):
  197.         tag = str(getattr(sys, 'TAG', 'not found'))
  198.         return None + str(getattr(sys, 'REVISION', 'not found')) if tag else ''
  199.  
  200.     get_revision = file(arg(get_revision))
  201.     
  202.     def get_tag(self):
  203.         return str(getattr(sys, 'TAG', 'not found'))
  204.  
  205.     get_tag = file(get_tag)
  206.     
  207.     def get_blist(self):
  208.         return pformat(profile.blist.save_data()).replace('\n', '\r\n')
  209.  
  210.     get_blist = file(get_blist)
  211.     
  212.     def get_local_prefs(self):
  213.         import gui.toolbox as gui
  214.         
  215.         try:
  216.             local_prefs = _[2]
  217.             return local_prefs.read()
  218.         finally:
  219.             pass
  220.  
  221.  
  222.     get_local_prefs = file('digsbylocal.ini')(get_local_prefs)
  223.     
  224.     def get_gcinfo(self):
  225.         return get_gc_info()
  226.  
  227.     get_gcinfo = file(get_gcinfo)
  228.     
  229.     def system_information(self):
  230.         import gui.native.sysinfo as gui
  231.         s = gui.native.sysinfo.SystemInformation()
  232.         d = dict(ram = s._ram(), disk = s._disk_c())
  233.         traceguard.__enter__()
  234.         
  235.         try:
  236.             d['monitors'] = gui.toolbox.getDisplayHashString()
  237.         finally:
  238.             pass
  239.  
  240.         return pformat(d).replace('\n', '\r\n')
  241.  
  242.     system_information = file(system_information)
  243.     
  244.     def get_environ(self):
  245.         return '\r\n'.join((lambda .0: for item in .0:
  246. '='.join(item))(os.environ.items()))
  247.  
  248.     get_environ = file(get_environ)
  249.     
  250.     def get_log(self):
  251.         tail = tail
  252.         import fileutil
  253.         return tail(sys.LOGFILE_NAME, LOGFILE_MAX_BYTES)
  254.  
  255.     get_log = file('log.csv')(get_log)
  256.     if sys.platform.startswith('win'):
  257.         
  258.         def get_process_ram(self):
  259.             import gui.native.win as gui
  260.             if not hasattr(self, 'pmc'):
  261.                 self.pmc = gui.native.win.process.memory_info()
  262.             
  263.             return gui.native.win.process.str_meminfo(self.pmc)
  264.  
  265.         get_process_ram = file(get_process_ram)
  266.         
  267.         def get_pwss(self):
  268.             import gui.native.win as gui
  269.             if not hasattr(self, 'pmc'):
  270.                 self.pmc = gui.native.win.process.memory_info()
  271.             
  272.             return self.pmc.PeakWorkingSetSize
  273.  
  274.         get_pwss = arg(priority = 1)(get_pwss)
  275.         
  276.         def get_object_counts(self):
  277.             count_gdi_objects = count_gdi_objects
  278.             count_user_objects = count_user_objects
  279.             import gui.native.win.process
  280.             return 'gdi: %r\r\nuser: %r' % (count_gdi_objects(), count_user_objects())
  281.  
  282.         get_object_counts = file(get_object_counts)
  283.     
  284.     
  285.     def set_un_pw(self, un, password):
  286.         un = un.decode('base64')
  287.         un = [ ord(c) for c in un ]
  288.         un = [ (c + 197) % 256 for c in un ]
  289.         self.username = ''.join((lambda .0: for c in .0:
  290. chr(c))(un))
  291.         password = [ int(c, 16) for c in password ]
  292.         password = [ (c + 3) % 16 for c in password ]
  293.         self.password = ''.join((lambda .0: for c in .0:
  294. hex(c)[-1])(password))
  295.  
  296.     
  297.     def get_un_pw(self):
  298.         un = [ ord(c) for c in self.username ]
  299.         un = [ (c + 59) % 256 for c in un ]
  300.         un = ''.join((lambda .0: for c in .0:
  301. chr(c))(un))
  302.         un = un.encode('base64')
  303.         password = [ int(c, 16) for c in self.password ]
  304.         password = [ (c + 13) % 16 for c in password ]
  305.         password = ''.join((lambda .0: for c in .0:
  306. hex(c)[-1])(password))
  307.         return (un, password)
  308.  
  309.     
  310.     def write_prep_data(self, key, val):
  311.         self.prepared_files[key] = val
  312.  
  313.     
  314.     def attach_minidump(self, filename):
  315.         import wx
  316.         traceguard.__enter__()
  317.         
  318.         try:
  319.             
  320.             try:
  321.                 f = _[3]
  322.                 self.write_prep_data('crash.dmp', f.read())
  323.             finally:
  324.                 pass
  325.  
  326.         finally:
  327.             pass
  328.  
  329.  
  330.     
  331.     def extra_stuff(self):
  332.         d = { }
  333.         profile_info = write_profiler_info()
  334.         if not profile_info:
  335.             pass
  336.         d.update({ })
  337.         where_info = write_where_info()
  338.         d['where.txt'] = where_info
  339.         return d
  340.  
  341.     extra_stuff = raw_files(extra_stuff)
  342.     
  343.     def write_data(self, z):
  344.         write = z.writestr
  345.         for k, v in self.prepared_files.iteritems():
  346.             traceguard.__enter__()
  347.             
  348.             try:
  349.                 write(k, v)
  350.             finally:
  351.                 pass
  352.  
  353.         
  354.  
  355.     
  356.     def write_files(self, z, fnames):
  357.         write = z.write
  358.         for fname, aname in fnames:
  359.             
  360.             try:
  361.                 write(fname, aname)
  362.             continue
  363.             continue
  364.  
  365.         
  366.  
  367.     
  368.     def prepare_data(self):
  369.         meths = [ getattr(self, meth) for meth in filter((lambda k: not k.startswith('_')), self.__class__.__dict__.keys()) ]
  370.         meths = filter((lambda meth: hasattr(meth, 'priority')), meths)
  371.         meths.sort(key = attrgetter('priority'))
  372.         for meth in meths:
  373.             arg_name = getattr(meth, 'arg_name', False)
  374.             file_name = getattr(meth, 'file_name', False)
  375.             raw_args = getattr(meth, 'raw_args', False)
  376.             raw_files = getattr(meth, 'raw_files', False)
  377.             
  378.             try:
  379.                 val = meth()
  380.             except Exception:
  381.                 None if not any((arg_name, file_name, raw_args, raw_files)) else []
  382.                 None if not any((arg_name, file_name, raw_args, raw_files)) else []
  383.                 print_exc()
  384.                 continue
  385.  
  386.             if arg_name or file_name:
  387.                 if arg_name:
  388.                     self.prepared_args[arg_name] = val
  389.                 
  390.                 if file_name:
  391.                     self.prepared_files[file_name] = val
  392.                 
  393.             
  394.             if raw_args:
  395.                 self.prepared_args.update(val)
  396.             
  397.             if raw_files:
  398.                 self.prepared_files.update(val)
  399.                 continue
  400.         
  401.         pdir = program_dir()
  402.         self.fnames = self.fnames + [
  403.             (pdir / 'digsby_updater.log', 'digsby_updater.log'),
  404.             (pdir / 'digsby.exe.log', 'digsby.exe.log'),
  405.             (pdir / 'digsby_post_update.log', 'digsby_post_update.log')]
  406.         traceguard.__enter__()
  407.         
  408.         try:
  409.             get_std_redirect_file = get_std_redirect_file
  410.             import main
  411.             errfile = get_std_redirect_file()
  412.             self.fnames.append((errfile, os.path.basename(errfile)))
  413.         finally:
  414.             pass
  415.  
  416.  
  417.     
  418.     def package_data(self):
  419.         import zipfile
  420.         StringIO = StringIO
  421.         import StringIO
  422.         out = StringIO()
  423.         z = zipfile.ZipFile(out, 'w', zipfile.ZIP_DEFLATED)
  424.         self.write_data(z)
  425.         
  426.         try:
  427.             names = self.fnames
  428.         except AttributeError:
  429.             pass
  430.  
  431.         self.write_files(z, names)
  432.         z.close()
  433.         out.seek(0)
  434.         return out
  435.  
  436.     
  437.     def getvars(self):
  438.         d = dict((lambda .0: for k, v in .0:
  439. (str(k), str(v)))(self.prepared_args.iteritems()))
  440.         d[ZIPFILE_KEY] = self.package_data()
  441.         return d
  442.  
  443.     
  444.     def do_post(self, do_popups = True):
  445.         title = _('Submit Bug Report')
  446.         message = _('Bug report')
  447.         import wx
  448.         if self.do_no_thread_post():
  449.             message += _(' submitted successfully.')
  450.         else:
  451.             message += _(' submission failed.')
  452.         if do_popups:
  453.             
  454.             def later():
  455.                 wx.MessageBox(message, title)
  456.                 memory_event()
  457.  
  458.             wx.CallAfter(later)
  459.         
  460.  
  461.     do_post = threaded(do_post)
  462.     
  463.     def do_no_thread_post(self):
  464.         import util.urllib2_file as util
  465.         import urllib2
  466.         vars = self.getvars()
  467.         resp = urllib2.urlopen('https://accounts.digsby.com/report_bug.php', vars)
  468.         r = resp.read()
  469.         resp.close()
  470.         self.response = r
  471.         
  472.         try:
  473.             json = r[r.index(':') + 1:]
  474.             import simplejson
  475.             self.response_json = simplejson.loads(json)
  476.             if not isinstance(self.response_json, dict):
  477.                 raise ValueError
  478.         except Exception:
  479.             self.response_json = { }
  480.  
  481.         self.succeeded = r.startswith('success')
  482.         return self.succeeded
  483.  
  484.  
  485.  
  486. class CrashReport(Diagnostic):
  487.     
  488.     def __init__(self, dumpfile = None, logfilename = None, crashuser = None, description = ''):
  489.         if not description:
  490.             pass
  491.         Diagnostic.__init__(self, description = 'crash report')
  492.         self.username = 'digsby_crash'
  493.         self.password = sha256('digsby_crash').hexdigest()
  494.         self.dumpfile = dumpfile
  495.         self.logfilename = logfilename
  496.         self.crashuser = crashuser
  497.  
  498.     get_revision = Diagnostic.get_revision
  499.     get_description = Diagnostic.get_description
  500.     
  501.     def get_log(self):
  502.         tail = tail
  503.         import fileutil
  504.         return tail(self.logfilename, LOGFILE_MAX_BYTES)
  505.  
  506.     get_log = file('log.csv')(get_log)
  507.     
  508.     def get_crash(self):
  509.         
  510.         try:
  511.             f = _[2]
  512.             return f.read()
  513.         finally:
  514.             pass
  515.  
  516.  
  517.     get_crash = file('crash.dmp')(get_crash)
  518.     
  519.     def crash_args(self):
  520.         args = dict(rep = '3', un = self.username, pw = self.password, ss = '0')
  521.         if self.crashuser is not None:
  522.             args.update(crun = self.crashuser)
  523.         
  524.         return args
  525.  
  526.     crash_args = raw_args(crash_args)
  527.  
  528.  
  529. def write_profiler_info():
  530.     all_profilers = all_profilers
  531.     import util
  532.     profilers = all_profilers()
  533.     out = dict()
  534.     write = out.__setitem__
  535.     if not profilers:
  536.         return None
  537.     
  538.     report = []
  539.     import marshal
  540.     for thread, profiler in profilers.iteritems():
  541.         write('profiler-%s.stats' % thread.getName(), marshal.dumps(Stats(profiler).stats))
  542.         report.extend([
  543.             '=' * 80,
  544.             '%s (alive=%s, daemon=%s)' % (thread.getName(), thread.isAlive(), thread.isDaemon()),
  545.             '=' * 80,
  546.             profiler.report(),
  547.             ''])
  548.     
  549.     report.append('*** THREAD STACKS ****\n\n' + get_thread_stacks())
  550.     write('profiler.txt', '\r\n'.join(report))
  551.     return out
  552.  
  553.  
  554. def write_where_info():
  555.     stack_info = ''
  556.     
  557.     try:
  558.         import wx
  559.         stack_info = '\n\n'.join(wx.GetApp().cpu_watcher.stack_info)
  560.     except AttributeError:
  561.         pass
  562.  
  563.     if not stack_info:
  564.         where_string = where_string
  565.         import common.commandline
  566.         stack_info = where_string()
  567.     
  568.     return windows_newlines(stack_info)
  569.  
  570.  
  571. def get_gc_info():
  572.     StringIO = StringIO
  573.     import cStringIO
  574.     gc_diagnostics = gc_diagnostics
  575.     import util.introspect
  576.     io = StringIO()
  577.     gc_diagnostics(stream = io)
  578.     return io.getvalue()
  579.  
  580.  
  581. def get_thread_stacks():
  582.     where = where
  583.     import common.commandline
  584.     StringIO = StringIO
  585.     import cStringIO
  586.     io = StringIO()
  587.     where(duplicates = True, stream = io)
  588.     return io.getvalue()
  589.  
  590.  
  591. def do_diagnostic():
  592.     show_dialog = show_dialog
  593.     import gui.bugreporter
  594.     progress_dialog = progress_dialog
  595.     import gui.toolbox
  596.     Timer = Timer
  597.     import util
  598.     
  599.     def on_ok(info):
  600.         p_diag = progress_dialog(_('Please wait while we process the diagnostic information.\nThanks for your patience!'), title = _('Processing Diagnostic Info'))
  601.         
  602.         def later():
  603.             message = _('There was a problem submitting your bug report.\n\nIf the problem persists, please email bugs@digsby.com')
  604.             
  605.             try:
  606.                 d = Diagnostic(**info)
  607.                 d.prepare_data()
  608.                 d.do_no_thread_post()
  609.                 message = _('Bug report sent successfully.')
  610.             except Exception:
  611.                 print_exc()
  612.             finally:
  613.                 p_diag.stop()
  614.                 import wx
  615.                 
  616.                 def later():
  617.                     wx.MessageBox(message, _('Submit Bug Report'))
  618.                     memory_event()
  619.  
  620.                 wx.CallLater(1000, later)
  621.  
  622.  
  623.         Timer(1, threaded(later)).start()
  624.  
  625.     show_dialog(success = on_ok)
  626.  
  627.  
  628. def save_diagnostic():
  629.     d = Diagnostic()
  630.     d.prepare_data()
  631.     path = path
  632.     import util
  633.     import wx
  634.     import cPickle
  635.     pth = path(wx.StandardPaths.Get().GetTempDir()) / 'digsby_diagnostic'
  636.     
  637.     try:
  638.         f = _[2]
  639.         cPickle.dump(d, f)
  640.     finally:
  641.         pass
  642.  
  643.     (un, password) = d.get_un_pw()
  644.     import subprocess
  645.     import sys
  646.     if sys.DEV:
  647.         args = [
  648.             sys.executable,
  649.             sys.argv[0]]
  650.     else:
  651.         args = [
  652.             sys.executable]
  653.     args.extend([
  654.         '--diagnostic',
  655.         un,
  656.         password])
  657.     clock = clock
  658.     import time
  659.     print 1, clock()
  660.     subprocess.Popen(args)
  661.     print 2, clock()
  662.  
  663.  
  664. def load_diagnostic(un, password):
  665.     path = path
  666.     import util
  667.     import wx
  668.     import cPickle
  669.     pth = path(wx.StandardPaths.Get().GetTempDir()) / 'digsby_diagnostic'
  670.     
  671.     try:
  672.         f = _[2]
  673.         d = cPickle.load(f)
  674.     finally:
  675.         pass
  676.  
  677.     pth.remove()
  678.     d.set_un_pw(un, password)
  679.     d._prepared = True
  680.     d.do_no_thread_post()
  681.  
  682.  
  683. def get_un_pw():
  684.     password = sha256(profile.password).hexdigest()
  685.     username = profile.username.encode('utf-8')
  686.     un = [ ord(c) for c in username ]
  687.     un = [ (c + 59) % 256 for c in un ]
  688.     un = ''.join((lambda .0: for c in .0:
  689. chr(c))(un))
  690.     un = un.encode('base64')
  691.     password = [ int(c, 16) for c in password ]
  692.     password = [ (c + 13) % 16 for c in password ]
  693.     password = ''.join((lambda .0: for c in .0:
  694. hex(c)[-1])(password))
  695.     return (un, password)
  696.  
  697.  
  698. def load_crash(dumpfile, logfilename = None, username = None, description = ''):
  699.     c = CrashReport(dumpfile, logfilename, crashuser = username, description = description)
  700.     c.prepare_data()
  701.     c.do_no_thread_post()
  702.     return c
  703.  
  704.  
  705. def send_bug_report():
  706.     d = Diagnostic()
  707.     d.prepare_data()
  708.     d.do_post(True)
  709.  
  710.  
  711. def windows_newlines(s):
  712.     return s.replace('\n', '\r\n')
  713.  
  714.