mirror of
https://github.com/MCV-Software/TWBlue.git
synced 2024-11-29 22:23:12 -06:00
Merge pull request #547 from Arfs6/create_update_profile
Create update profile
This commit is contained in:
commit
1963c13b48
@ -116,6 +116,7 @@ class Controller(object):
|
|||||||
# connect application events to GUI
|
# connect application events to GUI
|
||||||
widgetUtils.connect_event(self.view, widgetUtils.CLOSE_EVENT, self.exit_)
|
widgetUtils.connect_event(self.view, widgetUtils.CLOSE_EVENT, self.exit_)
|
||||||
widgetUtils.connect_event(self.view, widgetUtils.MENU, self.show_hide, menuitem=self.view.show_hide)
|
widgetUtils.connect_event(self.view, widgetUtils.MENU, self.show_hide, menuitem=self.view.show_hide)
|
||||||
|
widgetUtils.connect_event(self.view, widgetUtils.MENU, self.update_profile, menuitem=self.view.updateProfile)
|
||||||
widgetUtils.connect_event(self.view, widgetUtils.MENU, self.search, menuitem=self.view.menuitem_search)
|
widgetUtils.connect_event(self.view, widgetUtils.MENU, self.search, menuitem=self.view.menuitem_search)
|
||||||
# widgetUtils.connect_event(self.view, widgetUtils.MENU, self.list_manager, menuitem=self.view.lists)
|
# widgetUtils.connect_event(self.view, widgetUtils.MENU, self.list_manager, menuitem=self.view.lists)
|
||||||
widgetUtils.connect_event(self.view, widgetUtils.MENU, self.find, menuitem=self.view.find)
|
widgetUtils.connect_event(self.view, widgetUtils.MENU, self.find, menuitem=self.view.find)
|
||||||
@ -1085,3 +1086,11 @@ class Controller(object):
|
|||||||
"""Redirects the user to the issue page on github"""
|
"""Redirects the user to the issue page on github"""
|
||||||
log.debug("Redirecting the user to report an error...")
|
log.debug("Redirecting the user to report an error...")
|
||||||
webbrowser.open_new_tab(application.report_bugs_url)
|
webbrowser.open_new_tab(application.report_bugs_url)
|
||||||
|
|
||||||
|
def update_profile(self, *args):
|
||||||
|
"""Updates the users profile"""
|
||||||
|
log.debug("Update profile")
|
||||||
|
buffer = self.get_best_buffer()
|
||||||
|
handler = self.get_handler(buffer.session.type)
|
||||||
|
if handler:
|
||||||
|
handler.update_profile(buffer.session)
|
||||||
|
@ -4,10 +4,13 @@ import logging
|
|||||||
import output
|
import output
|
||||||
from pubsub import pub
|
from pubsub import pub
|
||||||
from mysc import restart
|
from mysc import restart
|
||||||
|
from mysc.thread_utils import call_threaded
|
||||||
from wxUI.dialogs.mastodon import search as search_dialogs
|
from wxUI.dialogs.mastodon import search as search_dialogs
|
||||||
from wxUI.dialogs.mastodon import dialogs
|
from wxUI.dialogs.mastodon import dialogs
|
||||||
from wxUI.dialogs import userAliasDialogs
|
from wxUI.dialogs import userAliasDialogs
|
||||||
from wxUI import commonMessageDialogs
|
from wxUI import commonMessageDialogs
|
||||||
|
from wxUI.dialogs.mastodon import updateProfile as update_profile_dialogs
|
||||||
|
from sessions.mastodon.utils import html_filter
|
||||||
from . import userActions, settings
|
from . import userActions, settings
|
||||||
|
|
||||||
log = logging.getLogger("controller.mastodon.handler")
|
log = logging.getLogger("controller.mastodon.handler")
|
||||||
@ -20,7 +23,7 @@ class Handler(object):
|
|||||||
# empty names mean the item will be Disabled.
|
# empty names mean the item will be Disabled.
|
||||||
self.menus = dict(
|
self.menus = dict(
|
||||||
# In application menu.
|
# In application menu.
|
||||||
updateProfile=None,
|
updateProfile=_("Update Profile"),
|
||||||
menuitem_search=_("&Search"),
|
menuitem_search=_("&Search"),
|
||||||
lists=None,
|
lists=None,
|
||||||
manageAliases=_("Manage user aliases"),
|
manageAliases=_("Manage user aliases"),
|
||||||
@ -255,3 +258,33 @@ class Handler(object):
|
|||||||
buffer.session.settings.write()
|
buffer.session.settings.write()
|
||||||
output.speak(_("Alias has been set correctly for {}.").format(user))
|
output.speak(_("Alias has been set correctly for {}.").format(user))
|
||||||
pub.sendMessage("alias-added")
|
pub.sendMessage("alias-added")
|
||||||
|
|
||||||
|
def update_profile(self, session):
|
||||||
|
"""Updates the users dialog"""
|
||||||
|
profile = session.api.me()
|
||||||
|
data = {
|
||||||
|
'display_name': profile.display_name,
|
||||||
|
'note': html_filter(profile.note),
|
||||||
|
'header': profile.header,
|
||||||
|
'avatar': profile.avatar,
|
||||||
|
'fields': [(field.name, html_filter(field.value)) for field in profile.fields],
|
||||||
|
'locked': profile.locked,
|
||||||
|
'bot': profile.bot,
|
||||||
|
# discoverable could be None, set it to False
|
||||||
|
'discoverable': profile.discoverable if profile.discoverable else False,
|
||||||
|
}
|
||||||
|
log.debug(f"arafat {data['fields']}")
|
||||||
|
dialog = update_profile_dialogs.UpdateProfileDialog(**data)
|
||||||
|
if dialog.ShowModal() != wx.ID_OK:
|
||||||
|
log.debug("User canceled dialog")
|
||||||
|
return
|
||||||
|
updated_data = dialog.data
|
||||||
|
if updated_data == data:
|
||||||
|
log.debug("No profile info was changed.")
|
||||||
|
return
|
||||||
|
# remove data that hasn't been updated
|
||||||
|
for key in data:
|
||||||
|
if data[key] == updated_data[key]:
|
||||||
|
del updated_data[key]
|
||||||
|
log.debug(f"Updating users profile with: {updated_data}")
|
||||||
|
call_threaded(session.api_call, "account_update_credentials", _("Update profile"), report_success=True, **updated_data)
|
||||||
|
204
src/wxUI/dialogs/mastodon/updateProfile.py
Normal file
204
src/wxUI/dialogs/mastodon/updateProfile.py
Normal file
@ -0,0 +1,204 @@
|
|||||||
|
import os
|
||||||
|
import requests
|
||||||
|
from io import BytesIO
|
||||||
|
|
||||||
|
import wx
|
||||||
|
|
||||||
|
|
||||||
|
def return_true():
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
class UpdateProfileDialog(wx.Dialog):
|
||||||
|
"""
|
||||||
|
A dialog for user to update his / her profile details.
|
||||||
|
layout is:
|
||||||
|
```
|
||||||
|
header
|
||||||
|
avatar
|
||||||
|
name
|
||||||
|
bio
|
||||||
|
meta data
|
||||||
|
```
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, display_name: str, note: str, header: str, avatar: str, fields: list, locked: bool, bot: bool, discoverable: bool):
|
||||||
|
"""Initialize update profile dialog
|
||||||
|
Parameters:
|
||||||
|
- display_name: The user's display name to show in the display name field
|
||||||
|
- note: The users bio to show in the bio field
|
||||||
|
- header: the users header pic link
|
||||||
|
- avatar: The users avatar pic link
|
||||||
|
"""
|
||||||
|
super().__init__(parent=None)
|
||||||
|
self.SetTitle(_("Update Profile"))
|
||||||
|
self.header = header
|
||||||
|
self.avatar = avatar
|
||||||
|
|
||||||
|
panel = wx.Panel(self)
|
||||||
|
sizer = wx.BoxSizer(wx.VERTICAL)
|
||||||
|
|
||||||
|
# create widgets
|
||||||
|
display_name_label = wx.StaticText(panel, label=_("Display Name"))
|
||||||
|
self.display_name = wx.TextCtrl(panel, value=display_name, style= wx.TE_PROCESS_ENTER, size=(200, 30))
|
||||||
|
name_sizer = wx.BoxSizer(wx.HORIZONTAL)
|
||||||
|
name_sizer.Add(display_name_label, wx.SizerFlags().Center())
|
||||||
|
name_sizer.Add(self.display_name, wx.SizerFlags().Center())
|
||||||
|
sizer.Add(name_sizer, wx.CENTER)
|
||||||
|
|
||||||
|
bio_label = wx.StaticText(panel, label=_("Bio"))
|
||||||
|
self.bio = wx.TextCtrl(panel, value=note, style=wx.TE_PROCESS_ENTER | wx.TE_MULTILINE, size=(400, 60))
|
||||||
|
bio_sizer = wx.BoxSizer(wx.HORIZONTAL)
|
||||||
|
bio_sizer.Add(bio_label, wx.SizerFlags().Center())
|
||||||
|
bio_sizer.Add(self.bio, wx.SizerFlags().Center())
|
||||||
|
sizer.Add(bio_sizer, wx.CENTER)
|
||||||
|
|
||||||
|
# header
|
||||||
|
header_label = wx.StaticText(panel, label=_("Header"))
|
||||||
|
try:
|
||||||
|
response = requests.get(self.header)
|
||||||
|
except requests.exceptions.RequestException:
|
||||||
|
# Create empty image
|
||||||
|
self.header_image = wx.StaticBitmap()
|
||||||
|
else:
|
||||||
|
image_bytes = BytesIO(response.content)
|
||||||
|
image = wx.Image(image_bytes, wx.BITMAP_TYPE_ANY)
|
||||||
|
image.Rescale(300, 100, wx.IMAGE_QUALITY_HIGH)
|
||||||
|
self.header_image = wx.StaticBitmap(panel, bitmap=image.ConvertToBitmap())
|
||||||
|
|
||||||
|
self.header_image.AcceptsFocusFromKeyboard = return_true
|
||||||
|
self.change_header = wx.Button(panel, label=_("Change header"))
|
||||||
|
header_sizer = wx.BoxSizer(wx.HORIZONTAL)
|
||||||
|
header_sizer.Add(header_label, wx.SizerFlags().Center())
|
||||||
|
header_sizer.Add(self.header_image, wx.SizerFlags().Center())
|
||||||
|
header_sizer.Add(self.change_header, wx.SizerFlags().Center())
|
||||||
|
sizer.Add(header_sizer, wx.CENTER)
|
||||||
|
|
||||||
|
# avatar
|
||||||
|
avatar_label = wx.StaticText(panel, label=_("Avatar"))
|
||||||
|
try:
|
||||||
|
response = requests.get(self.avatar)
|
||||||
|
except requests.exceptions.RequestException:
|
||||||
|
# Create empty image
|
||||||
|
self.avatar_image = wx.StaticBitmap()
|
||||||
|
else:
|
||||||
|
image_bytes = BytesIO(response.content)
|
||||||
|
image = wx.Image(image_bytes, wx.BITMAP_TYPE_ANY)
|
||||||
|
image.Rescale(150, 150, wx.IMAGE_QUALITY_HIGH)
|
||||||
|
self.avatar_image = wx.StaticBitmap(panel, bitmap=image.ConvertToBitmap())
|
||||||
|
|
||||||
|
self.avatar_image.AcceptsFocusFromKeyboard = return_true
|
||||||
|
self.change_avatar = wx.Button(panel, label=_("Change avatar"))
|
||||||
|
avatar_sizer = wx.BoxSizer(wx.HORIZONTAL)
|
||||||
|
avatar_sizer.Add(avatar_label, wx.SizerFlags().Center())
|
||||||
|
avatar_sizer.Add(self.avatar_image, wx.SizerFlags().Center())
|
||||||
|
avatar_sizer.Add(self.change_avatar, wx.SizerFlags().Center())
|
||||||
|
sizer.Add(avatar_sizer, wx.CENTER)
|
||||||
|
|
||||||
|
self.fields = []
|
||||||
|
for i in range(1, 5):
|
||||||
|
field_sizer = wx.BoxSizer(wx.HORIZONTAL)
|
||||||
|
field_label = wx.StaticText(panel, label=_("Field {}: Label").format(i))
|
||||||
|
field_sizer.Add(field_label, wx.SizerFlags().Center().Border(wx.ALL, 5))
|
||||||
|
|
||||||
|
label_textctrl = wx.TextCtrl(panel, style=wx.TE_PROCESS_ENTER | wx.TE_MULTILINE, size=(200, 30))
|
||||||
|
if i <= len(fields):
|
||||||
|
label_textctrl.SetValue(fields[i-1][0])
|
||||||
|
field_sizer.Add(label_textctrl, wx.SizerFlags().Expand().Border(wx.ALL, 5))
|
||||||
|
|
||||||
|
content_label = wx.StaticText(panel, label=_("Content"))
|
||||||
|
field_sizer.Add(content_label, wx.SizerFlags().Center().Border(wx.ALL, 5))
|
||||||
|
|
||||||
|
content_textctrl = wx.TextCtrl(panel, style=wx.TE_PROCESS_ENTER | wx.TE_MULTILINE, size=(400, 60))
|
||||||
|
if i <= len(fields):
|
||||||
|
content_textctrl.SetValue(fields[i-1][1])
|
||||||
|
field_sizer.Add(content_textctrl, wx.SizerFlags().Expand().Border(wx.ALL, 5))
|
||||||
|
sizer.Add(field_sizer, 0, wx.CENTER)
|
||||||
|
self.fields.append((label_textctrl, content_textctrl))
|
||||||
|
|
||||||
|
self.locked = wx.CheckBox(panel, label=_("Private account"))
|
||||||
|
self.locked.SetValue(locked)
|
||||||
|
self.bot = wx.CheckBox(panel, label=_("Bot account"))
|
||||||
|
self.bot.SetValue(bot)
|
||||||
|
self.discoverable = wx.CheckBox(panel, label=_("Discoverable account"))
|
||||||
|
self.discoverable.SetValue(discoverable)
|
||||||
|
sizer.Add(self.locked, wx.SizerFlags().Expand().Border(wx.ALL, 5))
|
||||||
|
sizer.Add(self.bot, wx.SizerFlags().Expand().Border(wx.ALL, 5))
|
||||||
|
sizer.Add(self.discoverable, wx.SizerFlags().Expand().Border(wx.ALL, 5))
|
||||||
|
|
||||||
|
ok = wx.Button(panel, wx.ID_OK, _(u"&OK"))
|
||||||
|
ok.SetDefault()
|
||||||
|
cancel = wx.Button(panel, wx.ID_CANCEL, _("&Close"))
|
||||||
|
self.SetEscapeId(cancel.GetId())
|
||||||
|
action_sizer = wx.BoxSizer(wx.HORIZONTAL)
|
||||||
|
action_sizer.Add(ok, wx.SizerFlags().Center())
|
||||||
|
action_sizer.Add(cancel, wx.SizerFlags().Center())
|
||||||
|
sizer.Add(action_sizer, wx.CENTER)
|
||||||
|
panel.SetSizer(sizer)
|
||||||
|
sizer.Fit(self)
|
||||||
|
self.Center()
|
||||||
|
|
||||||
|
# manage events
|
||||||
|
ok.Bind(wx.EVT_BUTTON, self.on_ok)
|
||||||
|
self.change_header.Bind(wx.EVT_BUTTON, self.on_change_header)
|
||||||
|
self.change_avatar.Bind(wx.EVT_BUTTON, self.on_change_avatar)
|
||||||
|
|
||||||
|
self.AutoLayout = True
|
||||||
|
|
||||||
|
def on_ok(self, *args):
|
||||||
|
"""Method called when user clicks ok in dialog"""
|
||||||
|
self.data = {
|
||||||
|
'display_name': self.display_name.GetValue(),
|
||||||
|
'note': self.bio.GetValue(),
|
||||||
|
'header': self.header,
|
||||||
|
'avatar': self.avatar,
|
||||||
|
'fields': [(label.GetValue(), content.GetValue()) for label, content in self.fields if label.GetValue() and content.GetValue()],
|
||||||
|
'locked': self.locked.GetValue(),
|
||||||
|
'bot': self.bot.GetValue(),
|
||||||
|
'discoverable': self.discoverable.GetValue(),
|
||||||
|
}
|
||||||
|
self.EndModal(wx.ID_OK)
|
||||||
|
|
||||||
|
def on_change_header(self, *args):
|
||||||
|
"""Display a dialog for the user to choose a picture and update the
|
||||||
|
appropriate attribute"""
|
||||||
|
wildcard = "Images (*.png;*.jpg;*.gif)|*.png;*.jpg;*.gif"
|
||||||
|
dlg = wx.FileDialog(self, _("Select header image - max 2MB"), wildcard=wildcard)
|
||||||
|
if dlg.ShowModal() == wx.CLOSE:
|
||||||
|
return
|
||||||
|
if os.path.getsize(dlg.GetPath()) > 2097152:
|
||||||
|
# File size exceeds the limit
|
||||||
|
message = _("The selected file is larger than 2MB. Do you want to select another file?")
|
||||||
|
caption = _("File more than 2MB")
|
||||||
|
style = wx.YES_NO | wx.ICON_WARNING
|
||||||
|
|
||||||
|
# Display the message box
|
||||||
|
result = wx.MessageBox(message, caption, style)
|
||||||
|
return self.on_change_header() if result == wx.YES else None
|
||||||
|
|
||||||
|
self.header = dlg.GetPath()
|
||||||
|
image = wx.Image(self.header, wx.BITMAP_TYPE_ANY)
|
||||||
|
image.Rescale(150, 150, wx.IMAGE_QUALITY_HIGH)
|
||||||
|
self.header_image.SetBitmap(image.ConvertToBitmap())
|
||||||
|
|
||||||
|
def on_change_avatar(self, *args):
|
||||||
|
"""Display a dialog for the user to choose a picture and update the
|
||||||
|
appropriate attribute"""
|
||||||
|
wildcard = "Images (*.png;*.jpg;*.gif)|*.png;*.jpg;*.gif"
|
||||||
|
dlg = wx.FileDialog(self, _("Select avatar image - max 2MB"), wildcard=wildcard)
|
||||||
|
if dlg.ShowModal() == wx.CLOSE:
|
||||||
|
return
|
||||||
|
if os.path.getsize(dlg.GetPath()) > 2097152:
|
||||||
|
# File size exceeds the limit
|
||||||
|
message = _("The selected file is larger than 2MB. Do you want to select another file?")
|
||||||
|
caption = _("File more than 2MB")
|
||||||
|
style = wx.YES_NO | wx.ICON_WARNING
|
||||||
|
|
||||||
|
# Display the message box
|
||||||
|
result = wx.MessageBox(message, caption, style)
|
||||||
|
return self.on_change_avatar() if result == wx.YES else None
|
||||||
|
|
||||||
|
self.avatar = dlg.GetPath()
|
||||||
|
image = wx.Image(self.avatar, wx.BITMAP_TYPE_ANY)
|
||||||
|
image.Rescale(150, 150, wx.IMAGE_QUALITY_HIGH)
|
||||||
|
self.avatar_image.SetBitmap(image.ConvertToBitmap())
|
@ -15,7 +15,6 @@ class mainFrame(wx.Frame):
|
|||||||
self.menubar_application = wx.Menu()
|
self.menubar_application = wx.Menu()
|
||||||
self.manage_accounts = self.menubar_application.Append(wx.ID_ANY, _(u"&Manage accounts"))
|
self.manage_accounts = self.menubar_application.Append(wx.ID_ANY, _(u"&Manage accounts"))
|
||||||
self.updateProfile = self.menubar_application.Append(wx.ID_ANY, _("&Update profile"))
|
self.updateProfile = self.menubar_application.Append(wx.ID_ANY, _("&Update profile"))
|
||||||
self.updateProfile.Enable(False)
|
|
||||||
self.show_hide = self.menubar_application.Append(wx.ID_ANY, _(u"&Hide window"))
|
self.show_hide = self.menubar_application.Append(wx.ID_ANY, _(u"&Hide window"))
|
||||||
self.menuitem_search = self.menubar_application.Append(wx.ID_ANY, _(u"&Search"))
|
self.menuitem_search = self.menubar_application.Append(wx.ID_ANY, _(u"&Search"))
|
||||||
self.lists = self.menubar_application.Append(wx.ID_ANY, _(u"&Lists manager"))
|
self.lists = self.menubar_application.Append(wx.ID_ANY, _(u"&Lists manager"))
|
||||||
|
Loading…
Reference in New Issue
Block a user