home *** CD-ROM | disk | FTP | other *** search
/ Maximum CD 2011 February / maximum-cd-2011-02.iso / DiscContents / digsby_setup85.exe / lib / gui / imwin / imwin_ads.pyo (.txt) < prev    next >
Encoding:
Python Compiled Bytecode  |  2010-11-24  |  13.1 KB  |  349 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyo (Python 2.6)
  3.  
  4. import wx
  5. import cgui
  6. import simplejson
  7. import random
  8. from time import time
  9. from gui.browser.webkit import WebKitWindow
  10. from common import pref
  11. from util.primitives.funcs import Delegate
  12. from logging import getLogger
  13. log = getLogger('imwin_ads')
  14. from util.net import UrlQuery
  15. IMFRAME_WITH_AD_MINSIZE = (490, 350)
  16. SHOULD_ROTATE = True
  17. CAMPAIGNS = {
  18.     'rubicon': 'http://serve.digsby.com/rubicon.html' }
  19. AD_PANEL_MINSIZE = (466, 58)
  20. AD_PANEL_MAXSIZE = (728, 90)
  21. allowed_trigger_modes = ('focus', 'sendim')
  22. allowed_time_modes = ('real', 'engagement')
  23. ad_scenarios = [
  24.     (120, 'real', 'focus'),
  25.     (180, 'real', 'focus'),
  26.     (240, 'real', 'focus'),
  27.     (60, 'engagement', 'focus'),
  28.     (90, 'engagement', 'focus'),
  29.     (120, 'engagement', 'focus'),
  30.     (180, 'engagement', 'focus'),
  31.     (120, 'real', 'sendim'),
  32.     (180, 'real', 'sendim'),
  33.     (240, 'real', 'sendim'),
  34.     (60, 'engagement', 'sendim'),
  35.     (90, 'engagement', 'sendim'),
  36.     (120, 'engagement', 'sendim'),
  37.     (180, 'engagement', 'sendim')]
  38.  
  39. def choose_ad_scenario():
  40.     s = ad_scenarios[:]
  41.     random.shuffle(s)
  42.     return s[0]
  43.  
  44.  
  45. class AdRotater(object):
  46.     
  47.     def __repr__(self):
  48.         return '<AdRotater (secs=%s, time_mode=%s, trigger_mode=%s) (%.02f secs engagement)>' % (self.timer_secs, self.time_mode, self.trigger_mode, self._engagement())
  49.  
  50.     
  51.     def __init__(self, timer_secs, time_mode, trigger_mode, current_time_func = time):
  52.         self.has_focus = False
  53.         self.timer_secs = timer_secs
  54.         self.time_mode = time_mode
  55.         self.trigger_mode = trigger_mode
  56.         self.scenario_identifier = '%s_%s_%s' % (timer_secs, time_mode, trigger_mode)
  57.         self._get_time = current_time_func
  58.         self._reset_time()
  59.         self.on_reload = Delegate()
  60.         if self.time_mode == 'engagement' and self.trigger_mode == 'focus':
  61.             self.wx_timer = wx.PyTimer(self._on_wxtimer)
  62.             self.wx_timer.StartRepeating(1000)
  63.         
  64.  
  65.     
  66.     def _on_wxtimer(self):
  67.         if not (self.timer.paused) and self.has_focus:
  68.             self.trigger_event('focus')
  69.         
  70.  
  71.     
  72.     def trigger_event(self, event):
  73.         if self.should_rotate(event):
  74.             self.on_reload()
  75.         
  76.  
  77.     
  78.     def should_rotate(self, trigger_event):
  79.         if not SHOULD_ROTATE:
  80.             return False
  81.         if self.trigger_mode != trigger_event:
  82.             return False
  83.         if not self._enough_time_elapsed():
  84.             return False
  85.         return True
  86.  
  87.     
  88.     def pause(self):
  89.         if self.time_mode == 'engagement':
  90.             return self.timer.pause()
  91.  
  92.     
  93.     def unpause(self):
  94.         if self.time_mode == 'engagement':
  95.             return self.timer.unpause()
  96.  
  97.     
  98.     def _reset_time(self):
  99.         self.timer = Timer(get_time_func = self._get_time)
  100.         self.timer.start()
  101.  
  102.     
  103.     def _engagement(self):
  104.         return self.timer.get_ticks()
  105.  
  106.     
  107.     def _enough_time_elapsed(self):
  108.         return self._engagement() >= self.timer_secs
  109.  
  110.  
  111. _ad_scenario = None
  112.  
  113. def ad_scenario():
  114.     global _ad_scenario
  115.     if _ad_scenario is None:
  116.         _ad_scenario = choose_ad_scenario()
  117.     
  118.     return _ad_scenario
  119.  
  120.  
  121. class AdPanel(WebKitWindow):
  122.     
  123.     def __init__(self, parent, rotater):
  124.         campaign = 'rubicon'
  125.         self.ad_url = UrlQuery(CAMPAIGNS[campaign], utm_source = 'digsby_client', utm_medium = 'im_window', utm_content = rotater.scenario_identifier, utm_campaign = campaign)
  126.         WebKitWindow.__init__(self, parent, url = self.ad_url, simple_events = True)
  127.         self.set_jsqueue_enabled(False)
  128.         self.set_window_open_redirects_to_browser(self._url_callback)
  129.         self.SetMinimumFontSize(10)
  130.         self.Bind(wx.webview.EVT_WEBVIEW_BEFORE_LOAD, self.OnBeforeLoad)
  131.         self.Bind(wx.webview.EVT_WEBVIEW_LOAD, self.on_loading)
  132.         self.SetMinSize(AD_PANEL_MINSIZE)
  133.         self.SetMaxSize(AD_PANEL_MAXSIZE)
  134.         self.rotater = rotater
  135.         setup_webview_logging = setup_webview_logging
  136.         import gui.browser.webkit
  137.         jslog = getLogger('imwin_ads_js')
  138.         setup_webview_logging(self, jslog)
  139.         self._did_notify_click = False
  140.  
  141.     
  142.     def URL(self):
  143.         return self.RunScript('window.location.href')
  144.  
  145.     URL = property(URL)
  146.     
  147.     def on_loading(self, e):
  148.         if e.State != wx.webview.WEBVIEW_LOAD_TRANSFERRING:
  149.             return e.Skip()
  150.         url = self.URL
  151.         if url and not url.startswith('http://serve.digsby.com') and url != getattr(self, '_did_hijack_url', None):
  152.             self._did_hijack_url = url
  153.             log.warning('!!!! escaped from serve.digsby.com: %r', url)
  154.             self._url_callback(url)
  155.             self.RefreshAd()
  156.         
  157.  
  158.     
  159.     def _url_callback(self, url):
  160.         wx.LaunchDefaultBrowser(url)
  161.         self.notify_click(url)
  162.  
  163.     
  164.     def OnBeforeLoad(self, e):
  165.         if e.NavigationType == wx.webview.WEBVIEW_NAV_LINK_CLICKED:
  166.             e.Cancel()
  167.             self._url_callback(e.URL)
  168.         else:
  169.             e.Skip()
  170.  
  171.     
  172.     def _reload_ad(self):
  173.         self._did_notify_click = False
  174.         self.rotater._reset_time()
  175.         log.info('Loading ad URL: %r', self.ad_url)
  176.         self.LoadURL(self.ad_url)
  177.  
  178.     
  179.     def notify_click(self, url):
  180.         if self._did_notify_click:
  181.             return None
  182.         self._did_notify_click = True
  183.         log.info('notifying ad click: %r', url)
  184.         self._track_analytics_event('click')
  185.  
  186.     
  187.     def _track_analytics_event(self, action):
  188.         script = '_gaq.push(%s);' % simplejson.dumps([
  189.             '_trackEvent',
  190.             self.rotater.scenario_identifier,
  191.             action])
  192.         print script
  193.         result = self.RunScript(script)
  194.         print 'RESULT', result
  195.  
  196.  
  197. GLASS_TRANSPARENT_COLOR = (0, 0, 0)
  198.  
  199. glass = lambda : if cgui.isGlassEnabled():
  200. passpref('imwin.ads_glass', default = True)
  201.  
  202. def construct_ad_panel(self, mainPanel):
  203.     self.SetMinSize(IMFRAME_WITH_AD_MINSIZE)
  204.     borderSize = 1
  205.     sz = self.Sizer = wx.BoxSizer(wx.VERTICAL)
  206.     sz.Add(mainPanel, 1, wx.EXPAND)
  207.     extra_top = 8
  208.     sz.Add((borderSize, borderSize + extra_top))
  209.     rotater = AdRotater(*ad_scenario())
  210.     ad_panel = AdPanel(self, rotater)
  211.     self._ad_rotater = rotater
  212.     self.on_engaged_start += rotater.unpause
  213.     self.on_engaged_end += rotater.pause
  214.     
  215.     def on_message(mode, imwin_ctrl):
  216.         if mode == 'im':
  217.             rotater.trigger_event('sendim')
  218.         
  219.  
  220.     self.on_sent_message += on_message
  221.     
  222.     def on_activate(e):
  223.         e.Skip()
  224.         rotater.has_focus = e.Active
  225.         if e.Active:
  226.             rotater.trigger_event('focus')
  227.         
  228.         if not glass():
  229.             self.Refresh()
  230.         
  231.  
  232.     self.Bind(wx.EVT_ACTIVATE, on_activate)
  233.     sz.Add(ad_panel, 0, wx.ALIGN_CENTER_HORIZONTAL)
  234.     sz.Add((borderSize, borderSize))
  235.     
  236.     def paint(e):
  237.         r = mainPanel.Rect
  238.         (x, y) = r.BottomLeft
  239.         x += (r.Width - x) / 2 - ad_panel.Size.width / 2
  240.         dc = wx.AutoBufferedPaintDC(self)
  241.         if glass():
  242.             dc.Brush = wx.Brush(wx.Color(*GLASS_TRANSPARENT_COLOR))
  243.             dc.DrawRectangleRect(self.ClientRect)
  244.         else:
  245.             dc.Brush = wx.Brush(get_frame_color(self.IsActive()))
  246.             dc.Pen = wx.TRANSPARENT_PEN
  247.             dc.DrawRectangleRect(wx.RectPS(r.BottomLeft, (r.Width, (self.ClientRect.height - r.Height) + 1)))
  248.         if not getattr(self, '_did_glass', False) and glass():
  249.             bottom = r if borderSize else r + borderSize * 2 + extra_top if not glass() else 0 + ad_panel.Size.height
  250.             cgui.glassExtendInto(self, 0, 0, 0, bottom)
  251.         
  252.  
  253.     self.Bind(wx.EVT_PAINT, paint)
  254.     (maxw, maxh) = AD_PANEL_MAXSIZE
  255.     
  256.     def on_resize(e = (None, (None, None, None, None, None, None if 'wxMSW' in wx.PlatformInfo else self), None)):
  257.         if hasattr(e, 'Skip'):
  258.             e.Skip()
  259.         
  260.         if wx.IsDestroyed(self):
  261.             return None
  262.         (w, h) = AD_PANEL_MAXSIZE
  263.         cwidth = self.ClientSize.width
  264.         ad_w = min(w, cwidth)
  265.         if ad_w < w:
  266.             ad_w -= 2
  267.         
  268.         zoom = float(ad_w) / w
  269.         ad_h = zoom * h
  270.         ad_s = (ad_w, ad_h)
  271.         position = mainPanel.Rect.BottomLeft + wx.Point((cwidth / 2 - ad_w / 2) + 1, 8)
  272.         r = wx.RectPS(position, ad_s)
  273.         ad_panel.SetMinSize(ad_s)
  274.         ad_panel.SetPageZoom(zoom)
  275.         ad_panel.Parent.Layout()
  276.         ad_panel.Parent.Refresh()
  277.  
  278.     self.Bind(wx.EVT_SIZE, on_resize)
  279.     
  280.     def RefreshAd():
  281.         ad_panel._reload_ad()
  282.         wx.CallLater(50, on_resize)
  283.  
  284.     rotater.on_reload += RefreshAd
  285.     ad_panel.OnDoc += on_resize
  286.     ad_panel.RefreshAd = RefreshAd
  287.     self.PushEventHandler(cgui.DragMixin(self))
  288.     return ad_panel
  289.  
  290. _cached_border_image = (None, None)
  291. _border_color = (93, 108, 122, 255)
  292.  
  293. def _get_border_image(sz):
  294.     global _cached_border_image
  295.     (w, h) = sz
  296.     sz = (w, h)
  297.     if _cached_border_image[0] == sz:
  298.         return _cached_border_image[1]
  299.     import PIL
  300.     img = PIL.Image.new('RGBA', (w, h), _border_color).WXB
  301.     _cached_border_image = (sz, img)
  302.     return img
  303.  
  304.  
  305. class Timer(object):
  306.     
  307.     def __init__(self, get_time_func = time):
  308.         self._get_time = get_time_func
  309.         self.start_ticks = 0
  310.         self.paused_ticks = 0
  311.         self.paused = False
  312.         self.started = False
  313.  
  314.     
  315.     def start(self):
  316.         self.started = True
  317.         self.paused = False
  318.         self.start_ticks = self._get_time()
  319.  
  320.     
  321.     def stop(self):
  322.         self.started = False
  323.         self.paused = False
  324.  
  325.     
  326.     def pause(self):
  327.         if not (self.started) or self.paused:
  328.             return None
  329.         self.paused = True
  330.         self.paused_ticks = self._get_time() - self.start_ticks
  331.  
  332.     
  333.     def unpause(self):
  334.         if not (self.started) or not (self.paused):
  335.             return None
  336.         self.paused = False
  337.         self.start_ticks = self._get_time() - self.paused_ticks
  338.         self.paused_ticks = 0
  339.  
  340.     
  341.     def get_ticks(self):
  342.         if not self.started:
  343.             return 0
  344.         if self.paused:
  345.             return self.paused_ticks
  346.         return self._get_time() - self.start_ticks
  347.  
  348.  
  349.