def generate_random(): 'Generates a years worth of random logs.' p = path('c:\\test') words = 'foo bar to be or not the and apple orange banana cherry futon proleptic gregorian ordinal'.split() cal = Calendar() for month in xrange(1, 12): for day in cal.itermonthdates(2007, month): messages = [] for x in xrange(2, randrange(20, 50)): shuffle(words) messages.append( S(buddy = S(name = 'digsby0%d' % randrange(1, 3)), timestamp = random_time_in_day(day), message = ' '.join(words[:randrange(1, len(words)+1)]))) messages.sort(key = lambda mobj: mobj['timestamp']) daylog = p / (day.isoformat() + '.html') with daylog.open('w') as f: f.write(html_header % dict(title = 'IM Logs with %s on %s' % ('digsby0%d' % randrange(1, 3), day.isoformat()))) for mobj in messages: f.write(generate_output_html(mobj))
def offline_contact(cinfo): protocol = S(name=cinfo['protocol'], service=cinfo['protocol'], username=cinfo['username'], self_buddy=S(name=cinfo['username']), connected=False) return OfflineBuddy(cinfo['name'], protocol)
def __init__(self, name, service): Observable.__init__(self) self.name = self.nice_name = name self._service = service self._notify_dirty = True self.protocol = p = S(name=self.service, self_buddy=S(name=name), connected=False)
def __init__(self, username, name): self.username = username self.protocol = self.name = name self.connection = S( protocol = name, username = username )
def parse_html_slow(html): 'Uses Beautiful Soup to parse messages out of a log file.' html = html.decode('utf-8', 'ignore') soup = soupify(html, markupMassage=((br_re, lambda m: '<br />'), )) messages = [] strptime = datetime.strptime for div in soup.findAll(message_divs): try: buddyname = div.findAll('span', class_buddy)[0].renderContents(None) timestamp = parse_timestamp(div['timestamp']) message = div.findAll('span', class_msgcontent)[0].renderContents(None) type = div['class'].replace('message', '').strip() auto = boolify(div.get('auto', 'false')) except Exception: print_exc() else: messages.append( Message(buddy=S(name=buddyname), timestamp=timestamp, message=message, type=type, auto=auto)) log_info('parse_html_slow with %d bytes returning %d messages', len(html), len(messages)) return messages
def load(self): dirs = [x for x in self.path.glob('*.emoticon') if x.isdir()] emoticons = odict() bitmaps = odict() title = self.path.name for dir in dirs: imgpath = dir / 'Emoticon.gif' if not imgpath.isfile(): continue smileys_path = (dir / 'TextEquivalents.txt') if not smileys_path.isfile(): continue smileys = smileys_path.lines() for smiley in smileys: smiley = smiley.strip() if not smiley: continue emoticons[smiley] = S(path=imgpath) if not imgpath in bitmaps: bitmaps[imgpath] = [smiley] else: bitmaps[imgpath].append(smiley) self.name = title self.emoticons = emoticons self.bitmaps = bitmaps self.post_load()
def load(self): emoticons_txt = self.path / 'Emoticons.plist' if not emoticons_txt.isfile(): return None, None title = self.path.name with file(emoticons_txt) as f: plist = tag(f.read()) toplevel = plist._children[0] converted = plisttype_to_pytype(toplevel) emoticons = odict() bitmaps = odict() for img_name, info in sorted(converted['Emoticons'].items()): smileys = info['Equivalents'] imgpath = self.path / img_name if imgpath.isfile(): for smiley in smileys: if not smiley: continue # for badly formed plists with <string></string> emoticons[smiley] = S(path=imgpath) if not imgpath in bitmaps: bitmaps[imgpath] = [smiley] else: bitmaps[imgpath].append(smiley) self.name = title self.emoticons = emoticons self.bitmaps = bitmaps self.post_load()
def load(self): theme = self.path / 'theme' if not theme.isfile(): return None, None smileys = defaultdict(list) emoticons = {} bitmaps = odict() title = self.path.name with file(theme) as f: for line in f: if line.count('\t') > 0: seq = filter(None, line.strip().split('\t')) if len(seq) >= 2: img, smiley = seq[:2] imgpath = self.path / img if imgpath.isfile(): emoticons[smiley.encode('xml')] = S(path=imgpath) if not imgpath in bitmaps: bitmaps[imgpath] = [smiley] else: bitmaps[imgpath].append(smiley) elif line.count('='): key, val = line.split('=', 1) if key.lower() == 'name': title = val self.name = title self.emoticons = emoticons self.bitmaps = bitmaps self.post_load()
def dialog_closed_callback(result): from util import Storage as S from time import time from common import pref, setpref result = S(result) invite_times = pref('usertrack.invite.dialog.results', type=dict, default={}) num_email_accts = len(p.emailaccounts) num_webmail_accts = len( [e.protocol in webmail_types for e in p.emailaccounts[:]]) track_data = dict(accts=len(result.accts), web_accts=num_webmail_accts, email_accts=num_email_accts, background=result.background, send=result.send) num_not_triggered = sum( t.get('background', False) for t in invite_times.values()) if not result.background or num_not_triggered < 5: invite_times[int(time())] = track_data setpref('usertrack.invite.dialog.results', invite_times) if result.send: from pprint import pprint print 'would send:' pprint(result.accts)
def construct_roomlist(self): ''' roomlist is constructed lazily ''' from gui.uberwidgets.skinsplitter import SkinSplitter from gui.imwin.imwin_gui import MSGSPLIT_FLAGS sash_pos = self.input_splitter.GetSashPosition() # construct the splitter self.roomlist_splitter = SkinSplitter(self.input_splitter, MSGSPLIT_FLAGS) self.roomlist_splitter.SetSashGravity(1) self.roomlist_splitter.Bind(wx.EVT_LEFT_UP, self._save_roomlist_splitter) def _on_top_maximize(e): e.Skip() # HACK: maximizing the IM window sometimes makes the roomlist splitter resize really big. # restore the size 100ms after a maximize to fix this problem. wx.CallLater(100, self._restore_roomlist_splitter) self.Top.Bind(wx.EVT_MAXIMIZE, _on_top_maximize) self.message_area.Reparent(self.roomlist_splitter) # construct the roomlist from gui.imwin.roomlist import RoomListPanel self.roomlist = RoomListPanel(self.roomlist_splitter, inviteCallback = self._on_invite_buddy, accountCallback = lambda: S(connection=self.convo.protocol)) self.do_input_split(self.roomlist_splitter) self.input_splitter.SetSashPosition(sash_pos)
def UpdateSkin(self): # no specific skinkey means look it up in MenuBar.MenuSkin mbskin = skin.get('MenuBar', None) if "wxMac" in wx.PlatformInfo or not mbskin or mbskin.get( 'menuskin', None) is None or mbskin.get( 'mode', 'skin').lower() == 'native': self.skin = S(native=True) native = True else: self.skin = skin.get(mbskin.menuskin) native = False self.skin.native = False if not native and not hasattr(self, 'popup'): # create a PopupWindow child for displaying a skinned menu self.popup = MenuPopupWindow(self.Window, self) elif not native: # since UpdateSkin is called on UMenus separately and does not descend the widget tree, # do it manually here. self.popup.UpdateSkin() self.popup.vlist.UpdateSkin() elif native: if hasattr(self, 'popup'): # destroy the skinned PopupWindow if we're in native mode self.popup.Destroy() del self.popup
def info(self): shot = self.screenshot if shot is not None: f = StringIO() shot.save(f, 'PNG') shot = f.getvalue() return S(description=self.input.Value, reproducible=self.reproduce, screenshot=shot)
def date_status(self, dt): # "Status" messages are reused as a form of date context for displaying # old messages in the history, and for when an IM window is open for # more than a day. # displayed timestamps need to be converted from UTC->local format_dt = fromutc(dt) return S(message = format_dt.strftime(self.date_context_format), timestamp = dt, buddy = None, type = None)
def UpdateSkin(self): self.dragimgs = S( bar=skin.get('BuddiesPanel.Dragimages.Bar'), #TODO: stretch? box=skin.get('BuddiesPanel.Dragimages.Box')) for renderer in self.renderers.itervalues(): renderer.UpdateSkin() bg = skin.get('BuddiesPanel.Backgrounds.List', lambda: SkinColor(wx.WHITE)) self.SetBackground(bg) self.RefreshAll()
def OnTabActivated(self, tab): ubertab = tab.Window.Tab ubertab.SetActive(True) tlw = tab.Window.Top tlw.Show() if tlw.IsIconized(): tlw.Iconize(False) # fake an EVT_ICONIZE to the im window here if hasattr(tlw, 'OnIconize'): from util import Storage as S tlw.OnIconize(S(Skip=Null, Iconized=lambda: False)) tlw.Raise()
def OnData(self, x, y, drag_result): "Called when OnDrop returns True. Get data and do something with it." with traceguard: self.GetData() # Copies data from drag source to self.dragging dragged = self.dragged dropped = S(files=dragged.file.GetFilenames(), bitmap=dragged.bitmap.GetBitmap(), text=dragged.text.GetText()) if dropped.files: i, unused_percent = self.list.hit_test_ex(wx.Point(x, y)) if i != -1: obj = self.list.model[i] # open a "send files" confirmation from common import caps obj = getattr(obj, 'file_buddy', obj) #metacontact @wx.CallAfter # so that we don't block the Drag and Drop def later(): if hasattr(obj, 'send_file') and caps.FILES in obj.caps: window = self.list.Top window.Raise() from gui.contactdialogs import send_files send_files(window, obj, dropped.files) else: msg = _("This buddy can't accept file transfers") wx.MessageBox(msg, _("Send File")) if dropped.bitmap: print dropped.bitmap print dir(dropped.bitmap) return drag_result if dropped.text: #print 'Dropped Text (%s)' % dropped.text pass if getattr(self.list, 'dragging_obj', None) is not None: self.list.on_drop_buddylistitem(self.list.dragging_obj) del self.dragged self.CreateNewDataObject() return drag_result
def maybe_done(): ctx['count'] += 1 if ctx['count'] < NUM_KEYWORDS: return if all_ads: self.endpoints = [] ad_objects = [] for url, data, ads, kwd in all_ads: ad_objects.extend(ads) from datetime import datetime self.endpoints.append( S(last_received_xml=prettyxml(data), last_keyword=kwd, last_url=url, last_update_time=datetime.now().isoformat())) return success(NewsItemList(1, 0, 0, items=ad_objects)) error(all_errors[0] if all_errors else None)
def load(self): emoticons_txt = self.path / 'emoticons.txt' if not emoticons_txt.isfile(): raise Exception("%r not found", emoticons_txt) title = self.path.name emoticons = {} bitmaps = odict() with file(emoticons_txt) as f: # the first nonblank line is the title for line in f: line = line.strip() if line: title = line break for line in f: line = line.strip() if not line: continue content = line.split() image_filename, smileys = content[0], content[1:] imgpath = self.path / image_filename if imgpath.isfile(): for smiley in smileys: emoticons[smiley.encode('xml')] = S(path=imgpath) if not imgpath in bitmaps: bitmaps[imgpath] = [smiley] else: bitmaps[imgpath].append(smiley) self.name = title self.emoticons = emoticons self.bitmaps = bitmaps self.post_load()
def parse_html_lxml(html): 'parses a logfile with lxml' messages = [] doc = lxml.html.document_fromstring(html, parser=lxmlparser()) for div in doc.xpath('//html/body/div'): try: message_type = div.attrib.get('class', '') if not 'message' in message_type: continue message_type = message_type.replace('message', '').strip() if not message_type in ('incoming', 'outgoing'): continue buddyname = div.find_class('buddy')[0].text timestamp = div.attrib.get('timestamp') if timestamp is not None: timestamp = parse_timestamp(timestamp) message = render_contents(div.find_class('msgcontent')[0]) auto = boolify(div.attrib.get('auto', 'false')) except Exception: print_exc() else: messages.append( Message( buddy=S(name=buddyname), timestamp=timestamp, message=message, type=message_type, auto=auto, has_autotext=auto, )) return messages
def construct(self): def Text(*a, **k): txt = StaticText(self, -1, *a, **k) txt.Wrap(520) return txt def BoldText(*a, **k): t = Text(*a, **k) t.SetBold() return t self.header = BoldText(_( 'Use this tool to submit a diagnostic log right after you experience a bug' ), style=ALIGN_CENTER) self.subheader = Text(_( "This diagnostic log file does not contain personal data such as the content of sent/received IMs, the content of emails, and the content of social network newsfeeds except where it directly pertains to an error." ), style=ALIGN_CENTER) self.subheader.SetSizerProps(expand=True) self.line = StaticLine(self) self.input_desc = BoldText( _('Please describe the bug in as much detail as possible. Include information such as what you were doing when the bug occurred and exactly what goes wrong.' )) self.input_desc.SetSizerProps(expand=True) self.input = TextCtrl(self, -1, size=(400, 200), style=wx.TE_MULTILINE) self.input.SetSizerProps(expand=True, proportion=1) radioPanel = self.radioPanel = sc.SizedPanel(self, -1) radioPanel.SetSizerType("horizontal") self.reproduce_text = wx.StaticText( radioPanel, -1, _('Can you consistently reproduce this bug?')) self.radios = S(yes=RadioButton(radioPanel, -1, _('&Yes'), style=wx.RB_GROUP), no=RadioButton(radioPanel, -1, _('&No')), unknown=RadioButton(radioPanel, -1, _("&Don't Know"))) self.radios.unknown.SetValue(True) self.screenshot_text = BoldText( _('If this is a visual bug, please attach a screenshot to this report.' )) self.screenshot_link = wx.HyperlinkCtrl(self, -1, _('Take Screenshot'), '#') self.screenshot_link.Bind(wx.EVT_HYPERLINK, self.OnScreenshot) self.screenshot_timer = ScreenshotTimer( SCREENSHOT_TIMER_SECS, lambda t: self.OnScreenshotLinkTimer( _('Taking Screenshot in {secs}').format(secs=t)), self.OnScreenshotTimer) self.Bind(wx.EVT_SIZE, self.OnSize)
def get_info(self): return S(name = self.name, account = self.get_acct())
def main(): def on_close(e): twitter.disconnect() import AsyncoreThread AsyncoreThread.join() f.Destroy() def droptables(): if wx.YES == wx.MessageBox( 'Are you sure you want to drop all tables?', style = wx.YES_NO, parent = f): twitter.clear_cache() def build_test_frame(): f = wx.Frame(None, title='Twitter Test') f.SetSize((500, 700)) f.Bind(wx.EVT_CLOSE, on_close) buttons = [] def button(title, callback): b = wx.Button(f, -1, title) b.Bind(wx.EVT_BUTTON, lambda e: callback()) buttons.append(b) def infobox(): from gui.toolbox import Monitor from gui.infobox.infobox import DEFAULT_INFOBOX_WIDTH from gui.infobox.infoboxapp import init_host, set_hosted_content f = wx.Frame(None) size = (DEFAULT_INFOBOX_WIDTH, Monitor.GetFromWindow(f).ClientArea.height * .75) f.SetClientSize(size) w = wx.webview.WebView(f) init_host(w) set_hosted_content(w, MockTwitterAccount(twitter)) f.Show() def popup(): twitter.webkitcontroller.evaljs('account.showTimelinePopup();') def fake_tweets(): j('fakeTweets(%d);' % int(fake_tweets_txt.Value)) twitter.webkitcontroller.webview.GarbageCollect() button('Open Window', twitter.open_timeline_window) button('Update', twitter.update) button('Infobox', infobox) button('Drop Tables', droptables) button('Popup', popup) button('Fake Tweets', fake_tweets) s = f.Sizer = wx.BoxSizer(wx.HORIZONTAL) v = wx.BoxSizer(wx.VERTICAL) v.AddMany(buttons) fake_tweets_txt = wx.TextCtrl(f, -1, '1000') v.Add(fake_tweets_txt) s.Add(v, 0, wx.EXPAND) v2 = wx.BoxSizer(wx.VERTICAL) stxt = wx.StaticText(f) v2.Add(stxt, 0, wx.EXPAND) from pprint import pformat from common.commandline import wkstats def update_text(): debug_txt = '\n\n'.join([ pformat(wkstats()), j('debugCounts()') ]) stxt.Label = debug_txt f.Sizer.Layout() f._timer = wx.PyTimer(update_text) f._timer.StartRepeating(1000) f.SetBackgroundColour(wx.WHITE) s.Add((50, 50)) s.Add(v2, 0, wx.EXPAND) return f from tests.testapp import testapp username, password = '******', 'no passwords' if len(sys.argv) > 2: username, password = sys.argv[1:3] app = testapp(skinname='Windows 7', plugins=True) global twitter # on console from twitter.twitter import TwitterProtocol twitter = TwitterProtocol(username, password) twitter.events.state_changed += lambda state: print('state changed:', state) twitter.events.reply += lambda screen_name: print('reply:', screen_name) import common.protocolmeta account_opts = common.protocolmeta.protocols['twitter']['defaults'].copy() if '--twitter-offline' in sys.argv: account_opts['offlineMode'] = True #import simplejson #account_opts['feeds'] = simplejson.loads('[{"type": "timeline", "name": "timeline"}, {"type": "mentions", "name": "mentions"}, {"type": "directs", "name": "directs"}, {"name": "group:1", "popups": false, "ids": [14337372, 9499402, 8517312, 7341872, 32218792, 9853162], "filter": false, "groupName": ".syntax", "type": "group"}, {"name": "search:1", "title": "foramilliondollars", "popups": false, "merge": false, "query": "#foramilliondollars", "save": true, "type": "search"}]') twitter.connect(account_opts) # mock an accountmanager/social networks list for the global status dialog from util.observe import ObservableList, Observable class TwitterAccount(Observable): service = protocol = 'twitter' enabled = True ONLINE = True def __init__(self, connection): Observable.__init__(self) self.display_name = self.name = connection.username self.connection = connection self.connection.account = self import digsbyprofile from util import Storage as S acctmgr = digsbyprofile.profile.account_manager = S( socialaccounts = ObservableList([TwitterAccount(twitter)]) ) digsbyprofile.profile.socialaccounts = acctmgr.socialaccounts global j j = twitter.webkitcontroller.evaljs def _html(): txt = twitter.webkitcontroller.FeedWindow.PageSource.encode('utf-8') from path import path p = path(r'c:\twitter.html') p.write_bytes(txt) wx.LaunchDefaultBrowser(p.url()) global html html = _html f = build_test_frame() f.Show() if '--drop' in sys.argv: twitter.clear_cache() wx.CallLater(500, twitter.open_timeline_window) app.MainLoop()
def msgobj(msg): return S(buddy=b, conversation=c, message=msg, timestamp=datetime.now())
add(pref('plugins.nowplaying.format', default=u'%(title)s - %(artist)s')) add(pref('plugins.nowplaying.backup_format', default=u'%(filename)s')) for fmt in formats[:]: if type(fmt) is not unicode: fmt = fmt.decode('ascii') try: fmt % format_dict except (KeyError, TypeError), e: formats.remove(fmt) if formats: retval = S(format_string = formats[0], format_args = format_dict, app = g('app')) else: retval = _no_song() return retval def currentSong(): ''' Discover the current song. Checks MODULE.currentSong() where MODULE is one of the modules listed above in player_order. ''' songs = []
def _no_song(): return S(format_string = '%(title)s', format_args = dict(title = NO_SONG_MESSAGE, is_blank = True,), app = '')
def __init__(self): self.connected_accounts = [] self.account_manager = S(connected_accounts = self.connected_accounts)
from util import Point2HTMLSize, Storage as S DEFAULTS = S(FONT='Times New Roman', SIZE=12, BACK=(255, 255, 255), FORE=(0, 0, 0)) def tohex(t, n=3): return ''.join('%02x' % c for c in t[:n]) pointsize_map = {8: 1, 10: 2, 12: 3, 14: 4, 18: 5, 24: 6, 36: 7, 38: 7} def aimsize(n): n = int(n) try: return pointsize_map[n] except KeyError: return Point2HTMLSize(n) def to_aimhtml(s, fmt, body_bgcolor=False, replace_newlines=False): ''' Given a string, and a fmt dictionary containing color and font information, returns "AIM" html. AIM html is a limited subset of HTML displayed by AIM clients. ''' before, after = '', ''