home *** CD-ROM | disk | FTP | other *** search
/ Maximum CD 2012 January / maximum-cd-2012-01.iso / DiscContents / digsby_setup.exe / lib / digsbysplash.pyo (.txt) < prev    next >
Encoding:
Python Compiled Bytecode  |  2011-10-05  |  28.4 KB  |  908 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyo (Python 2.6)
  3.  
  4. from __future__ import with_statement
  5. import wx
  6. import cgui
  7. from cgui import LoginWindow, IsMainThread
  8. from traceback import print_exc
  9. DEFAULT_SPLASH_POS = (300, 300)
  10. from cPickle import dump, load
  11. import os.path as os
  12. import sys
  13. import path
  14. import syck
  15. import re
  16. import logging
  17. log = logging.getLogger('loginwindow')
  18.  
  19. try:
  20.     _
  21. except:
  22.     
  23.     _ = lambda s: s
  24.  
  25. SIGN_IN = _('&Sign In')
  26. RESDIR = 'res'
  27. if not True:
  28.     pass
  29. USE_NEW_STORAGE = sys.DEV
  30. import datetime
  31. if datetime.date.today().timetuple()[1:3] == (3, 17):
  32.     digsby_logo_filename = 'digsby_stpatricks.png'
  33. else:
  34.     digsby_logo_filename = 'digsbybig.png'
  35. connection_errors = dict(auth = _('Authentication Error'), connlost = _('Connection Lost'), server = _('We are upgrading Digsby. Please try connecting again in a few minutes.'), client = _('Could not contact remote server. Check your network configuration.'))
  36.  
  37. class DataProblems(object):
  38.     BAD_USERNAME = _('Invalid Digsby Username')
  39.  
  40.  
  41. def GetUserTempDir():
  42.     import stdpaths
  43.     if getattr(sys, 'is_portable', False):
  44.         base_temp = stdpaths.temp / 'digsby'
  45.     else:
  46.         base_temp = stdpaths.userlocaldata
  47.     pth = path.path(base_temp) / 'temp'
  48.     if not pth.isdir():
  49.         os.makedirs(pth)
  50.     
  51.     return pth
  52.  
  53.  
  54. class SplashDiskStorage(object):
  55.     info_default = {
  56.         '': dict(username = '', password = '', save = False, autologin = False, pos = (200, 200)),
  57.         None: dict() }
  58.     last_default = ''
  59.     
  60.     def get_conf_dir(self):
  61.         import stdpaths
  62.         c_dir = stdpaths.userdata
  63.         
  64.         try:
  65.             return c_dir
  66.         finally:
  67.             if not os.path.exists(c_dir):
  68.                 os.mkdir(c_dir)
  69.             
  70.  
  71.  
  72.     
  73.     def get_splash_data_path(self):
  74.         return None(os.path.join, self.get_conf_dir() % self.data_file_name if sys.REVISION == 'dev' else '')
  75.  
  76.     
  77.     def crypt_pws(self, info, codec):
  78.         for user in info:
  79.             if 'password' in info[user]:
  80.                 if codec == 'encode':
  81.                     info[user]['password'] = self.simple_crypt(info[user]['password'].encode('utf8'), keymat = user.encode('utf8'))
  82.                 elif codec == 'decode':
  83.                     info[user]['password'] = self.simple_crypt(info[user]['password'], keymat = user.encode('utf8')).decode('utf8')
  84.                 else:
  85.                     raise AssertionError
  86.             codec == 'encode'
  87.         
  88.  
  89.     
  90.     def simple_crypt(self, s, k = None, keymat = ''):
  91.         raise NotImplementedError
  92.  
  93.     
  94.     def save_to_disk(self, last, info):
  95.         raise NotImplementedError
  96.  
  97.     
  98.     def load_from_disk(self):
  99.         raise NotImplementedError
  100.  
  101.     
  102.     def can_write(self):
  103.         fname = os.path.join(self.get_conf_dir(), '__test__')
  104.         test_data = 'test'
  105.         
  106.         try:
  107.             
  108.             try:
  109.                 f = _[1]
  110.                 f.write(test_data)
  111.             finally:
  112.                 pass
  113.  
  114.             
  115.             try:
  116.                 f = _[2]
  117.                 if f.read() == test_data:
  118.                     return True
  119.             finally:
  120.                 pass
  121.  
  122.             return False
  123.         except Exception:
  124.             return False
  125.         finally:
  126.             
  127.             try:
  128.                 if os.path.exists(fname):
  129.                     os.remove(fname)
  130.             except Exception:
  131.                 pass
  132.  
  133.  
  134.  
  135.  
  136.  
  137. class NewSplashDiskStorage(SplashDiskStorage):
  138.     data_file_name = 'logininfo%s.yaml'
  139.     
  140.     def __init__(self):
  141.         SplashDiskStorage.__init__(self)
  142.         self.fallback = OldSplashDiskStorage()
  143.  
  144.     
  145.     def get_conf_dir(self):
  146.         import stdpaths
  147.         c_dir = stdpaths.userlocaldata
  148.         
  149.         try:
  150.             return c_dir
  151.         finally:
  152.             if not os.path.exists(c_dir):
  153.                 os.makedirs(c_dir)
  154.             
  155.  
  156.  
  157.     
  158.     def simple_crypt(self, s, k = None, keymat = ''):
  159.         RC4 = RC4
  160.         import M2Crypto.RC4
  161.         if k is None:
  162.             k = self._get_key(keymat)
  163.         
  164.         return RC4(k).update(s)
  165.  
  166.     
  167.     def _get_key(self, keymat = ''):
  168.         keys = getattr(self, '_keys', None)
  169.         if keys is None:
  170.             keys = self._keys = { }
  171.         
  172.         key = keys.get(keymat, None)
  173.         if key is not None:
  174.             return key
  175.         sysident = sysident
  176.         import sysident
  177.         self._keys[keymat] = sysident(append = keymat)
  178.         return self._keys[keymat]
  179.  
  180.     
  181.     def load_from_disk(self):
  182.         path = self.get_splash_data_path()
  183.         
  184.         try:
  185.             
  186.             try:
  187.                 f = _[1]
  188.                 all_info = syck.load(f)
  189.             finally:
  190.                 pass
  191.  
  192.             info = all_info.get('users', self.info_default)
  193.             last = all_info.get('last', self.last_default)
  194.             self.crypt_pws(info, 'decode')
  195.         except Exception:
  196.             e = None
  197.             print_exc()
  198.             (last, info) = self.fallback.load_from_disk()
  199.             oldpth = self.fallback.get_splash_data_path()
  200.             if os.path.exists(oldpth):
  201.                 
  202.                 try:
  203.                     os.remove(oldpth)
  204.                 except Exception:
  205.                     print_exc()
  206.                 except:
  207.                     None<EXCEPTION MATCH>Exception
  208.                 
  209.  
  210.             None<EXCEPTION MATCH>Exception
  211.  
  212.         return (last, info)
  213.  
  214.     
  215.     def save_to_disk(self, last, info):
  216.         path = self.get_splash_data_path()
  217.         self.crypt_pws(info, 'encode')
  218.         for_yaml = {
  219.             'users': info,
  220.             'last': last }
  221.         
  222.         try:
  223.             
  224.             try:
  225.                 f = _[1]
  226.                 syck.dump(for_yaml, f)
  227.             finally:
  228.                 pass
  229.  
  230.         except Exception:
  231.             print_exc()
  232.  
  233.         self.crypt_pws(info, 'decode')
  234.         return True
  235.  
  236.  
  237.  
  238. class OldSplashDiskStorage(SplashDiskStorage):
  239.     data_file_name = 'digsby%s.dat'
  240.     
  241.     def simple_crypt(self, s, k = None, keymat = ''):
  242.         RC4 = RC4
  243.         import M2Crypto.RC4
  244.         if k is None:
  245.             k = 'foo'
  246.         
  247.         return RC4(k).update(s)
  248.  
  249.     
  250.     def load_from_disk(self):
  251.         path = self.get_splash_data_path()
  252.         last = self.last_default
  253.         info = self.info_default
  254.         
  255.         try:
  256.             if os.path.exists(path):
  257.                 
  258.                 try:
  259.                     f = _[1]
  260.                     last = load(f)
  261.                     info = load(f)
  262.                 finally:
  263.                     pass
  264.  
  265.                 self.crypt_pws(info, 'decode')
  266.         except Exception:
  267.             e = None
  268.             print_exc()
  269.  
  270.         return (last, info)
  271.  
  272.     
  273.     def save_to_disk(self, last, info):
  274.         path = self.get_splash_data_path()
  275.         self.crypt_pws(info, 'encode')
  276.         
  277.         try:
  278.             
  279.             try:
  280.                 f = _[1]
  281.                 dump(last, f)
  282.                 dump(info, f)
  283.             finally:
  284.                 pass
  285.  
  286.         except Exception:
  287.             print_exc()
  288.  
  289.         self.crypt_pws(info, 'decode')
  290.         return True
  291.  
  292.  
  293.  
  294. class PortableSplashDiskStorage(OldSplashDiskStorage):
  295.     pass
  296.  
  297.  
  298. def res(*a):
  299.     return os.path.join(RESDIR, *a)
  300.  
  301.  
  302. def digsby_icon_filename():
  303.     return res('digsby.ico')
  304.  
  305. _icon_bundle = None
  306.  
  307. def icon_bundle():
  308.     global _icon_bundle
  309.     if _icon_bundle is None:
  310.         _icon_bundle = wx.IconBundleFromFile(digsby_icon_filename(), wx.BITMAP_TYPE_ANY)
  311.     
  312.     return _icon_bundle
  313.  
  314.  
  315. class LoginController(object):
  316.     have_shown_updated = False
  317.     
  318.     def __init__(self, on_success = (lambda : pass), autologin_override = None):
  319.         self.allow_autologin = sys.opts.autologin
  320.         self.cancelling = False
  321.         self.on_success = on_success
  322.         if getattr(sys, 'is_portable', False):
  323.             self._datastore = PortableSplashDiskStorage()
  324.         elif USE_NEW_STORAGE:
  325.             self._datastore = NewSplashDiskStorage()
  326.         else:
  327.             self._datastore = OldSplashDiskStorage()
  328.         self._profile = sentinel
  329.         (username, self.allinfo) = self._datastore.load_from_disk()
  330.         position = self.allinfo.get('pos', DEFAULT_SPLASH_POS)
  331.         login_bitmap = wx.Bitmap(res('digsbybig.png'))
  332.         help_bitmap = wx.Bitmap(res('skins/default/help.png'))
  333.         revision_string = ' '.join((lambda .0: for x in .0:
  334. str(x))((getattr(sys, 'REVISION', ''), getattr(sys, 'TAG', ''), getattr(sys, 'BRAND', ''))))
  335.         show_languages = False
  336.         self.window = LoginWindow(None, position, login_bitmap, help_bitmap, str(revision_string), show_languages)
  337.         self.bind_events()
  338.         
  339.         try:
  340.             self._set_frame_icon()
  341.         except Exception:
  342.             print_exc()
  343.  
  344.         cgui.FitInMonitors(self.window)
  345.         
  346.         try:
  347.             info = self.allinfo[username]
  348.         except KeyError:
  349.             info = dict(username = self._get_window_username(), password = '', save = False, autologin = False, pos = DEFAULT_SPLASH_POS)
  350.  
  351.         
  352.         try:
  353.             status_message = self.allinfo[None]['status']
  354.             self.allinfo[None]['status'] = ''
  355.         except KeyError:
  356.             if None not in self.allinfo:
  357.                 self.allinfo[None] = dict(status = '')
  358.             elif 'status' not in self.allinfo[None]:
  359.                 self.allinfo[None]['status'] = ''
  360.             
  361.             status_message = ''
  362.  
  363.         if not status_message:
  364.             if not (self.have_shown_updated) and sys.opts.updated:
  365.                 status_message = _('Update Successful')
  366.                 LoginController.have_shown_updated = True
  367.             
  368.         
  369.         self.set_status(status_message)
  370.         self.apply_info(info)
  371.         if not info['password']:
  372.             autologin_override = False
  373.         
  374.         self._init_state(autologin_override)
  375.         self.setup_languages()
  376.  
  377.     
  378.     def setup_languages(self):
  379.         choice = self.window.LanguageChoice
  380.         if choice is None:
  381.             return None
  382.         languages = [
  383.             'English',
  384.             'English (1337)']
  385.         choice.Frozen().__enter__()
  386.         
  387.         try:
  388.             choice.Clear()
  389.             for lang in languages:
  390.                 choice.Append(lang)
  391.             
  392.             choice.SetSelection(0)
  393.         finally:
  394.             pass
  395.  
  396.  
  397.     
  398.     def _should_show_register(self):
  399.         if sys.opts.register:
  400.             return True
  401.         if not self._datastore.can_write():
  402.             return False
  403.         return not bool(self.allinfo)
  404.  
  405.     
  406.     def _set_frame_icon(self):
  407.         wx.Log.SetActiveTarget(wx.LogStderr())
  408.         wx.Log.EnableLogging(False)
  409.         self.window.SetIcons(icon_bundle())
  410.         wx.Log.EnableLogging(True)
  411.  
  412.     
  413.     def ShowWindow(self):
  414.         self.window.Show()
  415.         self.window.Raise()
  416.  
  417.     
  418.     def DestroyWindow(self):
  419.         import digsbyprofile
  420.         
  421.         try:
  422.             if digsbyprofile.profile and getattr(digsbyprofile.profile, 'connection', None) is not None:
  423.                 digsbyprofile.profile.connection.remove_observer(self.OnStatusChange, 'state')
  424.             
  425.             self.window.Hide()
  426.         finally:
  427.             self.window.Destroy()
  428.  
  429.  
  430.     
  431.     def bind_events(self):
  432.         bind = self.window.Bind
  433.         bind(wx.EVT_CHECKBOX, self.OnCheck)
  434.         bind(wx.EVT_TEXT, self.OnText)
  435.         bind(wx.EVT_BUTTON, self.OnButton, id = wx.ID_OK)
  436.         bind(wx.EVT_BUTTON, self.OnHelpButton, id = LoginWindow.HELPBUTTON)
  437.         bind(wx.EVT_HYPERLINK, self.OnPWLink, id = LoginWindow.FORGOTPASSWORD)
  438.         bind(wx.EVT_HYPERLINK, show_conn_settings, id = LoginWindow.CONNSETTINGS)
  439.         bind(wx.EVT_HYPERLINK, self.OnNoAcct, id = LoginWindow.NOACCOUNT)
  440.         bind(wx.EVT_CLOSE, self.OnClose)
  441.         bind(wx.EVT_CHOICE, self.OnLanguage, id = LoginWindow.LANGUAGE)
  442.  
  443.     
  444.     def OnLanguage(self, e):
  445.         print 'language:', e.String
  446.         print 'n:', e.Int
  447.  
  448.     
  449.     def _init_state(self, autologin_override):
  450.         self.OnCheck(None)
  451.         self.OnText(None)
  452.         if self._should_autologin(autologin_override):
  453.             
  454.             def paint():
  455.                 self.window.Refresh()
  456.                 self.window.Update()
  457.  
  458.             wx.CallAfter(paint)
  459.             wx.CallAfter(self.signin)
  460.         
  461.  
  462.     
  463.     def _should_autologin(self, autologin_override):
  464.         if not self.allow_autologin:
  465.             return False
  466.         if autologin_override is not None and not autologin_override:
  467.             return False
  468.         if (not self.window.GetAutoLogin() or autologin_override is not None) and not autologin_override:
  469.             return False
  470.         return True
  471.  
  472.     
  473.     def disconnect_prof(self):
  474.         import digsbyprofile as d
  475.         if d.profile:
  476.             call_later = call_later
  477.             import AsyncoreThread
  478.             call_later(d.profile.disconnect)
  479.             if d.profile is self._profile:
  480.                 self.unwatch_profile(d.profile)
  481.             
  482.         
  483.  
  484.     
  485.     def OnClose(self, evt):
  486.         sys.util_allowed = True
  487.         self.window.Hide()
  488.         self.cleanup()
  489.         wx.CallAfter(self.exit)
  490.  
  491.     
  492.     def cleanup(self):
  493.         
  494.         try:
  495.             self.disconnect_prof()
  496.             self.save_info()
  497.         except Exception:
  498.             print_exc()
  499.  
  500.  
  501.     
  502.     def exit(self):
  503.         
  504.         try:
  505.             self.DestroyWindow()
  506.         except:
  507.             print_exc()
  508.  
  509.         wx.GetApp().DigsbyCleanupAndQuit()
  510.  
  511.     
  512.     def watch_profile(self, p):
  513.         if self._profile is not sentinel:
  514.             self.unwatch_profile(self._profile)
  515.         
  516.         self._profile = p
  517.  
  518.     
  519.     def unwatch_profile(self, p = None):
  520.         if p is None:
  521.             p = self._profile
  522.         
  523.         if p is self._profile:
  524.             self._profile = sentinel
  525.         
  526.  
  527.     
  528.     def OnButton(self, evt):
  529.         self.signin()
  530.  
  531.     
  532.     def signin(self):
  533.         if 'digsbyprofile' not in sys.modules:
  534.             sys.util_allowed = True
  535.             self.set_status(_('Loading...'))
  536.             self.window.EnableControls(False, SIGN_IN, False)
  537.             self.window.Update()
  538.             m2 = m2
  539.             import M2Crypto
  540.             m2.rand_bytes(16)
  541.         
  542.         import digsbyprofile
  543.         if digsbyprofile.profile and digsbyprofile.profile.is_connected:
  544.             self.window.EnableControls(True, SIGN_IN, True)
  545.             self.disconnect_prof()
  546.             self.cancelling = True
  547.         else:
  548.             self.login()
  549.  
  550.     
  551.     def login(self):
  552.         (good_data, reason) = validate_data(self.get_info().values()[0])
  553.         if not good_data:
  554.             self.set_status(reason)
  555.             self.window.EnableControls(True, SIGN_IN, True)
  556.             self.window.Update()
  557.             return None
  558.         self.set_status(_('Connecting...'))
  559.         self.window.EnableControls(False, SIGN_IN)
  560.         self.window.Update()
  561.         self.save_info()
  562.         info = self.allinfo[self._get_window_username()]
  563.         
  564.         def myfunc():
  565.             import digsby
  566.             
  567.             try:
  568.                 print 'calling cb'
  569.                 self.cancelling = False
  570.                 self.on_success(info)
  571.                 import digsbyprofile
  572.                 self.watch_profile(digsbyprofile.profile)
  573.             except digsby.DigsbyLoginError:
  574.                 print 'login error'
  575.                 self.set_status(_('Login error!'))
  576.                 self.window.EnableControls(True, SIGN_IN, True)
  577.                 return None
  578.  
  579.             import digsbyprofile
  580.             if digsbyprofile.profile and getattr(digsbyprofile.profile, 'connection', None) is not None:
  581.                 conn = digsbyprofile.profile.connection
  582.                 cb = self.OnStatusChange
  583.                 conn.add_observer(cb, 'state')
  584.             
  585.  
  586.         wx.CallAfter(myfunc)
  587.  
  588.     
  589.     def OnText(self, evt):
  590.         self._ontextcount = getattr(self, '_ontextcount', 0) + 1
  591.         if getattr(self, '_in_on_text', False):
  592.             return evt.Skip()
  593.         self._in_on_text = True
  594.         
  595.         try:
  596.             if evt is not None:
  597.                 evt.Skip()
  598.             
  599.             window = self.window
  600.             if not hasattr(self, 'allinfo'):
  601.                 return None
  602.             if evt and evt.Id == LoginWindow.USERNAME:
  603.                 if self._get_window_username() in self.allinfo:
  604.                     self.apply_info(self.allinfo[self._get_window_username()], set_username = False)
  605.                 else:
  606.                     window.SetPassword('')
  607.             
  608.             if self._get_window_username():
  609.                 pass
  610.             enabled = bool(window.GetPassword())
  611.             window.FindWindowById(wx.ID_OK).Enable(enabled)
  612.         finally:
  613.             self._in_on_text = False
  614.  
  615.  
  616.     
  617.     def OnCheck(self, evt):
  618.         if not self.window.GetSaveInfo():
  619.             self.window.SetAutoLogin(False)
  620.         
  621.         if evt and evt.GetId() == LoginWindow.SAVEPASSWORD and evt.GetInt() and getattr(sys, 'is_portable', False):
  622.             if not self.do_portable_security_warning():
  623.                 self.window.SetAutoLogin(False)
  624.                 self.window.FindWindowById(LoginWindow.SAVEPASSWORD).Value = False
  625.                 self.save_info()
  626.                 return None
  627.         
  628.         if evt and evt.GetId() in (LoginWindow.SAVEPASSWORD, LoginWindow.AUTOLOGIN):
  629.             self.save_info()
  630.         
  631.  
  632.     
  633.     def do_portable_security_warning(self):
  634.         dlg = wx.MessageDialog(self.window, _('Your password will be saved on your portable device.\n\nAnyone with access to this device will be able to log into your Digsby account. Are you sure you want to save your password?'), _('Security Information'), wx.ICON_EXCLAMATION | wx.YES_NO)
  635.         response = dlg.ShowModal()
  636.         return response == wx.ID_YES
  637.  
  638.     
  639.     def OnPWLink(self, evt):
  640.         wx.LaunchDefaultBrowser('https://accounts.digsby.com/forgot_pw.php')
  641.  
  642.     
  643.     def OnNoAcct(self, evt):
  644.         show_register_page(self.window)
  645.  
  646.     
  647.     def OnHelpButton(self, evt = None):
  648.         wx.LaunchDefaultBrowser('http://wiki.digsby.com')
  649.  
  650.     
  651.     def OnStatusChange(self, src, attr, old, new):
  652.         wx.CallAfter(self.OnStatusChanged, src, attr, old, new)
  653.  
  654.     
  655.     def OnStatusChanged(self, src, attr, old, new):
  656.         if wx.IsDestroyed(self.window):
  657.             print >>sys.stderr, 'Warning: splash screen is Destroyed but still getting notified.'
  658.             return None
  659.         if self.cancelling and new != src.Statuses.OFFLINE:
  660.             src.disconnect()
  661.         
  662.         if new in (src.Statuses.CONNECTING, src.Statuses.AUTHENTICATING, src.Statuses.SYNC_PREFS, src.Statuses.AUTHORIZED):
  663.             self.window.EnableControls(False, SIGN_IN, False)
  664.         
  665.         
  666.         def f():
  667.             if self.cancelling or new == src.Statuses.OFFLINE:
  668.                 if self.cancelling:
  669.                     self.set_status('')
  670.                 else:
  671.                     self.set_status(src.offline_reason)
  672.                 self.window.EnableControls(True, SIGN_IN, True)
  673.             else:
  674.                 self.window.EnableControls(False, SIGN_IN)
  675.                 self.set_status(new)
  676.  
  677.         wx.CallAfter(f)
  678.  
  679.     
  680.     def set_status(self, label, window_title = None, do_conn_error = False):
  681.         conn_fail_message = _('Failed to Connect')
  682.         if not window_title:
  683.             pass
  684.         self.window.SetStatus(label, '')
  685.         if label == _('Authentication Error') and not getattr(self, 'auth_error_fired', False):
  686.             self.auth_error_fired = True
  687.             wx.MessageBox(_('Please make sure you have entered your Digsby username and password correctly.\nIf you need an account or forgot your password, use the links on the login screen. '), _('Authentication Error'))
  688.         
  689.         if do_conn_error:
  690.             if label == conn_fail_message and not getattr(self, 'connect_error_fired', False):
  691.                 self.connect_error_fired = True
  692.                 wx.MessageBox(_('Please check your Internet connection and make sure a firewall isn\'t blocking Digsby.\nIf you connect to the Internet through a proxy server,\nclick the "Connection Settings" link to set up the proxy.\nIf you are still unable to connect, email bugs@digsby.com for technical support.'), _('Failed to Connect'))
  693.             
  694.         
  695.  
  696.     
  697.     def _get_window_username(self):
  698.         return self.window.GetUsername().strip()
  699.  
  700.     
  701.     def get_info(self):
  702.         find = self.window.FindWindowById
  703.         window = self.window
  704.         username = self._get_window_username()
  705.         info_dict = dict(username = username, password = window.GetPassword(), save = window.GetSaveInfo(), autologin = window.GetAutoLogin())
  706.         return {
  707.             username: info_dict }
  708.  
  709.     
  710.     def apply_info(self, info, set_username = True):
  711.         w = self.window
  712.         if set_username:
  713.             w.SetUsername(info['username'])
  714.         
  715.         w.SetPassword(info['password'])
  716.         w.SetSaveInfo(info['save'])
  717.         w.SetAutoLogin(info['autologin'])
  718.  
  719.     
  720.     def set_username(self, username):
  721.         self.window.SetUsername(username)
  722.  
  723.     
  724.     def set_password(self, password):
  725.         self.window.SetPassword(password)
  726.  
  727.     
  728.     def save_info(self):
  729.         username = self._get_window_username()
  730.         self.allinfo.update(self.get_info())
  731.         info = self.allinfo[username]
  732.         password = info['password']
  733.         if not info['save']:
  734.             info['password'] = ''
  735.         
  736.         self.allinfo['pos'] = tuple(self.window.Position)
  737.         self._datastore.save_to_disk(username, self.allinfo)
  738.         if not info['password']:
  739.             info['password'] = password
  740.         
  741.  
  742.     
  743.     def proto_error(self, exc):
  744.         import digsby
  745.         msgbox = None
  746.         if exc is None:
  747.             message = _('Failed to Connect')
  748.         else:
  749.             
  750.             try:
  751.                 raise exc
  752.             except digsby.DigsbyLoginError:
  753.                 if exc.reason == 'auth':
  754.                     message = _('Authentication Error')
  755.                 elif exc.reason == 'connlost':
  756.                     message = _('Connection Lost')
  757.                 else:
  758.                     message = _('Failed to Connect')
  759.                 if exc.reason == 'server':
  760.                     msgbox = _('We are upgrading Digsby. Please try connecting again in a few minutes.')
  761.                 elif exc.reason == 'client':
  762.                     msgbox = _('Could not contact remote server. Check your network configuration.')
  763.                 
  764.             except Exception:
  765.                 print_exc()
  766.                 message = _('Failed to Connect')
  767.  
  768.         self.set_status(message, do_conn_error = True)
  769.         self.window.EnableControls(True, SIGN_IN, True)
  770.         self.disconnect_prof()
  771.         if msgbox is not None:
  772.             wx.MessageBox(msgbox, message)
  773.         
  774.  
  775.  
  776.  
  777. def _ensure_proxy_setup():
  778.     import wx.webview as wx
  779.     f = wx.Frame(None)
  780.     wx.webview.WebView(f)
  781.     f.Destroy()
  782.     import main
  783.     main.set_did_create_webview()
  784.  
  785.  
  786. def _register_frame(splash):
  787.     REGISTER_TITLE = _('Register a Digsby Account')
  788.     REGISTER_SIZE = (675, 421)
  789.     f = wx.Frame(splash, size = REGISTER_SIZE, title = REGISTER_TITLE, style = wx.DEFAULT_FRAME_STYLE & ~(wx.RESIZE_BORDER) | wx.STAY_ON_TOP)
  790.     f.SetBackgroundColour(wx.Color(168, 145, 102))
  791.     
  792.     def paint(e):
  793.         TEXT = _('Loading...')
  794.         dc = wx.PaintDC(f)
  795.         r = f.ClientRect
  796.         dc.Font = f.Font
  797.         (w, h) = dc.GetTextExtent(TEXT)
  798.         (x, y) = r.CenterPoint((w, h))
  799.         dc.Brush = wx.WHITE_BRUSH
  800.         dc.Pen = wx.TRANSPARENT_PEN
  801.         dc.DrawRoundedRectangle(x - 10, y - 10, w + 20, h + 20, 5)
  802.         dc.DrawText(TEXT, x, y)
  803.  
  804.     f.Bind(wx.EVT_PAINT, paint)
  805.     cgui.SetFrameIcon(f, wx.Image(res('skins/default/digsbybig.png')))
  806.     return f
  807.  
  808.  
  809. def show_register_page(splash):
  810.     import wx
  811.     REGISTER_URL = 'https://accounts.digsby.com/reg.php'
  812.     if sys.BRAND is not None:
  813.         REGISTER_URL = REGISTER_URL + '?code=' + sys.BRAND
  814.     
  815.     f = _register_frame(splash)
  816.     f.CenterOnScreen()
  817.     f.Show()
  818.     f.Update()
  819.     f.Sizer = wx.BoxSizer(wx.HORIZONTAL)
  820.     _ensure_proxy_setup()
  821.     UrlQuery = UrlQuery
  822.     import util.net
  823.     import wx.webview as wx
  824.     
  825.     class WebBrowser((wx.webview.WebView,)):
  826.         
  827.         def __init__(self, parent, url = (None,)):
  828.             wx.webview.WebView.__init__(self, parent)
  829.             if url is not None:
  830.                 self.LoadURL(url)
  831.             
  832.  
  833.  
  834.     browser = WebBrowser(f, url = REGISTER_URL)
  835.     browser.SetPosition((-3000, -3000))
  836.     
  837.     def on_nav(url):
  838.         if url.startswith(REGISTER_URL):
  839.             query = UrlQuery.parse(url)['query']
  840.             if query.get('done'):
  841.                 username = query.get('u')
  842.                 if username is not None:
  843.                     splash.FindWindowById(LoginWindow.USERNAME).Value = username
  844.                     
  845.                     def after():
  846.                         splash.FindWindowById(LoginWindow.PASSWORD).SetFocus()
  847.                         splash.Raise()
  848.  
  849.                     after = (wx.CallAfter,)(after)
  850.                 
  851.                 if query.get('s') == 'true':
  852.                     import hooks
  853.                     hooks.notify('digsby.browsersettings.set_homepage')
  854.                     hooks.notify('digsby.browsersettings.set_search')
  855.                 
  856.             
  857.         
  858.  
  859.     
  860.     def on_load(e):
  861.         if e.State == wx.webview.WEBVIEW_LOAD_DOC_COMPLETED:
  862.             on_nav(e.URL)
  863.         else:
  864.             e.Skip()
  865.  
  866.     browser.Bind(wx.webview.EVT_WEBVIEW_LOAD, on_load)
  867.     add_window_open_redirect = add_window_open_redirect
  868.     import gui.browser.webkit.webkitwindow
  869.     add_window_open_redirect(browser, blank_opens_browser = True)
  870.     
  871.     def later():
  872.         f.Sizer.Add(browser, 1, wx.EXPAND)
  873.         f.Layout()
  874.  
  875.     wx.CallLater(500, later)
  876.  
  877.  
  878. def show_conn_settings(evt):
  879.     sys.util_allowed = True
  880.     ProxyDialog = ProxyDialog
  881.     import gui.proxydialog
  882.     import util
  883.     p = ProxyDialog()
  884.     
  885.     def later():
  886.         
  887.         try:
  888.             p.ShowModal()
  889.         except Exception:
  890.             print_exc()
  891.         else:
  892.             import hooks
  893.             hooks.notify('proxy.info_changed', util.GetProxyInfo())
  894.         finally:
  895.             p.Destroy()
  896.  
  897.  
  898.     wx.CallAfter(later)
  899.  
  900.  
  901. def validate_data(info):
  902.     email_regex_string = '^(?:([a-zA-Z0-9_][a-zA-Z0-9_\\-\\.]*)(\\+[a-zA-Z0-9_\\-\\.]+)?@((?:[a-zA-Z0-9\\-_]+\\.?)*[a-zA-Z]{1,4}))$'
  903.     if not re.match(email_regex_string, info['username'] + '@digsby.org'):
  904.         log.error('Bad username: %r', info['username'])
  905.         return (False, DataProblems.BAD_USERNAME)
  906.     return (True, None)
  907.  
  908.