class Hotkey(Configuration, Interface, Gui): """A generic session providing global hotkey support""" def __init__(self, keymap={}, *args, **kwargs): super(Hotkey, self).__init__(*args, **kwargs) if 'keymap' not in self.config: self.config['keymap'] = dict() self.keymap = self.config['keymap'] #Load any keys passed in. self.update_dict(self.keymap, keymap) #Load default app-wide keystrokes. self.update_dict(self.keymap, configuration.main['keymap']) self.keyboard_handler = WXKeyboardHandler(application.main_frame) new = self.keyboard_handler.standardize_keymap(self.keymap) self.keymap.clear() self.keymap.update(new) self.active_keymap = dict() self.replaced_keys = {} self.modifiers_locked = False def activate(self): if self.active: return self.set_active_keymap(self.keymap) super(Hotkey, self).activate() def deactivate(self): self.unlock_modifiers() self.unregister_hotkeys() super(Hotkey, self).deactivate() def set_active_keymap(self, keymap): working = dict(keymap) keymap = {} for func in working: try: function = self._find_interface_function(func) except NotImplementedError: continue key = working[func] keymap[key] = function self.register_hotkeys(keymap) @always_call_after def register_hotkeys(self, keymap): self.keyboard_handler.register_keys(keymap) self.active_keymap = keymap def _find_interface_function(self, func): function = getattr(self.interface, func, None) if function is None: raise NotImplementedError new_func = partial(self.call_interface_function, function) return new_func @always_call_after def unregister_hotkeys(self): self.keyboard_handler.unregister_all_keys() def call_interface_function(self, function): if not self.active: return if global_vars.KeyboardHelp: try: output.speak(function.__doc__) finally: if function.func_name == "ToggleKeyboardHelp": self.execute_interface_function(function) else: self.execute_interface_function(function) def execute_interface_function(self, func): func() def key_description(self, func): return getattr(getattr(self.interface, func, None), '__doc__', None) def replace_active_keymap(self, new_keymap): self.unregister_hotkeys() self.register_hotkeys(new_keymap) def lock_modifiers(self, modifiers='control+win'): new_keymap = {} if not modifiers.endswith('+'): modifiers = '%s+' % modifiers for key in self.active_keymap: if modifiers in key: new_key = key.replace(modifiers, "") new_keymap[new_key] = self.active_keymap[key] else: new_keymap[key] = self.active_keymap[key] self.replace_active_keymap(new_keymap) self.modifiers_locked = True def unlock_modifiers(self): self.unregister_hotkeys() self.set_active_keymap(self.keymap) self.modifiers_locked = False
class Hotkey (Configuration, Interface, Gui): """A generic session providing global hotkey support""" def __init__(self, keymap={}, *args, **kwargs): super(Hotkey, self).__init__(*args, **kwargs) if 'keymap' not in self.config: self.config['keymap'] = dict() self.keymap = self.config['keymap'] #Load any keys passed in. self.update_dict(self.keymap, keymap) #Load default app-wide keystrokes. self.update_dict(self.keymap, configuration.main['keymap']) self.keyboard_handler = WXKeyboardHandler(application.main_frame) new = self.keyboard_handler.standardize_keymap(self.keymap) self.keymap.clear() self.keymap.update(new) self.active_keymap = dict() self.replaced_keys = {} self.modifiers_locked = False def activate(self): if self.active: return self.set_active_keymap(self.keymap) super(Hotkey, self).activate() def deactivate (self): self.unlock_modifiers() self.unregister_hotkeys() super(Hotkey, self).deactivate() def set_active_keymap(self, keymap): working = dict(keymap) keymap = {} for func in working: try: function = self._find_interface_function(func) except NotImplementedError: continue key = working[func] keymap[key] = function self.register_hotkeys(keymap) @always_call_after def register_hotkeys(self, keymap): self.keyboard_handler.register_keys(keymap) self.active_keymap = keymap def _find_interface_function(self, func): function = getattr(self.interface, func, None) if function is None: raise NotImplementedError new_func = partial(self.call_interface_function, function) return new_func @always_call_after def unregister_hotkeys(self): self.keyboard_handler.unregister_all_keys() def call_interface_function(self, function): if not self.active: return if global_vars.KeyboardHelp: try: output.speak(function.__doc__) finally: if function.func_name == "ToggleKeyboardHelp": self.execute_interface_function(function) else: self.execute_interface_function(function) def execute_interface_function(self, func): try: func() except: logging.exception("Error executing function %r") raise def key_description(self, func): return getattr(getattr(self.interface, func, None), '__doc__', None) def replace_active_keymap(self, new_keymap): self.unregister_hotkeys() self.register_hotkeys(new_keymap) def lock_modifiers(self, modifiers='control+win'): new_keymap = {} if not modifiers.endswith('+'): modifiers = '%s+' % modifiers for key in self.active_keymap: if modifiers in key: new_key = key.replace(modifiers, "") new_keymap[new_key] = self.active_keymap[key] else: new_keymap[key] = self.active_keymap[key] self.replace_active_keymap(new_keymap) self.modifiers_locked = True def unlock_modifiers(self): self.unregister_hotkeys() self.set_active_keymap(self.keymap) self.modifiers_locked = False
class mainFrame(wx.Frame): """ Main class of the Frame. This is the Main Window.""" ### MENU def makeMenus(self): """ Creates, bind and returns the menu bar for the application. Also in this function, the accel table is created.""" menuBar = wx.MenuBar() # Application menu app = wx.Menu() switch_account = app.Append(wx.NewId(), _(u"S&witch account")) self.Bind(wx.EVT_MENU, self.switch_account, switch_account) updateProfile = app.Append(wx.NewId(), _(u"&Update profile")) self.Bind(wx.EVT_MENU, self.update_profile, updateProfile) show_hide = app.Append(wx.NewId(), _(u"&Hide window")) self.Bind(wx.EVT_MENU, self.show_hide, show_hide) search = app.Append(wx.NewId(), _(u"&Search")) self.Bind(wx.EVT_MENU, self.search, search) trends = app.Append(wx.NewId(), _(u"View &trending topics")) self.Bind(wx.EVT_MENU, self.get_trending_topics, trends) lists = app.Append(wx.NewId(), _(u"&Lists manager")) self.Bind(wx.EVT_MENU, self.list_manager, lists) sounds_tutorial = app.Append(wx.NewId(), _(u"Sounds &tutorial")) self.Bind(wx.EVT_MENU, self.learn_sounds, sounds_tutorial) keystroke_editor = app.Append(wx.NewId(), _(u"&Edit keystrokes")) self.Bind(wx.EVT_MENU, self.edit_keystrokes, keystroke_editor) prefs = app.Append(wx.ID_PREFERENCES, _(u"&Preferences")) self.Bind(wx.EVT_MENU, self.preferences, prefs) close = app.Append(wx.ID_EXIT, _(u"E&xit")) self.Bind(wx.EVT_MENU, self.close, close) # Tweet menu tweet = wx.Menu() compose = tweet.Append(wx.NewId(), _(u"&Tweet")) self.Bind(wx.EVT_MENU, self.compose, compose) response = tweet.Append(wx.NewId(), _(u"Re&ply")) self.Bind(wx.EVT_MENU, self.reply, response) retweet = tweet.Append(wx.NewId(), _(u"&Retweet")) self.Bind(wx.EVT_MENU, self.retweet, retweet) fav = tweet.Append(wx.NewId(), _(u"Add to &favourites")) self.Bind(wx.EVT_MENU, self.fav, fav) unfav = tweet.Append(wx.NewId(), _(u"Remove from favo&urites")) self.Bind(wx.EVT_MENU, self.unfav, unfav) view = tweet.Append(wx.NewId(), _(u"&Show tweet")) self.Bind(wx.EVT_MENU, self.view, view) view_coordinates = tweet.Append(wx.NewId(), _(u"View &address")) self.Bind(wx.EVT_MENU, self.reverse_geocode, view_coordinates) delete = tweet.Append(wx.NewId(), _(u"&Delete")) self.Bind(wx.EVT_MENU, self.delete, delete) # User menu user = wx.Menu() follow = user.Append(wx.NewId(), _(u"&Follow")) self.Bind(wx.EVT_MENU, self.onFollow, follow) unfollow = user.Append(wx.NewId(), _(u"&Unfollow")) self.Bind(wx.EVT_MENU, self.onUnfollow, unfollow) mute = user.Append(wx.NewId(), _(u"&Mute")) self.Bind(wx.EVT_MENU, self.onMute, mute) unmute = user.Append(wx.NewId(), _(u"U&nmute")) self.Bind(wx.EVT_MENU, self.onUnmute, unmute) report = user.Append(wx.NewId(), _(u"&Report as spam")) self.Bind(wx.EVT_MENU, self.onReport, report) block = user.Append(wx.NewId(), _(u"&Block")) self.Bind(wx.EVT_MENU, self.onBlock, block) unblock = user.Append(wx.NewId(), _(u"Unb&lock")) self.Bind(wx.EVT_MENU, self.onUnblock, unblock) dm = user.Append(wx.NewId(), _(u"Direct me&ssage")) self.Bind(wx.EVT_MENU, self.dm, dm) addToList = user.Append(wx.NewId(), _(u"&Add to list")) self.Bind(wx.EVT_MENU, self.add_to_list, addToList) removeFromList = user.Append(wx.NewId(), _(u"R&emove from list")) self.Bind(wx.EVT_MENU, self.remove_from_list, removeFromList) viewLists = user.Append(wx.NewId(), _(u"&View lists")) self.Bind(wx.EVT_MENU, self.view_user_lists, viewLists) details = user.Append(wx.NewId(), _(u"Show user &profile")) self.Bind(wx.EVT_MENU, self.details, details) timeline = user.Append(wx.NewId(), _(u"&Timeline")) self.Bind(wx.EVT_MENU, self.open_timeline, timeline) favs = user.Append(wx.NewId(), _(u"V&iew favourites")) self.Bind(wx.EVT_MENU, self.favs_timeline, favs) # buffer menu buffer = wx.Menu() load_previous_items = buffer.Append(wx.NewId(), _(u"&Load previous items")) self.Bind(wx.EVT_MENU, self.get_more_items, load_previous_items) mute = buffer.Append(wx.NewId(), _(u"&Mute")) self.Bind(wx.EVT_MENU, self.toggle_mute, mute) autoread = buffer.Append(wx.NewId(), _(u"&Autoread tweets for this buffer")) self.Bind(wx.EVT_MENU, self.toggle_autoread, autoread) clear = buffer.Append(wx.NewId(), _(u"&Clear buffer")) self.Bind(wx.EVT_MENU, self.clear_list, clear) deleteTl = buffer.Append(wx.NewId(), _(u"&Remove buffer")) self.Bind(wx.EVT_MENU, self.delete_buffer, deleteTl) # Help Menu help = wx.Menu() doc = help.Append(-1, _(u"&Documentation")) self.Bind(wx.EVT_MENU, self.onManual, doc) changelog = help.Append(wx.NewId(), _(u"&What's new in this version?")) self.Bind(wx.EVT_MENU, self.onChangelog, changelog) check_for_updates = help.Append(wx.NewId(), _(u"&Check for updates")) self.Bind(wx.EVT_MENU, self.onCheckForUpdates, check_for_updates) reportError = help.Append(wx.NewId(), _(u"&Report an error")) self.Bind(wx.EVT_MENU, self.onReportBug, reportError) visit_website = help.Append(-1, _(u"TW Blue &website")) self.Bind(wx.EVT_MENU, self.onVisit_website, visit_website) about = help.Append(-1, _(u"About &TW Blue")) self.Bind(wx.EVT_MENU, self.onAbout, about) # Add all to the menu Bar menuBar.Append(app, _(u"&Application")) menuBar.Append(tweet, _(u"&Tweet")) menuBar.Append(user, _(u"&User")) menuBar.Append(buffer, _(u"&Buffer")) menuBar.Append(help, _(u"&Help")) downID = wx.NewId() upID = wx.NewId() leftID = wx.NewId() rightID = wx.NewId() if platform.system() == "Darwin": self.Bind(wx.EVT_MENU, self.down, id=downID) self.Bind(wx.EVT_MENU, self.up, id=upID) self.Bind(wx.EVT_MENU, self.left, id=leftID) self.Bind(wx.EVT_MENU, self.right, id=rightID) # Creates the acceleration table. self.accel_tbl = wx.AcceleratorTable([ (wx.ACCEL_CTRL, ord('N'), compose.GetId()), (wx.ACCEL_CTRL, ord('R'), response.GetId()), (wx.ACCEL_CTRL|wx.ACCEL_SHIFT, ord('R'), retweet.GetId()), (wx.ACCEL_CTRL, ord('F'), fav.GetId()), (wx.ACCEL_CTRL|wx.ACCEL_SHIFT, ord('F'), unfav.GetId()), (wx.ACCEL_CTRL|wx.ACCEL_SHIFT, ord('V'), view.GetId()), (wx.ACCEL_CTRL, ord('D'), dm.GetId()), (wx.ACCEL_CTRL, ord('Q'), close.GetId()), (wx.ACCEL_CTRL, ord('S'), follow.GetId()), (wx.ACCEL_CTRL|wx.ACCEL_SHIFT, ord('S'), unfollow.GetId()), (wx.ACCEL_CTRL, ord('K'), block.GetId()), (wx.ACCEL_CTRL|wx.ACCEL_SHIFT, ord('K'), report.GetId()), (wx.ACCEL_CTRL, ord('I'), timeline.GetId()), (wx.ACCEL_CTRL|wx.ACCEL_SHIFT, ord('I'), deleteTl.GetId()), (wx.ACCEL_CTRL, ord('M'), show_hide.GetId()), (wx.ACCEL_CTRL, ord('P'), updateProfile.GetId()), (wx.ACCEL_CTRL, wx.WXK_DOWN, downID), (wx.ACCEL_CTRL, wx.WXK_UP, upID), (wx.ACCEL_CTRL, wx.WXK_LEFT, leftID), (wx.ACCEL_CTRL, wx.WXK_RIGHT, rightID), ]) self.SetAcceleratorTable(self.accel_tbl) return menuBar ### MAIN def __init__(self, authorised=True, user_key=None, user_secret=None): """ Main function of this class.""" if authorised == False: self.user_key = user_key self.user_secret = user_secret else: self.user_key = self.user_secret = None log.debug("Loading temporal database...") self.db = db.db() # Gets the twitter object for future calls to the twitter Rest API. log.debug("Getting Twitter's Rest API...") self.twitter = twitter.twitter.twitter() super(mainFrame, self).__init__(None, -1, "TW Blue", size=(1600, 1600)) wx.GetApp().Bind(wx.EVT_QUERY_END_SESSION, self.exit) wx.GetApp().Bind(wx.EVT_END_SESSION, self.exit) log.debug(u"Creating the system tray icon... ") self.sysTray=sysTrayIcon.SysTrayIcon(self) panel = wx.Panel(self) self.sizer = wx.BoxSizer(wx.VERTICAL) self.SetTitle("TW Blue") try: updater.update_manager.check_for_update() except: wx.MessageDialog(self, _(u"An error occurred while looking for an update. It may be due to any problem either on our server or on your DNS servers. Please, try again later."), _(u"Error!"), wx.OK|wx.ICON_ERROR).ShowModal() self.SetMenuBar(self.makeMenus()) self.setup_twitter(panel) def logging_in_twblue(self, panel): log.debug("Retrieving username...") twitter.starting.start_user_info(config=self.db, twitter=self.twitter) config.main["twitter"]["user_name"] = self.db.settings["user_name"] self.SetTitle(u"@%s. - TW Blue" % (self.db.settings["user_name"])) self.nb = wx.Treebook(panel, -1) self.Bind(wx.EVT_CLOSE, self.close) self.nb.Bind(wx.EVT_TREEBOOK_PAGE_CHANGED, self.onPageChanged) # Gets the tabs for home, mentions, send and direct messages. log.debug("Creating buffers...") self.db.settings["buffers"] = [] account = buffers.accountPanel(self.nb, self.db.settings["user_name"]) self.nb.AddPage(account, self.db.settings["user_name"]) self.db.settings["buffers"].append(self.db.settings["user_name"]) account_index = self.db.settings["buffers"].index(self.db.settings["user_name"]) home = buffers.basePanel(self.nb, self, "home_timeline", self.twitter.twitter.get_home_timeline, sound="tweet_received.ogg") self.nb.InsertSubPage(account_index, home, _(u"Home")) self.db.settings["buffers"].append("home_timeline") self.nb.SetSelection(1) self.nb.GetPage(1).list.list.SetFocus() mentionsP = buffers.basePanel(self.nb, self, "mentions", self.twitter.twitter.get_mentions_timeline, sound="mention_received.ogg") self.nb.InsertSubPage(account_index, mentionsP, _("Mentions")) self.db.settings["buffers"].append("mentions") dms = buffers.dmPanel(self.nb, self, "direct_messages", self.twitter.twitter.get_direct_messages, sound="dm_received.ogg") self.nb.InsertSubPage(account_index, dms, _(u"Direct messages")) self.db.settings["buffers"].append("direct_messages") sent = buffers.basePanel(self.nb, self, "sent", self.twitter.twitter.get_user_timeline, argumento=self.db.settings["user_name"]) self.nb.InsertSubPage(account_index, sent, _(u"Sent")) self.db.settings["buffers"].append("sent") # If the user has enabled favs from config. if config.main["other_buffers"]["show_favourites"] == True: log.debug("Getting Favorited tweets...") favs = buffers.basePanel(self.nb, self, "favs", self.twitter.twitter.get_favorites) self.nb.InsertSubPage(account_index, favs, _(u"Favourites")) self.db.settings["buffers"].append("favs") # If followers are enabled from config. if config.main["other_buffers"]["show_followers"] == True: log.debug("Getting followers...") followers = buffers.peoplePanel(self.nb, self, "followers", self.twitter.twitter.get_followers_list, argumento=self.db.settings["user_name"], sound="update_followers.ogg") self.nb.InsertSubPage(account_index, followers, _(u"Followers")) self.db.settings["buffers"].append("followers") # Same here but for friends. if config.main["other_buffers"]["show_friends"] == True: log.debug("Getting friends...") friends = buffers.peoplePanel(self.nb, self, "friends", self.twitter.twitter.get_friends_list, argumento=self.db.settings["user_name"]) self.nb.InsertSubPage(account_index, friends, _(u"Friends")) self.db.settings["buffers"].append("friends") if config.main["other_buffers"]["show_blocks"] == True: blocked = buffers.peoplePanel(self.nb, self, "blocks", self.twitter.twitter.list_blocks) self.nb.InsertSubPage(account_index, blocked, _(u"Blocked users")) self.db.settings["buffers"].append("blocks") if config.main["other_buffers"]["show_muted_users"] == True: muteds = buffers.peoplePanel(self.nb, self, "muteds", self.twitter.twitter.get_muted_users_list) self.nb.InsertSubPage(account_index, muteds, _(u"Muted users")) self.db.settings["buffers"].append("muteds") if config.main["other_buffers"]["show_events"] == True: evt = buffers.eventsPanel(self.nb, self, sound="new_event.ogg") self.nb.InsertSubPage(account_index, evt, _(u"Events")) self.db.settings["buffers"].append("events") searches = buffers.emptyPanel(self.nb) self.nb.InsertSubPage(account_index, searches, _(u"Searches")) self.db.settings["buffers"].append("searches") for i in config.main["other_buffers"]["tweet_searches"]: self.nb.InsertSubPage(self.db.settings["buffers"].index("searches"), buffers.searchPanel(self.nb, self, "%s-search" % (i,), q=i, count=100), _(u"Search for %s" % (i,))) self.db.settings["buffers"].append("%s-search" % (i,)) timelines = buffers.emptyPanel(self.nb) self.nb.InsertSubPage(account_index, timelines, _(u"Timelines")) self.db.settings["buffers"].append("timelines") for i in config.main["other_buffers"]["timelines"]: self.nb.InsertSubPage(self.db.settings["buffers"].index("timelines"), buffers.basePanel(self.nb, self, i, self.twitter.twitter.get_user_timeline, argumento=i, timeline=True, sound="tweet_timeline.ogg"), _(u"Timeline for %s") % i) self.db.settings["buffers"].append(i) lists = buffers.emptyPanel(self.nb) self.nb.InsertSubPage(account_index, lists, _(u"Lists")) self.db.settings["buffers"].append("lists") for i in config.main["other_buffers"]["lists"]: self.nb.InsertSubPage(self.db.settings["buffers"].index("lists"), buffers.listPanel(self.nb, self, i+"-list", argumento=twitter.utils.find_list(i, self.db.settings["lists"])), _(u"List for %s") % i) self.db.settings["buffers"].append(i+"-list") ## favourites timelines favs_timelines = buffers.emptyPanel(self.nb) self.nb.InsertSubPage(account_index, favs_timelines, _(U"Favourites timelines")) self.db.settings["buffers"].append("favourites_timelines") for i in config.main["other_buffers"]["favourites_timelines"]: self.nb.InsertSubPage(self.db.settings["buffers"].index("favourites_timelines"), buffers.favsPanel(self.nb, self, i+"favs", argumento=i, sound="favourites_timeline_updated.ogg"), _(u"Favourites for %s") % i,) self.db.settings["buffers"].append(i+"favs") self.fav_stream = RepeatingTimer(180, self.get_fav_buffers) self.fav_stream.start() for i in config.main["other_buffers"]["trending_topic_buffers"]: buff = buffers.trendsPanel(self.nb, self, "%s_tt" % (i,), argumento=i, sound="trends_updated.ogg") timer = RepeatingTimer(300, buff.start_streams) timer.start() num = buff.start_streams() buff.put_items(num) self.nb.InsertSubPage(self.db.settings["buffers"].index(self.db.settings["user_name"]), buff, _(u"Trending topics for %s") % (buff.name,)) self.sizer.Add(self.nb, 0, wx.ALL, 5) if config.main["general"]["use_invisible_keyboard_shorcuts"] == True: km = self.create_invisible_keyboard_shorcuts() self.register_invisible_keyboard_shorcuts(km) panel.SetSizer(self.sizer) self.SetClientSize(self.sizer.CalcMin()) self.Bind(event.MyEVT_STARTED, self.onInit) self.Bind(event.EVT_RESULT, self.onMemberAdded) pub.subscribe(self.listen_streamerror, "streamError") pub.subscribe(self.listen_for_friends, "friendsReceived") call_threaded(self.init, run_streams=True) def init(self, run_streams=False): """ Calls the start_stream function for each stream tab.""" deleted = 0 for i in range(0, self.nb.GetPageCount()): if self.nb.GetPage(i).type == "account" or self.nb.GetPage(i).type == "empty": continue if i == self.nb.GetPageCount() and deleted > 0: i = i-1 deleted = deleted-1 # log.debug(u"Starting stream for %s..." % self.nb.GetPage(i).name_buffer) info_event = event.infoEvent(event.EVT_STARTED, 1) try: if self.nb.GetPage(i).type == "search": self.nb.GetPage(i).timer = RepeatingTimer(180, self.nb.GetPage(i).load_search) self.nb.GetPage(i).timer.start() num = self.nb.GetPage(i).start_streams() info_event.SetItem(i, num) wx.PostEvent(self, info_event) except TwythonError as e: continue except UnicodeDecodeError: # This happens when there is a bad internet connection continue output.speak(_(u"Ready")) if run_streams == True: self.get_home() self.get_tls() self.check_streams = RepeatingTimer(config.main["general"]["time_to_check_streams"], self.check_stream_up) self.check_streams.start() # If all it's done, then play a nice sound saying that all it's OK. sound.player.play("ready.ogg") autocompletionUsersSettings.execute_at_startup(window=self) def remove_list(self, id): for i in range(0, self.nb.GetPageCount()): if self.nb.GetPage(i).type == "list": if self.nb.GetPage(i).argumento == id: pos = self.nb.GetCurrentPage().remove_invalid_buffer() if pos != None: self.nb.DeletePage(pos) self.onMemberAdded() def onMemberAdded(self, ev): self.stream2.disconnect() del self.stream2 self.get_tls() def get_fav_buffers(self): for i in config.main["other_buffers"]["favourites_timelines"]: num = self.nb.GetPage(self.db.settings["buffers"].index(i+"favs")).start_streams() if num > 0: output.speak(_(u"%s favourites from %s") % (nun, i)) def setup_twitter(self, panel): """ Setting up the connection for twitter, or authenticate if the config file has valid credentials.""" # try: self.twitter.login(self.user_key, self.user_secret) self.logging_in_twblue(panel) log.info("Authorized in Twitter.") del self.user_key; del self.user_secret # except: # dlg1 = wx.MessageDialog(panel, _(u"Connection error. Try again later."), _(u"Error!"), wx.ICON_ERROR) # dlg1.ShowModal() # self.Close(True) def get_home(self): """ Gets the home stream, that manages home timeline, mentions, direct messages and sent.""" try: self.stream = twitter.buffers.stream.streamer(application.app_key, application.app_secret, config.main["twitter"]["user_key"], config.main["twitter"]["user_secret"], parent=self) stream_threaded(self.stream.user) except: self.stream.disconnect() def start_lists(self): for i in range(0, self.nb.GetPageCount()): if self.nb.GetPage(i).type == "list": self.nb.GetPage(i).retrieve_ids() def get_tls(self): """ Setting the stream for individual user timelines.""" # try: self.stream2 = twitter.buffers.indibidual.streamer(application.app_key, application.app_secret, config.main["twitter"]["user_key"], config.main["twitter"]["user_secret"], parent=self) # The self.ids contains all IDS for the follow argument of the stream. ids = "" # If we have more than 0 items on a list, then. for i in config.main["other_buffers"]["timelines"]: ids = ids+self.db.settings[i][0]["user"]["id_str"]+", " for i in range(0, self.nb.GetPageCount()): if self.nb.GetPage(i).type == "list": for z in self.nb.GetPage(i).users: ids+= str(z)+", " if ids != "": # try: stream_threaded(self.stream2.statuses.filter, follow=ids) # except: # pass # except: # self.stream2.disconnect() def check_stream_up(self): global function_reconnect_streams_running if function_reconnect_streams_running == True: return if not hasattr(self, "stream") and not hasattr(self, "stream2"): function_reconnect_streams_running = True self.init(run_streams=True) return # try: # urllib2.urlopen("http://74.125.228.231", timeout=5) # except urllib2.URLError: # if self.stream.connected == True: self.stream.disconnect() # if hasattr(self, "stream2") and self.stream2.connected: self.stream2.disconnect() # if config.main["general"]["announce_stream_status"] == True: output.speak(_(u"Streams disconnected. TW Blue will try to reconnect in a minute.")) # return # if self.stream.connected == False: # del self.stream # if config.main["general"]["announce_stream_status"] == True: output.speak(_(u"Reconnecting streams...")) # call_threaded(self.init) # self.get_home() # if hasattr(self, "stream2") and self.stream2.connected == False: # log.debug("Trying reconnects the timelines stream...") # del self.stream2 # self.get_tls() function_reconnect_streams_running = False ### Events def edit_keystrokes(self, ev=None): if hasattr(self, "keyboard_handler"): dlg = keystrokeEditorGUI.keystrokeEditor(parent=self, keyboard_handler=self.keyboard_handler) else: dlg = keystrokeEditorGUI.keystrokeEditor(parent=self) dlg.ShowModal() dlg.Destroy() def search(self, ev=None): dlg = dialogs.search.searchDialog() if dlg.ShowModal() == wx.ID_OK: term = dlg.term.GetValue() if dlg.tweets.GetValue() == True: search =buffers.searchPanel(self.nb, self, "%s-search" % (term,), q=term, count=100) self.nb.InsertSubPage(self.db.settings["buffers"].index("searches"), search, _(u"search for %s") % (term,)) self.db.settings["buffers"].append("%s-search" % (term,)) config.main["other_buffers"]["tweet_searches"].append(term) elif dlg.users.GetValue() == True: search =buffers.searchUsersPanel(self.nb, self, "%s_search" % (term,), q=term, count=20) self.nb.InsertSubPage(self.db.settings["buffers"].index("searches"), search, _(u"search users for %s") % (term,)) self.db.settings["buffers"].append("%s_search" % (term,)) timer = RepeatingTimer(180, search.load_search) timer.start() num = search.start_streams() search.put_items(num) dlg.Destroy() def learn_sounds(self, ev): SoundsTutorial.gui.soundsTutorial().ShowModal() def view_user_lists(self, ev=None): userDlg = dialogs.utils.selectUserDialog(parent=self, title=_(u"Select the user")) if userDlg.ShowModal() == wx.ID_OK: user = userDlg.cb.GetValue() else: return dlg = dialogs.lists.userListViewer(self, user) dlg.ShowModal() userDlg.Destroy() dlg.Destroy() def add_to_list(self, ev=None): userDlg = dialogs.utils.selectUserDialog(parent=self, title=_(u"Select the user")) if userDlg.ShowModal() == wx.ID_OK: user = userDlg.cb.GetValue() else: return dlg = dialogs.lists.addUserListDialog(self) if dlg.ShowModal() == wx.ID_OK: try: list = self.twitter.twitter.add_list_member(list_id=self.db.settings["lists"][dlg.lista.get_selected()]["id"], screen_name=user) older_list = twitter.utils.find_item(self.db.settings["lists"][dlg.lista.get_selected()]["id"], self.db.settings["lists"]) if list["mode"] == "private": self.db.settings["lists"].pop(older_list) self.db.settings["lists"].append(list) except TwythonError as e: output.speak("error %s: %s" % (e.error_code, e.msg)) userDlg.Destroy() dlg.Destroy() def remove_from_list(self, ev=None): userDlg = dialogs.utils.selectUserDialog(parent=self, title=_(u"Select the user")) if userDlg.ShowModal() == wx.ID_OK: user = userDlg.cb.GetValue() else: return dlg = dialogs.lists.removeUserListDialog(self) if dlg.ShowModal() == wx.ID_OK: try: list = self.twitter.twitter.delete_list_member(list_id=self.db.settings["lists"][dlg.lista.get_selected()]["id"], screen_name=user) older_list = twitter.utils.find_item(self.db.settings["lists"][dlg.get_selected()]["id"], self.db.settings["lists"]) if list["mode"] == "private": self.db.settings["lists"].pop(older_list) self.db.settings["lists"].append(list) except TwythonError as e: output.speak("error %s: %s" % (e.error_code, e.msg)) userDlg.Destroy() dlg.Destroy() def list_manager(self, ev): dlg = dialogs.lists.listViewer(self) dlg.ShowModal() self.stream2.disconnect() del self.stream2 self.get_tls() dlg.Destroy() def onInit(self, ev): if self.nb.GetPage(ev.GetItem()[0]).type != "search" or self.nb.GetPage(ev.GetItem()[0]).type != "favourites_timeline": self.nb.GetPage(ev.GetItem()[0]).put_items(ev.GetItem()[1]) def preferences(self, ev=None): dlg = dialogs.configuration.configurationDialog(self) dlg.ShowModal() dlg.Destroy() def update_profile(self, ev=None): dialogs.update_profile.updateProfile(self).ShowModal() def onManual(self, ev): lang = localization.get("documentation") os.chdir("documentation/%s" % (lang,)) webbrowser.open("manual.html") os.chdir("../../") def onChangelog(self, ev): lang = localization.get("documentation") os.chdir("documentation/%s" % (lang,)) webbrowser.open("changes.html") os.chdir("../../") def onVisit_website(self, ev): webbrowser.open("http://twblue.com.mx") def onReportBug(self, ev): issueReporterGUI.reportBug(self.db.settings["user_name"]).ShowModal() def onCheckForUpdates(self, ev): updater.update_manager.check_for_update(msg=True) def details(self, ev=None): """ This function shows details for the selected user.""" dlg = dialogs.utils.selectUserDialog(parent=self, title=_(u"User details")) if dlg.ShowModal() == wx.ID_OK: dialogs.show_user.showUserProfile(self.twitter, dlg.cb.GetValue()).ShowModal() dlg.Destroy() def delete(self, ev=None): """ Deleting a tweet or direct message.""" if self.nb.GetCurrentPage().name_buffer != "followers" and self.nb.GetCurrentPage() != "friends" and self.nb.GetCurrentPage().name_buffer != "events": dlg = wx.MessageDialog(self, _(u"Do you really want to delete this message? It will be eliminated from Twitter as well."), _(u"Delete"), wx.ICON_QUESTION|wx.YES_NO) if dlg.ShowModal() == wx.ID_YES: self.nb.GetCurrentPage().destroy_status(wx.EVT_MENU) else: return def onPageChanged(self, ev): """ Announces the new title for the tab.""" if platform.system() == "Darwin": output.speak(self.nb.GetPageText(self.nb.GetSelection())+",", True) def skip_blank_pages(self, forward=True): if self.nb.GetCurrentPage().type == "account" or self.nb.GetCurrentPage().type == "empty": self.nb.AdvanceSelection(forward) def close(self, ev=None): if config.main["general"]["ask_at_exit"] == True: dlg = wx.MessageDialog(self, _(u"Do you really want to close TW Blue?"), _(u"Exit"), wx.YES_NO|wx.ICON_QUESTION) if dlg.ShowModal() == wx.ID_YES: self.exit() dlg.Destroy() else: output.speak(_(u"Exiting...")) self.exit() def exit(self, event=None): config.main.write() log.debug("Exiting...") self.sysTray.RemoveIcon() self.sysTray.Destroy() try: self.check_streams.cancel() except AttributeError: pass sound.player.cleaner.cancel() try: self.stream.disconnect() log.debug("Stream disconnected.") except: pass try: self.stream2.disconnect() log.debug(u"Timelines stream disconnected.") except: pass wx.GetApp().ExitMainLoop() def onFollow(self, ev=None): """ Opens the follow dialog.""" dialogs.follow.follow(self.nb.GetCurrentPage(), "follow").ShowModal() def onUnfollow(self, ev=None): """ Opens the unfollow dialog.""" dialogs.follow.follow(self.nb.GetCurrentPage(), "unfollow").ShowModal() def onMute(self, ev=None): """ Opens the unfollow dialog.""" dialogs.follow.follow(self.nb.GetCurrentPage(), "mute").ShowModal() def onUnmute(self, ev=None): """ Opens the unfollow dialog.""" dialogs.follow.follow(self.nb.GetCurrentPage(), "unmute").ShowModal() def onReport(self, ev=None): """ Opens the report dialog, to report as spam to the specified user.""" dialogs.follow.follow(self.nb.GetCurrentPage(), "report").ShowModal() def onBlock(self, ev=None): """ Opens the "block" dialog, to block the user that you want.""" dialogs.follow.follow(self.nb.GetCurrentPage(), "block").ShowModal() def onUnblock(self, ev=None): """ Opens the "block" dialog, to block the user that you want.""" dialogs.follow.follow(self.nb.GetCurrentPage(), "unblock").ShowModal() def action(self, ev=None): dialogs.follow.follow(self.nb.GetCurrentPage()).ShowModal() def compose(self, ev=None): """ Opens the new tweet dialog.""" self.nb.GetCurrentPage().post_status(ev) def reply(self, ev=None): """ Opens the response dialog.""" self.nb.GetCurrentPage().onResponse(ev) def dm(self, ev=None): """ Opens the DM Dialog.""" # The direct_messages buffer has a method to post a diret messages while the other tabs does has not it. if self.nb.GetCurrentPage().name_buffer == "direct_messages": self.nb.GetCurrentPage().onResponse(ev) elif self.nb.GetCurrentPage().name_buffer == "events": return else: # dialogs.message.dm(_(u"Direct message to %s ") % (self.db.settings[self.nb.GetCurrentPage().name_buffer][self.nb.GetCurrentPage().get_selected()]["user"]["screen_name"]), "", "", self.nb.GetCurrentPage()).ShowModal() self.nb.GetCurrentPage().onDm(ev) def retweet(self, ev=None): if self.nb.GetCurrentPage().name_buffer != "direct_messages" and self.nb.GetCurrentPage().name_buffer != "followers" and self.nb.GetCurrentPage().name_buffer != "friends" and self.nb.GetCurrentPage().name_buffer != "events": self.nb.GetCurrentPage().onRetweet(ev) def view(self, ev=None): tp = self.nb.GetCurrentPage().type if tp == "buffer" or tp == "timeline" or tp == "favourites_timeline" or tp == "list" or tp == "search": try: id = self.db.settings[self.nb.GetCurrentPage().name_buffer][self.nb.GetCurrentPage().list.get_selected()]["id"] tweet = self.twitter.twitter.show_status(id=id) dialogs.message.viewTweet(tweet).ShowModal() except TwythonError as e: non_tweet = self.nb.GetCurrentPage().get_message(dialog=True) dialogs.message.viewNonTweet(non_tweet).ShowModal() else: non_tweet = self.nb.GetCurrentPage().get_message(dialog=True) dialogs.message.viewNonTweet(non_tweet).ShowModal() def fav(self, ev=None): if self.nb.GetCurrentPage().name_buffer != "direct_messages" and self.nb.GetCurrentPage().name_buffer != "followers" and self.nb.GetCurrentPage().name_buffer != "friends": try: self.twitter.twitter.create_favorite(id=self.db.settings[self.nb.GetCurrentPage().name_buffer][self.nb.GetCurrentPage().list.get_selected()]["id"]) sound.player.play("favourite.ogg") except TwythonError as e: output.speak(_(u"Error while adding to favourites."), True) sound.player.play("error.ogg") def unfav(self, ev=None): if self.nb.GetCurrentPage().name_buffer != "direct_messages" and self.nb.GetCurrentPage().name_buffer != "followers" and self.nb.GetCurrentPage().name_buffer != "friends": try: self.twitter.twitter.destroy_favorite(id=self.db.settings[self.nb.GetCurrentPage().name_buffer][self.nb.GetCurrentPage().list.get_selected()]["id"]) except TwythonError as e: output.speak(_(u"Error while removing from favourites."), True) sound.player.play("error.ogg") def open_timeline(self, ev=None): dlg = dialogs.utils.selectUserDialog(self, _(u"Individual timeline")) if dlg.ShowModal() == wx.ID_OK: user = twitter.utils.if_user_exists(self.twitter.twitter, dlg.cb.GetValue()) if user == None: wx.MessageDialog(None, _(u"The user does not exist"), _(u"Error"), wx.ICON_ERROR).ShowModal() dlg.Destroy() return if user not in config.main["other_buffers"]["timelines"]: config.main["other_buffers"]["timelines"].append(user) else: wx.MessageDialog(None, _(u"There's currently a timeline for this user. You are not able to open another"), _(u"Existing timeline"), wx.ICON_ERROR).ShowModal() dlg.Destroy() return sound.player.play("create_timeline.ogg") st = buffers.basePanel(self.nb, self, user, self.twitter.twitter.get_user_timeline, argumento=user, sound="ready.ogg", timeline=True) num = st.start_streams() self.db.settings["buffers"].append(user) if num == 0: wx.MessageDialog(None, _(u"This user has no tweets. You can't open a timeline for this user"), _(u"Error!"), wx.ICON_ERROR).ShowModal() self.db.settings.pop(user) # self.nb.DeletePage(self.db.settings["buffers"].index(user)) self.db.settings["buffers"].remove(user) else: self.nb.InsertSubPage(self.db.settings["buffers"].index("timelines"), st, _(u"Timeline for %s") % (user)) st.put_items(num) st.sound = "tweet_timeline.ogg" self.stream2.disconnect() del self.stream2 self.get_tls() dlg.Destroy() def favs_timeline(self, ev=None): dlg = dialogs.utils.selectUserDialog(self, _(u"List of favourites")) if dlg.ShowModal() == wx.ID_OK: user = twitter.utils.if_user_exists(self.twitter.twitter, dlg.cb.GetValue()) if user == None: wx.MessageDialog(None, _(u"The user does not exist"), _(u"Error"), wx.ICON_ERROR).ShowModal() dlg.Destroy() return if user not in config.main["other_buffers"]["favourites_timelines"]: config.main["other_buffers"]["favourites_timelines"].append(user) else: wx.MessageDialog(None, _(u"There's already a list of favourites for this user. You can't create another."), _(u"Existing list"), wx.ICON_ERROR).ShowModal() dlg.Destroy() return sound.player.play("create_timeline.ogg") st = buffers.favsPanel(self.nb, self, user+"-favs", argumento=user, sound="favourites_timeline_updated.ogg") self.nb.InsertSubPage(self.db.settings["buffers"].index("favourites_timelines"), st, _(u"Favourites for %s") % (user)) num = st.start_streams() self.db.settings["buffers"].append(user+"-favs") if num == 0: wx.MessageDialog(None, _(u"This user has no favourites. You can't create a list of favourites for this user."), _(u"Error!"), wx.ICON_ERROR).ShowModal() self.db.settings.pop(user+"-favs") self.nb.DeletePage(self.db.settings["buffers"].index(user+"-favs")) self.db.settings["buffers"].remove(user+"-favs") st.put_items(num) dlg.Destroy() def onAbout(self, ev=None): info = wx.AboutDialogInfo() info.SetName(application.name) info.SetVersion(application.version) info.SetDescription(application.description) info.SetCopyright(application.copyright) info.SetTranslators(application.translators) # info.SetLicence(application.licence) info.AddDeveloper(application.author) wx.AboutBox(info) def delete_buffer(self, ev=None): pos = self.nb.GetCurrentPage().remove_buffer() if pos != None: self.stream2.disconnect() del self.stream2 self.nb.DeletePage(self.nb.GetSelection()) sound.player.play("delete_timeline.ogg") self.get_tls() def delete_invalid_timeline(self): pos = self.nb.GetCurrentPage().remove_invalid_buffer() if pos != None: self.nb.DeletePage(self.nb.GetSelection()) ### Hidden Window def left(self, event=None): num = self.nb.GetSelection() if num == 0: self.nb.ChangeSelection(self.nb.GetPageCount()-1) else: self.nb.SetSelection(num-1) while self.nb.GetCurrentPage().type == "account" or self.nb.GetCurrentPage().type == "empty": self.skip_blank_pages(False) try: msg = _(u"%s, %s of %s") % (self.nb.GetPageText(self.nb.GetSelection()), self.nb.GetCurrentPage().list.get_selected()+1, self.nb.GetCurrentPage().list.get_count()) except: msg = _(u"%s. Empty") % (self.nb.GetPageText(self.nb.GetSelection())) output.speak(msg, 1) if self.showing == True: self.nb.GetCurrentPage().list.list.SetFocus() def right(self, event=None): num = self.nb.GetSelection() if num+1 == self.nb.GetPageCount(): self.nb.SetSelection(0) else: self.nb.SetSelection(num+1) while self.nb.GetCurrentPage().type == "account" or self.nb.GetCurrentPage().type == "empty": self.skip_blank_pages(True) try: msg = _(u"%s, %s of %s") % (self.nb.GetPageText(self.nb.GetSelection()), self.nb.GetCurrentPage().list.get_selected()+1, self.nb.GetCurrentPage().list.get_count()) except: msg = _(u"%s. Empty") % (self.nb.GetPageText(self.nb.GetSelection())) output.speak(msg, 1) if self.showing == True: self.nb.GetCurrentPage().list.list.SetFocus() def create_invisible_keyboard_shorcuts(self): keymap = {} for i in config.main["keymap"]: if hasattr(self, i): keymap[config.main["keymap"][i]] = getattr(self, i) return keymap def register_invisible_keyboard_shorcuts(self, keymap): self.keyboard_handler = WXKeyboardHandler(self) self.keyboard_handler.register_keys(keymap) def unregister_invisible_keyboard_shorcuts(self, keymap): try: self.keyboard_handler.unregister_keys(keymap) del self.keyboard_handler except AttributeError: pass def show_hide(self, ev=None): km = self.create_invisible_keyboard_shorcuts() if self.showing == True: if config.main["general"]["use_invisible_keyboard_shorcuts"] == False: self.register_invisible_keyboard_shorcuts(km) self.Hide() self.showing = False else: if config.main["general"]["use_invisible_keyboard_shorcuts"] == False: self.unregister_invisible_keyboard_shorcuts(km) self.Show() self.showing = True def toggle_global_mute(self, event=None): if config.main["sound"]["global_mute"] == False: config.main["sound"]["global_mute"] = True output.speak(_(u"Global mute on")) elif config.main["sound"]["global_mute"] == True: config.main["sound"]["global_mute"] = False output.speak(_(u"Global mute off")) def toggle_mute(self, event=None): buffer = self.nb.GetCurrentPage().name_buffer if buffer not in config.main["other_buffers"]["muted_buffers"]: config.main["other_buffers"]["muted_buffers"].append(buffer) output.speak(_(u"Buffer mute on")) elif buffer in config.main["other_buffers"]["muted_buffers"]: config.main["other_buffers"]["muted_buffers"].remove(buffer) output.speak(_(u"Buffer mute off")) def toggle_autoread(self, event=None): buffer = self.nb.GetCurrentPage().name_buffer if buffer not in config.main["other_buffers"]["autoread_buffers"]: config.main["other_buffers"]["autoread_buffers"].append(buffer) output.speak(_(u"The auto-reading of new tweets is enabled for this buffer")) elif buffer in config.main["other_buffers"]["autoread_buffers"]: config.main["other_buffers"]["autoread_buffers"].remove(buffer) output.speak(_(u"The auto-reading of new tweets is disabled for this buffer")) def repeat_item(self): output.speak(self.nb.GetCurrentPage().get_message(), 1) def copy_to_clipboard(self, event=None): output.Copy(self.nb.GetCurrentPage().get_message()) output.speak(_(u"Copied")) def clear_list(self, event=None): self.nb.GetCurrentPage().interact("clear_list") def conversation_up(self, evt=None): if config.main["general"]["reverse_timelines"] == True and evt == None: self.conversation_down("down") return id = self.db.settings[self.nb.GetCurrentPage().name_buffer][self.nb.GetCurrentPage().list.get_selected()]["in_reply_to_status_id_str"] pos = twitter.utils.find_previous_reply(id, self.db.settings["home_timeline"]) if pos != None: self.nb.ChangeSelection(1) self.nb.GetCurrentPage().list.select_item(pos) msg = _(u"%s") % (self.nb.GetCurrentPage().get_message()) output.speak(msg) def conversation_down(self, evt=None): if config.main["general"]["reverse_timelines"] == True and evt == None: self.conversation_up("up") return id = self.db.settings[self.nb.GetCurrentPage().name_buffer][self.nb.GetCurrentPage().list.get_selected()]["id_str"] # pos = twitter.utils.find_next_reply(id, self.db.settings["home_timeline"]) pos = twitter.utils.find_next_reply(id, self.db.settings["home_timeline"]) if pos != None: self.nb.ChangeSelection(1) self.nb.GetCurrentPage().list.select_item(pos) msg = _(u"%s") % (self.nb.GetCurrentPage().get_message()) output.speak(msg) def go_home(self): self.nb.GetCurrentPage().list.select_item(0) try: output.speak(self.nb.GetCurrentPage().get_message(), 1) except: pass def go_end(self): self.nb.GetCurrentPage().list.select_item(self.nb.GetCurrentPage().list.get_count()-1) try: output.speak(self.nb.GetCurrentPage().get_message(), 1) except: pass def go_page_up(self): if self.nb.GetCurrentPage().list.get_selected <= 20: index = 0 else: index = self.nb.GetCurrentPage().list.get_selected() - 20 self.nb.GetCurrentPage().list.select_item(index) try: output.speak(self.nb.GetCurrentPage().get_message(), 1) except: pass def go_page_down(self): if self.nb.GetCurrentPage().list.get_selected() >= self.nb.GetCurrentPage().list.get_count() - 20: index = self.nb.GetCurrentPage().list.get_count()-1 else: index = self.nb.GetCurrentPage().list.get_selected() + 20 self.nb.GetCurrentPage().list.select_item(index) try: output.speak(self.nb.GetCurrentPage().get_message(), 1) except: pass def volume_up(self): self.nb.GetCurrentPage().interact("volume_up") def volume_down(self): self.nb.GetCurrentPage().interact("volume_down") def url(self): self.nb.GetCurrentPage().interact("url") def audio(self): self.nb.GetCurrentPage().interact("audio") def up(self, event=None): pos = self.nb.GetCurrentPage().list.get_selected() index = self.nb.GetCurrentPage().list.get_selected()-1 try: self.nb.GetCurrentPage().list.select_item(index) except: pass if pos == self.nb.GetCurrentPage().list.get_selected(): sound.player.play("limit.ogg", False) try: output.speak(self.nb.GetCurrentPage().get_message(), 1) except: pass def down(self, event=None): index = self.nb.GetCurrentPage().list.get_selected()+1 pos = self.nb.GetCurrentPage().list.get_selected() try: self.nb.GetCurrentPage().list.select_item(index) except: pass if pos == self.nb.GetCurrentPage().list.get_selected(): sound.player.play("limit.ogg", False) try: output.speak(self.nb.GetCurrentPage().get_message(), 1) except: pass def get_more_items(self, event=None): self.nb.GetCurrentPage().get_more_items() def search_buffer(self, buffer_type=None, name_buffer=None): page = None for i in range(0, self.nb.GetPageCount()): page = self.nb.GetPage(i) if page.type != buffer_type: continue if page.name_buffer == name_buffer: return page return page def switch_account(self, ev): switchModule.switcher(self) def reverse_geocode(self, event=None): try: tweet = self.nb.GetCurrentPage().get_tweet() if tweet["coordinates"] != None: x = tweet["coordinates"]["coordinates"][0] y = tweet["coordinates"]["coordinates"][1] address = geocoder.reverse_geocode(y, x) if event == None: output.speak(address[0].__str__().decode("utf-8")) else: wx.MessageDialog(self, address[0].__str__().decode("utf-8"), _(u"Address"), wx.OK).ShowModal() else: output.speak(_(u"There are no coordinates in this tweet")) except GeocoderError: output.speak(_(u"There are no results for the coordinates in this tweet")) except ValueError: output.speak(_(u"Error decoding coordinates. Try again later.")) except KeyError: pass def view_reverse_geocode(self, event=None): try: tweet = self.nb.GetCurrentPage().get_tweet() if tweet["coordinates"] != None: x = tweet["coordinates"]["coordinates"][0] y = tweet["coordinates"]["coordinates"][1] address = geocoder.reverse_geocode(y, x) dialogs.message.viewNonTweet(address[0].__str__().decode("utf-8")).ShowModal() else: output.speak(_(u"There are no coordinates in this tweet")) except GeocoderError: output.speak(_(u"There are no results for the coordinates in this tweet")) except ValueError: output.speak(_(u"Error decoding coordinates. Try again later.")) except KeyError: pass def get_trending_topics(self, event=None): info = self.twitter.twitter.get_available_trends() trendingDialog = dialogs.trending.trendingTopicsDialog(info) if trendingDialog.ShowModal() == wx.ID_OK: if trendingDialog.country.GetValue() == True: woeid = trendingDialog.countries[trendingDialog.location.GetStringSelection()] elif trendingDialog.city.GetValue() == True: woeid = trendingDialog.cities[trendingDialog.location.GetStringSelection()] buff = buffers.trendsPanel(self.nb, self, "%s_tt" % (woeid,), argumento=woeid, sound="trends_updated.ogg") self.nb.InsertSubPage(self.db.settings["buffers"].index(self.db.settings["user_name"]), buff, _(u"Trending topics for %s") % (trendingDialog.location.GetStringSelection(),)) timer = RepeatingTimer(300, buff.start_streams) timer.start() num = buff.start_streams() config.main["other_buffers"]["trending_topic_buffers"].append(woeid) buff.put_items(num) def listen_streamerror(self): log.error("There is a connection error") if hasattr(self, "stream"): self.stream.disconnect() del self.stream if hasattr(self, "stream2"): self.stream2.disconnect() del self.stream2 def listen_for_friends(self): self.stream2.set_friends(self.stream.friends) ### Close App def Destroy(self): self.sysTray.Destroy() super(mainFrame, self).Destroy()