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

  1. # Source Generated with Decompyle++
  2. # File: in.pyo (Python 2.5)
  3.  
  4. from __future__ import with_statement
  5. import wx
  6. from gui import skin
  7. from gui.uberwidgets.PrefPanel import PrefPanel
  8. from gui.uberwidgets.UberCombo import UberCombo
  9. from gui.uberwidgets.simplemenu import SimpleMenuItem
  10. from gui.uberwidgets.UberButton import UberButton
  11. from gui.toolbox import persist_window_pos, snap_pref
  12. from gui.browser.webkit import WebKitWindow
  13. from cgui import SimplePanel
  14. from util import Storage
  15. from common import logger
  16. import logging
  17. log = logging.getLogger('pastbrowser')
  18. from wx import ALL, TOP, BOTTOM, LEFT, EXPAND, ALIGN_CENTER_VERTICAL, ALIGN_LEFT, ALIGN_RIGHT, VERTICAL, HORIZONTAL, WHITE, WHITE_BRUSH, TRANSPARENT_PEN, Color, BoxSizer, Brush, Rect
  19. TOPLESS = ALL & ~TOP
  20. BUTTON_SKIN = 'AppDefaults.PastButton'
  21. from wx import DateTimeFromDMY
  22. from wx.calendar import CAL_SUNDAY_FIRST, CAL_SEQUENTIAL_MONTH_SELECTION, CAL_SHOW_HOLIDAYS, EVT_CALENDAR_MONTH, EVT_CALENDAR_YEAR, EVT_CALENDAR_SEL_CHANGED, CalendarCtrl, CalendarDateAttr
  23.  
  24. def logpath_for_date(buddy, date):
  25.     year = '%d' % int(date.GetYear())
  26.     month = '%02d' % (date.GetMonth() + 1)
  27.     day = '%02d' % int(date.GetDay())
  28.     return buddy.dir / ''.join([
  29.         year,
  30.         '-',
  31.         month,
  32.         '-',
  33.         day,
  34.         '.html'])
  35.  
  36.  
  37. def MakeAccountItems():
  38.     logdir = logger.get_default_logging_dir()
  39.     protodirs = logdir.dirs()
  40.     accts = { }
  41.     for protodir in protodirs:
  42.         accts[protodir.name] = [ dir.name for dir in protodir.dirs() ]
  43.     
  44.     items = []
  45.     for proto in sorted(accts):
  46.         
  47.         try:
  48.             protoicon = skin.get('serviceicons.' + proto, None).ResizedSmaller(16)
  49.         except Exception:
  50.             []
  51.             []
  52.             []
  53.             continue
  54.         except:
  55.             []
  56.  
  57.         for acct in accts[proto]:
  58.             items.append(SimpleMenuItem([
  59.                 protoicon,
  60.                 acct], id = logdir / proto / acct))
  61.         
  62.     
  63.     return items
  64.  
  65.  
  66. def GetBuddies(acctdir):
  67.     buddies = []
  68.     for bdir in acctdir.dirs():
  69.         
  70.         try:
  71.             (name, service) = bdir.name.rsplit('_', 1)
  72.             serviceicon = skin.get('serviceicons.' + service, None).ResizedSmaller(16)
  73.         except Exception:
  74.             continue
  75.  
  76.         buddies.append(Storage(icon = serviceicon, name = name, service = service, dir = bdir))
  77.     
  78.     return buddies
  79.  
  80.  
  81. def GetDates(logdir):
  82.     dates = []
  83.     append = dates.append
  84.     for logfile in logdir.files():
  85.         datestring = logfile.name
  86.         
  87.         try:
  88.             (y, m, d) = datestring[:datestring.rfind('.')].split('-')
  89.             y = int(y)
  90.             m = int(m) - 1
  91.             d = int(d)
  92.         except Exception:
  93.             continue
  94.  
  95.         append(DateTimeFromDMY(d, m, y))
  96.     
  97.     return sorted(dates)
  98.  
  99. bgcolors = [
  100.     wx.Color(239, 239, 239),
  101.     wx.Color(255, 255, 255)]
  102. hovbgcolor = wx.Color(220, 220, 220)
  103.  
  104. def SelectAccountByDir(acctdir, combo):
  105.     for item in combo:
  106.         if acctdir == item.id:
  107.             combo.SetSelection(combo.GetIndex(item))
  108.             return True
  109.             continue
  110.     
  111.     return False
  112.  
  113.  
  114. class ListOBuddies(wx.VListBox):
  115.     
  116.     def __init__(self, parent):
  117.         wx.VListBox.__init__(self, parent, -1)
  118.         self.buddies = []
  119.         self.Hovered = -1
  120.         self.SetItemCount(0)
  121.         self.itemheight = max(self.Font.Height, 16) + 10
  122.         self.date = None
  123.         Bind = self.Bind
  124.         Bind(wx.EVT_MOTION, self.OnMotion)
  125.  
  126.     
  127.     def OnMotion(self, event):
  128.         rect = self.ClientRect
  129.         wap = wx.FindWindowAtPointer()
  130.         mp = event.Position
  131.         hit = self.HitTest(mp)
  132.         if not rect.Contains(mp) or not (wap == self):
  133.             while self.HasCapture():
  134.                 self.ReleaseMouse()
  135.             self.Hovered = -1
  136.             self.Refresh()
  137.             return None
  138.         elif not self.HasCapture():
  139.             self.CaptureMouse()
  140.         
  141.         self.Hovered = hit
  142.         self.Refresh()
  143.  
  144.     
  145.     def OnDrawBackground(self, dc, rect, n):
  146.         if self.Selection == n:
  147.             dc.Brush = Brush(wx.SystemSettings_GetColour(wx.SYS_COLOUR_HIGHLIGHT))
  148.         elif self.Hovered == n:
  149.             pass
  150.         
  151.         dc.Brush = Brush(bgcolors[n % len(bgcolors)])
  152.         dc.Pen = wx.TRANSPARENT_PEN
  153.         dc.DrawRectangleRect(rect)
  154.  
  155.     
  156.     def OnDrawItem(self, dc, rect, n):
  157.         dc.Font = self.Font
  158.         dc.TextForeground = None if self.Selection == n else wx.BLACK
  159.         buddy = self.buddies[n]
  160.         x = rect.x + 3
  161.         y = rect.y + rect.height // 2 - 8
  162.         dc.DrawBitmap(buddy.icon, x, y, True)
  163.         textrect = Rect(x + 16 + 3, rect.y, rect.Width - x - 38, rect.Height)
  164.         dc.DrawLabel(buddy.name, textrect, ALIGN_CENTER_VERTICAL | ALIGN_LEFT)
  165.  
  166.     
  167.     def OnMeasureItem(self, n):
  168.         return self.itemheight
  169.  
  170.     
  171.     def SetList(self, buddies):
  172.         self.buddies = buddies
  173.         self.SetItemCount(len(self.buddies))
  174.         if self.ItemCount:
  175.             self.SetSelection(0)
  176.         
  177.         wx.CallAfter(self.Refresh)
  178.  
  179.     
  180.     def SelectedBuddy(self):
  181.         return self.buddies[self.Selection]
  182.  
  183.     SelectedBuddy = property(SelectedBuddy)
  184.     
  185.     def SelectBuddy(self, service, name):
  186.         found = -1
  187.         for i, buddy in enumerate(self.buddies):
  188.             if buddy.name == name and buddy.service == service:
  189.                 found = i
  190.                 break
  191.                 continue
  192.         
  193.         self.Selection = found
  194.         if found != -1:
  195.             self.ProcessEvent(wx.CommandEvent(wx.wxEVT_COMMAND_LISTBOX_SELECTED))
  196.             self.Refresh()
  197.             return True
  198.         else:
  199.             self.Refresh()
  200.             return False
  201.  
  202.  
  203.  
  204. class BlatantFirefoxRipoff(wx.Panel):
  205.     
  206.     def __init__(self, parent, viewer):
  207.         wx.Panel.__init__(self, parent)
  208.         self.viewer = viewer
  209.         find_label = wx.StaticText(self, -1, _('Find'))
  210.         self.TextControl = find_input = wx.TextCtrl(self, -1, size = (180, -1), style = wx.TE_PROCESS_ENTER)
  211.         nextbutton = self.nextbutton = UberButton(self, label = 'Next', skin = 'AppDefaults.PastButton')
  212.         prevbutton = self.prevbutton = UberButton(self, label = 'Prev', skin = 'AppDefaults.PastButton')
  213.         sz = self.Sizer = wx.BoxSizer(wx.HORIZONTAL)
  214.         sz.AddMany([
  215.             (find_label, 0, TOP | BOTTOM | LEFT | ALIGN_CENTER_VERTICAL | ALIGN_RIGHT, 6),
  216.             (find_input, 0, TOP | BOTTOM | LEFT | ALIGN_CENTER_VERTICAL, 6),
  217.             (nextbutton, 0, TOP | BOTTOM | LEFT | ALIGN_CENTER_VERTICAL | EXPAND, 6),
  218.             (prevbutton, 0, TOP | BOTTOM | LEFT | ALIGN_CENTER_VERTICAL | EXPAND, 6)])
  219.         self.SetBackgroundStyle(wx.BG_STYLE_CUSTOM)
  220.         Bind = self.Bind
  221.         Bind(wx.EVT_PAINT, self.OnPaint)
  222.         self.SetBackgroundStyle(wx.BG_STYLE_CUSTOM)
  223.         fiBind = find_input.Bind
  224.         fiBind(wx.EVT_TEXT, self.OnFindText)
  225.         fiBind(wx.EVT_KEY_DOWN, self.OnFindKey)
  226.         nextbutton.Bind(wx.EVT_BUTTON, self.OnFindText)
  227.         prevbutton.Bind((wx.EVT_BUTTON,), (lambda e: self.OnFindText(e, False)))
  228.         self.EnableFindButtons('')
  229.  
  230.     
  231.     def OnFindKey(self, e):
  232.         c = e.KeyCode
  233.         if (c in (wx.WXK_RETURN, wx.WXK_F3) or c == ord('G')) and e.GetModifiers() in (wx.MOD_CMD, wx.MOD_CMD + wx.MOD_SHIFT):
  234.             self.OnFindText(forward = not e.ShiftDown())
  235.             self.TextControl.SetFocus()
  236.         else:
  237.             e.Skip()
  238.  
  239.     
  240.     def OnFindText(self, e = None, forward = True):
  241.         value = self.TextControl.Value
  242.         self.EnableFindButtons(value)
  243.         self.viewer.FindString(self.TextControl.Value, forward, False, True, True)
  244.  
  245.     
  246.     def EnableFindButtons(self, textctrl_value):
  247.         buttons_enabled = bool(textctrl_value)
  248.         self.nextbutton.Enable(buttons_enabled)
  249.         self.prevbutton.Enable(buttons_enabled)
  250.  
  251.     
  252.     def OnPaint(self, event):
  253.         rect = wx.RectS(self.ClientSize)
  254.         dc = wx.BufferedPaintDC(self)
  255.         dc.Brush = wx.WHITE_BRUSH
  256.         dc.Pen = wx.Pen(wx.Color(213, 213, 213))
  257.         dc.DrawRectangleRect(rect)
  258.  
  259.  
  260.  
  261. class PastBrowserPanel(SimplePanel):
  262.     
  263.     def __init__(self, parent):
  264.         SimplePanel.__init__(self, parent, wx.FULL_REPAINT_ON_RESIZE)
  265.         self.BackgroundColour = WHITE
  266.         self.Sizer = wx.BoxSizer(HORIZONTAL)
  267.         sz = wx.BoxSizer(HORIZONTAL)
  268.         self.Sizer.Add(sz, 1, EXPAND | ALL, 3)
  269.         leftcol = wx.BoxSizer(VERTICAL)
  270.         acctcombo = self.acctcombo = UberCombo(self, value = '', skinkey = 'AppDefaults.PrefCombo')
  271.         acctcont = PrefPanel(self, acctcombo, 'Account')
  272.         leftcol.Add(acctcont, 0, EXPAND | ALL, 3)
  273.         buddylist = self.buddylist = ListOBuddies(self)
  274.         buddycont = PrefPanel(self, buddylist, 'Buddy')
  275.         leftcol.Add(buddycont, 1, EXPAND | TOPLESS, 3)
  276.         style = wx.NO_BORDER | CAL_SUNDAY_FIRST | CAL_SEQUENTIAL_MONTH_SELECTION | CAL_SHOW_HOLIDAYS
  277.         cal = self.cal = CalendarCtrl(self, -1, wx.DateTime.Now(), wx.DefaultPosition, wx.DefaultSize, style)
  278.         cal.SetForegroundColour(wx.Color(160, 160, 160))
  279.         cal.SetHolidayColours(wx.BLACK, wx.WHITE)
  280.         cal.SetHeaderColours(Color(160, 160, 160), Color(239, 239, 239))
  281.         calcont = PrefPanel(self, cal, 'Date')
  282.         leftcol.Add(calcont, 0, EXPAND | TOPLESS, 3)
  283.         sz.Add(leftcol, 0, EXPAND)
  284.         viewpanel = wx.Panel(self)
  285.         viewer = self.viewer = WebKitWindow(viewpanel)
  286.         finder = self.finder = BlatantFirefoxRipoff(viewpanel, viewer)
  287.         viewer.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown)
  288.         finder.TextControl.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown)
  289.         nav = BoxSizer(wx.HORIZONTAL)
  290.         prev = self.prev = UberButton(viewpanel, label = '<-', skin = BUTTON_SKIN)
  291.         next = self.next = UberButton(viewpanel, label = '->', skin = BUTTON_SKIN)
  292.         datelabel = wx.StaticText(viewpanel, -1, style = wx.ALIGN_CENTER | wx.ST_NO_AUTORESIZE)
  293.         datelabel.SetMinSize((140, -1))
  294.         prev.Bind((wx.EVT_BUTTON,), (lambda e: self.Flip(-1)))
  295.         next.Bind((wx.EVT_BUTTON,), (lambda e: self.Flip(1)))
  296.         nav.AddStretchSpacer(1)
  297.         nav.AddMany([
  298.             (prev, 0, wx.EXPAND | wx.ALIGN_CENTER),
  299.             (datelabel, 0, wx.EXPAND | wx.ALIGN_CENTER),
  300.             (next, 0, wx.EXPAND | wx.ALIGN_CENTER)])
  301.         nav.AddStretchSpacer(1)
  302.         viewpanel.Sizer = wx.BoxSizer(wx.VERTICAL)
  303.         viewpanel.Sizer.AddMany([
  304.             (nav, 0, EXPAND),
  305.             (viewer, 1, EXPAND),
  306.             (finder, 0, EXPAND)])
  307.         sz.Add(PrefPanel(self, viewpanel, _('Conversation Log')), 1, EXPAND | ALL, 3)
  308.         Bind = self.Bind
  309.         Bind(wx.EVT_PAINT, self.OnPaint)
  310.         
  311.         def OnAcct(*a):
  312.             buddylist.SetList(GetBuddies(acctcombo.Value.id))
  313.             OnBuddy()
  314.  
  315.         
  316.         def OnBuddy(*a):
  317.             self.dates = GetDates(buddylist.SelectedBuddy.dir)
  318.             self.next.Enable(True)
  319.             self.prev.Enable(True)
  320.             self.cal.Enable(True)
  321.             OnCalChange()
  322.  
  323.         
  324.         def OnCalChange(*a):
  325.             caldate = cal.Date
  326.             currentyear = caldate.GetYear()
  327.             currentmonth = caldate.GetMonth()
  328.             relevantdates = (None, frozenset)((lambda .0: for date in .0:
  329. if date.GetYear() == currentyear and date.GetMonth() == currentmonth and date.GetDay():
  330. date.GetDay()continue)(self.dates))
  331.             SetHoliday = cal.SetHoliday
  332.             SetAttr = cal.SetAttr
  333.             for i in xrange(1, 32):
  334.                 if i in relevantdates:
  335.                     SetHoliday(i)
  336.                     continue
  337.                 SetAttr(i, CalendarDateAttr(Color(160, 160, 160)))
  338.             
  339.             OnDayChange()
  340.  
  341.         self.OnCalChange = OnCalChange
  342.         
  343.         def OnDayChange(*a):
  344.             date = cal.Date
  345.             self.date = date
  346.             datelabel.SetLabel(date.FormatDate())
  347.             if cal.GetAttr(date.GetDay()).IsHoliday():
  348.                 logpath = logpath_for_date(buddylist.SelectedBuddy, date)
  349.                 viewer.Frozen().__enter__()
  350.                 
  351.                 try:
  352.                     viewer.SetPageSource(logpath.text('utf-8', 'replace'), logpath.url())
  353.                     viewer.RunScript('window.scroll(0, 0);')
  354.                 finally:
  355.                     pass
  356.  
  357.             else:
  358.                 year = str(date.GetYear())
  359.                 month = date.GetMonth()
  360.                 month = wx.DateTime.GetMonthName(int(month))
  361.                 day = str(date.GetDay())
  362.                 viewer.SetPageSource('There are no chat logs for %s %s, %s with %s.' % (month, day, year, buddylist.SelectedBuddy.name), 'file:///C:/')
  363.             wx.CallAfter(cal.Refresh)
  364.  
  365.         self.OnDayChange = OnDayChange
  366.         acctcombo.SetCallbacks(value = OnAcct)
  367.         buddylist.Bind(wx.EVT_LISTBOX, OnBuddy)
  368.         cBind = cal.Bind
  369.         cBind(EVT_CALENDAR_YEAR, OnCalChange)
  370.         cBind(EVT_CALENDAR_MONTH, OnCalChange)
  371.         cBind(EVT_CALENDAR_SEL_CHANGED, OnDayChange)
  372.         acctcombo.SetItems(MakeAccountItems(), 0)
  373.  
  374.     
  375.     def OnKeyDown(self, event):
  376.         KeyCode = event.KeyCode
  377.         if KeyCode == wx.WXK_PAGEDOWN:
  378.             self.viewer.ScrollPages(1)
  379.         elif KeyCode == wx.WXK_PAGEUP:
  380.             self.viewer.ScrollPages(-1)
  381.         else:
  382.             event.Skip()
  383.  
  384.     
  385.     def Flip(self, delta):
  386.         log.info('Flip(%s)', delta)
  387.         log.info(' self.dates: %r', self.dates)
  388.         dates = self.dates
  389.         date = self.date
  390.         
  391.         try:
  392.             foundIndex = dates.index(date) + delta
  393.         except ValueError:
  394.             alldates = [
  395.                 DateTimeFromDMY(1, 1, 1900)] + dates + [
  396.                 DateTimeFromDMY(20, 10, 3000)]
  397.             foundIndex = len(dates) - 1
  398.             for i in xrange(1, len(alldates)):
  399.                 if date.IsStrictlyBetween(alldates[i - 1], alldates[i]):
  400.                     foundIndex = None if delta < 0 else i
  401.                     break
  402.                     continue
  403.             
  404.  
  405.         foundIndex = max(0, min(len(dates) - 1, foundIndex))
  406.         self.cal.SetDate(dates[foundIndex])
  407.         self.OnCalChange()
  408.  
  409.     
  410.     def OnPaint(self, event):
  411.         rect = wx.RectS(self.Size)
  412.         dc = wx.PaintDC(self)
  413.         dc.Brush = WHITE_BRUSH
  414.         dc.Pen = TRANSPARENT_PEN
  415.         dc.DrawRectangleRect(rect)
  416.  
  417.     
  418.     def OpenBuddyHistory(self, acctdir, acct, name, service):
  419.         if not SelectAccountByDir(acctdir, self.acctcombo):
  420.             self.next.Enable(False)
  421.             self.prev.Enable(False)
  422.             self.cal.Enable(False)
  423.             return self.NoHistory(name, service, acct)
  424.         
  425.         
  426.         def AfterOpenBuddyHistory():
  427.             if not self.buddylist.SelectBuddy(service, name):
  428.                 self.next.Enable(False)
  429.                 self.prev.Enable(False)
  430.                 self.cal.Enable(False)
  431.                 return self.NoHistory(name, service, acct)
  432.             
  433.             self.next.Enable(True)
  434.             self.prev.Enable(True)
  435.             self.cal.Enable(True)
  436.             self.Flip(1)
  437.  
  438.         wx.CallAfter(AfterOpenBuddyHistory)
  439.  
  440.     
  441.     def NoHistory(self, name, service, acct):
  442.         self.viewer.SetPageSource('There is no chat history for %s on %s with %s.' % (name, service, acct), 'file:///C:/')
  443.  
  444.  
  445.  
  446. class PastBrowser(wx.Frame):
  447.     
  448.     def __init__(self):
  449.         wx.Frame.__init__(self, None, -1, _('Past Chat Browser'), name = 'Past Chat Browser')
  450.         self.SetFrameIcon(skin.get('appdefaults.taskbaricon'))
  451.         sz = self.Sizer = wx.BoxSizer(VERTICAL)
  452.         self.pastbrowser = PastBrowserPanel(self)
  453.         sz.Add(self.pastbrowser, 1, EXPAND)
  454.         persist_window_pos(self, defaultPos = wx.Point(150, 150), defaultSize = wx.Size(700, 500))
  455.         snap_pref(self)
  456.  
  457.     
  458.     def MakeOrShow(cls):
  459.         win = PastBrowser.RaiseExisting()
  460.         if win is None:
  461.             win = PastBrowser()
  462.             wx.CallAfter(win.Show)
  463.         
  464.         return win
  465.  
  466.     MakeOrShow = classmethod(MakeOrShow)
  467.     
  468.     def MakeOrShowAndSelect(cls, buddydir):
  469.         acctdir = buddydir.parent
  470.         acct = acctdir.name
  471.         (name, service) = buddydir.name.rsplit('_', 1)
  472.         win = cls.MakeOrShow()
  473.         win.pastbrowser.OpenBuddyHistory(acctdir, acct, name, service)
  474.  
  475.     MakeOrShowAndSelect = classmethod(MakeOrShowAndSelect)
  476.  
  477. if __name__ == '__main__':
  478.     from tests.testapp import testapp
  479.     a = testapp(username = 'aaron')
  480.     from path import path
  481.     dir = path('C:\\Users\\Aaron\\Documents\\Digsby Logs\\aaron\\digsby\\aaron@digsby.org\\mike@digsby.org_digsby')
  482.     PastBrowser.MakeOrShowAndSelect(dir)
  483.     a.MainLoop()
  484.  
  485.