diff --git a/src/app-configuration.defaults b/src/app-configuration.defaults index 20eaa671..025eabd8 100644 --- a/src/app-configuration.defaults +++ b/src/app-configuration.defaults @@ -28,7 +28,7 @@ send_dm = string(default="control+win+d") add_to_favourites = string(default="alt+win+f") remove_from_favourites = string(default="alt+shift+win+f") follow = string(default="control+win+s") -details = string(default="control+win+alt+n") +user_details = string(default="control+win+alt+n") view_item = string(default="control+win+v") exit = string(default="control+win+f4") open_timeline = string(default="control+win+i") diff --git a/src/controller/buffersController.py b/src/controller/buffersController.py index d51dd322..daa88d68 100644 --- a/src/controller/buffersController.py +++ b/src/controller/buffersController.py @@ -7,7 +7,7 @@ import output import config import sound import messages -import updateProfile +import user import languageHandler import logging from twitter import compose, utils @@ -415,6 +415,19 @@ class baseBufferController(bufferController): except TwythonError: self.session.sound.play("error.ogg") + @_tweets_exist + def user_details(self): + tweet = self.get_tweet() + if self.type == "dm": + users = utils.get_all_users(tweet, self.session.db) + elif self.type == "people": + users = [tweet["screen_name"]] + else: + users = utils.get_all_users(tweet, self.session.db) + dlg = dialogs.utils.selectUserDialog(title=_(u"User details"), users=users) + if dlg.get_response() == widgetUtils.OK: + user.profileController(session=self.session, user=dlg.get_user()) + class eventsBufferController(bufferController): def __init__(self, parent, name, session, account, *args, **kwargs): super(eventsBufferController, self).__init__(parent, *args, **kwargs) @@ -545,7 +558,7 @@ class peopleBufferController(baseBufferController): self.buffer.list.clear() def url(self): - updateProfile.updateProfileController(self.session, user=self.get_right_tweet()["screen_name"]) + user.profileController(self.session, user=self.get_right_tweet()["screen_name"]) class searchBufferController(baseBufferController): def start_stream(self): diff --git a/src/controller/mainController.py b/src/controller/mainController.py index de18c7ab..61e6ea55 100644 --- a/src/controller/mainController.py +++ b/src/controller/mainController.py @@ -28,7 +28,7 @@ if platform.system() == "Windows": from keyboard_handler.wx_handler import WXKeyboardHandler import userActionsController import trendingTopics -import updateProfile +import user import webbrowser log = logging.getLogger("mainController") @@ -151,6 +151,7 @@ class Controller(object): widgetUtils.connect_event(self.view, widgetUtils.MENU, self.edit_keystrokes, menuitem=self.view.keystroke_editor) widgetUtils.connect_event(self.view, widgetUtils.MENU, self.manage_accounts, self.view.manage_accounts) widgetUtils.connect_event(self.view, widgetUtils.MENU, self.update_profile, menuitem=self.view.updateProfile) + widgetUtils.connect_event(self.view, widgetUtils.MENU, self.user_details, menuitem=self.view.details) widgetUtils.connect_event(self.view.nb, widgetUtils.NOTEBOOK_PAGE_CHANGED, self.buffer_changed) def __init__(self): @@ -1073,7 +1074,13 @@ class Controller(object): session_.sessions.pop(i) def update_profile(self, *args, **kwargs): - r = updateProfile.updateProfileController(self.get_best_buffer().session) + r = user.profileController(self.get_best_buffer().session) + + def user_details(self, *args, **kwargs): + buffer = self.get_current_buffer() + if not hasattr(buffer, "session") or buffer.session == None: return + if hasattr(buffer, "user_details"): + buffer.user_details() def __del__(self): config.app.write() \ No newline at end of file diff --git a/src/controller/updateProfile.py b/src/controller/updateProfile.py deleted file mode 100644 index ee46156e..00000000 --- a/src/controller/updateProfile.py +++ /dev/null @@ -1,67 +0,0 @@ -# -*- coding: utf-8 -*- -import widgetUtils -import output -from wxUI.dialogs import update_profile -from twython import TwythonError - -class updateProfileController(object): - def __init__(self, session, user=None): - super(updateProfileController, self).__init__() - self.file = None - self.session = session - self.user = user - self.dialog = update_profile.updateProfileDialog() - if user == None: - self.get_data(screen_name=self.session.db["user_name"]) - self.uploaded = False - widgetUtils.connect_event(self.dialog.upload_image, widgetUtils.BUTTON_PRESSED, self.upload_image) - else: - self.get_data(screen_name=self.user) - self.dialog.set_readonly() - if self.dialog.get_response() == widgetUtils.OK and self.user == None: - self.do_update() - - - def get_data(self, screen_name): - data = self.session.twitter.twitter.show_user(screen_name=screen_name) - self.dialog.set_name(data["name"]) - if data["url"] != None: - self.dialog.set_url(data["url"]) - if len(data["location"]) > 0: - self.dialog.set_location(data["location"]) - if len(data["description"]) > 0: - self.dialog.set_description(data["description"]) - - def get_image(self): - file = self.dialog.upload_picture() - if file != None: - self.file = open(file, "rb") - self.uploaded = True - self.dialog.change_upload_button(self.uploaded) - - def discard_image(self): - self.file = None - output.speak(_(u"Discarded")) - self.uploaded = False - self.dialog.change_upload_button(self.uploaded) - - def upload_image(self, *args, **kwargs): - if self.uploaded == False: - self.get_image() - elif self.uploaded == True: - self.discard_image() - - def do_update(self): - name = self.dialog.get("name") - description = self.dialog.get("description") - location = self.dialog.get("location") - url = self.dialog.get("url") - if self.file != None: - try: - self.session.twitter.twitter.update_profile_image(image=self.file) - except TwythonError as e: - output.speak(u"Error %s. %s" % (e.error_code, e.msg)) - try: - self.session.twitter.twitter.update_profile(name=name, description=description, location=location, url=url) - except TwythonError as e: - output.speak(u"Error %s. %s" % (e.error_code, e.msg)) \ No newline at end of file diff --git a/src/controller/user.py b/src/controller/user.py new file mode 100644 index 00000000..e4494f69 --- /dev/null +++ b/src/controller/user.py @@ -0,0 +1,99 @@ +# -*- coding: utf-8 -*- +import webbrowser +import widgetUtils +import output +from wxUI.dialogs import update_profile, show_user +from twython import TwythonError + +class profileController(object): + def __init__(self, session, user=None): + super(profileController, self).__init__() + self.file = None + self.session = session + self.user = user + if user == None: + self.dialog = update_profile.updateProfileDialog() + self.get_data(screen_name=self.session.db["user_name"]) + self.fill_profile_fields() + self.uploaded = False + widgetUtils.connect_event(self.dialog.upload_image, widgetUtils.BUTTON_PRESSED, self.upload_image) + else: + self.dialog = show_user.showUserProfile() + self.get_data(screen_name=self.user) + string = self.get_user_info() + self.dialog.set("text", string) + self.dialog.set_title(_(u"Information for %s") % (self.data["screen_name"])) + if self.data["url"] != None: + self.dialog.enable_url() + widgetUtils.connect_event(self.dialog.url, widgetUtils.BUTTON_PRESSED, self.visit_url) + if self.dialog.get_response() == widgetUtils.OK and self.user == None: + self.do_update() + + def get_data(self, screen_name): + self.data = self.session.twitter.twitter.show_user(screen_name=screen_name) + + def fill_profile_fields(self): + self.dialog.set_name(self.data["name"]) + if self.data["url"] != None: + self.dialog.set_url(self.data["url"]) + if len(self.data["location"]) > 0: + self.dialog.set_location(self.data["location"]) + if len(self.data["description"]) > 0: + self.dialog.set_description(self.data["description"]) + + def get_image(self): + file = self.dialog.upload_picture() + if file != None: + self.file = open(file, "rb") + self.uploaded = True + self.dialog.change_upload_button(self.uploaded) + + def discard_image(self): + self.file = None + output.speak(_(u"Discarded")) + self.uploaded = False + self.dialog.change_upload_button(self.uploaded) + + def upload_image(self, *args, **kwargs): + if self.uploaded == False: + self.get_image() + elif self.uploaded == True: + self.discard_image() + + def do_update(self): + if self.user != None: return + name = self.dialog.get("name") + description = self.dialog.get("description") + location = self.dialog.get("location") + url = self.dialog.get("url") + if self.file != None: + try: + self.session.twitter.twitter.update_profile_image(image=self.file) + except TwythonError as e: + output.speak(u"Error %s. %s" % (e.error_code, e.msg)) + try: + self.session.twitter.twitter.update_profile(name=name, description=description, location=location, url=url) + except TwythonError as e: + output.speak(u"Error %s. %s" % (e.error_code, e.msg)) + + def get_user_info(self): + + string = u"" + string = string + _(u"Username: @%s\n") % (self.data["screen_name"]) + string = string + _(u"Name: %s\n") % (self.data["name"]) + if self.data["location"] != "": + string = string + _(u"Location: %s\n") % (self.data["location"]) + if self.data["url"] != None: + string = string+ _(u"URL: %s\n") % (self.data["url"]) + if self.data["description"] != "": + string = string+ _(u"Bio: %s\n") % (self.data["description"]) + if self.data["protected"] == True: protected = _(u"Yes") + else: protected = _(u"No") + string = string+ _(u"Protected: %s\n") % (protected) + string = string+_(u"Followers: %s\n Friends: %s\n") % (self.data["followers_count"], self.data["friends_count"]) + string = string+ _(u"Tweets: %s\n") % (self.data["statuses_count"]) + string = string+ _(u"Favourites: %s") % (self.data["favourites_count"]) + return string + + def visit_url(self, *args, **kwargs): + webbrowser.open_new_tab(self.data["url"]) \ No newline at end of file diff --git a/src/keystrokeEditor/constants.py b/src/keystrokeEditor/constants.py index d5968f86..1bbc44d8 100644 --- a/src/keystrokeEditor/constants.py +++ b/src/keystrokeEditor/constants.py @@ -17,7 +17,7 @@ actions = { "add_to_favourites": _(u"Mark as favourite"), "remove_from_favourites": _(u"Remove from favourites"), "follow": _(u"Open the actions dialogue"), -"details": _(u"See user details"), +"user_details": _(u"See user details"), "view_item": _(u"Show tweet"), "exit": _(u"Quit"), "open_timeline": _(u"Open user timeline"), diff --git a/src/wxUI/dialogs/__init__.py b/src/wxUI/dialogs/__init__.py index 47d00ab9..6e018d3c 100644 --- a/src/wxUI/dialogs/__init__.py +++ b/src/wxUI/dialogs/__init__.py @@ -1 +1 @@ -import baseDialog, trends, configuration, lists, message, search, show_user, update_profile, urlList, userSelection +import baseDialog, trends, configuration, lists, message, search, show_user, update_profile, urlList, userSelection, utils diff --git a/src/wxUI/dialogs/baseDialog.py b/src/wxUI/dialogs/baseDialog.py index aa1ad33f..b48a194b 100644 --- a/src/wxUI/dialogs/baseDialog.py +++ b/src/wxUI/dialogs/baseDialog.py @@ -23,3 +23,6 @@ class BaseWXDialog(wx.Dialog): elif hasattr(control, "ChangeValue"): return getattr(control, "ChangeValue")(text) else: return -1 else: return 0 + + def set_title(self, title): + self.SetTitle(title) diff --git a/src/wxUI/dialogs/show_user.py b/src/wxUI/dialogs/show_user.py index cfe7b191..ecc601a2 100644 --- a/src/wxUI/dialogs/show_user.py +++ b/src/wxUI/dialogs/show_user.py @@ -1,17 +1,17 @@ # -*- coding: utf-8 -*- import wx +import baseDialog -class showUserProfile(wx.Dialog): - def __init__(self, screen_name): - super(showUserProfile, self).__init__(self, None, -1) - self.SetTitle(_(u"Information for %s") % (screen_name)) +class showUserProfile(baseDialog.BaseWXDialog): + def __init__(self): + super(showUserProfile, self).__init__(parent=None, id=wx.NewId()) panel = wx.Panel(self) sizer = wx.BoxSizer(wx.VERTICAL) static = wx.StaticText(panel, -1, _(u"Details")) sizer.Add(static, 0, wx.ALL, 5) - text = wx.TextCtrl(panel, -1, style=wx.TE_MULTILINE|wx.TE_READONLY) - text.SetFocus() - sizer.Add(text, 0, wx.ALL|wx.EXPAND, 5) + self.text = wx.TextCtrl(panel, -1, style=wx.TE_MULTILINE|wx.TE_READONLY, size=(350, 250)) + self.text.SetFocus() + sizer.Add(self.text, 0, wx.ALL|wx.EXPAND, 5) self.url = wx.Button(panel, -1, _(u"Go to URL"), size=wx.DefaultSize) self.url.Disable() close = wx.Button(panel, wx.ID_CANCEL, _(u"Close")) @@ -19,10 +19,8 @@ class showUserProfile(wx.Dialog): btnSizer.Add(self.url, 0, wx.ALL, 5) btnSizer.Add(close, 0, wx.ALL, 5) sizer.Add(btnSizer, 0, wx.ALL, 5) - text.ChangeValue(self.compose_string()) - text.SetSize(text.GetBestSize()) panel.SetSizer(sizer) self.SetClientSize(sizer.CalcMin()) - def get_response(self): - return self.ShowModal() \ No newline at end of file + def enable_url(self, enabled=True): + self.url.Enable(enabled) \ No newline at end of file diff --git a/src/wxUI/dialogs/utils.py b/src/wxUI/dialogs/utils.py new file mode 100644 index 00000000..eaf75e5e --- /dev/null +++ b/src/wxUI/dialogs/utils.py @@ -0,0 +1,46 @@ +# -*- coding: utf-8 -*- +############################################################ +# Copyright (c) 2013, 2014 Manuel Eduardo Cortéz Vallejo +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# +############################################################ +import wx +import baseDialog + +class selectUserDialog(baseDialog.BaseWXDialog): + def __init__(self, title, users): + super(selectUserDialog, self).__init__(parent=None, id=wx.NewId(), title=title) + panel = wx.Panel(self) + userSizer = wx.BoxSizer() + self.cb = wx.ComboBox(panel, -1, choices=users, value=users[0], size=wx.DefaultSize) + self.cb.SetFocus() + userSizer.Add(wx.StaticText(panel, -1, _(u"User")), 0, wx.ALL, 5) + userSizer.Add(self.cb) + sizer = wx.BoxSizer(wx.VERTICAL) + ok = wx.Button(panel, wx.ID_OK, _(u"OK")) + ok.SetDefault() +# ok.Bind(wx.EVT_BUTTON, self.onok) + cancel = wx.Button(panel, wx.ID_CANCEL, _(u"Close")) + btnsizer = wx.BoxSizer() + btnsizer.Add(ok, 0, wx.ALL, 5) + btnsizer.Add(cancel, 0, wx.ALL, 5) + sizer.Add(userSizer, 0, wx.ALL, 5) + sizer.Add(btnsizer, 0, wx.ALL, 5) + panel.SetSizer(sizer) + self.SetClientSize(sizer.CalcMin()) + + def get_user(self): + return self.cb.GetValue() + diff --git a/src/wxUI/view.py b/src/wxUI/view.py index c4b9847e..8d41171a 100644 --- a/src/wxUI/view.py +++ b/src/wxUI/view.py @@ -18,7 +18,7 @@ class mainFrame(wx.Frame): self.menuitem_search = app.Append(wx.NewId(), _(u"&Search")) self.trends = app.Append(wx.NewId(), _(u"View &trending topics")) self.lists = app.Append(wx.NewId(), _(u"&Lists manager")) - self.lists.Enable(True) + self.lists.Enable(False) self.sounds_tutorial = app.Append(wx.NewId(), _(u"Sounds &tutorial")) self.keystroke_editor = app.Append(wx.NewId(), _(u"&Edit keystrokes")) self.account_settings = app.Append(wx.NewId(), _(u"Account se&ttings")) @@ -53,7 +53,6 @@ class mainFrame(wx.Frame): self.viewLists = user.Append(wx.NewId(), _(u"&View lists")) self.viewLists.Enable(False) self.details = user.Append(wx.NewId(), _(u"Show user &profile")) - self.details.Enable(False) self.timeline = user.Append(wx.NewId(), _(u"&Timeline")) self.timeline.Enable(False) self.favs = user.Append(wx.NewId(), _(u"V&iew favourites"))