changed indentation from tabs to spaces
This commit is contained in:
parent
5c02a67ac7
commit
4bdba42eab
@ -8,24 +8,24 @@ log = logging.getLogger("authenticator.official")
|
|||||||
class AuthenticationError(Exception): pass
|
class AuthenticationError(Exception): pass
|
||||||
|
|
||||||
def login(user, password):
|
def login(user, password):
|
||||||
""" Generates authentication workflow at VK servers. """
|
""" Generates authentication workflow at VK servers. """
|
||||||
log.info("Authenticating user account.")
|
log.info("Authenticating user account.")
|
||||||
access_token = None
|
access_token = None
|
||||||
try:
|
try:
|
||||||
params = CommonParams(supported_clients.VK_OFFICIAL.user_agent)
|
params = CommonParams(supported_clients.VK_OFFICIAL.user_agent)
|
||||||
receiver = TokenReceiverOfficial(user, password, params, "GET_CODE")
|
receiver = TokenReceiverOfficial(user, password, params, "GET_CODE")
|
||||||
access_token = receiver.get_token()["access_token"]
|
access_token = receiver.get_token()["access_token"]
|
||||||
log.debug("got a valid access token for {}".format(user))
|
log.debug("got a valid access token for {}".format(user))
|
||||||
except TokenException as err:
|
except TokenException as err:
|
||||||
if err.code == TokenException.TWOFA_REQ and 'validation_sid' in err.extra:
|
if err.code == TokenException.TWOFA_REQ and 'validation_sid' in err.extra:
|
||||||
log.debug("User requires two factor verification. Calling methods to send an SMS...")
|
log.debug("User requires two factor verification. Calling methods to send an SMS...")
|
||||||
try:
|
try:
|
||||||
TwoFAHelper(params).validate_phone(err.extra['validation_sid'])
|
TwoFAHelper(params).validate_phone(err.extra['validation_sid'])
|
||||||
except TokenException as err:
|
except TokenException as err:
|
||||||
if err.code == TokenException.TWOFA_ERR:
|
if err.code == TokenException.TWOFA_ERR:
|
||||||
wxUI.two_auth_limit()
|
wxUI.two_auth_limit()
|
||||||
raise AuthenticationError("Error authentication two factor auth.")
|
raise AuthenticationError("Error authentication two factor auth.")
|
||||||
code, remember = wxUI.two_factor_auth()
|
code, remember = wxUI.two_factor_auth()
|
||||||
receiver = TokenReceiverOfficial(user, password, params, code)
|
receiver = TokenReceiverOfficial(user, password, params, code)
|
||||||
access_token = receiver.get_token()["access_token"]
|
access_token = receiver.get_token()["access_token"]
|
||||||
return access_token
|
return access_token
|
||||||
|
@ -5,16 +5,16 @@ import wx
|
|||||||
import widgetUtils
|
import widgetUtils
|
||||||
|
|
||||||
def two_factor_auth():
|
def two_factor_auth():
|
||||||
code = None
|
code = None
|
||||||
dlg = wx.TextEntryDialog(None, _("Please provide the authentication code you have received from VK."), _("Two factor authentication code"))
|
dlg = wx.TextEntryDialog(None, _("Please provide the authentication code you have received from VK."), _("Two factor authentication code"))
|
||||||
response = dlg.ShowModal()
|
response = dlg.ShowModal()
|
||||||
if response == widgetUtils.OK:
|
if response == widgetUtils.OK:
|
||||||
code = dlg.GetValue()
|
code = dlg.GetValue()
|
||||||
dlg.Destroy()
|
dlg.Destroy()
|
||||||
return (code, True)
|
return (code, True)
|
||||||
|
|
||||||
def bad_password():
|
def bad_password():
|
||||||
return wx.MessageDialog(None, _("Your password or email address are incorrect. Please fix the mistakes and try it again."), _("Wrong data"), wx.ICON_ERROR).ShowModal()
|
return wx.MessageDialog(None, _("Your password or email address are incorrect. Please fix the mistakes and try it again."), _("Wrong data"), wx.ICON_ERROR).ShowModal()
|
||||||
|
|
||||||
def two_auth_limit():
|
def two_auth_limit():
|
||||||
return wx.MessageDialog(None, _("It seems you have reached the limits to request authorization via SMS. Please try it again in a couple of hours."), _("Error requiring sms verification"), wx.ICON_ERROR).ShowModal()
|
return wx.MessageDialog(None, _("It seems you have reached the limits to request authorization via SMS. Please try it again in a couple of hours."), _("Error requiring sms verification"), wx.ICON_ERROR).ShowModal()
|
||||||
|
@ -11,7 +11,6 @@ MAINSPEC = "app-configuration.defaults"
|
|||||||
|
|
||||||
app = None
|
app = None
|
||||||
def setup ():
|
def setup ():
|
||||||
global app
|
global app
|
||||||
log.debug("Loading global app settings...")
|
log.debug("Loading global app settings...")
|
||||||
app = config_utils.load_config(os.path.join(paths.config_path(), MAINFILE), os.path.join(paths.app_path(), MAINSPEC))
|
app = config_utils.load_config(os.path.join(paths.config_path(), MAINFILE), os.path.join(paths.app_path(), MAINSPEC))
|
||||||
|
|
||||||
|
@ -6,68 +6,68 @@ import string
|
|||||||
class ConfigLoadError(Exception): pass
|
class ConfigLoadError(Exception): pass
|
||||||
|
|
||||||
def load_config(config_path, configspec_path=None, *args, **kwargs):
|
def load_config(config_path, configspec_path=None, *args, **kwargs):
|
||||||
if os.path.exists(config_path):
|
if os.path.exists(config_path):
|
||||||
clean_config(config_path)
|
clean_config(config_path)
|
||||||
spec = ConfigObj(configspec_path, encoding='UTF8', list_values=False, _inspec=True)
|
spec = ConfigObj(configspec_path, encoding='UTF8', list_values=False, _inspec=True)
|
||||||
try:
|
try:
|
||||||
config = ConfigObj(infile=config_path, configspec=spec, create_empty=True, encoding='UTF8', *args, **kwargs)
|
config = ConfigObj(infile=config_path, configspec=spec, create_empty=True, encoding='UTF8', *args, **kwargs)
|
||||||
except ParseError:
|
except ParseError:
|
||||||
raise ConfigLoadError("Unable to load %r" % config_path)
|
raise ConfigLoadError("Unable to load %r" % config_path)
|
||||||
validator = Validator()
|
validator = Validator()
|
||||||
validated = config.validate(validator, copy=True)
|
validated = config.validate(validator, copy=True)
|
||||||
if validated == True:
|
if validated == True:
|
||||||
config.write()
|
config.write()
|
||||||
return config
|
return config
|
||||||
|
|
||||||
def is_blank(arg):
|
def is_blank(arg):
|
||||||
"Check if a line is blank."
|
"Check if a line is blank."
|
||||||
for c in arg:
|
for c in arg:
|
||||||
if c not in string.whitespace:
|
if c not in string.whitespace:
|
||||||
return False
|
return False
|
||||||
return True
|
return True
|
||||||
def get_keys(path):
|
def get_keys(path):
|
||||||
"Gets the keys of a configobj config file."
|
"Gets the keys of a configobj config file."
|
||||||
res=[]
|
res=[]
|
||||||
fin=open(path)
|
fin=open(path)
|
||||||
for line in fin:
|
for line in fin:
|
||||||
if not is_blank(line):
|
if not is_blank(line):
|
||||||
res.append(line[0:line.find('=')].strip())
|
res.append(line[0:line.find('=')].strip())
|
||||||
fin.close()
|
fin.close()
|
||||||
return res
|
return res
|
||||||
|
|
||||||
def hist(keys):
|
def hist(keys):
|
||||||
"Generates a histogram of an iterable."
|
"Generates a histogram of an iterable."
|
||||||
res={}
|
res={}
|
||||||
for k in keys:
|
for k in keys:
|
||||||
res[k]=res.setdefault(k,0)+1
|
res[k]=res.setdefault(k,0)+1
|
||||||
return res
|
return res
|
||||||
|
|
||||||
def find_problems(hist):
|
def find_problems(hist):
|
||||||
"Takes a histogram and returns a list of items occurring more than once."
|
"Takes a histogram and returns a list of items occurring more than once."
|
||||||
res=[]
|
res=[]
|
||||||
for k,v in list(hist.items()):
|
for k,v in list(hist.items()):
|
||||||
if v>1:
|
if v>1:
|
||||||
res.append(k)
|
res.append(k)
|
||||||
return res
|
return res
|
||||||
|
|
||||||
def clean_config(path):
|
def clean_config(path):
|
||||||
"Cleans a config file. If duplicate values are found, delete all of them and just use the default."
|
"Cleans a config file. If duplicate values are found, delete all of them and just use the default."
|
||||||
orig=[]
|
orig=[]
|
||||||
cleaned=[]
|
cleaned=[]
|
||||||
fin=open(path)
|
fin=open(path)
|
||||||
for line in fin:
|
for line in fin:
|
||||||
orig.append(line)
|
orig.append(line)
|
||||||
fin.close()
|
fin.close()
|
||||||
for p in find_problems(hist(get_keys(path))):
|
for p in find_problems(hist(get_keys(path))):
|
||||||
for o in orig:
|
for o in orig:
|
||||||
o.strip()
|
o.strip()
|
||||||
if p not in o:
|
if p not in o:
|
||||||
cleaned.append(o)
|
cleaned.append(o)
|
||||||
if len(cleaned) != 0:
|
if len(cleaned) != 0:
|
||||||
cam=open(path,'w')
|
cam=open(path,'w')
|
||||||
for c in cleaned:
|
for c in cleaned:
|
||||||
cam.write(c)
|
cam.write(c)
|
||||||
cam.close()
|
cam.close()
|
||||||
return True
|
return True
|
||||||
else:
|
else:
|
||||||
return False
|
return False
|
||||||
|
@ -21,289 +21,289 @@ from .wall import wallBuffer
|
|||||||
log = logging.getLogger("controller.buffers.audio")
|
log = logging.getLogger("controller.buffers.audio")
|
||||||
|
|
||||||
class audioBuffer(wallBuffer):
|
class audioBuffer(wallBuffer):
|
||||||
def create_tab(self, parent):
|
def create_tab(self, parent):
|
||||||
self.tab = audio.audioTab(parent)
|
self.tab = audio.audioTab(parent)
|
||||||
self.tab.name = self.name
|
self.tab.name = self.name
|
||||||
self.connect_events()
|
self.connect_events()
|
||||||
if self.name == "me_audio":
|
if self.name == "me_audio":
|
||||||
self.tab.post.Enable(True)
|
self.tab.post.Enable(True)
|
||||||
|
|
||||||
def get_event(self, ev):
|
def get_event(self, ev):
|
||||||
if ev.GetKeyCode() == wx.WXK_RETURN:
|
if ev.GetKeyCode() == wx.WXK_RETURN:
|
||||||
if len(self.tab.list.get_multiple_selection()) < 2:
|
if len(self.tab.list.get_multiple_selection()) < 2:
|
||||||
event = "play_all"
|
event = "play_all"
|
||||||
else:
|
else:
|
||||||
event = "play_audio"
|
event = "play_audio"
|
||||||
else:
|
else:
|
||||||
event = None
|
event = None
|
||||||
ev.Skip()
|
ev.Skip()
|
||||||
if event != None:
|
if event != None:
|
||||||
try:
|
try:
|
||||||
getattr(self, event)(skip_pause=True)
|
getattr(self, event)(skip_pause=True)
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def connect_events(self):
|
def connect_events(self):
|
||||||
widgetUtils.connect_event(self.tab.play, widgetUtils.BUTTON_PRESSED, self.play_audio)
|
widgetUtils.connect_event(self.tab.play, widgetUtils.BUTTON_PRESSED, self.play_audio)
|
||||||
widgetUtils.connect_event(self.tab.play_all, widgetUtils.BUTTON_PRESSED, self.play_all)
|
widgetUtils.connect_event(self.tab.play_all, widgetUtils.BUTTON_PRESSED, self.play_all)
|
||||||
pub.subscribe(self.change_label, "playback-changed")
|
pub.subscribe(self.change_label, "playback-changed")
|
||||||
super(audioBuffer, self).connect_events()
|
super(audioBuffer, self).connect_events()
|
||||||
|
|
||||||
def play_audio(self, *args, **kwargs):
|
def play_audio(self, *args, **kwargs):
|
||||||
if player.player.check_is_playing() and not "skip_pause" in kwargs:
|
if player.player.check_is_playing() and not "skip_pause" in kwargs:
|
||||||
return pub.sendMessage("pause")
|
return pub.sendMessage("pause")
|
||||||
selected = self.tab.list.get_multiple_selection()
|
selected = self.tab.list.get_multiple_selection()
|
||||||
if len(selected) == 0:
|
if len(selected) == 0:
|
||||||
return
|
return
|
||||||
elif len(selected) == 1:
|
elif len(selected) == 1:
|
||||||
pub.sendMessage("play", object=self.session.db[self.name]["items"][selected[0]])
|
pub.sendMessage("play", object=self.session.db[self.name]["items"][selected[0]])
|
||||||
else:
|
else:
|
||||||
selected_audios = [self.session.db[self.name]["items"][item] for item in selected]
|
selected_audios = [self.session.db[self.name]["items"][item] for item in selected]
|
||||||
pub.sendMessage("play-all", list_of_songs=selected_audios)
|
pub.sendMessage("play-all", list_of_songs=selected_audios)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def play_next(self, *args, **kwargs):
|
def play_next(self, *args, **kwargs):
|
||||||
selected = self.tab.list.get_selected()
|
selected = self.tab.list.get_selected()
|
||||||
if selected < 0:
|
if selected < 0:
|
||||||
selected = 0
|
selected = 0
|
||||||
if self.tab.list.get_count() <= selected+1:
|
if self.tab.list.get_count() <= selected+1:
|
||||||
newpos = 0
|
newpos = 0
|
||||||
else:
|
else:
|
||||||
newpos = selected+1
|
newpos = selected+1
|
||||||
self.tab.list.select_item(newpos)
|
self.tab.list.select_item(newpos)
|
||||||
self.play_audio()
|
self.play_audio()
|
||||||
|
|
||||||
def play_previous(self, *args, **kwargs):
|
def play_previous(self, *args, **kwargs):
|
||||||
selected = self.tab.list.get_selected()
|
selected = self.tab.list.get_selected()
|
||||||
if selected <= 0:
|
if selected <= 0:
|
||||||
selected = self.tab.list.get_count()
|
selected = self.tab.list.get_count()
|
||||||
newpos = selected-1
|
newpos = selected-1
|
||||||
self.tab.list.select_item(newpos)
|
self.tab.list.select_item(newpos)
|
||||||
self.play_audio()
|
self.play_audio()
|
||||||
|
|
||||||
def open_post(self, *args, **kwargs):
|
def open_post(self, *args, **kwargs):
|
||||||
selected = self.tab.list.get_multiple_selection()
|
selected = self.tab.list.get_multiple_selection()
|
||||||
if len(selected) < 1:
|
if len(selected) < 1:
|
||||||
return
|
return
|
||||||
audios = [self.session.db[self.name]["items"][audio] for audio in selected]
|
audios = [self.session.db[self.name]["items"][audio] for audio in selected]
|
||||||
a = presenters.displayAudioPresenter(session=self.session, postObject=audios, interactor=interactors.displayAudioInteractor(), view=views.displayAudio())
|
a = presenters.displayAudioPresenter(session=self.session, postObject=audios, interactor=interactors.displayAudioInteractor(), view=views.displayAudio())
|
||||||
|
|
||||||
def play_all(self, *args, **kwargs):
|
def play_all(self, *args, **kwargs):
|
||||||
selected = self.tab.list.get_selected()
|
selected = self.tab.list.get_selected()
|
||||||
if selected == -1:
|
if selected == -1:
|
||||||
selected = 0
|
selected = 0
|
||||||
if self.name not in self.session.db:
|
if self.name not in self.session.db:
|
||||||
return
|
return
|
||||||
audios = [i for i in self.session.db[self.name]["items"][selected:]]
|
audios = [i for i in self.session.db[self.name]["items"][selected:]]
|
||||||
pub.sendMessage("play-all", list_of_songs=audios)
|
pub.sendMessage("play-all", list_of_songs=audios)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def remove_buffer(self, mandatory=False):
|
def remove_buffer(self, mandatory=False):
|
||||||
if "me_audio" == self.name or "popular_audio" == self.name or "recommended_audio" == self.name:
|
if "me_audio" == self.name or "popular_audio" == self.name or "recommended_audio" == self.name:
|
||||||
output.speak(_("This buffer can't be deleted"))
|
output.speak(_("This buffer can't be deleted"))
|
||||||
return False
|
return False
|
||||||
else:
|
else:
|
||||||
if mandatory == False:
|
if mandatory == False:
|
||||||
dlg = commonMessages.remove_buffer()
|
dlg = commonMessages.remove_buffer()
|
||||||
else:
|
else:
|
||||||
dlg = widgetUtils.YES
|
dlg = widgetUtils.YES
|
||||||
if dlg == widgetUtils.YES:
|
if dlg == widgetUtils.YES:
|
||||||
self.session.db.pop(self.name)
|
self.session.db.pop(self.name)
|
||||||
return True
|
return True
|
||||||
else:
|
else:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def get_more_items(self, *args, **kwargs):
|
def get_more_items(self, *args, **kwargs):
|
||||||
# Translators: Some buffers can't use the get previous item feature due to API limitations.
|
# Translators: Some buffers can't use the get previous item feature due to API limitations.
|
||||||
output.speak(_("This buffer doesn't support getting more items."))
|
output.speak(_("This buffer doesn't support getting more items."))
|
||||||
|
|
||||||
def onFocus(self, event, *args, **kwargs):
|
def onFocus(self, event, *args, **kwargs):
|
||||||
event.Skip()
|
event.Skip()
|
||||||
|
|
||||||
def add_to_library(self, *args, **kwargs):
|
def add_to_library(self, *args, **kwargs):
|
||||||
call_threaded(self._add_to_library, *args, **kwargs)
|
call_threaded(self._add_to_library, *args, **kwargs)
|
||||||
|
|
||||||
def _add_to_library(self, *args, **kwargs):
|
def _add_to_library(self, *args, **kwargs):
|
||||||
selected = self.tab.list.get_multiple_selection()
|
selected = self.tab.list.get_multiple_selection()
|
||||||
if len(selected) < 1:
|
if len(selected) < 1:
|
||||||
return
|
return
|
||||||
audios = [self.session.db[self.name]["items"][audio] for audio in selected]
|
audios = [self.session.db[self.name]["items"][audio] for audio in selected]
|
||||||
errors_detected = 0
|
errors_detected = 0
|
||||||
for i in audios:
|
for i in audios:
|
||||||
args = {}
|
args = {}
|
||||||
args["audio_id"] = i["id"]
|
args["audio_id"] = i["id"]
|
||||||
if "album_id" in i:
|
if "album_id" in i:
|
||||||
args["album_id"] = i["album_id"]
|
args["album_id"] = i["album_id"]
|
||||||
args["owner_id"] = i["owner_id"]
|
args["owner_id"] = i["owner_id"]
|
||||||
try:
|
try:
|
||||||
audio = self.session.vk.client.audio.add(**args)
|
audio = self.session.vk.client.audio.add(**args)
|
||||||
except VkApiError:
|
except VkApiError:
|
||||||
errors_detected = errors_detected + 1
|
errors_detected = errors_detected + 1
|
||||||
continue
|
continue
|
||||||
if audio != None and int(audio) < 21:
|
if audio != None and int(audio) < 21:
|
||||||
errors_detected = errors_detected + 1
|
errors_detected = errors_detected + 1
|
||||||
if errors_detected == 0:
|
if errors_detected == 0:
|
||||||
if len(selected) == 1:
|
if len(selected) == 1:
|
||||||
msg = _("Audio added to your library")
|
msg = _("Audio added to your library")
|
||||||
elif len(selected) > 1 and len(selected) < 5:
|
elif len(selected) > 1 and len(selected) < 5:
|
||||||
msg = _("{0} audios were added to your library.").format(len(selected),)
|
msg = _("{0} audios were added to your library.").format(len(selected),)
|
||||||
else:
|
else:
|
||||||
msg = _("{audios} audios were added to your library.").format(audios=len(selected),)
|
msg = _("{audios} audios were added to your library.").format(audios=len(selected),)
|
||||||
output.speak(msg)
|
output.speak(msg)
|
||||||
else:
|
else:
|
||||||
output.speak(_("{0} errors occurred while attempting to add {1} audios to your library.").format(errors_detected, len(selected)))
|
output.speak(_("{0} errors occurred while attempting to add {1} audios to your library.").format(errors_detected, len(selected)))
|
||||||
|
|
||||||
def remove_from_library(self, *args, **kwargs):
|
def remove_from_library(self, *args, **kwargs):
|
||||||
call_threaded(self._remove_from_library, *args, **kwargs)
|
call_threaded(self._remove_from_library, *args, **kwargs)
|
||||||
|
|
||||||
def _remove_from_library(self, *args, **kwargs):
|
def _remove_from_library(self, *args, **kwargs):
|
||||||
selected = self.tab.list.get_multiple_selection()
|
selected = self.tab.list.get_multiple_selection()
|
||||||
if len(selected) < 1:
|
if len(selected) < 1:
|
||||||
return
|
return
|
||||||
audios = [self.session.db[self.name]["items"][audio] for audio in selected]
|
audios = [self.session.db[self.name]["items"][audio] for audio in selected]
|
||||||
errors_detected = 0
|
errors_detected = 0
|
||||||
audios_removed = 0
|
audios_removed = 0
|
||||||
for i in range(0, len(selected)):
|
for i in range(0, len(selected)):
|
||||||
args = {}
|
args = {}
|
||||||
args["audio_id"] = audios[i]["id"]
|
args["audio_id"] = audios[i]["id"]
|
||||||
args["owner_id"] = self.session.user_id
|
args["owner_id"] = self.session.user_id
|
||||||
result = self.session.vk.client.audio.delete(**args)
|
result = self.session.vk.client.audio.delete(**args)
|
||||||
if int(result) != 1:
|
if int(result) != 1:
|
||||||
errors_dtected = errors_detected + 1
|
errors_dtected = errors_detected + 1
|
||||||
else:
|
else:
|
||||||
self.session.db[self.name]["items"].pop(selected[i]-audios_removed)
|
self.session.db[self.name]["items"].pop(selected[i]-audios_removed)
|
||||||
self.tab.list.remove_item(selected[i]-audios_removed)
|
self.tab.list.remove_item(selected[i]-audios_removed)
|
||||||
audios_removed = audios_removed + 1
|
audios_removed = audios_removed + 1
|
||||||
if errors_detected == 0:
|
if errors_detected == 0:
|
||||||
if len(selected) == 1:
|
if len(selected) == 1:
|
||||||
msg = _("Audio removed.")
|
msg = _("Audio removed.")
|
||||||
elif len(selected) > 1 and len(selected) < 5:
|
elif len(selected) > 1 and len(selected) < 5:
|
||||||
msg = _("{0} audios were removed.").format(len(selected),)
|
msg = _("{0} audios were removed.").format(len(selected),)
|
||||||
else:
|
else:
|
||||||
msg = _("{audios} audios were removed.").format(audios=len(selected),)
|
msg = _("{audios} audios were removed.").format(audios=len(selected),)
|
||||||
output.speak(msg)
|
output.speak(msg)
|
||||||
else:
|
else:
|
||||||
output.speak(_("{0} errors occurred while attempting to remove {1} audios.").format(errors_detected, len(selected)))
|
output.speak(_("{0} errors occurred while attempting to remove {1} audios.").format(errors_detected, len(selected)))
|
||||||
|
|
||||||
def move_to_album(self, *args, **kwargs):
|
def move_to_album(self, *args, **kwargs):
|
||||||
if len(self.session.audio_albums) == 0:
|
if len(self.session.audio_albums) == 0:
|
||||||
return commonMessages.no_audio_albums()
|
return commonMessages.no_audio_albums()
|
||||||
album = selector.album(_("Select the album where you want to move this song"), self.session)
|
album = selector.album(_("Select the album where you want to move this song"), self.session)
|
||||||
if album.item == None:
|
if album.item == None:
|
||||||
return
|
return
|
||||||
call_threaded(self._move_to_album, album.item, *args, **kwargs)
|
call_threaded(self._move_to_album, album.item, *args, **kwargs)
|
||||||
|
|
||||||
def _move_to_album(self, album, *args, **kwargs):
|
def _move_to_album(self, album, *args, **kwargs):
|
||||||
selected = self.tab.list.get_multiple_selection()
|
selected = self.tab.list.get_multiple_selection()
|
||||||
if len(selected) < 1:
|
if len(selected) < 1:
|
||||||
return
|
return
|
||||||
audios = [self.session.db[self.name]["items"][audio] for audio in selected]
|
audios = [self.session.db[self.name]["items"][audio] for audio in selected]
|
||||||
errors_detected = 0
|
errors_detected = 0
|
||||||
for i in audios:
|
for i in audios:
|
||||||
id = i["id"]
|
id = i["id"]
|
||||||
try:
|
try:
|
||||||
response = self.session.vk.client.audio.add(playlist_id=album, audio_id=id, owner_id=i["owner_id"])
|
response = self.session.vk.client.audio.add(playlist_id=album, audio_id=id, owner_id=i["owner_id"])
|
||||||
except VkApiError:
|
except VkApiError:
|
||||||
errors_detected = errors_detected + 1
|
errors_detected = errors_detected + 1
|
||||||
if errors_detected == 0:
|
if errors_detected == 0:
|
||||||
if len(selected) == 1:
|
if len(selected) == 1:
|
||||||
msg = _("Audio added to playlist.")
|
msg = _("Audio added to playlist.")
|
||||||
elif len(selected) > 1 and len(selected) < 5:
|
elif len(selected) > 1 and len(selected) < 5:
|
||||||
msg = _("{0} audios were added to playlist.").format(len(selected),)
|
msg = _("{0} audios were added to playlist.").format(len(selected),)
|
||||||
else:
|
else:
|
||||||
msg = _("{audios} audios were added to playlist.").format(audios=len(selected),)
|
msg = _("{audios} audios were added to playlist.").format(audios=len(selected),)
|
||||||
output.speak(msg)
|
output.speak(msg)
|
||||||
else:
|
else:
|
||||||
output.speak(_("{0} errors occurred while attempting to add {1} audios to your playlist.").format(errors_detected, len(selected)))
|
output.speak(_("{0} errors occurred while attempting to add {1} audios to your playlist.").format(errors_detected, len(selected)))
|
||||||
|
|
||||||
def get_menu(self):
|
def get_menu(self):
|
||||||
p = self.get_post()
|
p = self.get_post()
|
||||||
if p == None:
|
if p == None:
|
||||||
return
|
return
|
||||||
m = menus.audioMenu()
|
m = menus.audioMenu()
|
||||||
widgetUtils.connect_event(m, widgetUtils.MENU, self.open_post, menuitem=m.open)
|
widgetUtils.connect_event(m, widgetUtils.MENU, self.open_post, menuitem=m.open)
|
||||||
widgetUtils.connect_event(m, widgetUtils.MENU, self.play_audio, menuitem=m.play)
|
widgetUtils.connect_event(m, widgetUtils.MENU, self.play_audio, menuitem=m.play)
|
||||||
widgetUtils.connect_event(m, widgetUtils.MENU, self.move_to_album, menuitem=m.move)
|
widgetUtils.connect_event(m, widgetUtils.MENU, self.move_to_album, menuitem=m.move)
|
||||||
widgetUtils.connect_event(m, widgetUtils.MENU, self.download, menuitem=m.download)
|
widgetUtils.connect_event(m, widgetUtils.MENU, self.download, menuitem=m.download)
|
||||||
widgetUtils.connect_event(m, widgetUtils.MENU, self.select_all, menuitem=m.select)
|
widgetUtils.connect_event(m, widgetUtils.MENU, self.select_all, menuitem=m.select)
|
||||||
widgetUtils.connect_event(m, widgetUtils.MENU, self.deselect_all, menuitem=m.deselect)
|
widgetUtils.connect_event(m, widgetUtils.MENU, self.deselect_all, menuitem=m.deselect)
|
||||||
# if owner_id is the current user, the audio is added to the user's audios.
|
# if owner_id is the current user, the audio is added to the user's audios.
|
||||||
if p["owner_id"] == self.session.user_id:
|
if p["owner_id"] == self.session.user_id:
|
||||||
m.library.SetItemLabel(_("&Remove"))
|
m.library.SetItemLabel(_("&Remove"))
|
||||||
widgetUtils.connect_event(m, widgetUtils.MENU, self.remove_from_library, menuitem=m.library)
|
widgetUtils.connect_event(m, widgetUtils.MENU, self.remove_from_library, menuitem=m.library)
|
||||||
else:
|
else:
|
||||||
widgetUtils.connect_event(m, widgetUtils.MENU, self.add_to_library, menuitem=m.library)
|
widgetUtils.connect_event(m, widgetUtils.MENU, self.add_to_library, menuitem=m.library)
|
||||||
return m
|
return m
|
||||||
|
|
||||||
def post(self, *args, **kwargs):
|
def post(self, *args, **kwargs):
|
||||||
""" Uploads an audio to the current user's library from the computer. """
|
""" Uploads an audio to the current user's library from the computer. """
|
||||||
file = self.tab.get_file_to_upload()
|
file = self.tab.get_file_to_upload()
|
||||||
if file == None:
|
if file == None:
|
||||||
return
|
return
|
||||||
audio_tags = ID3(file)
|
audio_tags = ID3(file)
|
||||||
if "TIT2" in audio_tags:
|
if "TIT2" in audio_tags:
|
||||||
title = audio_tags["TIT2"].text[0]
|
title = audio_tags["TIT2"].text[0]
|
||||||
else:
|
else:
|
||||||
title = _("Untitled")
|
title = _("Untitled")
|
||||||
if "TPE1" in audio_tags:
|
if "TPE1" in audio_tags:
|
||||||
artist = audio_tags["TPE1"].text[0]
|
artist = audio_tags["TPE1"].text[0]
|
||||||
else:
|
else:
|
||||||
artist = _("Unknown artist")
|
artist = _("Unknown artist")
|
||||||
uploader = upload.VkUpload(self.session.vk.session_object)
|
uploader = upload.VkUpload(self.session.vk.session_object)
|
||||||
call_threaded(uploader.audio, file, title=title, artist=artist)
|
call_threaded(uploader.audio, file, title=title, artist=artist)
|
||||||
|
|
||||||
def open_in_browser(self, *args, **kwargs):
|
def open_in_browser(self, *args, **kwargs):
|
||||||
post = self.get_post()
|
post = self.get_post()
|
||||||
if post == None:
|
if post == None:
|
||||||
return
|
return
|
||||||
url = "https://vk.com/audio{user_id}_{post_id}".format(user_id=post["owner_id"], post_id=post["id"])
|
url = "https://vk.com/audio{user_id}_{post_id}".format(user_id=post["owner_id"], post_id=post["id"])
|
||||||
webbrowser.open_new_tab(url)
|
webbrowser.open_new_tab(url)
|
||||||
|
|
||||||
def change_label(self, stopped):
|
def change_label(self, stopped):
|
||||||
if hasattr(self.tab, "play"):
|
if hasattr(self.tab, "play"):
|
||||||
if stopped == False:
|
if stopped == False:
|
||||||
self.tab.play.SetLabel(_("P&ause"))
|
self.tab.play.SetLabel(_("P&ause"))
|
||||||
else:
|
else:
|
||||||
self.tab.play.SetLabel(_("P&lay"))
|
self.tab.play.SetLabel(_("P&lay"))
|
||||||
|
|
||||||
def __del__(self):
|
def __del__(self):
|
||||||
pub.unsubscribe(self.change_label, "playback-changed")
|
pub.unsubscribe(self.change_label, "playback-changed")
|
||||||
|
|
||||||
def download(self, *args, **kwargs):
|
def download(self, *args, **kwargs):
|
||||||
selected = self.tab.list.get_multiple_selection()
|
selected = self.tab.list.get_multiple_selection()
|
||||||
if len(selected) < 1:
|
if len(selected) < 1:
|
||||||
return
|
return
|
||||||
audios = [self.session.db[self.name]["items"][audio] for audio in selected]
|
audios = [self.session.db[self.name]["items"][audio] for audio in selected]
|
||||||
if len(audios) == 0:
|
if len(audios) == 0:
|
||||||
return
|
return
|
||||||
elif len(audios) == 1:
|
elif len(audios) == 1:
|
||||||
multiple = False
|
multiple = False
|
||||||
filename = utils.safe_filename("{0} - {1}.mp3".format(audios[0]["title"], audios[0]["artist"]))
|
filename = utils.safe_filename("{0} - {1}.mp3".format(audios[0]["title"], audios[0]["artist"]))
|
||||||
else:
|
else:
|
||||||
multiple = True
|
multiple = True
|
||||||
filename = "" # No default filename for multiple files.
|
filename = "" # No default filename for multiple files.
|
||||||
path = self.tab.get_download_path(filename=filename, multiple=multiple)
|
path = self.tab.get_download_path(filename=filename, multiple=multiple)
|
||||||
self.download_threaded(path, multiple, audios)
|
self.download_threaded(path, multiple, audios)
|
||||||
|
|
||||||
def download_threaded(self, path, multiple, audios):
|
def download_threaded(self, path, multiple, audios):
|
||||||
if multiple == False:
|
if multiple == False:
|
||||||
url = audios[0]["url"]
|
url = audios[0]["url"]
|
||||||
pub.sendMessage("download-file", url=url, filename=path)
|
pub.sendMessage("download-file", url=url, filename=path)
|
||||||
return
|
return
|
||||||
else:
|
else:
|
||||||
downloads = []
|
downloads = []
|
||||||
for i in audios:
|
for i in audios:
|
||||||
filename = utils.safe_filename("{0} - {1}.mp3".format(i["title"], i["artist"]))
|
filename = utils.safe_filename("{0} - {1}.mp3".format(i["title"], i["artist"]))
|
||||||
filepath = os.path.join(path, filename)
|
filepath = os.path.join(path, filename)
|
||||||
downloads.append((utils.transform_audio_url(i["url"]), filepath))
|
downloads.append((utils.transform_audio_url(i["url"]), filepath))
|
||||||
pub.sendMessage("download-files", downloads=downloads)
|
pub.sendMessage("download-files", downloads=downloads)
|
||||||
|
|
||||||
def select_all(self, *args, **kwargs):
|
def select_all(self, *args, **kwargs):
|
||||||
items = self.tab.list.list.GetItemCount()
|
items = self.tab.list.list.GetItemCount()
|
||||||
for i in range(0, items):
|
for i in range(0, items):
|
||||||
self.tab.list.list.SetItemImage(i, 1)
|
self.tab.list.list.SetItemImage(i, 1)
|
||||||
|
|
||||||
def deselect_all(self, *args, **kwargs):
|
def deselect_all(self, *args, **kwargs):
|
||||||
items = self.tab.list.list.GetItemCount()
|
items = self.tab.list.list.GetItemCount()
|
||||||
for i in range(0, items):
|
for i in range(0, items):
|
||||||
self.tab.list.list.SetItemImage(i, 0)
|
self.tab.list.list.SetItemImage(i, 0)
|
||||||
|
@ -9,26 +9,26 @@ from .audio import audioBuffer
|
|||||||
log = logging.getLogger("controller.buffers.audioPlaylist")
|
log = logging.getLogger("controller.buffers.audioPlaylist")
|
||||||
|
|
||||||
class audioAlbumBuffer(audioBuffer):
|
class audioAlbumBuffer(audioBuffer):
|
||||||
""" this buffer was supposed to be used with audio albums
|
""" this buffer was supposed to be used with audio albums
|
||||||
but is deprecated as VK removed its audio support for third party apps."""
|
but is deprecated as VK removed its audio support for third party apps."""
|
||||||
|
|
||||||
def create_tab(self, parent):
|
def create_tab(self, parent):
|
||||||
self.tab = audioAlbum.audioAlbumTab(parent)
|
self.tab = audioAlbum.audioAlbumTab(parent)
|
||||||
self.tab.play.Enable(False)
|
self.tab.play.Enable(False)
|
||||||
self.tab.play_all.Enable(False)
|
self.tab.play_all.Enable(False)
|
||||||
self.connect_events()
|
self.connect_events()
|
||||||
self.tab.name = self.name
|
self.tab.name = self.name
|
||||||
if hasattr(self, "can_post") and self.can_post == False and hasattr(self.tab, "post"):
|
if hasattr(self, "can_post") and self.can_post == False and hasattr(self.tab, "post"):
|
||||||
self.tab.post.Enable(False)
|
self.tab.post.Enable(False)
|
||||||
|
|
||||||
def connect_events(self):
|
def connect_events(self):
|
||||||
super(audioAlbumBuffer, self).connect_events()
|
super(audioAlbumBuffer, self).connect_events()
|
||||||
widgetUtils.connect_event(self.tab.load, widgetUtils.BUTTON_PRESSED, self.load_album)
|
widgetUtils.connect_event(self.tab.load, widgetUtils.BUTTON_PRESSED, self.load_album)
|
||||||
|
|
||||||
def load_album(self, *args, **kwargs):
|
def load_album(self, *args, **kwargs):
|
||||||
output.speak(_("Loading album..."))
|
output.speak(_("Loading album..."))
|
||||||
self.can_get_items = True
|
self.can_get_items = True
|
||||||
self.tab.load.Enable(False)
|
self.tab.load.Enable(False)
|
||||||
wx.CallAfter(self.get_items)
|
wx.CallAfter(self.get_items)
|
||||||
self.tab.play.Enable(True)
|
self.tab.play.Enable(True)
|
||||||
self.tab.play_all.Enable(True)
|
self.tab.play_all.Enable(True)
|
||||||
|
@ -22,286 +22,286 @@ log = logging.getLogger("controller.buffers.chat")
|
|||||||
|
|
||||||
class chatBuffer(homeBuffer):
|
class chatBuffer(homeBuffer):
|
||||||
|
|
||||||
def insert(self, item, reversed=False):
|
def insert(self, item, reversed=False):
|
||||||
""" Add a new item to the list. Uses session.composefunc for parsing the dictionary and create a valid result for putting it in the list."""
|
""" Add a new item to the list. Uses session.composefunc for parsing the dictionary and create a valid result for putting it in the list."""
|
||||||
# as this tab is based in a text control, we have to overwrite the defaults.
|
# as this tab is based in a text control, we have to overwrite the defaults.
|
||||||
item_ = getattr(renderers, self.compose_function)(item, self.session)
|
item_ = getattr(renderers, self.compose_function)(item, self.session)
|
||||||
# the self.chat dictionary will have (first_line, last_line) as keys and message ID as a value for looking into it when needed.
|
# the self.chat dictionary will have (first_line, last_line) as keys and message ID as a value for looking into it when needed.
|
||||||
# Here we will get first and last line of a chat message appended to the history.
|
# Here we will get first and last line of a chat message appended to the history.
|
||||||
values = self.tab.add_message(item_[0], reverse=reversed)
|
values = self.tab.add_message(item_[0], reverse=reversed)
|
||||||
self.chats[values] = item["id"]
|
self.chats[values] = item["id"]
|
||||||
|
|
||||||
def get_focused_post(self):
|
def get_focused_post(self):
|
||||||
""" Gets chat message currently in focus"""
|
""" Gets chat message currently in focus"""
|
||||||
# this function replaces self.get_post for this buffer, as we rely in a TextCtrl control for getting chats.
|
# this function replaces self.get_post for this buffer, as we rely in a TextCtrl control for getting chats.
|
||||||
# Instead of the traditional method to do the trick.
|
# Instead of the traditional method to do the trick.
|
||||||
# Get text position here.
|
# Get text position here.
|
||||||
position = self.tab.history.PositionToXY(self.tab.history.GetInsertionPoint())
|
position = self.tab.history.PositionToXY(self.tab.history.GetInsertionPoint())
|
||||||
id_ = None
|
id_ = None
|
||||||
# The dictionary keys should be looked in reverse order as we are interested in the last result only.
|
# The dictionary keys should be looked in reverse order as we are interested in the last result only.
|
||||||
for i in reversed(list(self.chats.keys())):
|
for i in reversed(list(self.chats.keys())):
|
||||||
# Check if position[2] (line position) matches with something in self.chats
|
# Check if position[2] (line position) matches with something in self.chats
|
||||||
# (All messages, except the last one, should be able to be matched here).
|
# (All messages, except the last one, should be able to be matched here).
|
||||||
# position[2]+1 is added because line may start with 0, while in wx.TextCtrl.GetNumberOfLines() it returns a value counting from 1.
|
# position[2]+1 is added because line may start with 0, while in wx.TextCtrl.GetNumberOfLines() it returns a value counting from 1.
|
||||||
if position[2]+1 >= i[0]:
|
if position[2]+1 >= i[0]:
|
||||||
id_ = self.chats[i]
|
id_ = self.chats[i]
|
||||||
# If we find our chat message, let's skip the rest of the loop.
|
# If we find our chat message, let's skip the rest of the loop.
|
||||||
break
|
break
|
||||||
# Retrieve here the object based in id_
|
# Retrieve here the object based in id_
|
||||||
if id_ != None:
|
if id_ != None:
|
||||||
for i in self.session.db[self.name]["items"]:
|
for i in self.session.db[self.name]["items"]:
|
||||||
if i["id"] == id_:
|
if i["id"] == id_:
|
||||||
return i
|
return i
|
||||||
return False
|
return False
|
||||||
|
|
||||||
get_post = get_focused_post
|
get_post = get_focused_post
|
||||||
|
|
||||||
def onFocus(self, event, *args, **kwargs):
|
def onFocus(self, event, *args, **kwargs):
|
||||||
if event.GetKeyCode() == wx.WXK_UP or event.GetKeyCode() == wx.WXK_DOWN or event.GetKeyCode() == wx.WXK_START or event.GetKeyCode() == wx.WXK_PAGEUP or event.GetKeyCode() == wx.WXK_PAGEDOWN or event.GetKeyCode() == wx.WXK_END:
|
if event.GetKeyCode() == wx.WXK_UP or event.GetKeyCode() == wx.WXK_DOWN or event.GetKeyCode() == wx.WXK_START or event.GetKeyCode() == wx.WXK_PAGEUP or event.GetKeyCode() == wx.WXK_PAGEDOWN or event.GetKeyCode() == wx.WXK_END:
|
||||||
msg = self.get_focused_post()
|
msg = self.get_focused_post()
|
||||||
if msg == False: # Handle the case where the last line of the control cannot be matched to anything.
|
if msg == False: # Handle the case where the last line of the control cannot be matched to anything.
|
||||||
return
|
return
|
||||||
# Mark unread conversations as read.
|
# Mark unread conversations as read.
|
||||||
if "read_state" in msg and msg["read_state"] == 0 and "out" in msg and msg["out"] == 0:
|
if "read_state" in msg and msg["read_state"] == 0 and "out" in msg and msg["out"] == 0:
|
||||||
self.session.soundplayer.play("message_unread.ogg")
|
self.session.soundplayer.play("message_unread.ogg")
|
||||||
call_threaded(self.session.vk.client.messages.markAsRead, peer_id=self.kwargs["peer_id"])
|
call_threaded(self.session.vk.client.messages.markAsRead, peer_id=self.kwargs["peer_id"])
|
||||||
[i.update(read_state=1) for i in self.session.db[self.name]["items"]]
|
[i.update(read_state=1) for i in self.session.db[self.name]["items"]]
|
||||||
if "attachments" in msg and len(msg["attachments"]) > 0:
|
if "attachments" in msg and len(msg["attachments"]) > 0:
|
||||||
self.tab.attachments.list.Enable(True)
|
self.tab.attachments.list.Enable(True)
|
||||||
self.attachments = list()
|
self.attachments = list()
|
||||||
self.tab.attachments.clear()
|
self.tab.attachments.clear()
|
||||||
self.parse_attachments(msg)
|
self.parse_attachments(msg)
|
||||||
else:
|
else:
|
||||||
self.tab.attachments.list.Enable(False)
|
self.tab.attachments.list.Enable(False)
|
||||||
self.tab.attachments.clear()
|
self.tab.attachments.clear()
|
||||||
event.Skip()
|
event.Skip()
|
||||||
|
|
||||||
def create_tab(self, parent):
|
def create_tab(self, parent):
|
||||||
self.tab = chat.chatTab(parent)
|
self.tab = chat.chatTab(parent)
|
||||||
self.attachments = list()
|
self.attachments = list()
|
||||||
self.connect_events()
|
self.connect_events()
|
||||||
self.tab.name = self.name
|
self.tab.name = self.name
|
||||||
if hasattr(self, "can_post") and self.can_post == False and hasattr(self.tab, "post"):
|
if hasattr(self, "can_post") and self.can_post == False and hasattr(self.tab, "post"):
|
||||||
self.tab.post.Enable(False)
|
self.tab.post.Enable(False)
|
||||||
|
|
||||||
def connect_events(self):
|
def connect_events(self):
|
||||||
widgetUtils.connect_event(self.tab.send, widgetUtils.BUTTON_PRESSED, self.send_chat_to_user)
|
widgetUtils.connect_event(self.tab.send, widgetUtils.BUTTON_PRESSED, self.send_chat_to_user)
|
||||||
widgetUtils.connect_event(self.tab.attachment, widgetUtils.BUTTON_PRESSED, self.add_attachment)
|
widgetUtils.connect_event(self.tab.attachment, widgetUtils.BUTTON_PRESSED, self.add_attachment)
|
||||||
widgetUtils.connect_event(self.tab.text, widgetUtils.KEYPRESS, self.catch_enter)
|
widgetUtils.connect_event(self.tab.text, widgetUtils.KEYPRESS, self.catch_enter)
|
||||||
widgetUtils.connect_event(self.tab.actions, widgetUtils.BUTTON_PRESSED, self.actions)
|
widgetUtils.connect_event(self.tab.actions, widgetUtils.BUTTON_PRESSED, self.actions)
|
||||||
self.tab.set_focus_function(self.onFocus)
|
self.tab.set_focus_function(self.onFocus)
|
||||||
|
|
||||||
def catch_enter(self, event, *args, **kwargs):
|
def catch_enter(self, event, *args, **kwargs):
|
||||||
shift=event.ShiftDown()
|
shift=event.ShiftDown()
|
||||||
if event.GetKeyCode() == wx.WXK_RETURN and shift == False:
|
if event.GetKeyCode() == wx.WXK_RETURN and shift == False:
|
||||||
return self.send_chat_to_user()
|
return self.send_chat_to_user()
|
||||||
t = time.time()
|
t = time.time()
|
||||||
if event.GetUnicodeKey() != wx.WXK_NONE and t-self.last_keypress > 5:
|
if event.GetUnicodeKey() != wx.WXK_NONE and t-self.last_keypress > 5:
|
||||||
self.last_keypress = t
|
self.last_keypress = t
|
||||||
call_threaded(self.session.vk.client.messages.setActivity, peer_id=self.kwargs["peer_id"], type="typing")
|
call_threaded(self.session.vk.client.messages.setActivity, peer_id=self.kwargs["peer_id"], type="typing")
|
||||||
event.Skip()
|
event.Skip()
|
||||||
|
|
||||||
def get_items(self, show_nextpage=False):
|
def get_items(self, show_nextpage=False):
|
||||||
""" Update buffer with newest items or get older items in the buffer."""
|
""" Update buffer with newest items or get older items in the buffer."""
|
||||||
if self.can_get_items == False: return
|
if self.can_get_items == False: return
|
||||||
retrieved = True
|
retrieved = True
|
||||||
try:
|
try:
|
||||||
num = getattr(self.session, "get_page")(show_nextpage=show_nextpage, name=self.name, *self.args, **self.kwargs)
|
num = getattr(self.session, "get_page")(show_nextpage=show_nextpage, name=self.name, *self.args, **self.kwargs)
|
||||||
except VkApiError as err:
|
except VkApiError as err:
|
||||||
log.error("Error {0}: {1}".format(err.code, err.error))
|
log.error("Error {0}: {1}".format(err.code, err.error))
|
||||||
retrieved = err.code
|
retrieved = err.code
|
||||||
return retrieved
|
return retrieved
|
||||||
except:
|
except:
|
||||||
log.exception("Connection error when updating buffer %s. Will try again in 2 minutes" % (self.name,))
|
log.exception("Connection error when updating buffer %s. Will try again in 2 minutes" % (self.name,))
|
||||||
return False
|
return False
|
||||||
if not hasattr(self, "tab"):
|
if not hasattr(self, "tab"):
|
||||||
# Create GUI associated to this buffer.
|
# Create GUI associated to this buffer.
|
||||||
self.create_tab(self.parent)
|
self.create_tab(self.parent)
|
||||||
# Add name to the new control so we could look for it when needed.
|
# Add name to the new control so we could look for it when needed.
|
||||||
self.tab.name = self.name
|
self.tab.name = self.name
|
||||||
if show_nextpage == False:
|
if show_nextpage == False:
|
||||||
if self.tab.history.GetValue() != "" and num > 0:
|
if self.tab.history.GetValue() != "" and num > 0:
|
||||||
v = [i for i in self.session.db[self.name]["items"][:num]]
|
v = [i for i in self.session.db[self.name]["items"][:num]]
|
||||||
[self.insert(i, False) for i in v]
|
[self.insert(i, False) for i in v]
|
||||||
else:
|
else:
|
||||||
[self.insert(i) for i in self.session.db[self.name]["items"][:num]]
|
[self.insert(i) for i in self.session.db[self.name]["items"][:num]]
|
||||||
else:
|
else:
|
||||||
if num > 0:
|
if num > 0:
|
||||||
# At this point we save more CPU and mathematical work if we just delete everything in the chat history and readd all messages.
|
# At this point we save more CPU and mathematical work if we just delete everything in the chat history and readd all messages.
|
||||||
# Otherwise we'd have to insert new lines at the top and recalculate positions everywhere else.
|
# Otherwise we'd have to insert new lines at the top and recalculate positions everywhere else.
|
||||||
# Firstly, we'd have to save the current focused object so we will place the user in the right part of the text after loading everything again.
|
# Firstly, we'd have to save the current focused object so we will place the user in the right part of the text after loading everything again.
|
||||||
focused_post = self.get_post()
|
focused_post = self.get_post()
|
||||||
self.chats = dict()
|
self.chats = dict()
|
||||||
wx.CallAfter(self.tab.history.SetValue, "")
|
wx.CallAfter(self.tab.history.SetValue, "")
|
||||||
v = [i for i in self.session.db[self.name]["items"]]
|
v = [i for i in self.session.db[self.name]["items"]]
|
||||||
[self.insert(i) for i in v]
|
[self.insert(i) for i in v]
|
||||||
# Now it's time to set back the focus in the post.
|
# Now it's time to set back the focus in the post.
|
||||||
for i in self.chats.keys():
|
for i in self.chats.keys():
|
||||||
if self.chats[i] == focused_post["id"]:
|
if self.chats[i] == focused_post["id"]:
|
||||||
line = i[0]
|
line = i[0]
|
||||||
wx.CallAfter(self.tab.history.SetInsertionPoint, self.tab.history.XYToPosition(0, line))
|
wx.CallAfter(self.tab.history.SetInsertionPoint, self.tab.history.XYToPosition(0, line))
|
||||||
output.speak(_("Items loaded"))
|
output.speak(_("Items loaded"))
|
||||||
break
|
break
|
||||||
if self.unread == True and num > 0:
|
if self.unread == True and num > 0:
|
||||||
self.session.db[self.name]["items"][-1].update(read_state=0)
|
self.session.db[self.name]["items"][-1].update(read_state=0)
|
||||||
return retrieved
|
return retrieved
|
||||||
|
|
||||||
def get_more_items(self):
|
def get_more_items(self):
|
||||||
output.speak(_("Getting more items..."))
|
output.speak(_("Getting more items..."))
|
||||||
call_threaded(self.get_items, show_nextpage=True)
|
call_threaded(self.get_items, show_nextpage=True)
|
||||||
|
|
||||||
def add_attachment(self, *args, **kwargs):
|
def add_attachment(self, *args, **kwargs):
|
||||||
a = presenters.attachPresenter(session=self.session, view=views.attachDialog(voice_messages=True), interactor=interactors.attachInteractor())
|
a = presenters.attachPresenter(session=self.session, view=views.attachDialog(voice_messages=True), interactor=interactors.attachInteractor())
|
||||||
if len(a.attachments) != 0:
|
if len(a.attachments) != 0:
|
||||||
self.attachments_to_be_sent = a.attachments
|
self.attachments_to_be_sent = a.attachments
|
||||||
|
|
||||||
def send_chat_to_user(self, *args, **kwargs):
|
def send_chat_to_user(self, *args, **kwargs):
|
||||||
text = self.tab.text.GetValue()
|
text = self.tab.text.GetValue()
|
||||||
if text == "" and not hasattr(self, "attachments_to_be_sent"):
|
if text == "" and not hasattr(self, "attachments_to_be_sent"):
|
||||||
wx.Bell()
|
wx.Bell()
|
||||||
return
|
return
|
||||||
self.tab.text.SetValue("")
|
self.tab.text.SetValue("")
|
||||||
post_arguments = dict(random_id = random.randint(0, 100000), peer_id=self.kwargs["peer_id"])
|
post_arguments = dict(random_id = random.randint(0, 100000), peer_id=self.kwargs["peer_id"])
|
||||||
if len(text) > 0:
|
if len(text) > 0:
|
||||||
post_arguments.update(message=text)
|
post_arguments.update(message=text)
|
||||||
if hasattr(self, "attachments_to_be_sent") and len(self.attachments_to_be_sent) > 0:
|
if hasattr(self, "attachments_to_be_sent") and len(self.attachments_to_be_sent) > 0:
|
||||||
attachments = self.attachments_to_be_sent[::]
|
attachments = self.attachments_to_be_sent[::]
|
||||||
else:
|
else:
|
||||||
attachments = []
|
attachments = []
|
||||||
call_threaded(pub.sendMessage, "post", parent_endpoint="messages", child_endpoint="send", from_buffer=self.name, attachments_list=attachments, post_arguments=post_arguments)
|
call_threaded(pub.sendMessage, "post", parent_endpoint="messages", child_endpoint="send", from_buffer=self.name, attachments_list=attachments, post_arguments=post_arguments)
|
||||||
if hasattr(self, "attachments_to_be_sent"):
|
if hasattr(self, "attachments_to_be_sent"):
|
||||||
del self.attachments_to_be_sent
|
del self.attachments_to_be_sent
|
||||||
|
|
||||||
def __init__(self, unread=False, *args, **kwargs):
|
def __init__(self, unread=False, *args, **kwargs):
|
||||||
super(chatBuffer, self).__init__(*args, **kwargs)
|
super(chatBuffer, self).__init__(*args, **kwargs)
|
||||||
self.unread = unread
|
self.unread = unread
|
||||||
self.chats = dict()
|
self.chats = dict()
|
||||||
self.peer_typing = 0
|
self.peer_typing = 0
|
||||||
self.last_keypress = time.time()
|
self.last_keypress = time.time()
|
||||||
|
|
||||||
def parse_attachments(self, post):
|
def parse_attachments(self, post):
|
||||||
attachments = []
|
attachments = []
|
||||||
|
|
||||||
if "attachments" in post:
|
if "attachments" in post:
|
||||||
for i in post["attachments"]:
|
for i in post["attachments"]:
|
||||||
# We don't need the photos_list attachment, so skip it.
|
# We don't need the photos_list attachment, so skip it.
|
||||||
if i["type"] == "photos_list":
|
if i["type"] == "photos_list":
|
||||||
continue
|
continue
|
||||||
try:
|
try:
|
||||||
rendered_object = renderers.add_attachment(i)
|
rendered_object = renderers.add_attachment(i)
|
||||||
except:
|
except:
|
||||||
log.exception("Error parsing the following attachment on chat: %r" % (i,))
|
log.exception("Error parsing the following attachment on chat: %r" % (i,))
|
||||||
attachments.append(rendered_object)
|
attachments.append(rendered_object)
|
||||||
self.attachments.append(i)
|
self.attachments.append(i)
|
||||||
self.tab.attachments.list.Bind(wx.EVT_LIST_ITEM_ACTIVATED, self.open_attachment)
|
self.tab.attachments.list.Bind(wx.EVT_LIST_ITEM_ACTIVATED, self.open_attachment)
|
||||||
self.tab.insert_attachments(attachments)
|
self.tab.insert_attachments(attachments)
|
||||||
|
|
||||||
def open_attachment(self, *args, **kwargs):
|
def open_attachment(self, *args, **kwargs):
|
||||||
index = self.tab.attachments.get_selected()
|
index = self.tab.attachments.get_selected()
|
||||||
attachment = self.attachments[index]
|
attachment = self.attachments[index]
|
||||||
if attachment["type"] == "audio":
|
if attachment["type"] == "audio":
|
||||||
a = presenters.displayAudioPresenter(session=self.session, postObject=[attachment["audio"]], interactor=interactors.displayAudioInteractor(), view=views.displayAudio())
|
a = presenters.displayAudioPresenter(session=self.session, postObject=[attachment["audio"]], interactor=interactors.displayAudioInteractor(), view=views.displayAudio())
|
||||||
elif attachment["type"] == "audio_message":
|
elif attachment["type"] == "audio_message":
|
||||||
link = attachment["audio_message"]["link_mp3"]
|
link = attachment["audio_message"]["link_mp3"]
|
||||||
pub.sendMessage("play-message", message_url=link)
|
pub.sendMessage("play-message", message_url=link)
|
||||||
elif attachment["type"] == "link":
|
elif attachment["type"] == "link":
|
||||||
output.speak(_("Opening URL..."), True)
|
output.speak(_("Opening URL..."), True)
|
||||||
webbrowser.open_new_tab(attachment["link"]["url"])
|
webbrowser.open_new_tab(attachment["link"]["url"])
|
||||||
elif attachment["type"] == "doc":
|
elif attachment["type"] == "doc":
|
||||||
output.speak(_("Opening document in web browser..."))
|
output.speak(_("Opening document in web browser..."))
|
||||||
webbrowser.open(attachment["doc"]["url"])
|
webbrowser.open(attachment["doc"]["url"])
|
||||||
elif attachment["type"] == "video":
|
elif attachment["type"] == "video":
|
||||||
# it seems VK doesn't like to attach video links as normal URLS, so we'll have to
|
# it seems VK doesn't like to attach video links as normal URLS, so we'll have to
|
||||||
# get the full video object and use its "player" key which will open a webbrowser in their site with a player for the video.
|
# get the full video object and use its "player" key which will open a webbrowser in their site with a player for the video.
|
||||||
# see https://vk.com/dev/attachments_w and and https://vk.com/dev/video.get
|
# see https://vk.com/dev/attachments_w and and https://vk.com/dev/video.get
|
||||||
# However, the flash player isn't good for visually impaired people (when you press play you won't be able to close the window with alt+f4), so it could be good to use the HTML5 player.
|
# However, the flash player isn't good for visually impaired people (when you press play you won't be able to close the window with alt+f4), so it could be good to use the HTML5 player.
|
||||||
# For firefox, see https://addons.mozilla.org/ru/firefox/addon/force-html5-video-player-at-vk/
|
# For firefox, see https://addons.mozilla.org/ru/firefox/addon/force-html5-video-player-at-vk/
|
||||||
# May be I could use a dialogue here for inviting people to use this addon in firefox. It seems it isn't possible to use this html5 player from the player URL.
|
# May be I could use a dialogue here for inviting people to use this addon in firefox. It seems it isn't possible to use this html5 player from the player URL.
|
||||||
object_id = "{0}_{1}".format(attachment["video"]["owner_id"], attachment["video"]["id"])
|
object_id = "{0}_{1}".format(attachment["video"]["owner_id"], attachment["video"]["id"])
|
||||||
video_object = self.session.vk.client.video.get(owner_id=attachment["video"]["owner_id"], videos=object_id)
|
video_object = self.session.vk.client.video.get(owner_id=attachment["video"]["owner_id"], videos=object_id)
|
||||||
video_object = video_object["items"][0]
|
video_object = video_object["items"][0]
|
||||||
output.speak(_("Opening video in web browser..."), True)
|
output.speak(_("Opening video in web browser..."), True)
|
||||||
webbrowser.open_new_tab(video_object["player"])
|
webbrowser.open_new_tab(video_object["player"])
|
||||||
elif attachment["type"] == "photo":
|
elif attachment["type"] == "photo":
|
||||||
output.speak(_("Opening photo in web browser..."), True)
|
output.speak(_("Opening photo in web browser..."), True)
|
||||||
# Possible photo sizes for looking in the attachment information. Try to use the biggest photo available.
|
# Possible photo sizes for looking in the attachment information. Try to use the biggest photo available.
|
||||||
possible_sizes = [1280, 604, 130, 75]
|
possible_sizes = [1280, 604, 130, 75]
|
||||||
url = ""
|
url = ""
|
||||||
for i in possible_sizes:
|
for i in possible_sizes:
|
||||||
if "photo_{0}".format(i,) in attachment["photo"]:
|
if "photo_{0}".format(i,) in attachment["photo"]:
|
||||||
url = attachment["photo"]["photo_{0}".format(i,)]
|
url = attachment["photo"]["photo_{0}".format(i,)]
|
||||||
break
|
break
|
||||||
if url != "":
|
if url != "":
|
||||||
webbrowser.open_new_tab(url)
|
webbrowser.open_new_tab(url)
|
||||||
if attachment["type"] == "wall":
|
if attachment["type"] == "wall":
|
||||||
pub.sendMessage("open-post", post_object=attachment["wall"], controller_="displayPost")
|
pub.sendMessage("open-post", post_object=attachment["wall"], controller_="displayPost")
|
||||||
else:
|
else:
|
||||||
log.debug("Unhandled attachment: %r" % (attachment,))
|
log.debug("Unhandled attachment: %r" % (attachment,))
|
||||||
|
|
||||||
def clear_reads(self):
|
def clear_reads(self):
|
||||||
for i in self.session.db[self.name]["items"]:
|
for i in self.session.db[self.name]["items"]:
|
||||||
if "read_state" in i and i["read_state"] == 0:
|
if "read_state" in i and i["read_state"] == 0:
|
||||||
i["read_state"] = 1
|
i["read_state"] = 1
|
||||||
|
|
||||||
def remove_buffer(self, mandatory=False):
|
def remove_buffer(self, mandatory=False):
|
||||||
""" Remove buffer if the current buffer is not the logged user's wall."""
|
""" Remove buffer if the current buffer is not the logged user's wall."""
|
||||||
if mandatory == False:
|
if mandatory == False:
|
||||||
dlg = commonMessages.remove_buffer()
|
dlg = commonMessages.remove_buffer()
|
||||||
else:
|
else:
|
||||||
dlg = widgetUtils.YES
|
dlg = widgetUtils.YES
|
||||||
if dlg == widgetUtils.YES:
|
if dlg == widgetUtils.YES:
|
||||||
self.session.db.pop(self.name)
|
self.session.db.pop(self.name)
|
||||||
return True
|
return True
|
||||||
else:
|
else:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def open_in_browser(self, *args, **kwargs):
|
def open_in_browser(self, *args, **kwargs):
|
||||||
peer_id = self.kwargs["peer_id"]
|
peer_id = self.kwargs["peer_id"]
|
||||||
url = "https://vk.com/im?sel={peer_id}".format(peer_id=peer_id)
|
url = "https://vk.com/im?sel={peer_id}".format(peer_id=peer_id)
|
||||||
webbrowser.open_new_tab(url)
|
webbrowser.open_new_tab(url)
|
||||||
|
|
||||||
def actions(self, *args, **kwargs):
|
def actions(self, *args, **kwargs):
|
||||||
menu = menus.toolsMenu()
|
menu = menus.toolsMenu()
|
||||||
widgetUtils.connect_event(menu, widgetUtils.MENU, self.translate_action, menuitem=menu.translate)
|
widgetUtils.connect_event(menu, widgetUtils.MENU, self.translate_action, menuitem=menu.translate)
|
||||||
widgetUtils.connect_event(menu, widgetUtils.MENU, self.spellcheck_action, menuitem=menu.spellcheck)
|
widgetUtils.connect_event(menu, widgetUtils.MENU, self.spellcheck_action, menuitem=menu.spellcheck)
|
||||||
self.tab.PopupMenu(menu, self.tab.actions.GetPosition())
|
self.tab.PopupMenu(menu, self.tab.actions.GetPosition())
|
||||||
|
|
||||||
def translate(self, text):
|
def translate(self, text):
|
||||||
dlg = translator.gui.translateDialog()
|
dlg = translator.gui.translateDialog()
|
||||||
if dlg.get_response() == widgetUtils.OK:
|
if dlg.get_response() == widgetUtils.OK:
|
||||||
language_dict = translator.translator.available_languages()
|
language_dict = translator.translator.available_languages()
|
||||||
for k in language_dict:
|
for k in language_dict:
|
||||||
if language_dict[k] == dlg.dest_lang.GetStringSelection():
|
if language_dict[k] == dlg.dest_lang.GetStringSelection():
|
||||||
dst = k
|
dst = k
|
||||||
msg = translator.translator.translate(text, dst)
|
msg = translator.translator.translate(text, dst)
|
||||||
dlg.Destroy()
|
dlg.Destroy()
|
||||||
return msg
|
return msg
|
||||||
|
|
||||||
def spellcheck(self, text):
|
def spellcheck(self, text):
|
||||||
checker = SpellChecker.spellchecker.spellChecker(text)
|
checker = SpellChecker.spellchecker.spellChecker(text)
|
||||||
if hasattr(checker, "fixed_text"):
|
if hasattr(checker, "fixed_text"):
|
||||||
final_text = checker.fixed_text
|
final_text = checker.fixed_text
|
||||||
return final_text
|
return final_text
|
||||||
|
|
||||||
def translate_action(self, *args, **kwargs):
|
def translate_action(self, *args, **kwargs):
|
||||||
text = self.tab.text.GetValue()
|
text = self.tab.text.GetValue()
|
||||||
if text == "":
|
if text == "":
|
||||||
wx.Bell()
|
wx.Bell()
|
||||||
return
|
return
|
||||||
translated = self.translate(text)
|
translated = self.translate(text)
|
||||||
if translated != None:
|
if translated != None:
|
||||||
self.tab.text.ChangeValue(translated)
|
self.tab.text.ChangeValue(translated)
|
||||||
self.tab.text.SetFocus()
|
self.tab.text.SetFocus()
|
||||||
|
|
||||||
def spellcheck_action(self, *args, **kwargs):
|
def spellcheck_action(self, *args, **kwargs):
|
||||||
text = self.tab.text.GetValue()
|
text = self.tab.text.GetValue()
|
||||||
fixed = self.spellcheck(text)
|
fixed = self.spellcheck(text)
|
||||||
if fixed != None:
|
if fixed != None:
|
||||||
self.tab.text.ChangeValue(fixed)
|
self.tab.text.ChangeValue(fixed)
|
||||||
self.tab.text.SetFocus()
|
self.tab.text.SetFocus()
|
||||||
|
|
||||||
def translate_message(self, *args, **kwargs):
|
def translate_message(self, *args, **kwargs):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def spellcheck_message(self, *args, **kwargs):
|
def spellcheck_message(self, *args, **kwargs):
|
||||||
pass
|
pass
|
||||||
|
@ -16,53 +16,53 @@ log = logging.getLogger("controller.buffers.communityBoard")
|
|||||||
|
|
||||||
class communityBoardBuffer(wallBuffer):
|
class communityBoardBuffer(wallBuffer):
|
||||||
|
|
||||||
def create_tab(self, parent):
|
def create_tab(self, parent):
|
||||||
self.tab = communityBoard.communityBoardTab(parent)
|
self.tab = communityBoard.communityBoardTab(parent)
|
||||||
self.connect_events()
|
self.connect_events()
|
||||||
self.tab.name = self.name
|
self.tab.name = self.name
|
||||||
if "can_create_topic" not in self.session.db["group_info"][self.kwargs["group_id"]*-1] or ("can_create_topic" in self.session.db["group_info"][self.kwargs["group_id"]*-1] and self.session.db["group_info"][self.kwargs["group_id"]*-1]["can_create_topic"] != True):
|
if "can_create_topic" not in self.session.db["group_info"][self.kwargs["group_id"]*-1] or ("can_create_topic" in self.session.db["group_info"][self.kwargs["group_id"]*-1] and self.session.db["group_info"][self.kwargs["group_id"]*-1]["can_create_topic"] != True):
|
||||||
self.tab.post.Enable(False)
|
self.tab.post.Enable(False)
|
||||||
|
|
||||||
def onFocus(self, event, *args, **kwargs):
|
def onFocus(self, event, *args, **kwargs):
|
||||||
event.Skip()
|
event.Skip()
|
||||||
|
|
||||||
def open_post(self, *args, **kwargs):
|
def open_post(self, *args, **kwargs):
|
||||||
""" Opens the currently focused post."""
|
""" Opens the currently focused post."""
|
||||||
post = self.get_post()
|
post = self.get_post()
|
||||||
if post == None:
|
if post == None:
|
||||||
return
|
return
|
||||||
a = presenters.displayTopicPresenter(session=self.session, postObject=post, group_id=self.kwargs["group_id"], interactor=interactors.displayPostInteractor(), view=views.displayTopic())
|
a = presenters.displayTopicPresenter(session=self.session, postObject=post, group_id=self.kwargs["group_id"], interactor=interactors.displayPostInteractor(), view=views.displayTopic())
|
||||||
|
|
||||||
def open_in_browser(self, *args, **kwargs):
|
def open_in_browser(self, *args, **kwargs):
|
||||||
post = self.get_post()
|
post = self.get_post()
|
||||||
if post == None:
|
if post == None:
|
||||||
return
|
return
|
||||||
# In order to load the selected topic we firstly have to catch the group_id, which is present in self.kwargs
|
# In order to load the selected topic we firstly have to catch the group_id, which is present in self.kwargs
|
||||||
# After getting the group_id we should make it negative
|
# After getting the group_id we should make it negative
|
||||||
group_id = self.kwargs["group_id"]*-1
|
group_id = self.kwargs["group_id"]*-1
|
||||||
url = "https://vk.com/topic{group_id}_{topic_id}".format(group_id=group_id, topic_id=post["id"])
|
url = "https://vk.com/topic{group_id}_{topic_id}".format(group_id=group_id, topic_id=post["id"])
|
||||||
webbrowser.open_new_tab(url)
|
webbrowser.open_new_tab(url)
|
||||||
|
|
||||||
def post(self, *args, **kwargs):
|
def post(self, *args, **kwargs):
|
||||||
menu = wx.Menu()
|
menu = wx.Menu()
|
||||||
user1 = self.session.get_user(self.session.user_id)
|
user1 = self.session.get_user(self.session.user_id)
|
||||||
user2 = self.session.get_user(-1*self.kwargs["group_id"])
|
user2 = self.session.get_user(-1*self.kwargs["group_id"])
|
||||||
user = menu.Append(wx.NewId(), _("Post as {user1_nom}").format(**user1))
|
user = menu.Append(wx.NewId(), _("Post as {user1_nom}").format(**user1))
|
||||||
group = menu.Append(wx.NewId(), _("Post as {user1_nom}").format(**user2))
|
group = menu.Append(wx.NewId(), _("Post as {user1_nom}").format(**user2))
|
||||||
menu.Bind(widgetUtils.MENU, lambda evt: self._post(evt, 1), group)
|
menu.Bind(widgetUtils.MENU, lambda evt: self._post(evt, 1), group)
|
||||||
menu.Bind(widgetUtils.MENU, lambda evt: self._post(evt, 0), user)
|
menu.Bind(widgetUtils.MENU, lambda evt: self._post(evt, 0), user)
|
||||||
self.tab.post.PopupMenu(menu, self.tab.post.GetPosition())
|
self.tab.post.PopupMenu(menu, self.tab.post.GetPosition())
|
||||||
|
|
||||||
def _post(self, event, from_group):
|
def _post(self, event, from_group):
|
||||||
owner_id = self.kwargs["group_id"]
|
owner_id = self.kwargs["group_id"]
|
||||||
user = self.session.get_user(-1*owner_id, key="user1")
|
user = self.session.get_user(-1*owner_id, key="user1")
|
||||||
title = _("Create topic in {user1_nom}").format(**user)
|
title = _("Create topic in {user1_nom}").format(**user)
|
||||||
p = presenters.createPostPresenter(session=self.session, interactor=interactors.createPostInteractor(), view=views.createTopicDialog(title=title, message="", text="", topic_title=""))
|
p = presenters.createPostPresenter(session=self.session, interactor=interactors.createPostInteractor(), view=views.createTopicDialog(title=title, message="", text="", topic_title=""))
|
||||||
if hasattr(p, "text") or hasattr(p, "privacy"):
|
if hasattr(p, "text") or hasattr(p, "privacy"):
|
||||||
title = p.view.title.GetValue()
|
title = p.view.title.GetValue()
|
||||||
msg = p.text
|
msg = p.text
|
||||||
post_arguments = dict(title=title, text=msg, group_id=owner_id, from_group=from_group)
|
post_arguments = dict(title=title, text=msg, group_id=owner_id, from_group=from_group)
|
||||||
attachments = []
|
attachments = []
|
||||||
if hasattr(p, "attachments"):
|
if hasattr(p, "attachments"):
|
||||||
attachments = p.attachments
|
attachments = p.attachments
|
||||||
call_threaded(pub.sendMessage, "post", parent_endpoint="board", child_endpoint="addTopic", from_buffer=self.name, attachments_list=attachments, post_arguments=post_arguments)
|
call_threaded(pub.sendMessage, "post", parent_endpoint="board", child_endpoint="addTopic", from_buffer=self.name, attachments_list=attachments, post_arguments=post_arguments)
|
||||||
|
@ -6,11 +6,11 @@ from .documents import documentsBuffer
|
|||||||
log = logging.getLogger("controller.buffers.communityDocuments")
|
log = logging.getLogger("controller.buffers.communityDocuments")
|
||||||
|
|
||||||
class communityDocumentsBuffer(documentsBuffer):
|
class communityDocumentsBuffer(documentsBuffer):
|
||||||
can_get_items = True
|
can_get_items = True
|
||||||
|
|
||||||
def create_tab(self, parent):
|
def create_tab(self, parent):
|
||||||
self.tab = communityDocuments.communityDocumentsTab(parent)
|
self.tab = communityDocuments.communityDocumentsTab(parent)
|
||||||
self.connect_events()
|
self.connect_events()
|
||||||
self.tab.name = self.name
|
self.tab.name = self.name
|
||||||
if hasattr(self, "can_post") and self.can_post == False and hasattr(self.tab, "post"):
|
if hasattr(self, "can_post") and self.can_post == False and hasattr(self.tab, "post"):
|
||||||
self.tab.post.Enable(False)
|
self.tab.post.Enable(False)
|
||||||
|
@ -8,19 +8,19 @@ log = logging.getLogger("controller.buffers.communityPeople")
|
|||||||
|
|
||||||
class communityPeopleBuffer(peopleBuffer):
|
class communityPeopleBuffer(peopleBuffer):
|
||||||
|
|
||||||
def get_menu(self, *args, **kwargs):
|
def get_menu(self, *args, **kwargs):
|
||||||
user = self.get_post()
|
user = self.get_post()
|
||||||
m = wx.Menu()
|
m = wx.Menu()
|
||||||
if user.get("can_post") == True:
|
if user.get("can_post") == True:
|
||||||
can_post = m.Append(wx.NewId(), _("&Post on user's wall"))
|
can_post = m.Append(wx.NewId(), _("&Post on user's wall"))
|
||||||
widgetUtils.connect_event(m, widgetUtils.MENU, self.post, menuitem=can_post)
|
widgetUtils.connect_event(m, widgetUtils.MENU, self.post, menuitem=can_post)
|
||||||
if user.get("can_write_private_message") == True:
|
if user.get("can_write_private_message") == True:
|
||||||
can_write_message = m.Append(wx.Id(), _("Send message"))
|
can_write_message = m.Append(wx.Id(), _("Send message"))
|
||||||
widgetUtils.connect_event(m, widgetUtils.MENU, self.new_chat, menuitem=can_write_message)
|
widgetUtils.connect_event(m, widgetUtils.MENU, self.new_chat, menuitem=can_write_message)
|
||||||
profile = m.Append(wx.NewId(), _("View profile"))
|
profile = m.Append(wx.NewId(), _("View profile"))
|
||||||
widgetUtils.connect_event(m, widgetUtils.MENU, self.open_person_profile, menuitem=profile)
|
widgetUtils.connect_event(m, widgetUtils.MENU, self.open_person_profile, menuitem=profile)
|
||||||
timeline = m.Append(wx.NewId(), _("Open timeline"))
|
timeline = m.Append(wx.NewId(), _("Open timeline"))
|
||||||
widgetUtils.connect_event(m, widgetUtils.MENU, self.open_timeline, menuitem=timeline)
|
widgetUtils.connect_event(m, widgetUtils.MENU, self.open_timeline, menuitem=timeline)
|
||||||
open_in_browser = m.Append(wx.NewId(), _("Open in vk.com"))
|
open_in_browser = m.Append(wx.NewId(), _("Open in vk.com"))
|
||||||
widgetUtils.connect_event(m, widgetUtils.MENU, self.open_in_browser, menuitem=open_in_browser)
|
widgetUtils.connect_event(m, widgetUtils.MENU, self.open_in_browser, menuitem=open_in_browser)
|
||||||
return m
|
return m
|
||||||
|
@ -16,54 +16,54 @@ log = logging.getLogger("controller.buffers.communityWall")
|
|||||||
|
|
||||||
class communityWallBuffer(wallBuffer):
|
class communityWallBuffer(wallBuffer):
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
super(communityWallBuffer, self).__init__(*args, **kwargs)
|
super(communityWallBuffer, self).__init__(*args, **kwargs)
|
||||||
self.group_id = self.kwargs["owner_id"]
|
self.group_id = self.kwargs["owner_id"]
|
||||||
|
|
||||||
def create_tab(self, parent):
|
def create_tab(self, parent):
|
||||||
self.tab = communityWall.communityWallTab(parent)
|
self.tab = communityWall.communityWallTab(parent)
|
||||||
self.connect_events()
|
self.connect_events()
|
||||||
self.tab.name = self.name
|
self.tab.name = self.name
|
||||||
self.tab.post.Enable(False)
|
self.tab.post.Enable(False)
|
||||||
|
|
||||||
def connect_events(self):
|
def connect_events(self):
|
||||||
super(communityWallBuffer, self).connect_events()
|
super(communityWallBuffer, self).connect_events()
|
||||||
widgetUtils.connect_event(self.tab.load, widgetUtils.BUTTON_PRESSED, self.load_community)
|
widgetUtils.connect_event(self.tab.load, widgetUtils.BUTTON_PRESSED, self.load_community)
|
||||||
|
|
||||||
def load_community(self, *args, **kwargs):
|
def load_community(self, *args, **kwargs):
|
||||||
output.speak(_("Loading community..."))
|
output.speak(_("Loading community..."))
|
||||||
self.can_get_items = True
|
self.can_get_items = True
|
||||||
self.tab.load.Enable(False)
|
self.tab.load.Enable(False)
|
||||||
wx.CallAfter(self.get_items)
|
wx.CallAfter(self.get_items)
|
||||||
|
|
||||||
def get_items(self, *args, **kwargs):
|
def get_items(self, *args, **kwargs):
|
||||||
""" This method retrieves community information, useful to show different parts of the community itself."""
|
""" This method retrieves community information, useful to show different parts of the community itself."""
|
||||||
if self.can_get_items:
|
if self.can_get_items:
|
||||||
# Strangely, groups.get does not return counters so we need those to show options for loading specific posts for communities.
|
# Strangely, groups.get does not return counters so we need those to show options for loading specific posts for communities.
|
||||||
group_info = self.session.vk.client.groups.getById(group_ids=-1*self.kwargs["owner_id"], fields="counters")[0]
|
group_info = self.session.vk.client.groups.getById(group_ids=-1*self.kwargs["owner_id"], fields="counters")[0]
|
||||||
self.session.db["group_info"][self.group_id].update(group_info)
|
self.session.db["group_info"][self.group_id].update(group_info)
|
||||||
if "can_post" in self.session.db["group_info"][self.group_id] and self.session.db["group_info"][self.group_id]["can_post"] == True:
|
if "can_post" in self.session.db["group_info"][self.group_id] and self.session.db["group_info"][self.group_id]["can_post"] == True:
|
||||||
self.tab.post.Enable(True)
|
self.tab.post.Enable(True)
|
||||||
super(communityWallBuffer, self).get_items(*args, **kwargs)
|
super(communityWallBuffer, self).get_items(*args, **kwargs)
|
||||||
|
|
||||||
def post(self, *args, **kwargs):
|
def post(self, *args, **kwargs):
|
||||||
menu = wx.Menu()
|
menu = wx.Menu()
|
||||||
user1 = self.session.get_user(self.session.user_id)
|
user1 = self.session.get_user(self.session.user_id)
|
||||||
user2 = self.session.get_user(self.kwargs["owner_id"])
|
user2 = self.session.get_user(self.kwargs["owner_id"])
|
||||||
user = menu.Append(wx.NewId(), _("Post as {user1_nom}").format(**user1))
|
user = menu.Append(wx.NewId(), _("Post as {user1_nom}").format(**user1))
|
||||||
group = menu.Append(wx.NewId(), _("Post as {user1_nom}").format(**user2))
|
group = menu.Append(wx.NewId(), _("Post as {user1_nom}").format(**user2))
|
||||||
menu.Bind(widgetUtils.MENU, lambda evt: self._post(evt, 1), group)
|
menu.Bind(widgetUtils.MENU, lambda evt: self._post(evt, 1), group)
|
||||||
menu.Bind(widgetUtils.MENU, lambda evt: self._post(evt, 0), user)
|
menu.Bind(widgetUtils.MENU, lambda evt: self._post(evt, 0), user)
|
||||||
self.tab.post.PopupMenu(menu, self.tab.post.GetPosition())
|
self.tab.post.PopupMenu(menu, self.tab.post.GetPosition())
|
||||||
|
|
||||||
def _post(self, event, from_group):
|
def _post(self, event, from_group):
|
||||||
owner_id = self.kwargs["owner_id"]
|
owner_id = self.kwargs["owner_id"]
|
||||||
user = self.session.get_user(owner_id, key="user1")
|
user = self.session.get_user(owner_id, key="user1")
|
||||||
title = _("Post to {user1_nom}'s wall").format(**user)
|
title = _("Post to {user1_nom}'s wall").format(**user)
|
||||||
p = presenters.createPostPresenter(session=self.session, interactor=interactors.createPostInteractor(), view=views.createPostDialog(title=title, message="", text=""))
|
p = presenters.createPostPresenter(session=self.session, interactor=interactors.createPostInteractor(), view=views.createPostDialog(title=title, message="", text=""))
|
||||||
if hasattr(p, "text") or hasattr(p, "privacy"):
|
if hasattr(p, "text") or hasattr(p, "privacy"):
|
||||||
post_arguments=dict(privacy=p.privacy, message=p.text, owner_id=owner_id, from_group=from_group)
|
post_arguments=dict(privacy=p.privacy, message=p.text, owner_id=owner_id, from_group=from_group)
|
||||||
attachments = []
|
attachments = []
|
||||||
if hasattr(p, "attachments"):
|
if hasattr(p, "attachments"):
|
||||||
attachments = p.attachments
|
attachments = p.attachments
|
||||||
call_threaded(pub.sendMessage, "post", parent_endpoint="wall", child_endpoint="post", from_buffer=self.name, attachments_list=attachments, post_arguments=post_arguments)
|
call_threaded(pub.sendMessage, "post", parent_endpoint="wall", child_endpoint="post", from_buffer=self.name, attachments_list=attachments, post_arguments=post_arguments)
|
||||||
|
@ -17,77 +17,77 @@ from .wall import wallBuffer
|
|||||||
log = logging.getLogger("controller.buffers.documents")
|
log = logging.getLogger("controller.buffers.documents")
|
||||||
|
|
||||||
class documentsBuffer(wallBuffer):
|
class documentsBuffer(wallBuffer):
|
||||||
can_get_items = False
|
can_get_items = False
|
||||||
|
|
||||||
def create_tab(self, parent):
|
def create_tab(self, parent):
|
||||||
self.tab = documents.documentsTab(parent)
|
self.tab = documents.documentsTab(parent)
|
||||||
self.connect_events()
|
self.connect_events()
|
||||||
self.tab.name = self.name
|
self.tab.name = self.name
|
||||||
if hasattr(self, "can_post") and self.can_post == False and hasattr(self.tab, "post"):
|
if hasattr(self, "can_post") and self.can_post == False and hasattr(self.tab, "post"):
|
||||||
self.tab.post.Enable(False)
|
self.tab.post.Enable(False)
|
||||||
|
|
||||||
def onFocus(self, event, *args,**kwargs):
|
def onFocus(self, event, *args,**kwargs):
|
||||||
post = self.get_post()
|
post = self.get_post()
|
||||||
if post == None:
|
if post == None:
|
||||||
return
|
return
|
||||||
original_date = arrow.get(post["date"])
|
original_date = arrow.get(post["date"])
|
||||||
created_at = original_date.humanize(locale=languageHandler.curLang[:2])
|
created_at = original_date.humanize(locale=languageHandler.curLang[:2])
|
||||||
self.tab.list.list.SetItem(self.tab.list.get_selected(), 4, created_at)
|
self.tab.list.list.SetItem(self.tab.list.get_selected(), 4, created_at)
|
||||||
event.Skip()
|
event.Skip()
|
||||||
|
|
||||||
def connect_events(self):
|
def connect_events(self):
|
||||||
super(documentsBuffer, self).connect_events()
|
super(documentsBuffer, self).connect_events()
|
||||||
# Check if we have a load button in the tab, because documents community buffers don't include it.
|
# Check if we have a load button in the tab, because documents community buffers don't include it.
|
||||||
if hasattr(self.tab, "load"):
|
if hasattr(self.tab, "load"):
|
||||||
widgetUtils.connect_event(self.tab.load, widgetUtils.BUTTON_PRESSED, self.load_documents)
|
widgetUtils.connect_event(self.tab.load, widgetUtils.BUTTON_PRESSED, self.load_documents)
|
||||||
|
|
||||||
def load_documents(self, *args, **kwargs):
|
def load_documents(self, *args, **kwargs):
|
||||||
output.speak(_("Loading documents..."))
|
output.speak(_("Loading documents..."))
|
||||||
self.can_get_items = True
|
self.can_get_items = True
|
||||||
self.tab.load.Enable(False)
|
self.tab.load.Enable(False)
|
||||||
wx.CallAfter(self.get_items)
|
wx.CallAfter(self.get_items)
|
||||||
|
|
||||||
def get_menu(self):
|
def get_menu(self):
|
||||||
p = self.get_post()
|
p = self.get_post()
|
||||||
if p == None:
|
if p == None:
|
||||||
return
|
return
|
||||||
if p["owner_id"] == self.session.user_id:
|
if p["owner_id"] == self.session.user_id:
|
||||||
added = True
|
added = True
|
||||||
else:
|
else:
|
||||||
added = False
|
added = False
|
||||||
m = menus.documentMenu(added)
|
m = menus.documentMenu(added)
|
||||||
widgetUtils.connect_event(m, widgetUtils.MENU, self.add_remove_document, menuitem=m.action)
|
widgetUtils.connect_event(m, widgetUtils.MENU, self.add_remove_document, menuitem=m.action)
|
||||||
widgetUtils.connect_event(m, widgetUtils.MENU, self.download, menuitem=m.download)
|
widgetUtils.connect_event(m, widgetUtils.MENU, self.download, menuitem=m.download)
|
||||||
widgetUtils.connect_event(m, widgetUtils.MENU, self.open_in_browser, menuitem=m.open_in_browser)
|
widgetUtils.connect_event(m, widgetUtils.MENU, self.open_in_browser, menuitem=m.open_in_browser)
|
||||||
return m
|
return m
|
||||||
|
|
||||||
def add_remove_document(self, *args, **kwargs):
|
def add_remove_document(self, *args, **kwargs):
|
||||||
p = self.get_post()
|
p = self.get_post()
|
||||||
if p == None:
|
if p == None:
|
||||||
return
|
return
|
||||||
if p["owner_id"] == self.session.user_id:
|
if p["owner_id"] == self.session.user_id:
|
||||||
result = self.session.vk.client.docs.delete(owner_id=p["owner_id"], doc_id=p["id"])
|
result = self.session.vk.client.docs.delete(owner_id=p["owner_id"], doc_id=p["id"])
|
||||||
if result == 1:
|
if result == 1:
|
||||||
output.speak(_("The document has been successfully deleted."))
|
output.speak(_("The document has been successfully deleted."))
|
||||||
self.session.db[self.name]["items"].pop(self.tab.list.get_selected())
|
self.session.db[self.name]["items"].pop(self.tab.list.get_selected())
|
||||||
self.tab.list.remove_item(self.tab.list.get_selected())
|
self.tab.list.remove_item(self.tab.list.get_selected())
|
||||||
else:
|
else:
|
||||||
result = self.session.vk.client.docs.add(owner_id=p["owner_id"], doc_id=p["id"])
|
result = self.session.vk.client.docs.add(owner_id=p["owner_id"], doc_id=p["id"])
|
||||||
output.speak(_("The document has been successfully added."))
|
output.speak(_("The document has been successfully added."))
|
||||||
|
|
||||||
def download(self, *args, **kwargs):
|
def download(self, *args, **kwargs):
|
||||||
post = self.get_post()
|
post = self.get_post()
|
||||||
filename = utils.safe_filename(post["title"])
|
filename = utils.safe_filename(post["title"])
|
||||||
# If document does not end in .extension we must fix it so the file dialog will save it properly later.
|
# If document does not end in .extension we must fix it so the file dialog will save it properly later.
|
||||||
if filename.endswith(post["ext"]) == False:
|
if filename.endswith(post["ext"]) == False:
|
||||||
filename = filename+ "."+post["ext"]
|
filename = filename+ "."+post["ext"]
|
||||||
filepath = self.tab.get_download_path(filename)
|
filepath = self.tab.get_download_path(filename)
|
||||||
if filepath != None:
|
if filepath != None:
|
||||||
pub.sendMessage("download-file", url=post["url"], filename=filepath)
|
pub.sendMessage("download-file", url=post["url"], filename=filepath)
|
||||||
|
|
||||||
def open_in_browser(self, *args, **kwargs):
|
def open_in_browser(self, *args, **kwargs):
|
||||||
post = self.get_post()
|
post = self.get_post()
|
||||||
if post == None:
|
if post == None:
|
||||||
return
|
return
|
||||||
url = "https://vk.com/doc{user_id}_{post_id}".format(user_id=post["owner_id"], post_id=post["id"])
|
url = "https://vk.com/doc{user_id}_{post_id}".format(user_id=post["owner_id"], post_id=post["id"])
|
||||||
webbrowser.open_new_tab(url)
|
webbrowser.open_new_tab(url)
|
||||||
|
@ -8,20 +8,20 @@ log = logging.getLogger("controller.buffers.empty")
|
|||||||
|
|
||||||
class emptyBuffer(object):
|
class emptyBuffer(object):
|
||||||
|
|
||||||
def __init__(self, name=None, parent=None, *args, **kwargs):
|
def __init__(self, name=None, parent=None, *args, **kwargs):
|
||||||
self.tab = empty.emptyTab(parent=parent, name=name)
|
self.tab = empty.emptyTab(parent=parent, name=name)
|
||||||
self.name = name
|
self.name = name
|
||||||
|
|
||||||
def get_items(self, *args, **kwargs):
|
def get_items(self, *args, **kwargs):
|
||||||
if not hasattr(self, "tab"):
|
if not hasattr(self, "tab"):
|
||||||
# Create GUI associated to this buffer.
|
# Create GUI associated to this buffer.
|
||||||
self.create_tab(self.parent)
|
self.create_tab(self.parent)
|
||||||
# Add name to the new control so we could look for it when needed.
|
# Add name to the new control so we could look for it when needed.
|
||||||
self.tab.name = self.name
|
self.tab.name = self.name
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def get_more_items(self, *args, **kwargs):
|
def get_more_items(self, *args, **kwargs):
|
||||||
output.speak(_("This buffer doesn't support getting more items."))
|
output.speak(_("This buffer doesn't support getting more items."))
|
||||||
|
|
||||||
def remove_buffer(self, mandatory=False):
|
def remove_buffer(self, mandatory=False):
|
||||||
return False
|
return False
|
||||||
|
@ -9,73 +9,73 @@ log = logging.getLogger("controller.buffers.friendRequests")
|
|||||||
|
|
||||||
class friendRequestsBuffer(peopleBuffer):
|
class friendRequestsBuffer(peopleBuffer):
|
||||||
|
|
||||||
def get_items(self, show_nextpage=False):
|
def get_items(self, show_nextpage=False):
|
||||||
if self.can_get_items == False: return
|
if self.can_get_items == False: return
|
||||||
retrieved = True
|
retrieved = True
|
||||||
try:
|
try:
|
||||||
ids = self.session.vk.client.friends.getRequests(*self.args, **self.kwargs)
|
ids = self.session.vk.client.friends.getRequests(*self.args, **self.kwargs)
|
||||||
except VkApiError as err:
|
except VkApiError as err:
|
||||||
log.error("Error {0}: {1}".format(err.code, err.error))
|
log.error("Error {0}: {1}".format(err.code, err.error))
|
||||||
retrieved = err.code
|
retrieved = err.code
|
||||||
return retrieved
|
return retrieved
|
||||||
except:
|
except:
|
||||||
log.exception("Connection error when updating buffer %s. Will try again in 2 minutes" % (self.name,))
|
log.exception("Connection error when updating buffer %s. Will try again in 2 minutes" % (self.name,))
|
||||||
return False
|
return False
|
||||||
num = self.session.get_page(name=self.name, show_nextpage=show_nextpage, endpoint="get", parent_endpoint="users", count=1000, user_ids=", ".join([str(i) for i in ids["items"]]), fields="uid, first_name, last_name, last_seen")
|
num = self.session.get_page(name=self.name, show_nextpage=show_nextpage, endpoint="get", parent_endpoint="users", count=1000, user_ids=", ".join([str(i) for i in ids["items"]]), fields="uid, first_name, last_name, last_seen")
|
||||||
if not hasattr(self, "tab"):
|
if not hasattr(self, "tab"):
|
||||||
# Create GUI associated to this buffer.
|
# Create GUI associated to this buffer.
|
||||||
self.create_tab(self.parent)
|
self.create_tab(self.parent)
|
||||||
# Add name to the new control so we could look for it when needed.
|
# Add name to the new control so we could look for it when needed.
|
||||||
self.tab.name = self.name
|
self.tab.name = self.name
|
||||||
if show_nextpage == False:
|
if show_nextpage == False:
|
||||||
if self.tab.list.get_count() > 0 and num > 0:
|
if self.tab.list.get_count() > 0 and num > 0:
|
||||||
v = [i for i in self.session.db[self.name]["items"][:num]]
|
v = [i for i in self.session.db[self.name]["items"][:num]]
|
||||||
v.reverse()
|
v.reverse()
|
||||||
[wx.CallAfter(self.insert, i, True) for i in v]
|
[wx.CallAfter(self.insert, i, True) for i in v]
|
||||||
else:
|
else:
|
||||||
[wx.CallAfter(self.insert, i) for i in self.session.db[self.name]["items"][:num]]
|
[wx.CallAfter(self.insert, i) for i in self.session.db[self.name]["items"][:num]]
|
||||||
return retrieved
|
return retrieved
|
||||||
|
|
||||||
def accept_friendship(self, *args, **kwargs):
|
def accept_friendship(self, *args, **kwargs):
|
||||||
""" Adds a person to a list of friends. This method is done for accepting someone else's friend request.
|
""" Adds a person to a list of friends. This method is done for accepting someone else's friend request.
|
||||||
https://vk.com/dev/friends.add
|
https://vk.com/dev/friends.add
|
||||||
"""
|
"""
|
||||||
person = self.get_post()
|
person = self.get_post()
|
||||||
if person == None:
|
if person == None:
|
||||||
return
|
return
|
||||||
result = self.session.vk.client.friends.add(user_id=person["id"])
|
result = self.session.vk.client.friends.add(user_id=person["id"])
|
||||||
if result == 2:
|
if result == 2:
|
||||||
msg = _("{0} {1} now is your friend.").format(person["first_name"], person["last_name"])
|
msg = _("{0} {1} now is your friend.").format(person["first_name"], person["last_name"])
|
||||||
pub.sendMessage("notify", message=msg)
|
pub.sendMessage("notify", message=msg)
|
||||||
self.session.db[self.name]["items"].pop(self.tab.list.get_selected())
|
self.session.db[self.name]["items"].pop(self.tab.list.get_selected())
|
||||||
self.tab.list.remove_item(self.tab.list.get_selected())
|
self.tab.list.remove_item(self.tab.list.get_selected())
|
||||||
|
|
||||||
def decline_friendship(self, *args, **kwargs):
|
def decline_friendship(self, *args, **kwargs):
|
||||||
""" Declines a freind request.
|
""" Declines a freind request.
|
||||||
https://vk.com/dev/friends.delete
|
https://vk.com/dev/friends.delete
|
||||||
"""
|
"""
|
||||||
person = self.get_post()
|
person = self.get_post()
|
||||||
if person == None:
|
if person == None:
|
||||||
return
|
return
|
||||||
result = self.session.vk.client.friends.delete(user_id=person["id"])
|
result = self.session.vk.client.friends.delete(user_id=person["id"])
|
||||||
if "out_request_deleted" in result:
|
if "out_request_deleted" in result:
|
||||||
msg = _("You've deleted the friends request to {0} {1}.").format(person["first_name"], person["last_name"])
|
msg = _("You've deleted the friends request to {0} {1}.").format(person["first_name"], person["last_name"])
|
||||||
elif "in_request_deleted" in result:
|
elif "in_request_deleted" in result:
|
||||||
msg = _("You've declined the friend request of {0} {1}.").format(person["first_name"], person["last_name"])
|
msg = _("You've declined the friend request of {0} {1}.").format(person["first_name"], person["last_name"])
|
||||||
pub.sendMessage("notify", message=msg)
|
pub.sendMessage("notify", message=msg)
|
||||||
self.session.db[self.name]["items"].pop(self.tab.list.get_selected())
|
self.session.db[self.name]["items"].pop(self.tab.list.get_selected())
|
||||||
self.tab.list.remove_item(self.tab.list.get_selected())
|
self.tab.list.remove_item(self.tab.list.get_selected())
|
||||||
|
|
||||||
def keep_as_follower(self, *args, **kwargs):
|
def keep_as_follower(self, *args, **kwargs):
|
||||||
""" Adds a person to The followers list of the current user.
|
""" Adds a person to The followers list of the current user.
|
||||||
https://vk.com/dev/friends.add
|
https://vk.com/dev/friends.add
|
||||||
"""
|
"""
|
||||||
person = self.get_post()
|
person = self.get_post()
|
||||||
if person == None:
|
if person == None:
|
||||||
return
|
return
|
||||||
result = self.session.vk.client.friends.add(user_id=person["id"], follow=1)
|
result = self.session.vk.client.friends.add(user_id=person["id"], follow=1)
|
||||||
if result == 2:
|
if result == 2:
|
||||||
msg = _("{0} {1} is following you.").format(person["first_name"], person["last_name"])
|
msg = _("{0} {1} is following you.").format(person["first_name"], person["last_name"])
|
||||||
pub.sendMessage("notify", message=msg)
|
pub.sendMessage("notify", message=msg)
|
||||||
self.session.db[self.name]["items"].pop(self.tab.list.get_selected())
|
self.session.db[self.name]["items"].pop(self.tab.list.get_selected())
|
||||||
self.tab.list.remove_item(self.tab.list.get_selected())
|
self.tab.list.remove_item(self.tab.list.get_selected())
|
||||||
|
@ -20,313 +20,313 @@ from wxUI import commonMessages, menus
|
|||||||
log = logging.getLogger("controller.buffers.home")
|
log = logging.getLogger("controller.buffers.home")
|
||||||
|
|
||||||
class homeBuffer(object):
|
class homeBuffer(object):
|
||||||
""" a basic representation of a buffer. Other buffers should be derived from this class. This buffer represents the "news feed" """
|
""" a basic representation of a buffer. Other buffers should be derived from this class. This buffer represents the "news feed" """
|
||||||
|
|
||||||
def get_post(self):
|
def get_post(self):
|
||||||
""" Return the currently focused post."""
|
""" Return the currently focused post."""
|
||||||
# Handle case where there are no items in the buffer.
|
# Handle case where there are no items in the buffer.
|
||||||
if self.tab.list.get_count() == 0:
|
if self.tab.list.get_count() == 0:
|
||||||
wx.Bell()
|
wx.Bell()
|
||||||
return None
|
return None
|
||||||
return self.session.db[self.name]["items"][self.tab.list.get_selected()]
|
return self.session.db[self.name]["items"][self.tab.list.get_selected()]
|
||||||
|
|
||||||
def __init__(self, parent=None, name="", session=None, composefunc=None, create_tab=True, *args, **kwargs):
|
def __init__(self, parent=None, name="", session=None, composefunc=None, create_tab=True, *args, **kwargs):
|
||||||
""" Constructor:
|
""" Constructor:
|
||||||
@parent wx.Treebook: parent for the buffer panel,
|
@parent wx.Treebook: parent for the buffer panel,
|
||||||
@name str: Name for saving this buffer's data in the local storage variable,
|
@name str: Name for saving this buffer's data in the local storage variable,
|
||||||
@session sessionmanager.session.vkSession: Session for performing operations in the Vk API. This session should be logged in when this class is instanciated.
|
@session sessionmanager.session.vkSession: Session for performing operations in the Vk API. This session should be logged in when this class is instanciated.
|
||||||
@composefunc str: This function will be called for composing the result which will be put in the listCtrl. Composefunc should exist in the sessionmanager.renderers module.
|
@composefunc str: This function will be called for composing the result which will be put in the listCtrl. Composefunc should exist in the sessionmanager.renderers module.
|
||||||
args and kwargs will be passed to get_items() without any filtering. Be careful there.
|
args and kwargs will be passed to get_items() without any filtering. Be careful there.
|
||||||
"""
|
"""
|
||||||
super(homeBuffer, self).__init__()
|
super(homeBuffer, self).__init__()
|
||||||
self.parent = parent
|
self.parent = parent
|
||||||
self.args = args
|
self.args = args
|
||||||
self.kwargs = kwargs
|
self.kwargs = kwargs
|
||||||
self.session = session
|
self.session = session
|
||||||
self.compose_function = composefunc
|
self.compose_function = composefunc
|
||||||
self.name = name
|
self.name = name
|
||||||
if create_tab:
|
if create_tab:
|
||||||
self.create_tab(self.parent)
|
self.create_tab(self.parent)
|
||||||
#Update_function will be called every 3 minutes and it should be able to
|
#Update_function will be called every 3 minutes and it should be able to
|
||||||
# Get all new items in the buffer and sort them properly in the CtrlList.
|
# Get all new items in the buffer and sort them properly in the CtrlList.
|
||||||
# ToDo: Shall we allow dinamically set for update_function?
|
# ToDo: Shall we allow dinamically set for update_function?
|
||||||
self.update_function = "get_page"
|
self.update_function = "get_page"
|
||||||
self.name = name
|
self.name = name
|
||||||
# source_key and post_key will point to the keys for sender and posts in VK API objects.
|
# source_key and post_key will point to the keys for sender and posts in VK API objects.
|
||||||
# They can be changed in the future for other item types in different buffers.
|
# They can be changed in the future for other item types in different buffers.
|
||||||
self.user_key = "source_id"
|
self.user_key = "source_id"
|
||||||
self.post_key = "post_id"
|
self.post_key = "post_id"
|
||||||
# When set to False, update_function won't be executed here.
|
# When set to False, update_function won't be executed here.
|
||||||
self.can_get_items = True
|
self.can_get_items = True
|
||||||
|
|
||||||
def create_tab(self, parent):
|
def create_tab(self, parent):
|
||||||
""" Create the Wx panel."""
|
""" Create the Wx panel."""
|
||||||
self.tab = home.homeTab(parent)
|
self.tab = home.homeTab(parent)
|
||||||
# Bind local events (they will respond to events happened in the buffer).
|
# Bind local events (they will respond to events happened in the buffer).
|
||||||
self.connect_events()
|
self.connect_events()
|
||||||
self.tab.name = self.name
|
self.tab.name = self.name
|
||||||
if hasattr(self, "can_post") and self.can_post == False and hasattr(self.tab, "post"):
|
if hasattr(self, "can_post") and self.can_post == False and hasattr(self.tab, "post"):
|
||||||
self.tab.post.Enable(False)
|
self.tab.post.Enable(False)
|
||||||
|
|
||||||
def insert(self, item, reversed=False):
|
def insert(self, item, reversed=False):
|
||||||
""" Add a new item to the list. Uses renderers.composefunc for parsing the dictionary and create a valid result for putting it in the list."""
|
""" Add a new item to the list. Uses renderers.composefunc for parsing the dictionary and create a valid result for putting it in the list."""
|
||||||
try:
|
try:
|
||||||
item_ = getattr(renderers, self.compose_function)(item, self.session)
|
item_ = getattr(renderers, self.compose_function)(item, self.session)
|
||||||
wx.CallAfter(self.tab.list.insert_item, reversed, *item_)
|
wx.CallAfter(self.tab.list.insert_item, reversed, *item_)
|
||||||
except:
|
except:
|
||||||
log.exception(item)
|
log.exception(item)
|
||||||
|
|
||||||
def get_items(self, show_nextpage=False):
|
def get_items(self, show_nextpage=False):
|
||||||
""" Retrieve items from the VK API. This function is called repeatedly by the main controller and users could call it implicitly as well with the update buffer option.
|
""" Retrieve items from the VK API. This function is called repeatedly by the main controller and users could call it implicitly as well with the update buffer option.
|
||||||
@show_nextpage boolean: If it's true, it will try to load previous results.
|
@show_nextpage boolean: If it's true, it will try to load previous results.
|
||||||
"""
|
"""
|
||||||
if self.can_get_items == False: return
|
if self.can_get_items == False: return
|
||||||
retrieved = True # Control variable for handling unauthorised/connection errors.
|
retrieved = True # Control variable for handling unauthorised/connection errors.
|
||||||
try:
|
try:
|
||||||
num = getattr(self.session, "get_newsfeed")(show_nextpage=show_nextpage, name=self.name, *self.args, **self.kwargs)
|
num = getattr(self.session, "get_newsfeed")(show_nextpage=show_nextpage, name=self.name, *self.args, **self.kwargs)
|
||||||
except VkApiError as err:
|
except VkApiError as err:
|
||||||
log.error("Error {0}: {1}".format(err.code, err.error))
|
log.error("Error {0}: {1}".format(err.code, err.error))
|
||||||
retrieved = err.code
|
retrieved = err.code
|
||||||
return retrieved
|
return retrieved
|
||||||
except:
|
except:
|
||||||
log.exception("Connection error when updating buffer %s. Will try again in 2 minutes" % (self.name,))
|
log.exception("Connection error when updating buffer %s. Will try again in 2 minutes" % (self.name,))
|
||||||
return False
|
return False
|
||||||
if not hasattr(self, "tab"):
|
if not hasattr(self, "tab"):
|
||||||
# Create GUI associated to this buffer.
|
# Create GUI associated to this buffer.
|
||||||
self.create_tab(self.parent)
|
self.create_tab(self.parent)
|
||||||
# Add name to the new control so we could look for it when needed.
|
# Add name to the new control so we could look for it when needed.
|
||||||
if show_nextpage == False:
|
if show_nextpage == False:
|
||||||
if self.tab.list.get_count() > 0 and num > 0:
|
if self.tab.list.get_count() > 0 and num > 0:
|
||||||
v = [i for i in self.session.db[self.name]["items"][:num]]
|
v = [i for i in self.session.db[self.name]["items"][:num]]
|
||||||
v.reverse()
|
v.reverse()
|
||||||
[wx.CallAfter(self.insert, i, True) for i in v]
|
[wx.CallAfter(self.insert, i, True) for i in v]
|
||||||
else:
|
else:
|
||||||
[wx.CallAfter(self.insert, i) for i in self.session.db[self.name]["items"][:num]]
|
[wx.CallAfter(self.insert, i) for i in self.session.db[self.name]["items"][:num]]
|
||||||
else:
|
else:
|
||||||
if num > 0:
|
if num > 0:
|
||||||
[wx.CallAfter(self.insert, i, False) for i in self.session.db[self.name]["items"][-num:]]
|
[wx.CallAfter(self.insert, i, False) for i in self.session.db[self.name]["items"][-num:]]
|
||||||
return retrieved
|
return retrieved
|
||||||
|
|
||||||
def get_more_items(self):
|
def get_more_items(self):
|
||||||
""" Returns previous items in the buffer."""
|
""" Returns previous items in the buffer."""
|
||||||
self.get_items(show_nextpage=True)
|
self.get_items(show_nextpage=True)
|
||||||
|
|
||||||
def post(self, *args, **kwargs):
|
def post(self, *args, **kwargs):
|
||||||
""" Create a post in the current user's wall.
|
""" Create a post in the current user's wall.
|
||||||
This process is handled in two parts. This is the first part, where the GUI is created and user can send the post.
|
This process is handled in two parts. This is the first part, where the GUI is created and user can send the post.
|
||||||
During the second part (threaded), the post will be sent to the API."""
|
During the second part (threaded), the post will be sent to the API."""
|
||||||
p = presenters.createPostPresenter(session=self.session, interactor=interactors.createPostInteractor(), view=views.createPostDialog(title=_("Write your post"), message="", text=""))
|
p = presenters.createPostPresenter(session=self.session, interactor=interactors.createPostInteractor(), view=views.createPostDialog(title=_("Write your post"), message="", text=""))
|
||||||
if hasattr(p, "text") or hasattr(p, "privacy"):
|
if hasattr(p, "text") or hasattr(p, "privacy"):
|
||||||
post_arguments=dict(privacy=p.privacy, message=p.text)
|
post_arguments=dict(privacy=p.privacy, message=p.text)
|
||||||
attachments = []
|
attachments = []
|
||||||
if hasattr(p, "attachments"):
|
if hasattr(p, "attachments"):
|
||||||
attachments = p.attachments
|
attachments = p.attachments
|
||||||
call_threaded(pub.sendMessage, "post", parent_endpoint="wall", child_endpoint="post", from_buffer=self.name, attachments_list=attachments, post_arguments=post_arguments)
|
call_threaded(pub.sendMessage, "post", parent_endpoint="wall", child_endpoint="post", from_buffer=self.name, attachments_list=attachments, post_arguments=post_arguments)
|
||||||
|
|
||||||
def connect_events(self):
|
def connect_events(self):
|
||||||
""" Bind all events to this buffer"""
|
""" Bind all events to this buffer"""
|
||||||
widgetUtils.connect_event(self.tab.post, widgetUtils.BUTTON_PRESSED, self.post)
|
widgetUtils.connect_event(self.tab.post, widgetUtils.BUTTON_PRESSED, self.post)
|
||||||
widgetUtils.connect_event(self.tab.list.list, widgetUtils.KEYPRESS, self.get_event)
|
widgetUtils.connect_event(self.tab.list.list, widgetUtils.KEYPRESS, self.get_event)
|
||||||
widgetUtils.connect_event(self.tab.list.list, wx.EVT_CONTEXT_MENU, self.show_menu)
|
widgetUtils.connect_event(self.tab.list.list, wx.EVT_CONTEXT_MENU, self.show_menu)
|
||||||
self.tab.set_focus_function(self.onFocus)
|
self.tab.set_focus_function(self.onFocus)
|
||||||
|
|
||||||
def show_menu(self, ev, pos=0, *args, **kwargs):
|
def show_menu(self, ev, pos=0, *args, **kwargs):
|
||||||
""" Show contextual menu when pressing menu key or right mouse click in a list item."""
|
""" Show contextual menu when pressing menu key or right mouse click in a list item."""
|
||||||
if self.tab.list.get_count() == 0: return
|
if self.tab.list.get_count() == 0: return
|
||||||
menu = self.get_menu()
|
menu = self.get_menu()
|
||||||
if pos != 0:
|
if pos != 0:
|
||||||
self.tab.PopupMenu(menu, pos)
|
self.tab.PopupMenu(menu, pos)
|
||||||
else:
|
else:
|
||||||
self.tab.PopupMenu(menu, self.tab.list.list.GetPosition())
|
self.tab.PopupMenu(menu, self.tab.list.list.GetPosition())
|
||||||
|
|
||||||
def show_menu_by_key(self, ev):
|
def show_menu_by_key(self, ev):
|
||||||
""" Show contextual menu when menu key is pressed"""
|
""" Show contextual menu when menu key is pressed"""
|
||||||
if self.tab.list.get_count() == 0:
|
if self.tab.list.get_count() == 0:
|
||||||
return
|
return
|
||||||
if ev.GetKeyCode() == wx.WXK_WINDOWS_MENU:
|
if ev.GetKeyCode() == wx.WXK_WINDOWS_MENU:
|
||||||
self.show_menu(widgetUtils.MENU, pos=self.tab.list.list.GetPosition())
|
self.show_menu(widgetUtils.MENU, pos=self.tab.list.list.GetPosition())
|
||||||
|
|
||||||
def get_menu(self):
|
def get_menu(self):
|
||||||
""" Returns contextual menu options. They will change according to the focused item"""
|
""" Returns contextual menu options. They will change according to the focused item"""
|
||||||
p = self.get_post()
|
p = self.get_post()
|
||||||
if p == None:
|
if p == None:
|
||||||
return
|
return
|
||||||
# determine if the current user is able to delete the object.
|
# determine if the current user is able to delete the object.
|
||||||
if "can_delete" in p:
|
if "can_delete" in p:
|
||||||
can_delete = True==p["can_delete"]
|
can_delete = True==p["can_delete"]
|
||||||
else:
|
else:
|
||||||
can_delete = False
|
can_delete = False
|
||||||
m = menus.postMenu(can_delete=can_delete)
|
m = menus.postMenu(can_delete=can_delete)
|
||||||
if ("likes" in p) == False:
|
if ("likes" in p) == False:
|
||||||
m.like.Enable(False)
|
m.like.Enable(False)
|
||||||
elif p["likes"]["user_likes"] == 1:
|
elif p["likes"]["user_likes"] == 1:
|
||||||
m.like.Enable(False)
|
m.like.Enable(False)
|
||||||
m.dislike.Enable(True)
|
m.dislike.Enable(True)
|
||||||
if ("comments" in p) == False:
|
if ("comments" in p) == False:
|
||||||
m.comment.Enable(False)
|
m.comment.Enable(False)
|
||||||
m.open_in_browser.Enable(False)
|
m.open_in_browser.Enable(False)
|
||||||
if "type" in p and p["type"] != "friend" and p["type"] != "audio" and p["type"] != "video" and p["type"] != "playlist" or self.name != "home_timeline":
|
if "type" in p and p["type"] != "friend" and p["type"] != "audio" and p["type"] != "video" and p["type"] != "playlist" or self.name != "home_timeline":
|
||||||
m.open_in_browser.Enable(True)
|
m.open_in_browser.Enable(True)
|
||||||
widgetUtils.connect_event(m, widgetUtils.MENU, self.open_post, menuitem=m.open)
|
widgetUtils.connect_event(m, widgetUtils.MENU, self.open_post, menuitem=m.open)
|
||||||
widgetUtils.connect_event(m, widgetUtils.MENU, self.do_like, menuitem=m.like)
|
widgetUtils.connect_event(m, widgetUtils.MENU, self.do_like, menuitem=m.like)
|
||||||
widgetUtils.connect_event(m, widgetUtils.MENU, self.do_dislike, menuitem=m.dislike)
|
widgetUtils.connect_event(m, widgetUtils.MENU, self.do_dislike, menuitem=m.dislike)
|
||||||
widgetUtils.connect_event(m, widgetUtils.MENU, self.do_comment, menuitem=m.comment)
|
widgetUtils.connect_event(m, widgetUtils.MENU, self.do_comment, menuitem=m.comment)
|
||||||
widgetUtils.connect_event(m, widgetUtils.MENU, self.open_in_browser, menuitem=m.open_in_browser)
|
widgetUtils.connect_event(m, widgetUtils.MENU, self.open_in_browser, menuitem=m.open_in_browser)
|
||||||
if hasattr(m, "view_profile"):
|
if hasattr(m, "view_profile"):
|
||||||
widgetUtils.connect_event(m, widgetUtils.MENU, self.open_person_profile, menuitem=m.view_profile)
|
widgetUtils.connect_event(m, widgetUtils.MENU, self.open_person_profile, menuitem=m.view_profile)
|
||||||
if hasattr(m, "delete"):
|
if hasattr(m, "delete"):
|
||||||
widgetUtils.connect_event(m, widgetUtils.MENU, self.delete, menuitem=m.delete)
|
widgetUtils.connect_event(m, widgetUtils.MENU, self.delete, menuitem=m.delete)
|
||||||
return m
|
return m
|
||||||
|
|
||||||
def do_like(self, *args, **kwargs):
|
def do_like(self, *args, **kwargs):
|
||||||
""" Set like in the currently focused post."""
|
""" Set like in the currently focused post."""
|
||||||
post = self.get_post()
|
post = self.get_post()
|
||||||
if post == None:
|
if post == None:
|
||||||
return
|
return
|
||||||
user = post[self.user_key]
|
user = post[self.user_key]
|
||||||
id = post[self.post_key]
|
id = post[self.post_key]
|
||||||
if "type" in post:
|
if "type" in post:
|
||||||
type_ = post["type"]
|
type_ = post["type"]
|
||||||
else:
|
else:
|
||||||
type_ = "post"
|
type_ = "post"
|
||||||
l = self.session.vk.client.likes.add(owner_id=user, item_id=id, type=type_)
|
l = self.session.vk.client.likes.add(owner_id=user, item_id=id, type=type_)
|
||||||
self.session.db[self.name]["items"][self.tab.list.get_selected()]["likes"]["count"] = l["likes"]
|
self.session.db[self.name]["items"][self.tab.list.get_selected()]["likes"]["count"] = l["likes"]
|
||||||
self.session.db[self.name]["items"][self.tab.list.get_selected()]["likes"]["user_likes"] = 1
|
self.session.db[self.name]["items"][self.tab.list.get_selected()]["likes"]["user_likes"] = 1
|
||||||
# Translators: This will be used when user presses like.
|
# Translators: This will be used when user presses like.
|
||||||
output.speak(_("You liked this"))
|
output.speak(_("You liked this"))
|
||||||
|
|
||||||
def do_dislike(self, *args, **kwargs):
|
def do_dislike(self, *args, **kwargs):
|
||||||
""" Set dislike (undo like) in the currently focused post."""
|
""" Set dislike (undo like) in the currently focused post."""
|
||||||
post = self.get_post()
|
post = self.get_post()
|
||||||
if post == None:
|
if post == None:
|
||||||
return
|
return
|
||||||
user = post[self.user_key]
|
user = post[self.user_key]
|
||||||
id = post[self.post_key]
|
id = post[self.post_key]
|
||||||
if "type" in post:
|
if "type" in post:
|
||||||
type_ = post["type"]
|
type_ = post["type"]
|
||||||
else:
|
else:
|
||||||
type_ = "post"
|
type_ = "post"
|
||||||
l = self.session.vk.client.likes.delete(owner_id=user, item_id=id, type=type_)
|
l = self.session.vk.client.likes.delete(owner_id=user, item_id=id, type=type_)
|
||||||
self.session.db[self.name]["items"][self.tab.list.get_selected()]["likes"]["count"] = l["likes"]
|
self.session.db[self.name]["items"][self.tab.list.get_selected()]["likes"]["count"] = l["likes"]
|
||||||
self.session.db[self.name]["items"][self.tab.list.get_selected()]["likes"]["user_likes"] = 2
|
self.session.db[self.name]["items"][self.tab.list.get_selected()]["likes"]["user_likes"] = 2
|
||||||
# Translators: This will be user in 'dislike'
|
# Translators: This will be user in 'dislike'
|
||||||
output.speak(_("You don't like this"))
|
output.speak(_("You don't like this"))
|
||||||
|
|
||||||
def do_comment(self, *args, **kwargs):
|
def do_comment(self, *args, **kwargs):
|
||||||
""" Make a comment into the currently focused post."""
|
""" Make a comment into the currently focused post."""
|
||||||
post = self.get_post()
|
post = self.get_post()
|
||||||
if post == None:
|
if post == None:
|
||||||
return
|
return
|
||||||
comment = presenters.createPostPresenter(session=self.session, interactor=interactors.createPostInteractor(), view=views.createPostDialog(title=_("Add a comment"), message="", text="", mode="comment"))
|
comment = presenters.createPostPresenter(session=self.session, interactor=interactors.createPostInteractor(), view=views.createPostDialog(title=_("Add a comment"), message="", text="", mode="comment"))
|
||||||
if hasattr(comment, "text") or hasattr(comment, "privacy"):
|
if hasattr(comment, "text") or hasattr(comment, "privacy"):
|
||||||
msg = comment.text
|
msg = comment.text
|
||||||
try:
|
try:
|
||||||
user = post[self.user_key]
|
user = post[self.user_key]
|
||||||
id = post[self.post_key]
|
id = post[self.post_key]
|
||||||
self.session.vk.client.wall.addComment(owner_id=user, post_id=id, text=msg)
|
self.session.vk.client.wall.addComment(owner_id=user, post_id=id, text=msg)
|
||||||
output.speak(_("You've posted a comment"))
|
output.speak(_("You've posted a comment"))
|
||||||
except Exception as msg:
|
except Exception as msg:
|
||||||
log.error(msg)
|
log.error(msg)
|
||||||
|
|
||||||
def delete(self, *args, **kwargs):
|
def delete(self, *args, **kwargs):
|
||||||
post = self.get_post()
|
post = self.get_post()
|
||||||
if ("type" in post and post["type"] == "post") or self.name != "newsfeed":
|
if ("type" in post and post["type"] == "post") or self.name != "newsfeed":
|
||||||
question = commonMessages.remove_post()
|
question = commonMessages.remove_post()
|
||||||
if question == widgetUtils.NO:
|
if question == widgetUtils.NO:
|
||||||
return
|
return
|
||||||
if "owner_id" in self.kwargs:
|
if "owner_id" in self.kwargs:
|
||||||
result = self.session.vk.client.wall.delete(owner_id=self.kwargs["owner_id"], post_id=post[self.post_key])
|
result = self.session.vk.client.wall.delete(owner_id=self.kwargs["owner_id"], post_id=post[self.post_key])
|
||||||
else:
|
else:
|
||||||
result = self.session.vk.client.wall.delete(post_id=post[self.post_key])
|
result = self.session.vk.client.wall.delete(post_id=post[self.post_key])
|
||||||
pub.sendMessage("post_deleted", post_id=post[self.post_key])
|
pub.sendMessage("post_deleted", post_id=post[self.post_key])
|
||||||
self.session.db[self.name]["items"].pop(self.tab.list.get_selected())
|
self.session.db[self.name]["items"].pop(self.tab.list.get_selected())
|
||||||
self.tab.list.remove_item(self.tab.list.get_selected())
|
self.tab.list.remove_item(self.tab.list.get_selected())
|
||||||
|
|
||||||
def get_event(self, ev):
|
def get_event(self, ev):
|
||||||
""" Parses keyboard input in the ListCtrl and executes the event associated with user keypresses."""
|
""" Parses keyboard input in the ListCtrl and executes the event associated with user keypresses."""
|
||||||
if ev.GetKeyCode() == wx.WXK_RETURN: event = "open_post"
|
if ev.GetKeyCode() == wx.WXK_RETURN: event = "open_post"
|
||||||
else:
|
else:
|
||||||
event = None
|
event = None
|
||||||
ev.Skip()
|
ev.Skip()
|
||||||
if event != None:
|
if event != None:
|
||||||
try:
|
try:
|
||||||
getattr(self, event)()
|
getattr(self, event)()
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def volume_down(self):
|
def volume_down(self):
|
||||||
""" Decreases player volume by 2%"""
|
""" Decreases player volume by 2%"""
|
||||||
player.player.volume = player.player.volume-2
|
player.player.volume = player.player.volume-2
|
||||||
|
|
||||||
def volume_up(self):
|
def volume_up(self):
|
||||||
""" Increases player volume by 2%"""
|
""" Increases player volume by 2%"""
|
||||||
player.player.volume = player.player.volume+2
|
player.player.volume = player.player.volume+2
|
||||||
|
|
||||||
def play_audio(self, *args, **kwargs):
|
def play_audio(self, *args, **kwargs):
|
||||||
""" Play audio in currently focused buffer, if possible."""
|
""" Play audio in currently focused buffer, if possible."""
|
||||||
post = self.get_post()
|
post = self.get_post()
|
||||||
if post == None:
|
if post == None:
|
||||||
return
|
return
|
||||||
if "type" in post and post["type"] == "audio":
|
if "type" in post and post["type"] == "audio":
|
||||||
pub.sendMessage("play", object=post["audio"]["items"][0])
|
pub.sendMessage("play", object=post["audio"]["items"][0])
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def open_person_profile(self, *args, **kwargs):
|
def open_person_profile(self, *args, **kwargs):
|
||||||
""" Views someone's profile."""
|
""" Views someone's profile."""
|
||||||
selected = self.get_post()
|
selected = self.get_post()
|
||||||
if selected == None:
|
if selected == None:
|
||||||
return
|
return
|
||||||
# Check all possible keys for an user object in VK API.
|
# Check all possible keys for an user object in VK API.
|
||||||
keys = ["from_id", "source_id", "id"]
|
keys = ["from_id", "source_id", "id"]
|
||||||
for i in keys:
|
for i in keys:
|
||||||
if i in selected:
|
if i in selected:
|
||||||
pub.sendMessage("user-profile", person=selected[i])
|
pub.sendMessage("user-profile", person=selected[i])
|
||||||
break
|
break
|
||||||
|
|
||||||
def open_post(self, *args, **kwargs):
|
def open_post(self, *args, **kwargs):
|
||||||
""" Opens the currently focused post."""
|
""" Opens the currently focused post."""
|
||||||
post = self.get_post()
|
post = self.get_post()
|
||||||
if post == None:
|
if post == None:
|
||||||
return
|
return
|
||||||
if "type" in post and post["type"] == "audio":
|
if "type" in post and post["type"] == "audio":
|
||||||
a = presenters.displayAudioPresenter(session=self.session, postObject=post["audio"]["items"], interactor=interactors.displayAudioInteractor(), view=views.displayAudio())
|
a = presenters.displayAudioPresenter(session=self.session, postObject=post["audio"]["items"], interactor=interactors.displayAudioInteractor(), view=views.displayAudio())
|
||||||
elif "type" in post and post["type"] == "friend":
|
elif "type" in post and post["type"] == "friend":
|
||||||
pub.sendMessage("open-post", post_object=post, controller_="displayFriendship", vars=dict(caption=_("{user1_nom} added the following friends")))
|
pub.sendMessage("open-post", post_object=post, controller_="displayFriendship", vars=dict(caption=_("{user1_nom} added the following friends")))
|
||||||
else:
|
else:
|
||||||
pub.sendMessage("open-post", post_object=post, controller_="displayPost")
|
pub.sendMessage("open-post", post_object=post, controller_="displayPost")
|
||||||
|
|
||||||
def pause_audio(self, *args, **kwargs):
|
def pause_audio(self, *args, **kwargs):
|
||||||
""" pauses audio playback."""
|
""" pauses audio playback."""
|
||||||
pub.sendMessage("pause")
|
pub.sendMessage("pause")
|
||||||
|
|
||||||
def remove_buffer(self, mandatory):
|
def remove_buffer(self, mandatory):
|
||||||
""" Function for removing a buffer. Returns True if removal is successful, False otherwise"""
|
""" Function for removing a buffer. Returns True if removal is successful, False otherwise"""
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def get_users(self):
|
def get_users(self):
|
||||||
""" Returns source user in the post."""
|
""" Returns source user in the post."""
|
||||||
post = self.get_post()
|
post = self.get_post()
|
||||||
if post == None:
|
if post == None:
|
||||||
return
|
return
|
||||||
if ("type" in post) == False:
|
if ("type" in post) == False:
|
||||||
return [post["from_id"]]
|
return [post["from_id"]]
|
||||||
else:
|
else:
|
||||||
return [post["source_id"]]
|
return [post["source_id"]]
|
||||||
|
|
||||||
def onFocus(self, event, *args,**kwargs):
|
def onFocus(self, event, *args,**kwargs):
|
||||||
""" Function executed when the item in a list is selected.
|
""" Function executed when the item in a list is selected.
|
||||||
For this buffer it updates the date of posts in the list."""
|
For this buffer it updates the date of posts in the list."""
|
||||||
post = self.get_post()
|
post = self.get_post()
|
||||||
if post == None:
|
if post == None:
|
||||||
return
|
return
|
||||||
original_date = arrow.get(post["date"])
|
original_date = arrow.get(post["date"])
|
||||||
created_at = original_date.humanize(locale=languageHandler.curLang[:2])
|
created_at = original_date.humanize(locale=languageHandler.curLang[:2])
|
||||||
self.tab.list.list.SetItem(self.tab.list.get_selected(), 2, created_at)
|
self.tab.list.list.SetItem(self.tab.list.get_selected(), 2, created_at)
|
||||||
event.Skip()
|
event.Skip()
|
||||||
|
|
||||||
def open_in_browser(self, *args, **kwargs):
|
def open_in_browser(self, *args, **kwargs):
|
||||||
post = self.get_post()
|
post = self.get_post()
|
||||||
if post == None:
|
if post == None:
|
||||||
return
|
return
|
||||||
url = "https://vk.com/wall{user_id}_{post_id}".format(user_id=post["source_id"], post_id=post["post_id"])
|
url = "https://vk.com/wall{user_id}_{post_id}".format(user_id=post["source_id"], post_id=post["post_id"])
|
||||||
webbrowser.open_new_tab(url)
|
webbrowser.open_new_tab(url)
|
||||||
|
@ -7,10 +7,10 @@ log = logging.getLogger("controller.buffers")
|
|||||||
|
|
||||||
class notificationBuffer(wallBuffer):
|
class notificationBuffer(wallBuffer):
|
||||||
|
|
||||||
def create_tab(self, parent):
|
def create_tab(self, parent):
|
||||||
self.tab = notification.notificationTab(parent)
|
self.tab = notification.notificationTab(parent)
|
||||||
self.connect_events()
|
self.connect_events()
|
||||||
self.tab.name = self.name
|
self.tab.name = self.name
|
||||||
|
|
||||||
def onFocus(self, event, *args, **kwargs):
|
def onFocus(self, event, *args, **kwargs):
|
||||||
event.Skip()
|
event.Skip()
|
||||||
|
@ -21,205 +21,205 @@ log = logging.getLogger("controller.buffers.friends")
|
|||||||
|
|
||||||
class peopleBuffer(wallBuffer):
|
class peopleBuffer(wallBuffer):
|
||||||
|
|
||||||
def post(self, *args, **kwargs):
|
def post(self, *args, **kwargs):
|
||||||
user = self.get_post()
|
user = self.get_post()
|
||||||
if "can_post" not in user: # retrieve data if not present in the object.
|
if "can_post" not in user: # retrieve data if not present in the object.
|
||||||
user = self.session.vk.client.users.get(user_ids=user["id"], fields="can_post")[0]
|
user = self.session.vk.client.users.get(user_ids=user["id"], fields="can_post")[0]
|
||||||
if user.get("can_post") == True:
|
if user.get("can_post") == True:
|
||||||
user_str = self.session.get_user(user["id"], key="user1")
|
user_str = self.session.get_user(user["id"], key="user1")
|
||||||
title = _("Post to {user1_nom}'s wall").format(**user_str)
|
title = _("Post to {user1_nom}'s wall").format(**user_str)
|
||||||
p = presenters.createPostPresenter(session=self.session, interactor=interactors.createPostInteractor(), view=views.createPostDialog(title=title, message="", text=""))
|
p = presenters.createPostPresenter(session=self.session, interactor=interactors.createPostInteractor(), view=views.createPostDialog(title=title, message="", text=""))
|
||||||
if hasattr(p, "text") or hasattr(p, "privacy"):
|
if hasattr(p, "text") or hasattr(p, "privacy"):
|
||||||
post_arguments=dict(privacy=p.privacy, message=p.text, owner_id=user["id"])
|
post_arguments=dict(privacy=p.privacy, message=p.text, owner_id=user["id"])
|
||||||
attachments = []
|
attachments = []
|
||||||
if hasattr(p, "attachments"):
|
if hasattr(p, "attachments"):
|
||||||
attachments = p.attachments
|
attachments = p.attachments
|
||||||
call_threaded(pub.sendMessage, "post", parent_endpoint="wall", child_endpoint="post", from_buffer=self.name, attachments_list=attachments, post_arguments=post_arguments)
|
call_threaded(pub.sendMessage, "post", parent_endpoint="wall", child_endpoint="post", from_buffer=self.name, attachments_list=attachments, post_arguments=post_arguments)
|
||||||
|
|
||||||
def create_tab(self, parent):
|
def create_tab(self, parent):
|
||||||
self.tab = people.peopleTab(parent)
|
self.tab = people.peopleTab(parent)
|
||||||
self.connect_events()
|
self.connect_events()
|
||||||
self.tab.name = self.name
|
self.tab.name = self.name
|
||||||
if hasattr(self, "can_post") and self.can_post == False and hasattr(self.tab, "post"):
|
if hasattr(self, "can_post") and self.can_post == False and hasattr(self.tab, "post"):
|
||||||
self.tab.post.Enable(False)
|
self.tab.post.Enable(False)
|
||||||
|
|
||||||
def connect_events(self):
|
def connect_events(self):
|
||||||
super(peopleBuffer, self).connect_events()
|
super(peopleBuffer, self).connect_events()
|
||||||
widgetUtils.connect_event(self.tab.new_chat, widgetUtils.BUTTON_PRESSED, self.new_chat)
|
widgetUtils.connect_event(self.tab.new_chat, widgetUtils.BUTTON_PRESSED, self.new_chat)
|
||||||
|
|
||||||
def new_chat(self, *args, **kwargs):
|
def new_chat(self, *args, **kwargs):
|
||||||
user = self.get_post()
|
user = self.get_post()
|
||||||
if user == None:
|
if user == None:
|
||||||
return
|
return
|
||||||
user_id = user["id"]
|
user_id = user["id"]
|
||||||
pub.sendMessage("new-chat", user_id=user_id)
|
pub.sendMessage("new-chat", user_id=user_id)
|
||||||
|
|
||||||
def onFocus(self, *args, **kwargs):
|
def onFocus(self, *args, **kwargs):
|
||||||
post = self.get_post()
|
post = self.get_post()
|
||||||
if post == None:
|
if post == None:
|
||||||
return
|
return
|
||||||
if post.get("can_post") == True:
|
if post.get("can_post") == True:
|
||||||
self.tab.post.Enable(True)
|
self.tab.post.Enable(True)
|
||||||
else:
|
else:
|
||||||
self.tab.post.Enable(False)
|
self.tab.post.Enable(False)
|
||||||
# Check if we are allowed to contact people. this might be false for communitiy members.
|
# Check if we are allowed to contact people. this might be false for communitiy members.
|
||||||
if post.get("can_write_private_message") == True:
|
if post.get("can_write_private_message") == True:
|
||||||
self.tab.new_chat.Enable(True)
|
self.tab.new_chat.Enable(True)
|
||||||
else:
|
else:
|
||||||
self.tab.new_chat.Enable(False)
|
self.tab.new_chat.Enable(False)
|
||||||
if ("last_seen" in post) == False: return
|
if ("last_seen" in post) == False: return
|
||||||
original_date = arrow.get(post["last_seen"]["time"])
|
original_date = arrow.get(post["last_seen"]["time"])
|
||||||
now = arrow.now()
|
now = arrow.now()
|
||||||
original_date.to(now.tzinfo)
|
original_date.to(now.tzinfo)
|
||||||
diffdate = now-original_date
|
diffdate = now-original_date
|
||||||
if diffdate.days == 0 and diffdate.seconds <= 360:
|
if diffdate.days == 0 and diffdate.seconds <= 360:
|
||||||
online_status = _("Online")
|
online_status = _("Online")
|
||||||
else:
|
else:
|
||||||
# Translators: This is the date of last seen
|
# Translators: This is the date of last seen
|
||||||
online_status = _("Last seen {0}").format(original_date.humanize(locale=languageHandler.curLang[:2]),)
|
online_status = _("Last seen {0}").format(original_date.humanize(locale=languageHandler.curLang[:2]),)
|
||||||
self.tab.list.list.SetItem(self.tab.list.get_selected(), 1, online_status)
|
self.tab.list.list.SetItem(self.tab.list.get_selected(), 1, online_status)
|
||||||
|
|
||||||
def open_timeline(self, *args, **kwargs):
|
def open_timeline(self, *args, **kwargs):
|
||||||
user = self.get_post()
|
user = self.get_post()
|
||||||
if user == None:
|
if user == None:
|
||||||
return
|
return
|
||||||
a = timeline.timelineDialog([self.session.get_user(user["id"])["user1_gen"]], show_selector=False)
|
a = timeline.timelineDialog([self.session.get_user(user["id"])["user1_gen"]], show_selector=False)
|
||||||
if a.get_response() == widgetUtils.OK:
|
if a.get_response() == widgetUtils.OK:
|
||||||
buffer_type = a.get_buffer_type()
|
buffer_type = a.get_buffer_type()
|
||||||
user_id = user["id"]
|
user_id = user["id"]
|
||||||
pub.sendMessage("create-timeline", user_id=user_id, buffer_type=buffer_type)
|
pub.sendMessage("create-timeline", user_id=user_id, buffer_type=buffer_type)
|
||||||
|
|
||||||
def get_menu(self, *args, **kwargs):
|
def get_menu(self, *args, **kwargs):
|
||||||
""" display menu for people buffers (friends and requests)"""
|
""" display menu for people buffers (friends and requests)"""
|
||||||
# If this is an incoming requests buffer, there is a flag in the peopleMenu that shows a few new options.
|
# If this is an incoming requests buffer, there is a flag in the peopleMenu that shows a few new options.
|
||||||
# So let's make sure we call it accordingly.
|
# So let's make sure we call it accordingly.
|
||||||
if self.name == "friend_requests":
|
if self.name == "friend_requests":
|
||||||
m = menus.peopleMenu(is_request=True)
|
m = menus.peopleMenu(is_request=True)
|
||||||
# Connect the accept and decline methods from here.
|
# Connect the accept and decline methods from here.
|
||||||
widgetUtils.connect_event(m, widgetUtils.MENU, self.accept_friendship, menuitem=m.accept)
|
widgetUtils.connect_event(m, widgetUtils.MENU, self.accept_friendship, menuitem=m.accept)
|
||||||
widgetUtils.connect_event(m, widgetUtils.MENU, self.decline_friendship, menuitem=m.decline)
|
widgetUtils.connect_event(m, widgetUtils.MENU, self.decline_friendship, menuitem=m.decline)
|
||||||
widgetUtils.connect_event(m, widgetUtils.MENU, self.keep_as_follower, menuitem=m.keep_as_follower)
|
widgetUtils.connect_event(m, widgetUtils.MENU, self.keep_as_follower, menuitem=m.keep_as_follower)
|
||||||
elif self.name == "subscribers":
|
elif self.name == "subscribers":
|
||||||
m = menus.peopleMenu(is_subscriber=True)
|
m = menus.peopleMenu(is_subscriber=True)
|
||||||
widgetUtils.connect_event(m, widgetUtils.MENU, self.accept_friendship, menuitem=m.add)
|
widgetUtils.connect_event(m, widgetUtils.MENU, self.accept_friendship, menuitem=m.add)
|
||||||
else:
|
else:
|
||||||
m = menus.peopleMenu(is_request=False)
|
m = menus.peopleMenu(is_request=False)
|
||||||
widgetUtils.connect_event(m, widgetUtils.MENU, self.decline_friendship, menuitem=m.decline)
|
widgetUtils.connect_event(m, widgetUtils.MENU, self.decline_friendship, menuitem=m.decline)
|
||||||
widgetUtils.connect_event(m, widgetUtils.MENU, self.block_person, menuitem=m.block)
|
widgetUtils.connect_event(m, widgetUtils.MENU, self.block_person, menuitem=m.block)
|
||||||
# It is not allowed to send messages to people who is not your friends, so let's disable it if we're in a pending or outgoing requests buffer.
|
# It is not allowed to send messages to people who is not your friends, so let's disable it if we're in a pending or outgoing requests buffer.
|
||||||
if "friend_requests" in self.name:
|
if "friend_requests" in self.name:
|
||||||
m.message.Enable(False)
|
m.message.Enable(False)
|
||||||
widgetUtils.connect_event(m, widgetUtils.MENU, self.new_chat, menuitem=m.message)
|
widgetUtils.connect_event(m, widgetUtils.MENU, self.new_chat, menuitem=m.message)
|
||||||
widgetUtils.connect_event(m, widgetUtils.MENU, self.open_timeline, menuitem=m.timeline)
|
widgetUtils.connect_event(m, widgetUtils.MENU, self.open_timeline, menuitem=m.timeline)
|
||||||
widgetUtils.connect_event(m, widgetUtils.MENU, self.open_person_profile, menuitem=m.view_profile)
|
widgetUtils.connect_event(m, widgetUtils.MENU, self.open_person_profile, menuitem=m.view_profile)
|
||||||
widgetUtils.connect_event(m, widgetUtils.MENU, self.open_in_browser, menuitem=m.open_in_browser)
|
widgetUtils.connect_event(m, widgetUtils.MENU, self.open_in_browser, menuitem=m.open_in_browser)
|
||||||
return m
|
return m
|
||||||
|
|
||||||
def open_post(self, *args, **kwargs): pass
|
def open_post(self, *args, **kwargs): pass
|
||||||
|
|
||||||
def play_audio(self, *args, **kwargs): return False
|
def play_audio(self, *args, **kwargs): return False
|
||||||
|
|
||||||
def pause_audio(self, *args, **kwargs): pass
|
def pause_audio(self, *args, **kwargs): pass
|
||||||
|
|
||||||
def accept_friendship(self, *args, **kwargs):
|
def accept_friendship(self, *args, **kwargs):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def decline_friendship(self, *args, **kwargs):
|
def decline_friendship(self, *args, **kwargs):
|
||||||
person = self.get_post()
|
person = self.get_post()
|
||||||
if person == None:
|
if person == None:
|
||||||
return
|
return
|
||||||
user = self.session.get_user(person["id"])
|
user = self.session.get_user(person["id"])
|
||||||
question = commonMessages.remove_friend(user)
|
question = commonMessages.remove_friend(user)
|
||||||
if question == widgetUtils.NO:
|
if question == widgetUtils.NO:
|
||||||
return
|
return
|
||||||
result = self.session.vk.client.friends.delete(user_id=person["id"])
|
result = self.session.vk.client.friends.delete(user_id=person["id"])
|
||||||
if "friend_deleted" in result:
|
if "friend_deleted" in result:
|
||||||
msg = _("You've removed {user1_nom} from your friends.").format(**user,)
|
msg = _("You've removed {user1_nom} from your friends.").format(**user,)
|
||||||
pub.sendMessage("notify", message=msg)
|
pub.sendMessage("notify", message=msg)
|
||||||
self.session.db[self.name]["items"].pop(self.tab.list.get_selected())
|
self.session.db[self.name]["items"].pop(self.tab.list.get_selected())
|
||||||
self.tab.list.remove_item(self.tab.list.get_selected())
|
self.tab.list.remove_item(self.tab.list.get_selected())
|
||||||
|
|
||||||
def block_person(self, *args, **kwargs):
|
def block_person(self, *args, **kwargs):
|
||||||
person = self.get_post()
|
person = self.get_post()
|
||||||
if person == None:
|
if person == None:
|
||||||
return
|
return
|
||||||
user = self.session.get_user(person["id"])
|
user = self.session.get_user(person["id"])
|
||||||
question = commonMessages.block_person(user)
|
question = commonMessages.block_person(user)
|
||||||
if question == widgetUtils.NO:
|
if question == widgetUtils.NO:
|
||||||
return
|
return
|
||||||
result = self.session.vk.client.account.ban(owner_id=person["id"])
|
result = self.session.vk.client.account.ban(owner_id=person["id"])
|
||||||
if result == 1:
|
if result == 1:
|
||||||
msg = _("You've blocked {user1_nom} from your friends.").format(**user,)
|
msg = _("You've blocked {user1_nom} from your friends.").format(**user,)
|
||||||
pub.sendMessage("notify", message=msg)
|
pub.sendMessage("notify", message=msg)
|
||||||
self.session.db[self.name]["items"].pop(self.tab.list.get_selected())
|
self.session.db[self.name]["items"].pop(self.tab.list.get_selected())
|
||||||
self.tab.list.remove_item(self.tab.list.get_selected())
|
self.tab.list.remove_item(self.tab.list.get_selected())
|
||||||
|
|
||||||
def keep_as_follower(self, *args, **kwargs):
|
def keep_as_follower(self, *args, **kwargs):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def add_person(self, person):
|
def add_person(self, person):
|
||||||
# This tracks if the user already exists here, in such case we just will update the last_seen variable
|
# This tracks if the user already exists here, in such case we just will update the last_seen variable
|
||||||
existing = False
|
existing = False
|
||||||
for i in self.session.db[self.name]["items"]:
|
for i in self.session.db[self.name]["items"]:
|
||||||
if person["id"] == i["id"]:
|
if person["id"] == i["id"]:
|
||||||
existing = True
|
existing = True
|
||||||
i["last_seen"]["time"] = person["last_seen"]["time"]
|
i["last_seen"]["time"] = person["last_seen"]["time"]
|
||||||
break
|
break
|
||||||
# Add the new user to the buffer just if it does not exists previously.
|
# Add the new user to the buffer just if it does not exists previously.
|
||||||
if existing == False:
|
if existing == False:
|
||||||
# Ensure the user won't loose the focus after the new item is added.
|
# Ensure the user won't loose the focus after the new item is added.
|
||||||
focused_item = self.tab.list.get_selected()+1
|
focused_item = self.tab.list.get_selected()+1
|
||||||
self.session.db[self.name]["items"].insert(0, person)
|
self.session.db[self.name]["items"].insert(0, person)
|
||||||
self.insert(person, True)
|
self.insert(person, True)
|
||||||
# Selects back the previously focused item.
|
# Selects back the previously focused item.
|
||||||
self.tab.list.select_item(focused_item)
|
self.tab.list.select_item(focused_item)
|
||||||
|
|
||||||
def remove_person(self, user_id):
|
def remove_person(self, user_id):
|
||||||
# Make sure the user is present in the buffer, otherwise don't attempt to remove a None Value from the list.
|
# Make sure the user is present in the buffer, otherwise don't attempt to remove a None Value from the list.
|
||||||
user = None
|
user = None
|
||||||
focused_user = self.get_post()
|
focused_user = self.get_post()
|
||||||
for i in self.session.db[self.name]["items"]:
|
for i in self.session.db[self.name]["items"]:
|
||||||
if i["id"] == user_id:
|
if i["id"] == user_id:
|
||||||
user = i
|
user = i
|
||||||
break
|
break
|
||||||
if user != None:
|
if user != None:
|
||||||
person_index = self.session.db[self.name]["items"].index(user)
|
person_index = self.session.db[self.name]["items"].index(user)
|
||||||
focused_item = self.tab.list.get_selected()
|
focused_item = self.tab.list.get_selected()
|
||||||
self.session.db[self.name]["items"].pop(person_index)
|
self.session.db[self.name]["items"].pop(person_index)
|
||||||
self.tab.list.remove_item(person_index)
|
self.tab.list.remove_item(person_index)
|
||||||
if user != focused_user:
|
if user != focused_user:
|
||||||
# Let's find the position of the previously focused user.
|
# Let's find the position of the previously focused user.
|
||||||
focus = None
|
focus = None
|
||||||
for i in range(0, len(self.session.db[self.name]["items"])):
|
for i in range(0, len(self.session.db[self.name]["items"])):
|
||||||
if focused_user["id"] == self.session.db[self.name]["items"][i]["id"]:
|
if focused_user["id"] == self.session.db[self.name]["items"][i]["id"]:
|
||||||
self.tab.list.select_item(i)
|
self.tab.list.select_item(i)
|
||||||
return
|
return
|
||||||
elif user == focused_user and person_index < self.tab.list.get_count():
|
elif user == focused_user and person_index < self.tab.list.get_count():
|
||||||
self.tab.list.select_item(person_index)
|
self.tab.list.select_item(person_index)
|
||||||
else:
|
else:
|
||||||
self.tab.list.select_item(self.tab.list.get_count()-1)
|
self.tab.list.select_item(self.tab.list.get_count()-1)
|
||||||
|
|
||||||
def get_friend(self, user_id):
|
def get_friend(self, user_id):
|
||||||
for i in self.session.db["friends_"]["items"]:
|
for i in self.session.db["friends_"]["items"]:
|
||||||
if i["id"] == user_id:
|
if i["id"] == user_id:
|
||||||
return i
|
return i
|
||||||
log.exception("Getting user manually...")
|
log.exception("Getting user manually...")
|
||||||
user = self.session.vk.client.users.get(user_ids=event.user_id, fields="last_seen")[0]
|
user = self.session.vk.client.users.get(user_ids=event.user_id, fields="last_seen")[0]
|
||||||
return user
|
return user
|
||||||
|
|
||||||
def update_online(self):
|
def update_online(self):
|
||||||
online_users = self.session.vk.client.friends.getOnline()
|
online_users = self.session.vk.client.friends.getOnline()
|
||||||
now = time.time()
|
now = time.time()
|
||||||
for i in self.session.db[self.name]["items"]:
|
for i in self.session.db[self.name]["items"]:
|
||||||
if i["id"] in online_users:
|
if i["id"] in online_users:
|
||||||
i["last_seen"]["time"] = now
|
i["last_seen"]["time"] = now
|
||||||
else:
|
else:
|
||||||
log.exception("Removing an user from online status manually... %r" % (i))
|
log.exception("Removing an user from online status manually... %r" % (i))
|
||||||
self.remove_person(i["id"])
|
self.remove_person(i["id"])
|
||||||
|
|
||||||
def open_in_browser(self, *args, **kwargs):
|
def open_in_browser(self, *args, **kwargs):
|
||||||
post = self.get_post()
|
post = self.get_post()
|
||||||
if post == None:
|
if post == None:
|
||||||
return
|
return
|
||||||
url = "https://vk.com/id{user_id}".format(user_id=post["id"])
|
url = "https://vk.com/id{user_id}".format(user_id=post["id"])
|
||||||
webbrowser.open_new_tab(url)
|
webbrowser.open_new_tab(url)
|
||||||
|
@ -12,114 +12,114 @@ from .wall import wallBuffer
|
|||||||
log = logging.getLogger("controller.buffers.video")
|
log = logging.getLogger("controller.buffers.video")
|
||||||
|
|
||||||
class videoBuffer(wallBuffer):
|
class videoBuffer(wallBuffer):
|
||||||
""" This buffer represents video elements, and it can be used for showing videos for the logged user or someone else."""
|
""" This buffer represents video elements, and it can be used for showing videos for the logged user or someone else."""
|
||||||
|
|
||||||
def create_tab(self, parent):
|
def create_tab(self, parent):
|
||||||
self.tab = video.videoTab(parent)
|
self.tab = video.videoTab(parent)
|
||||||
self.connect_events()
|
self.connect_events()
|
||||||
self.tab.name = self.name
|
self.tab.name = self.name
|
||||||
if hasattr(self, "can_post") and self.can_post == False and hasattr(self.tab, "post"):
|
if hasattr(self, "can_post") and self.can_post == False and hasattr(self.tab, "post"):
|
||||||
self.tab.post.Enable(False)
|
self.tab.post.Enable(False)
|
||||||
|
|
||||||
def connect_events(self):
|
def connect_events(self):
|
||||||
widgetUtils.connect_event(self.tab.play, widgetUtils.BUTTON_PRESSED, self.play_audio)
|
widgetUtils.connect_event(self.tab.play, widgetUtils.BUTTON_PRESSED, self.play_audio)
|
||||||
super(videoBuffer, self).connect_events()
|
super(videoBuffer, self).connect_events()
|
||||||
|
|
||||||
def play_audio(self, *args, **kwargs):
|
def play_audio(self, *args, **kwargs):
|
||||||
""" Due to inheritance this method should be called play_audio, but play the currently focused video.
|
""" Due to inheritance this method should be called play_audio, but play the currently focused video.
|
||||||
Opens a webbrowser pointing to the video's URL."""
|
Opens a webbrowser pointing to the video's URL."""
|
||||||
selected = self.tab.list.get_selected()
|
selected = self.tab.list.get_selected()
|
||||||
if self.tab.list.get_count() == 0:
|
if self.tab.list.get_count() == 0:
|
||||||
return
|
return
|
||||||
if selected == -1:
|
if selected == -1:
|
||||||
selected = 0
|
selected = 0
|
||||||
output.speak(_("Opening video in webbrowser..."))
|
output.speak(_("Opening video in webbrowser..."))
|
||||||
webbrowser.open_new_tab(self.session.db[self.name]["items"][selected]["player"])
|
webbrowser.open_new_tab(self.session.db[self.name]["items"][selected]["player"])
|
||||||
# print self.session.db[self.name]["items"][selected]
|
# print self.session.db[self.name]["items"][selected]
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def open_post(self, *args, **kwargs):
|
def open_post(self, *args, **kwargs):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def remove_buffer(self, mandatory=False):
|
def remove_buffer(self, mandatory=False):
|
||||||
if "me_video" == self.name:
|
if "me_video" == self.name:
|
||||||
output.speak(_("This buffer can't be deleted"))
|
output.speak(_("This buffer can't be deleted"))
|
||||||
return False
|
return False
|
||||||
else:
|
else:
|
||||||
if mandatory == False:
|
if mandatory == False:
|
||||||
dlg = commonMessages.remove_buffer()
|
dlg = commonMessages.remove_buffer()
|
||||||
else:
|
else:
|
||||||
dlg = widgetUtils.YES
|
dlg = widgetUtils.YES
|
||||||
if dlg == widgetUtils.YES:
|
if dlg == widgetUtils.YES:
|
||||||
self.session.db.pop(self.name)
|
self.session.db.pop(self.name)
|
||||||
return True
|
return True
|
||||||
else:
|
else:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def get_more_items(self, *args, **kwargs):
|
def get_more_items(self, *args, **kwargs):
|
||||||
# Translators: Some buffers can't use the get previous item feature due to API limitations.
|
# Translators: Some buffers can't use the get previous item feature due to API limitations.
|
||||||
output.speak(_("This buffer doesn't support getting more items."))
|
output.speak(_("This buffer doesn't support getting more items."))
|
||||||
|
|
||||||
def onFocus(self, event, *args, **kwargs):
|
def onFocus(self, event, *args, **kwargs):
|
||||||
event.Skip()
|
event.Skip()
|
||||||
|
|
||||||
def add_to_library(self, *args, **kwargs):
|
def add_to_library(self, *args, **kwargs):
|
||||||
post = self.get_post()
|
post = self.get_post()
|
||||||
if post == None:
|
if post == None:
|
||||||
return
|
return
|
||||||
args = {}
|
args = {}
|
||||||
args["video_id"] = post["id"]
|
args["video_id"] = post["id"]
|
||||||
if "album_id" in post:
|
if "album_id" in post:
|
||||||
args["album_id"] = post["album_id"]
|
args["album_id"] = post["album_id"]
|
||||||
args["owner_id"] = post["owner_id"]
|
args["owner_id"] = post["owner_id"]
|
||||||
video = self.session.vk.client.video.add(**args)
|
video = self.session.vk.client.video.add(**args)
|
||||||
if video != None and int(video) > 21:
|
if video != None and int(video) > 21:
|
||||||
output.speak(_("Video added to your library"))
|
output.speak(_("Video added to your library"))
|
||||||
|
|
||||||
def remove_from_library(self, *args, **kwargs):
|
def remove_from_library(self, *args, **kwargs):
|
||||||
post = self.get_post()
|
post = self.get_post()
|
||||||
if post == None:
|
if post == None:
|
||||||
return
|
return
|
||||||
args = {}
|
args = {}
|
||||||
args["video_id"] = post["id"]
|
args["video_id"] = post["id"]
|
||||||
args["owner_id"] = self.session.user_id
|
args["owner_id"] = self.session.user_id
|
||||||
result = self.session.vk.client.video.delete(**args)
|
result = self.session.vk.client.video.delete(**args)
|
||||||
if int(result) == 1:
|
if int(result) == 1:
|
||||||
output.speak(_("Removed video from library"))
|
output.speak(_("Removed video from library"))
|
||||||
self.tab.list.remove_item(self.tab.list.get_selected())
|
self.tab.list.remove_item(self.tab.list.get_selected())
|
||||||
|
|
||||||
def move_to_album(self, *args, **kwargs):
|
def move_to_album(self, *args, **kwargs):
|
||||||
if len(self.session.video_albums) == 0:
|
if len(self.session.video_albums) == 0:
|
||||||
return commonMessages.no_video_albums()
|
return commonMessages.no_video_albums()
|
||||||
post= self.get_post()
|
post= self.get_post()
|
||||||
if post == None:
|
if post == None:
|
||||||
return
|
return
|
||||||
album = selector.album(_("Select the album where you want to move this video"), self.session, "video_albums")
|
album = selector.album(_("Select the album where you want to move this video"), self.session, "video_albums")
|
||||||
if album.item == None: return
|
if album.item == None: return
|
||||||
id = post["id"]
|
id = post["id"]
|
||||||
response = self.session.vk.client.video.addToAlbum(album_ids=album.item, video_id=id, target_id=self.session.user_id, owner_id=self.get_post()["owner_id"])
|
response = self.session.vk.client.video.addToAlbum(album_ids=album.item, video_id=id, target_id=self.session.user_id, owner_id=self.get_post()["owner_id"])
|
||||||
if response == 1:
|
if response == 1:
|
||||||
# Translators: Used when the user has moved an video to an album.
|
# Translators: Used when the user has moved an video to an album.
|
||||||
output.speak(_("Moved"))
|
output.speak(_("Moved"))
|
||||||
|
|
||||||
def get_menu(self):
|
def get_menu(self):
|
||||||
""" We'll use the same menu that is used for audio items, as the options are exactly the same"""
|
""" We'll use the same menu that is used for audio items, as the options are exactly the same"""
|
||||||
p = self.get_post()
|
p = self.get_post()
|
||||||
if p == None:
|
if p == None:
|
||||||
return
|
return
|
||||||
m = menus.audioMenu()
|
m = menus.audioMenu()
|
||||||
widgetUtils.connect_event(m, widgetUtils.MENU, self.move_to_album, menuitem=m.move)
|
widgetUtils.connect_event(m, widgetUtils.MENU, self.move_to_album, menuitem=m.move)
|
||||||
# if owner_id is the current user, the audio is added to the user's audios.
|
# if owner_id is the current user, the audio is added to the user's audios.
|
||||||
if p["owner_id"] == self.session.user_id:
|
if p["owner_id"] == self.session.user_id:
|
||||||
m.library.SetItemLabel(_("&Remove"))
|
m.library.SetItemLabel(_("&Remove"))
|
||||||
widgetUtils.connect_event(m, widgetUtils.MENU, self.remove_from_library, menuitem=m.library)
|
widgetUtils.connect_event(m, widgetUtils.MENU, self.remove_from_library, menuitem=m.library)
|
||||||
else:
|
else:
|
||||||
widgetUtils.connect_event(m, widgetUtils.MENU, self.add_to_library, menuitem=m.library)
|
widgetUtils.connect_event(m, widgetUtils.MENU, self.add_to_library, menuitem=m.library)
|
||||||
return m
|
return m
|
||||||
|
|
||||||
def open_in_browser(self, *args, **kwargs):
|
def open_in_browser(self, *args, **kwargs):
|
||||||
post = self.get_post()
|
post = self.get_post()
|
||||||
if post == None:
|
if post == None:
|
||||||
return
|
return
|
||||||
url = "https://vk.com/video{user_id}_{video_id}".format(user_id=post["owner_id"], video_id=post["id"])
|
url = "https://vk.com/video{user_id}_{video_id}".format(user_id=post["owner_id"], video_id=post["id"])
|
||||||
webbrowser.open_new_tab(url)
|
webbrowser.open_new_tab(url)
|
||||||
|
@ -10,21 +10,21 @@ log = logging.getLogger("controller.buffers")
|
|||||||
|
|
||||||
class videoAlbumBuffer(videoBuffer):
|
class videoAlbumBuffer(videoBuffer):
|
||||||
|
|
||||||
def create_tab(self, parent):
|
def create_tab(self, parent):
|
||||||
self.tab = video.videoAlbumTab(parent)
|
self.tab = video.videoAlbumTab(parent)
|
||||||
self.tab.play.Enable(False)
|
self.tab.play.Enable(False)
|
||||||
self.connect_events()
|
self.connect_events()
|
||||||
self.tab.name = self.name
|
self.tab.name = self.name
|
||||||
if hasattr(self, "can_post") and self.can_post == False and hasattr(self.tab, "post"):
|
if hasattr(self, "can_post") and self.can_post == False and hasattr(self.tab, "post"):
|
||||||
self.tab.post.Enable(False)
|
self.tab.post.Enable(False)
|
||||||
|
|
||||||
def connect_events(self):
|
def connect_events(self):
|
||||||
super(videoAlbumBuffer, self).connect_events()
|
super(videoAlbumBuffer, self).connect_events()
|
||||||
widgetUtils.connect_event(self.tab.load, widgetUtils.BUTTON_PRESSED, self.load_album)
|
widgetUtils.connect_event(self.tab.load, widgetUtils.BUTTON_PRESSED, self.load_album)
|
||||||
|
|
||||||
def load_album(self, *args, **kwargs):
|
def load_album(self, *args, **kwargs):
|
||||||
output.speak(_("Loading album..."))
|
output.speak(_("Loading album..."))
|
||||||
self.can_get_items = True
|
self.can_get_items = True
|
||||||
self.tab.load.Enable(False)
|
self.tab.load.Enable(False)
|
||||||
wx.CallAfter(self.get_items)
|
wx.CallAfter(self.get_items)
|
||||||
self.tab.play.Enable(True)
|
self.tab.play.Enable(True)
|
||||||
|
@ -17,88 +17,88 @@ from .home import homeBuffer
|
|||||||
log = logging.getLogger("controller.buffers.wall")
|
log = logging.getLogger("controller.buffers.wall")
|
||||||
|
|
||||||
class wallBuffer(homeBuffer):
|
class wallBuffer(homeBuffer):
|
||||||
""" This buffer represents an user's wall. It may be used either for the current user or someone else."""
|
""" This buffer represents an user's wall. It may be used either for the current user or someone else."""
|
||||||
|
|
||||||
def get_items(self, show_nextpage=False):
|
def get_items(self, show_nextpage=False):
|
||||||
""" Update buffer with newest items or get older items in the buffer."""
|
""" Update buffer with newest items or get older items in the buffer."""
|
||||||
if self.can_get_items == False: return
|
if self.can_get_items == False: return
|
||||||
retrieved = True
|
retrieved = True
|
||||||
try:
|
try:
|
||||||
num = getattr(self.session, "get_page")(show_nextpage=show_nextpage, name=self.name, *self.args, **self.kwargs)
|
num = getattr(self.session, "get_page")(show_nextpage=show_nextpage, name=self.name, *self.args, **self.kwargs)
|
||||||
except VkApiError as err:
|
except VkApiError as err:
|
||||||
log.error("Error {0}: {1}".format(err.code, err.error))
|
log.error("Error {0}: {1}".format(err.code, err.error))
|
||||||
retrieved = err.code
|
retrieved = err.code
|
||||||
return retrieved
|
return retrieved
|
||||||
except:
|
except:
|
||||||
log.exception("Connection error when updating buffer %s. Will try again in 2 minutes" % (self.name,))
|
log.exception("Connection error when updating buffer %s. Will try again in 2 minutes" % (self.name,))
|
||||||
return False
|
return False
|
||||||
if not hasattr(self, "tab"):
|
if not hasattr(self, "tab"):
|
||||||
# Create GUI associated to this buffer.
|
# Create GUI associated to this buffer.
|
||||||
self.create_tab(self.parent)
|
self.create_tab(self.parent)
|
||||||
# Add name to the new control so we could look for it when needed.
|
# Add name to the new control so we could look for it when needed.
|
||||||
self.tab.name = self.name
|
self.tab.name = self.name
|
||||||
if show_nextpage == False:
|
if show_nextpage == False:
|
||||||
if self.tab.list.get_count() > 0 and num > 0:
|
if self.tab.list.get_count() > 0 and num > 0:
|
||||||
v = [i for i in self.session.db[self.name]["items"][:num]]
|
v = [i for i in self.session.db[self.name]["items"][:num]]
|
||||||
v.reverse()
|
v.reverse()
|
||||||
[wx.CallAfter(self.insert, i, True) for i in v]
|
[wx.CallAfter(self.insert, i, True) for i in v]
|
||||||
else:
|
else:
|
||||||
[wx.CallAfter(self.insert, i) for i in self.session.db[self.name]["items"][:num]]
|
[wx.CallAfter(self.insert, i) for i in self.session.db[self.name]["items"][:num]]
|
||||||
else:
|
else:
|
||||||
if num > 0:
|
if num > 0:
|
||||||
[wx.CallAfter(self.insert, i, False) for i in self.session.db[self.name]["items"][-num:]]
|
[wx.CallAfter(self.insert, i, False) for i in self.session.db[self.name]["items"][-num:]]
|
||||||
return retrieved
|
return retrieved
|
||||||
|
|
||||||
def remove_buffer(self, mandatory=False):
|
def remove_buffer(self, mandatory=False):
|
||||||
""" Remove buffer if the current buffer is not the logged user's wall."""
|
""" Remove buffer if the current buffer is not the logged user's wall."""
|
||||||
if "me_feed" == self.name:
|
if "me_feed" == self.name:
|
||||||
output.speak(_("This buffer can't be deleted"))
|
output.speak(_("This buffer can't be deleted"))
|
||||||
return False
|
return False
|
||||||
else:
|
else:
|
||||||
if mandatory == False:
|
if mandatory == False:
|
||||||
dlg = commonMessages.remove_buffer()
|
dlg = commonMessages.remove_buffer()
|
||||||
else:
|
else:
|
||||||
dlg = widgetUtils.YES
|
dlg = widgetUtils.YES
|
||||||
if dlg == widgetUtils.YES:
|
if dlg == widgetUtils.YES:
|
||||||
self.session.db.pop(self.name)
|
self.session.db.pop(self.name)
|
||||||
return True
|
return True
|
||||||
else:
|
else:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
super(wallBuffer, self).__init__(*args, **kwargs)
|
super(wallBuffer, self).__init__(*args, **kwargs)
|
||||||
self.user_key = "from_id"
|
self.user_key = "from_id"
|
||||||
self.post_key = "id"
|
self.post_key = "id"
|
||||||
self.can_post = True
|
self.can_post = True
|
||||||
self.can_write_private_message = True
|
self.can_write_private_message = True
|
||||||
# if this is an user timeline we must check permissions to hide buttons when needed.
|
# if this is an user timeline we must check permissions to hide buttons when needed.
|
||||||
if "owner_id" in self.kwargs and self.kwargs["owner_id"] > 0 and "feed" in self.name:
|
if "owner_id" in self.kwargs and self.kwargs["owner_id"] > 0 and "feed" in self.name:
|
||||||
permissions = self.session.vk.client.users.get(user_ids=self.kwargs["owner_id"], fields="can_post, can_see_all_posts, can_write_private_message")
|
permissions = self.session.vk.client.users.get(user_ids=self.kwargs["owner_id"], fields="can_post, can_see_all_posts, can_write_private_message")
|
||||||
self.can_post = permissions[0]["can_post"]
|
self.can_post = permissions[0]["can_post"]
|
||||||
self.can_see_all_posts = permissions[0]["can_see_all_posts"]
|
self.can_see_all_posts = permissions[0]["can_see_all_posts"]
|
||||||
self.can_write_private_message = permissions[0]["can_write_private_message"]
|
self.can_write_private_message = permissions[0]["can_write_private_message"]
|
||||||
log.debug("Checked permissions on buffer {0}, permissions were {1}".format(self.name, permissions))
|
log.debug("Checked permissions on buffer {0}, permissions were {1}".format(self.name, permissions))
|
||||||
|
|
||||||
def post(self, *args, **kwargs):
|
def post(self, *args, **kwargs):
|
||||||
""" Create a post in the wall for the specified user
|
""" Create a post in the wall for the specified user
|
||||||
This process is handled in two parts. This is the first part, where the GUI is created and user can send the post.
|
This process is handled in two parts. This is the first part, where the GUI is created and user can send the post.
|
||||||
During the second part (threaded), the post will be sent to the API."""
|
During the second part (threaded), the post will be sent to the API."""
|
||||||
if "owner_id" not in self.kwargs:
|
if "owner_id" not in self.kwargs:
|
||||||
return super(wallBuffer, self).post()
|
return super(wallBuffer, self).post()
|
||||||
owner_id = self.kwargs["owner_id"]
|
owner_id = self.kwargs["owner_id"]
|
||||||
user = self.session.get_user(owner_id, key="user1")
|
user = self.session.get_user(owner_id, key="user1")
|
||||||
title = _("Post to {user1_nom}'s wall").format(**user)
|
title = _("Post to {user1_nom}'s wall").format(**user)
|
||||||
p = presenters.createPostPresenter(session=self.session, interactor=interactors.createPostInteractor(), view=views.createPostDialog(title=title, message="", text=""))
|
p = presenters.createPostPresenter(session=self.session, interactor=interactors.createPostInteractor(), view=views.createPostDialog(title=title, message="", text=""))
|
||||||
if hasattr(p, "text") or hasattr(p, "privacy"):
|
if hasattr(p, "text") or hasattr(p, "privacy"):
|
||||||
post_arguments=dict(privacy=p.privacy, message=p.text, owner_id=owner_id)
|
post_arguments=dict(privacy=p.privacy, message=p.text, owner_id=owner_id)
|
||||||
attachments = []
|
attachments = []
|
||||||
if hasattr(p, "attachments"):
|
if hasattr(p, "attachments"):
|
||||||
attachments = p.attachments
|
attachments = p.attachments
|
||||||
call_threaded(pub.sendMessage, "post", parent_endpoint="wall", child_endpoint="post", from_buffer=self.name, attachments_list=attachments, post_arguments=post_arguments)
|
call_threaded(pub.sendMessage, "post", parent_endpoint="wall", child_endpoint="post", from_buffer=self.name, attachments_list=attachments, post_arguments=post_arguments)
|
||||||
|
|
||||||
def open_in_browser(self, *args, **kwargs):
|
def open_in_browser(self, *args, **kwargs):
|
||||||
post = self.get_post()
|
post = self.get_post()
|
||||||
if post == None:
|
if post == None:
|
||||||
return
|
return
|
||||||
url = "https://vk.com/wall{user_id}_{post_id}".format(user_id=post["from_id"], post_id=post["id"])
|
url = "https://vk.com/wall{user_id}_{post_id}".format(user_id=post["from_id"], post_id=post["id"])
|
||||||
webbrowser.open_new_tab(url)
|
webbrowser.open_new_tab(url)
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -4,24 +4,23 @@ from wxUI.dialogs import selector as gui
|
|||||||
|
|
||||||
class album(object):
|
class album(object):
|
||||||
|
|
||||||
def __init__(self, title, session, album_type="audio_albums"):
|
def __init__(self, title, session, album_type="audio_albums"):
|
||||||
super(album, self).__init__()
|
super(album, self).__init__()
|
||||||
self.item = None
|
self.item = None
|
||||||
self.session = session
|
self.session = session
|
||||||
if not hasattr(self.session, album_type):
|
if not hasattr(self.session, album_type):
|
||||||
return
|
return
|
||||||
self.albums = getattr(self.session, album_type)
|
self.albums = getattr(self.session, album_type)
|
||||||
self.dialog = gui.selectAlbum(title=title, albums=self.get_albums_as_string())
|
self.dialog = gui.selectAlbum(title=title, albums=self.get_albums_as_string())
|
||||||
response = self.dialog.get_response()
|
response = self.dialog.get_response()
|
||||||
if response == widgetUtils.OK:
|
if response == widgetUtils.OK:
|
||||||
self.item = self.search_item(self.dialog.get_string())
|
self.item = self.search_item(self.dialog.get_string())
|
||||||
|
|
||||||
def get_albums_as_string(self):
|
def get_albums_as_string(self):
|
||||||
return [i["title"] for i in self.albums]
|
return [i["title"] for i in self.albums]
|
||||||
|
|
||||||
def search_item(self, item):
|
|
||||||
for i in self.albums:
|
|
||||||
if i["title"] == item:
|
|
||||||
return i["id"]
|
|
||||||
return None
|
|
||||||
|
|
||||||
|
def search_item(self, item):
|
||||||
|
for i in self.albums:
|
||||||
|
if i["title"] == item:
|
||||||
|
return i["id"]
|
||||||
|
return None
|
||||||
|
@ -3,4 +3,4 @@ from __future__ import unicode_literals
|
|||||||
from . import spellchecker
|
from . import spellchecker
|
||||||
import platform
|
import platform
|
||||||
if platform.system() == "Windows":
|
if platform.system() == "Windows":
|
||||||
from .wx_ui import *
|
from .wx_ui import *
|
||||||
|
@ -15,62 +15,62 @@ from enchant import tokenize
|
|||||||
log = logging.getLogger("extra.SpellChecker.spellChecker")
|
log = logging.getLogger("extra.SpellChecker.spellChecker")
|
||||||
|
|
||||||
class spellChecker(object):
|
class spellChecker(object):
|
||||||
def __init__(self, text):
|
def __init__(self, text):
|
||||||
super(spellChecker, self).__init__()
|
super(spellChecker, self).__init__()
|
||||||
self.active = True
|
self.active = True
|
||||||
try:
|
try:
|
||||||
if config.app["app-settings"]["language"] == "system":
|
if config.app["app-settings"]["language"] == "system":
|
||||||
log.debug("Using the system language")
|
log.debug("Using the system language")
|
||||||
self.dict = enchant.DictWithPWL(languageHandler.curLang[:2], os.path.join(paths.config_path(), "wordlist.dict"))
|
self.dict = enchant.DictWithPWL(languageHandler.curLang[:2], os.path.join(paths.config_path(), "wordlist.dict"))
|
||||||
else:
|
else:
|
||||||
log.debug("Using language: %s" % (languageHandler.getLanguage(),))
|
log.debug("Using language: %s" % (languageHandler.getLanguage(),))
|
||||||
self.dict = enchant.DictWithPWL(languageHandler.getLanguage()[:2], os.path.join(paths.config_path(), "wordlist.dict"))
|
self.dict = enchant.DictWithPWL(languageHandler.getLanguage()[:2], os.path.join(paths.config_path(), "wordlist.dict"))
|
||||||
except DictNotFoundError:
|
except DictNotFoundError:
|
||||||
log.exception("Dictionary for language %s not found." % (languageHandler.getLanguage(),))
|
log.exception("Dictionary for language %s not found." % (languageHandler.getLanguage(),))
|
||||||
wx_ui.dict_not_found_error()
|
wx_ui.dict_not_found_error()
|
||||||
self.active = False
|
self.active = False
|
||||||
self.checker = SpellChecker(self.dict, filters=[twitterFilter.TwitterFilter, tokenize.EmailFilter, tokenize.URLFilter])
|
self.checker = SpellChecker(self.dict, filters=[twitterFilter.TwitterFilter, tokenize.EmailFilter, tokenize.URLFilter])
|
||||||
self.checker.set_text(text)
|
self.checker.set_text(text)
|
||||||
if self.active == True:
|
if self.active == True:
|
||||||
log.debug("Creating dialog...")
|
log.debug("Creating dialog...")
|
||||||
self.dialog = wx_ui.spellCheckerDialog()
|
self.dialog = wx_ui.spellCheckerDialog()
|
||||||
widgetUtils.connect_event(self.dialog.ignore, widgetUtils.BUTTON_PRESSED, self.ignore)
|
widgetUtils.connect_event(self.dialog.ignore, widgetUtils.BUTTON_PRESSED, self.ignore)
|
||||||
widgetUtils.connect_event(self.dialog.ignoreAll, widgetUtils.BUTTON_PRESSED, self.ignoreAll)
|
widgetUtils.connect_event(self.dialog.ignoreAll, widgetUtils.BUTTON_PRESSED, self.ignoreAll)
|
||||||
widgetUtils.connect_event(self.dialog.replace, widgetUtils.BUTTON_PRESSED, self.replace)
|
widgetUtils.connect_event(self.dialog.replace, widgetUtils.BUTTON_PRESSED, self.replace)
|
||||||
widgetUtils.connect_event(self.dialog.replaceAll, widgetUtils.BUTTON_PRESSED, self.replaceAll)
|
widgetUtils.connect_event(self.dialog.replaceAll, widgetUtils.BUTTON_PRESSED, self.replaceAll)
|
||||||
widgetUtils.connect_event(self.dialog.add, widgetUtils.BUTTON_PRESSED, self.add)
|
widgetUtils.connect_event(self.dialog.add, widgetUtils.BUTTON_PRESSED, self.add)
|
||||||
self.check()
|
self.check()
|
||||||
self.dialog.get_response()
|
self.dialog.get_response()
|
||||||
self.fixed_text = self.checker.get_text()
|
self.fixed_text = self.checker.get_text()
|
||||||
|
|
||||||
def check(self):
|
def check(self):
|
||||||
try:
|
try:
|
||||||
next(self.checker)
|
next(self.checker)
|
||||||
textToSay = _(u"Misspelled word: %s") % (self.checker.word,)
|
textToSay = _(u"Misspelled word: %s") % (self.checker.word,)
|
||||||
context = u"... %s %s %s" % (self.checker.leading_context(10), self.checker.word, self.checker.trailing_context(10))
|
context = u"... %s %s %s" % (self.checker.leading_context(10), self.checker.word, self.checker.trailing_context(10))
|
||||||
self.dialog.set_title(textToSay)
|
self.dialog.set_title(textToSay)
|
||||||
output.speak(textToSay)
|
output.speak(textToSay)
|
||||||
self.dialog.set_word_and_suggestions(word=self.checker.word, context=context, suggestions=self.checker.suggest())
|
self.dialog.set_word_and_suggestions(word=self.checker.word, context=context, suggestions=self.checker.suggest())
|
||||||
except StopIteration:
|
except StopIteration:
|
||||||
log.debug("Process finished.")
|
log.debug("Process finished.")
|
||||||
wx_ui.finished()
|
wx_ui.finished()
|
||||||
self.dialog.Destroy()
|
self.dialog.Destroy()
|
||||||
|
|
||||||
def ignore(self, ev):
|
def ignore(self, ev):
|
||||||
self.check()
|
self.check()
|
||||||
|
|
||||||
def ignoreAll(self, ev):
|
def ignoreAll(self, ev):
|
||||||
self.checker.ignore_always(word=self.checker.word)
|
self.checker.ignore_always(word=self.checker.word)
|
||||||
self.check()
|
self.check()
|
||||||
|
|
||||||
def replace(self, ev):
|
def replace(self, ev):
|
||||||
self.checker.replace(self.dialog.get_selected_suggestion())
|
self.checker.replace(self.dialog.get_selected_suggestion())
|
||||||
self.check()
|
self.check()
|
||||||
|
|
||||||
def replaceAll(self, ev):
|
def replaceAll(self, ev):
|
||||||
self.checker.replace_always(self.dialog.get_selected_suggestion())
|
self.checker.replace_always(self.dialog.get_selected_suggestion())
|
||||||
self.check()
|
self.check()
|
||||||
|
|
||||||
def add(self, ev):
|
def add(self, ev):
|
||||||
self.checker.add()
|
self.checker.add()
|
||||||
self.check()
|
self.check()
|
||||||
|
@ -21,63 +21,63 @@ import wx
|
|||||||
import application
|
import application
|
||||||
|
|
||||||
class spellCheckerDialog(wx.Dialog):
|
class spellCheckerDialog(wx.Dialog):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super(spellCheckerDialog, self).__init__(None, 1)
|
super(spellCheckerDialog, self).__init__(None, 1)
|
||||||
panel = wx.Panel(self)
|
panel = wx.Panel(self)
|
||||||
sizer = wx.BoxSizer(wx.VERTICAL)
|
sizer = wx.BoxSizer(wx.VERTICAL)
|
||||||
word = wx.StaticText(panel, -1, _(u"Misspelled word"))
|
word = wx.StaticText(panel, -1, _(u"Misspelled word"))
|
||||||
self.word = wx.TextCtrl(panel, -1)
|
self.word = wx.TextCtrl(panel, -1)
|
||||||
wordBox = wx.BoxSizer(wx.HORIZONTAL)
|
wordBox = wx.BoxSizer(wx.HORIZONTAL)
|
||||||
wordBox.Add(word, 0, wx.ALL, 5)
|
wordBox.Add(word, 0, wx.ALL, 5)
|
||||||
wordBox.Add(self.word, 0, wx.ALL, 5)
|
wordBox.Add(self.word, 0, wx.ALL, 5)
|
||||||
context = wx.StaticText(panel, -1, _(u"Context"))
|
context = wx.StaticText(panel, -1, _(u"Context"))
|
||||||
self.context = wx.TextCtrl(panel, -1)
|
self.context = wx.TextCtrl(panel, -1)
|
||||||
contextBox = wx.BoxSizer(wx.HORIZONTAL)
|
contextBox = wx.BoxSizer(wx.HORIZONTAL)
|
||||||
contextBox.Add(context, 0, wx.ALL, 5)
|
contextBox.Add(context, 0, wx.ALL, 5)
|
||||||
contextBox.Add(self.context, 0, wx.ALL, 5)
|
contextBox.Add(self.context, 0, wx.ALL, 5)
|
||||||
suggest = wx.StaticText(panel, -1, _(u"Suggestions"))
|
suggest = wx.StaticText(panel, -1, _(u"Suggestions"))
|
||||||
self.suggestions = wx.ListBox(panel, -1, choices=[], style=wx.LB_SINGLE)
|
self.suggestions = wx.ListBox(panel, -1, choices=[], style=wx.LB_SINGLE)
|
||||||
suggestionsBox = wx.BoxSizer(wx.HORIZONTAL)
|
suggestionsBox = wx.BoxSizer(wx.HORIZONTAL)
|
||||||
suggestionsBox.Add(suggest, 0, wx.ALL, 5)
|
suggestionsBox.Add(suggest, 0, wx.ALL, 5)
|
||||||
suggestionsBox.Add(self.suggestions, 0, wx.ALL, 5)
|
suggestionsBox.Add(self.suggestions, 0, wx.ALL, 5)
|
||||||
self.ignore = wx.Button(panel, -1, _(u"&Ignore"))
|
self.ignore = wx.Button(panel, -1, _(u"&Ignore"))
|
||||||
self.ignoreAll = wx.Button(panel, -1, _(u"I&gnore all"))
|
self.ignoreAll = wx.Button(panel, -1, _(u"I&gnore all"))
|
||||||
self.replace = wx.Button(panel, -1, _(u"&Replace"))
|
self.replace = wx.Button(panel, -1, _(u"&Replace"))
|
||||||
self.replaceAll = wx.Button(panel, -1, _(u"R&eplace all"))
|
self.replaceAll = wx.Button(panel, -1, _(u"R&eplace all"))
|
||||||
self.add = wx.Button(panel, -1, _(u"&Add to personal dictionary"))
|
self.add = wx.Button(panel, -1, _(u"&Add to personal dictionary"))
|
||||||
close = wx.Button(panel, wx.ID_CANCEL)
|
close = wx.Button(panel, wx.ID_CANCEL)
|
||||||
btnBox = wx.BoxSizer(wx.HORIZONTAL)
|
btnBox = wx.BoxSizer(wx.HORIZONTAL)
|
||||||
btnBox.Add(self.ignore, 0, wx.ALL, 5)
|
btnBox.Add(self.ignore, 0, wx.ALL, 5)
|
||||||
btnBox.Add(self.ignoreAll, 0, wx.ALL, 5)
|
btnBox.Add(self.ignoreAll, 0, wx.ALL, 5)
|
||||||
btnBox.Add(self.replace, 0, wx.ALL, 5)
|
btnBox.Add(self.replace, 0, wx.ALL, 5)
|
||||||
btnBox.Add(self.replaceAll, 0, wx.ALL, 5)
|
btnBox.Add(self.replaceAll, 0, wx.ALL, 5)
|
||||||
btnBox.Add(self.add, 0, wx.ALL, 5)
|
btnBox.Add(self.add, 0, wx.ALL, 5)
|
||||||
btnBox.Add(close, 0, wx.ALL, 5)
|
btnBox.Add(close, 0, wx.ALL, 5)
|
||||||
sizer.Add(wordBox, 0, wx.ALL, 5)
|
sizer.Add(wordBox, 0, wx.ALL, 5)
|
||||||
sizer.Add(contextBox, 0, wx.ALL, 5)
|
sizer.Add(contextBox, 0, wx.ALL, 5)
|
||||||
sizer.Add(suggestionsBox, 0, wx.ALL, 5)
|
sizer.Add(suggestionsBox, 0, wx.ALL, 5)
|
||||||
sizer.Add(btnBox, 0, wx.ALL, 5)
|
sizer.Add(btnBox, 0, wx.ALL, 5)
|
||||||
panel.SetSizer(sizer)
|
panel.SetSizer(sizer)
|
||||||
self.SetClientSize(sizer.CalcMin())
|
self.SetClientSize(sizer.CalcMin())
|
||||||
|
|
||||||
|
|
||||||
def get_response(self):
|
def get_response(self):
|
||||||
return self.ShowModal()
|
return self.ShowModal()
|
||||||
|
|
||||||
def set_title(self, title):
|
def set_title(self, title):
|
||||||
return self.SetTitle(title)
|
return self.SetTitle(title)
|
||||||
|
|
||||||
def set_word_and_suggestions(self, word, context, suggestions):
|
def set_word_and_suggestions(self, word, context, suggestions):
|
||||||
self.word.SetValue(word)
|
self.word.SetValue(word)
|
||||||
self.context.ChangeValue(context)
|
self.context.ChangeValue(context)
|
||||||
self.suggestions.Set(suggestions)
|
self.suggestions.Set(suggestions)
|
||||||
self.suggestions.SetFocus()
|
self.suggestions.SetFocus()
|
||||||
|
|
||||||
def get_selected_suggestion(self):
|
def get_selected_suggestion(self):
|
||||||
return self.suggestions.GetStringSelection()
|
return self.suggestions.GetStringSelection()
|
||||||
|
|
||||||
def dict_not_found_error():
|
def dict_not_found_error():
|
||||||
wx.MessageDialog(None, _(u"An error has occurred. There are no dictionaries available for the selected language in {0}").format(application.name,), _(u"Error"), wx.ICON_ERROR).ShowModal()
|
wx.MessageDialog(None, _(u"An error has occurred. There are no dictionaries available for the selected language in {0}").format(application.name,), _(u"Error"), wx.ICON_ERROR).ShowModal()
|
||||||
|
|
||||||
def finished():
|
def finished():
|
||||||
wx.MessageDialog(None, _(u"Spell check complete."), application.name, style=wx.OK).ShowModal()
|
wx.MessageDialog(None, _(u"Spell check complete."), application.name, style=wx.OK).ShowModal()
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
import platform
|
import platform
|
||||||
if platform.system() == "Windows":
|
if platform.system() == "Windows":
|
||||||
from . import wx_ui as gui
|
from . import wx_ui as gui
|
||||||
from . import translator
|
from . import translator
|
@ -9,12 +9,12 @@ log = logging.getLogger("extras.translator")
|
|||||||
t = None
|
t = None
|
||||||
|
|
||||||
def translate(text="", target="en"):
|
def translate(text="", target="en"):
|
||||||
global t
|
global t
|
||||||
log.debug("Received translation request for language %s, text=%s" % (target, text))
|
log.debug("Received translation request for language %s, text=%s" % (target, text))
|
||||||
if t == None:
|
if t == None:
|
||||||
t = Translator()
|
t = Translator()
|
||||||
vars = dict(text=text, dest=target)
|
vars = dict(text=text, dest=target)
|
||||||
return t.translate(**vars).text
|
return t.translate(**vars).text
|
||||||
|
|
||||||
supported_langs = None
|
supported_langs = None
|
||||||
|
|
||||||
@ -113,4 +113,4 @@ languages = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
def available_languages():
|
def available_languages():
|
||||||
return dict(sorted(languages.items(), key=lambda x: x[1]))
|
return dict(sorted(languages.items(), key=lambda x: x[1]))
|
||||||
|
@ -21,25 +21,25 @@ import wx
|
|||||||
from widgetUtils import BaseDialog
|
from widgetUtils import BaseDialog
|
||||||
|
|
||||||
class translateDialog(BaseDialog):
|
class translateDialog(BaseDialog):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
languages = []
|
languages = []
|
||||||
language_dict = translator.available_languages()
|
language_dict = translator.available_languages()
|
||||||
for k in language_dict:
|
for k in language_dict:
|
||||||
languages.append(language_dict[k])
|
languages.append(language_dict[k])
|
||||||
super(translateDialog, self).__init__(None, -1, title=_(u"Translate message"))
|
super(translateDialog, self).__init__(None, -1, title=_(u"Translate message"))
|
||||||
panel = wx.Panel(self)
|
panel = wx.Panel(self)
|
||||||
sizer = wx.BoxSizer(wx.VERTICAL)
|
sizer = wx.BoxSizer(wx.VERTICAL)
|
||||||
staticDest = wx.StaticText(panel, -1, _(u"Target language"))
|
staticDest = wx.StaticText(panel, -1, _(u"Target language"))
|
||||||
self.dest_lang = wx.ComboBox(panel, -1, choices=languages, style = wx.CB_READONLY)
|
self.dest_lang = wx.ComboBox(panel, -1, choices=languages, style = wx.CB_READONLY)
|
||||||
self.dest_lang.SetFocus()
|
self.dest_lang.SetFocus()
|
||||||
self.dest_lang.SetSelection(0)
|
self.dest_lang.SetSelection(0)
|
||||||
listSizer = wx.BoxSizer(wx.HORIZONTAL)
|
listSizer = wx.BoxSizer(wx.HORIZONTAL)
|
||||||
listSizer.Add(staticDest)
|
listSizer.Add(staticDest)
|
||||||
listSizer.Add(self.dest_lang)
|
listSizer.Add(self.dest_lang)
|
||||||
ok = wx.Button(panel, wx.ID_OK)
|
ok = wx.Button(panel, wx.ID_OK)
|
||||||
ok.SetDefault()
|
ok.SetDefault()
|
||||||
cancel = wx.Button(panel, wx.ID_CANCEL)
|
cancel = wx.Button(panel, wx.ID_CANCEL)
|
||||||
self.SetEscapeId(wx.ID_CANCEL)
|
self.SetEscapeId(wx.ID_CANCEL)
|
||||||
|
|
||||||
def get(self, control):
|
def get(self, control):
|
||||||
return getattr(self, control).GetSelection()
|
return getattr(self, control).GetSelection()
|
||||||
|
@ -8,7 +8,7 @@ from . import fix_win32com
|
|||||||
from . import fix_libloader
|
from . import fix_libloader
|
||||||
|
|
||||||
def setup():
|
def setup():
|
||||||
fix_requests.fix()
|
fix_requests.fix()
|
||||||
# if hasattr(sys, "frozen"):
|
# if hasattr(sys, "frozen"):
|
||||||
fix_libloader.fix()
|
fix_libloader.fix()
|
||||||
fix_win32com.fix()
|
fix_win32com.fix()
|
||||||
|
@ -12,25 +12,25 @@ from libloader import com
|
|||||||
fixed=False
|
fixed=False
|
||||||
|
|
||||||
def patched_getmodule(modname):
|
def patched_getmodule(modname):
|
||||||
mod=__import__(modname)
|
mod=__import__(modname)
|
||||||
return sys.modules[modname]
|
return sys.modules[modname]
|
||||||
|
|
||||||
def load_com(*names):
|
def load_com(*names):
|
||||||
global fixed
|
global fixed
|
||||||
if fixed==False:
|
if fixed==False:
|
||||||
gencache._GetModule=patched_getmodule
|
gencache._GetModule=patched_getmodule
|
||||||
com.prepare_gencache()
|
com.prepare_gencache()
|
||||||
fixed=True
|
fixed=True
|
||||||
result = None
|
result = None
|
||||||
for name in names:
|
for name in names:
|
||||||
try:
|
try:
|
||||||
result = gencache.EnsureDispatch(name)
|
result = gencache.EnsureDispatch(name)
|
||||||
break
|
break
|
||||||
except com_error:
|
except com_error:
|
||||||
continue
|
continue
|
||||||
if result is None:
|
if result is None:
|
||||||
raise com_error("Unable to load any of the provided com objects.")
|
raise com_error("Unable to load any of the provided com objects.")
|
||||||
return result
|
return result
|
||||||
|
|
||||||
def fix():
|
def fix():
|
||||||
com.load_com = load_com
|
com.load_com = load_com
|
||||||
|
@ -7,6 +7,6 @@ import logging
|
|||||||
log = logging.getLogger("fixes.fix_requests")
|
log = logging.getLogger("fixes.fix_requests")
|
||||||
|
|
||||||
def fix():
|
def fix():
|
||||||
log.debug("Applying fix for requests...")
|
log.debug("Applying fix for requests...")
|
||||||
os.environ["REQUESTS_CA_BUNDLE"] = os.path.join(paths.app_path(), "cacert.pem")#.encode(paths.fsencoding)
|
os.environ["REQUESTS_CA_BUNDLE"] = os.path.join(paths.app_path(), "cacert.pem")#.encode(paths.fsencoding)
|
||||||
# log.debug("Changed CA path to %s" % (os.environ["REQUESTS_CA_BUNDLE"]))#.decode(paths.fsencoding)))
|
# log.debug("Changed CA path to %s" % (os.environ["REQUESTS_CA_BUNDLE"]))#.decode(paths.fsencoding)))
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
import win32com.client
|
import win32com.client
|
||||||
def fix():
|
def fix():
|
||||||
if win32com.client.gencache.is_readonly == True:
|
if win32com.client.gencache.is_readonly == True:
|
||||||
win32com.client.gencache.is_readonly = False
|
win32com.client.gencache.is_readonly = False
|
||||||
win32com.client.gencache.Rebuild()
|
win32com.client.gencache.Rebuild()
|
||||||
|
@ -8,86 +8,86 @@ from . import base
|
|||||||
|
|
||||||
class attachInteractor(base.baseInteractor):
|
class attachInteractor(base.baseInteractor):
|
||||||
|
|
||||||
def insert_attachment(self, attachment):
|
def insert_attachment(self, attachment):
|
||||||
self.view.attachments.insert_item(False, *attachment)
|
self.view.attachments.insert_item(False, *attachment)
|
||||||
|
|
||||||
def remove_attachment(self, attachment):
|
def remove_attachment(self, attachment):
|
||||||
self.view.attachments.remove_item(attachment)
|
self.view.attachments.remove_item(attachment)
|
||||||
|
|
||||||
def install(self, *args, **kwargs):
|
def install(self, *args, **kwargs):
|
||||||
super(attachInteractor, self).install(*args, **kwargs)
|
super(attachInteractor, self).install(*args, **kwargs)
|
||||||
widgetUtils.connect_event(self.view.photo, widgetUtils.BUTTON_PRESSED, self.on_image)
|
widgetUtils.connect_event(self.view.photo, widgetUtils.BUTTON_PRESSED, self.on_image)
|
||||||
widgetUtils.connect_event(self.view.audio, widgetUtils.BUTTON_PRESSED, self.on_audio)
|
widgetUtils.connect_event(self.view.audio, widgetUtils.BUTTON_PRESSED, self.on_audio)
|
||||||
widgetUtils.connect_event(self.view.document, widgetUtils.BUTTON_PRESSED, self.on_document)
|
widgetUtils.connect_event(self.view.document, widgetUtils.BUTTON_PRESSED, self.on_document)
|
||||||
if hasattr(self.view, "voice_message"):
|
if hasattr(self.view, "voice_message"):
|
||||||
widgetUtils.connect_event(self.view.voice_message, widgetUtils.BUTTON_PRESSED, self.on_upload_voice_message)
|
widgetUtils.connect_event(self.view.voice_message, widgetUtils.BUTTON_PRESSED, self.on_upload_voice_message)
|
||||||
widgetUtils.connect_event(self.view.remove, widgetUtils.BUTTON_PRESSED, self.on_remove_attachment)
|
widgetUtils.connect_event(self.view.remove, widgetUtils.BUTTON_PRESSED, self.on_remove_attachment)
|
||||||
pub.subscribe(self.insert_attachment, self.modulename+"_insert_attachment")
|
pub.subscribe(self.insert_attachment, self.modulename+"_insert_attachment")
|
||||||
pub.subscribe(self.remove_attachment, self.modulename+"_remove_attachment")
|
pub.subscribe(self.remove_attachment, self.modulename+"_remove_attachment")
|
||||||
|
|
||||||
def uninstall(self):
|
def uninstall(self):
|
||||||
super(attachInteractor, self).uninstall()
|
super(attachInteractor, self).uninstall()
|
||||||
pub.unsubscribe(self.insert_attachment, self.modulename+"_insert_attachment")
|
pub.unsubscribe(self.insert_attachment, self.modulename+"_insert_attachment")
|
||||||
pub.unsubscribe(self.remove_attachment, self.modulename+"_remove_attachment")
|
pub.unsubscribe(self.remove_attachment, self.modulename+"_remove_attachment")
|
||||||
|
|
||||||
def on_image(self, *args, **kwargs):
|
def on_image(self, *args, **kwargs):
|
||||||
""" display menu for adding image attachments. """
|
""" display menu for adding image attachments. """
|
||||||
m = attachMenu()
|
m = attachMenu()
|
||||||
# disable add from VK as it is not supported in images, yet.
|
# disable add from VK as it is not supported in images, yet.
|
||||||
m.add.Enable(False)
|
m.add.Enable(False)
|
||||||
widgetUtils.connect_event(m, widgetUtils.MENU, self.on_upload_image, menuitem=m.upload)
|
widgetUtils.connect_event(m, widgetUtils.MENU, self.on_upload_image, menuitem=m.upload)
|
||||||
self.view.PopupMenu(m, self.view.photo.GetPosition())
|
self.view.PopupMenu(m, self.view.photo.GetPosition())
|
||||||
|
|
||||||
def on_audio(self, *args, **kwargs):
|
def on_audio(self, *args, **kwargs):
|
||||||
""" display menu to add audio attachments."""
|
""" display menu to add audio attachments."""
|
||||||
m = attachMenu()
|
m = attachMenu()
|
||||||
widgetUtils.connect_event(m, widgetUtils.MENU, self.on_upload_audio, menuitem=m.upload)
|
widgetUtils.connect_event(m, widgetUtils.MENU, self.on_upload_audio, menuitem=m.upload)
|
||||||
widgetUtils.connect_event(m, widgetUtils.MENU, self.on_add_audio, menuitem=m.add)
|
widgetUtils.connect_event(m, widgetUtils.MENU, self.on_add_audio, menuitem=m.add)
|
||||||
self.view.PopupMenu(m, self.view.audio.GetPosition())
|
self.view.PopupMenu(m, self.view.audio.GetPosition())
|
||||||
|
|
||||||
def on_document(self, *args, **kwargs):
|
def on_document(self, *args, **kwargs):
|
||||||
""" display menu for adding document attachments. """
|
""" display menu for adding document attachments. """
|
||||||
m = attachMenu()
|
m = attachMenu()
|
||||||
# disable add from VK as it is not supported in documents, yet.
|
# disable add from VK as it is not supported in documents, yet.
|
||||||
m.add.Enable(False)
|
m.add.Enable(False)
|
||||||
widgetUtils.connect_event(m, widgetUtils.MENU, self.on_upload_document, menuitem=m.upload)
|
widgetUtils.connect_event(m, widgetUtils.MENU, self.on_upload_document, menuitem=m.upload)
|
||||||
self.view.PopupMenu(m, self.view.photo.GetPosition())
|
self.view.PopupMenu(m, self.view.photo.GetPosition())
|
||||||
|
|
||||||
def on_upload_image(self, *args, **kwargs):
|
def on_upload_image(self, *args, **kwargs):
|
||||||
""" allows uploading an image from the computer.
|
""" allows uploading an image from the computer.
|
||||||
"""
|
"""
|
||||||
image, description = self.view.get_image()
|
image, description = self.view.get_image()
|
||||||
if image != None:
|
if image != None:
|
||||||
self.presenter.upload_image(image, description)
|
self.presenter.upload_image(image, description)
|
||||||
|
|
||||||
def on_upload_audio(self, *args, **kwargs):
|
def on_upload_audio(self, *args, **kwargs):
|
||||||
""" Allows uploading an audio file from the computer. Only mp3 files are supported. """
|
""" Allows uploading an audio file from the computer. Only mp3 files are supported. """
|
||||||
audio = self.view.get_audio()
|
audio = self.view.get_audio()
|
||||||
if audio != None:
|
if audio != None:
|
||||||
self.presenter.upload_audio(audio)
|
self.presenter.upload_audio(audio)
|
||||||
|
|
||||||
def on_upload_document(self, *args, **kwargs):
|
def on_upload_document(self, *args, **kwargs):
|
||||||
""" allows uploading a document from the computer.
|
""" allows uploading a document from the computer.
|
||||||
"""
|
"""
|
||||||
document = self.view.get_document()
|
document = self.view.get_document()
|
||||||
if document != None:
|
if document != None:
|
||||||
if document.endswith(".mp3") or document.endswith(".exe"):
|
if document.endswith(".mp3") or document.endswith(".exe"):
|
||||||
self.view.invalid_attachment()
|
self.view.invalid_attachment()
|
||||||
return
|
return
|
||||||
self.presenter.upload_document(document)
|
self.presenter.upload_document(document)
|
||||||
|
|
||||||
def on_upload_voice_message(self, *args, **kwargs):
|
def on_upload_voice_message(self, *args, **kwargs):
|
||||||
self.presenter.upload_voice_message()
|
self.presenter.upload_voice_message()
|
||||||
|
|
||||||
def on_add_audio(self, *args, **kwargs):
|
def on_add_audio(self, *args, **kwargs):
|
||||||
""" Allow adding an audio directly from the user's audio library."""
|
""" Allow adding an audio directly from the user's audio library."""
|
||||||
audios = self.presenter.get_available_audios()
|
audios = self.presenter.get_available_audios()
|
||||||
select = selector.selectAttachment(_("Select the audio files you want to send"), audios)
|
select = selector.selectAttachment(_("Select the audio files you want to send"), audios)
|
||||||
if select.get_response() == widgetUtils.OK and select.attachments.GetCount() > 0:
|
if select.get_response() == widgetUtils.OK and select.attachments.GetCount() > 0:
|
||||||
attachments = select.get_all_attachments()
|
attachments = select.get_all_attachments()
|
||||||
self.presenter.take_audios(attachments)
|
self.presenter.take_audios(attachments)
|
||||||
|
|
||||||
def on_remove_attachment(self, *args, **kwargs):
|
def on_remove_attachment(self, *args, **kwargs):
|
||||||
""" Remove the currently focused item from the attachments list."""
|
""" Remove the currently focused item from the attachments list."""
|
||||||
current_item = self.view.attachments.get_selected()
|
current_item = self.view.attachments.get_selected()
|
||||||
self.presenter.remove_attachment(current_item)
|
self.presenter.remove_attachment(current_item)
|
||||||
|
@ -5,25 +5,25 @@ from pubsub import pub
|
|||||||
from . import base
|
from . import base
|
||||||
|
|
||||||
class audioRecorderInteractor(base.baseInteractor):
|
class audioRecorderInteractor(base.baseInteractor):
|
||||||
def install(self, presenter, view, modulename="audiorecorder"):
|
def install(self, presenter, view, modulename="audiorecorder"):
|
||||||
super(audioRecorderInteractor, self).install(view=view, presenter=presenter, modulename=modulename)
|
super(audioRecorderInteractor, self).install(view=view, presenter=presenter, modulename=modulename)
|
||||||
widgetUtils.connect_event(view.play, widgetUtils.BUTTON_PRESSED, self.on_play)
|
widgetUtils.connect_event(view.play, widgetUtils.BUTTON_PRESSED, self.on_play)
|
||||||
widgetUtils.connect_event(view.record, widgetUtils.BUTTON_PRESSED, self.on_record)
|
widgetUtils.connect_event(view.record, widgetUtils.BUTTON_PRESSED, self.on_record)
|
||||||
widgetUtils.connect_event(view.discard, widgetUtils.BUTTON_PRESSED, self.on_discard)
|
widgetUtils.connect_event(view.discard, widgetUtils.BUTTON_PRESSED, self.on_discard)
|
||||||
|
|
||||||
def start(self):
|
def start(self):
|
||||||
result = self.view.get_response()
|
result = self.view.get_response()
|
||||||
if result == widgetUtils.OK:
|
if result == widgetUtils.OK:
|
||||||
self.on_postprocess()
|
self.on_postprocess()
|
||||||
|
|
||||||
def on_record(self, *args, **kwargs):
|
def on_record(self, *args, **kwargs):
|
||||||
self.presenter.toggle_recording()
|
self.presenter.toggle_recording()
|
||||||
|
|
||||||
def on_discard(self, *args, **kwargs):
|
def on_discard(self, *args, **kwargs):
|
||||||
self.presenter.discard_recording()
|
self.presenter.discard_recording()
|
||||||
|
|
||||||
def on_play(self, *args, **kwargs):
|
def on_play(self, *args, **kwargs):
|
||||||
self.presenter.play()
|
self.presenter.play()
|
||||||
|
|
||||||
def on_postprocess(self):
|
def on_postprocess(self):
|
||||||
self.presenter.postprocess()
|
self.presenter.postprocess()
|
||||||
|
@ -3,38 +3,38 @@ from pubsub import pub
|
|||||||
|
|
||||||
class baseInteractor(object):
|
class baseInteractor(object):
|
||||||
|
|
||||||
def install(self, view, presenter, modulename):
|
def install(self, view, presenter, modulename):
|
||||||
self.modulename = modulename
|
self.modulename = modulename
|
||||||
self.view = view
|
self.view = view
|
||||||
self.presenter = presenter
|
self.presenter = presenter
|
||||||
pub.subscribe(self.disable_control, "{modulename}_disable_control".format(modulename=modulename))
|
pub.subscribe(self.disable_control, "{modulename}_disable_control".format(modulename=modulename))
|
||||||
pub.subscribe(self.enable_control, "{modulename}_enable_control".format(modulename=modulename))
|
pub.subscribe(self.enable_control, "{modulename}_enable_control".format(modulename=modulename))
|
||||||
pub.subscribe(self.set_label, "{modulename}_set_label".format(modulename=modulename))
|
pub.subscribe(self.set_label, "{modulename}_set_label".format(modulename=modulename))
|
||||||
pub.subscribe(self.focus_control, "{modulename}_focus_control".format(modulename=modulename))
|
pub.subscribe(self.focus_control, "{modulename}_focus_control".format(modulename=modulename))
|
||||||
pub.subscribe(self.set_title, "{modulename}_set_title".format(modulename=modulename))
|
pub.subscribe(self.set_title, "{modulename}_set_title".format(modulename=modulename))
|
||||||
|
|
||||||
def uninstall(self):
|
def uninstall(self):
|
||||||
pub.unsubscribe(self.disable_control, "{modulename}_disable_control".format(modulename=self.modulename))
|
pub.unsubscribe(self.disable_control, "{modulename}_disable_control".format(modulename=self.modulename))
|
||||||
pub.unsubscribe(self.enable_control, "{modulename}_enable_control".format(modulename=self.modulename))
|
pub.unsubscribe(self.enable_control, "{modulename}_enable_control".format(modulename=self.modulename))
|
||||||
pub.unsubscribe(self.set_label, "{modulename}_set_label".format(modulename=self.modulename))
|
pub.unsubscribe(self.set_label, "{modulename}_set_label".format(modulename=self.modulename))
|
||||||
pub.unsubscribe(self.focus_control, "{modulename}_focus_control".format(modulename=self.modulename))
|
pub.unsubscribe(self.focus_control, "{modulename}_focus_control".format(modulename=self.modulename))
|
||||||
pub.unsubscribe(self.set_title, "{modulename}_set_title".format(modulename=self.modulename))
|
pub.unsubscribe(self.set_title, "{modulename}_set_title".format(modulename=self.modulename))
|
||||||
self.view.Destroy()
|
self.view.Destroy()
|
||||||
|
|
||||||
def start(self):
|
def start(self):
|
||||||
self.result = self.view.get_response()
|
self.result = self.view.get_response()
|
||||||
|
|
||||||
def disable_control(self, control):
|
def disable_control(self, control):
|
||||||
self.view.disable(control)
|
self.view.disable(control)
|
||||||
|
|
||||||
def enable_control(self, control):
|
def enable_control(self, control):
|
||||||
self.view.enable(control)
|
self.view.enable(control)
|
||||||
|
|
||||||
def focus_control(self, control):
|
def focus_control(self, control):
|
||||||
getattr(self.view, control).SetFocus()
|
getattr(self.view, control).SetFocus()
|
||||||
|
|
||||||
def set_label(self, control, label):
|
def set_label(self, control, label):
|
||||||
self.view.set(control, label)
|
self.view.set(control, label)
|
||||||
|
|
||||||
def set_title(self, value):
|
def set_title(self, value):
|
||||||
self.view.SetTitle(value)
|
self.view.SetTitle(value)
|
||||||
|
@ -6,26 +6,26 @@ from . import base
|
|||||||
|
|
||||||
class blacklistInteractor(base.baseInteractor):
|
class blacklistInteractor(base.baseInteractor):
|
||||||
|
|
||||||
def add_items(self, control, items):
|
def add_items(self, control, items):
|
||||||
if not hasattr(self.view, control):
|
if not hasattr(self.view, control):
|
||||||
raise AttributeError("The control is not present in the view.")
|
raise AttributeError("The control is not present in the view.")
|
||||||
for i in items:
|
for i in items:
|
||||||
getattr(self.view, control).insert_item(False, *i)
|
getattr(self.view, control).insert_item(False, *i)
|
||||||
|
|
||||||
def install(self, *args, **kwargs):
|
def install(self, *args, **kwargs):
|
||||||
super(blacklistInteractor, self).install(*args, **kwargs)
|
super(blacklistInteractor, self).install(*args, **kwargs)
|
||||||
widgetUtils.connect_event(self.view.unblock, widgetUtils.BUTTON_PRESSED, self.on_unblock)
|
widgetUtils.connect_event(self.view.unblock, widgetUtils.BUTTON_PRESSED, self.on_unblock)
|
||||||
pub.subscribe(self.add_items, self.modulename+"_add_items")
|
pub.subscribe(self.add_items, self.modulename+"_add_items")
|
||||||
|
|
||||||
def uninstall(self):
|
def uninstall(self):
|
||||||
super(blacklistInteractor, self).uninstall()
|
super(blacklistInteractor, self).uninstall()
|
||||||
pub.unsubscribe(self.add_items, self.modulename+"_add_items")
|
pub.unsubscribe(self.add_items, self.modulename+"_add_items")
|
||||||
|
|
||||||
|
|
||||||
def on_unblock(self, *args, **kwargs):
|
def on_unblock(self, *args, **kwargs):
|
||||||
question = commonMessages.unblock_person()
|
question = commonMessages.unblock_person()
|
||||||
if question == widgetUtils.NO:
|
if question == widgetUtils.NO:
|
||||||
return
|
return
|
||||||
item = self.view.persons.get_selected()
|
item = self.view.persons.get_selected()
|
||||||
if self.presenter.unblock_person(item) == 1:
|
if self.presenter.unblock_person(item) == 1:
|
||||||
self.view.persons.remove_item(item)
|
self.view.persons.remove_item(item)
|
||||||
|
@ -6,67 +6,67 @@ from . import base
|
|||||||
|
|
||||||
class configurationInteractor(base.baseInteractor):
|
class configurationInteractor(base.baseInteractor):
|
||||||
|
|
||||||
def create_tab(self, tab, arglist=dict()):
|
def create_tab(self, tab, arglist=dict()):
|
||||||
getattr(self.view, "create_"+tab)(**arglist)
|
getattr(self.view, "create_"+tab)(**arglist)
|
||||||
|
|
||||||
def set_setting(self, tab, setting, value):
|
def set_setting(self, tab, setting, value):
|
||||||
self.view.set_value(tab, setting, value)
|
self.view.set_value(tab, setting, value)
|
||||||
|
|
||||||
def restart(self):
|
def restart(self):
|
||||||
dlg = restart_program_dialog()
|
dlg = restart_program_dialog()
|
||||||
if dlg == widgetUtils.YES:
|
if dlg == widgetUtils.YES:
|
||||||
self.presenter.restart_application()
|
self.presenter.restart_application()
|
||||||
|
|
||||||
def set_language(self, language):
|
def set_language(self, language):
|
||||||
self.view.general.language.SetSelection(language)
|
self.view.general.language.SetSelection(language)
|
||||||
|
|
||||||
def install(self, *args, **kwargs):
|
def install(self, *args, **kwargs):
|
||||||
super(configurationInteractor, self).install(*args, **kwargs)
|
super(configurationInteractor, self).install(*args, **kwargs)
|
||||||
pub.subscribe(self.create_tab, self.modulename+"_create_tab")
|
pub.subscribe(self.create_tab, self.modulename+"_create_tab")
|
||||||
pub.subscribe(self.set_setting, self.modulename+"_set")
|
pub.subscribe(self.set_setting, self.modulename+"_set")
|
||||||
pub.subscribe(self.restart, self.modulename+"_restart_program")
|
pub.subscribe(self.restart, self.modulename+"_restart_program")
|
||||||
pub.subscribe(self.set_language, self.modulename+"_set_language")
|
pub.subscribe(self.set_language, self.modulename+"_set_language")
|
||||||
|
|
||||||
def uninstall(self):
|
def uninstall(self):
|
||||||
super(configurationInteractor, self).uninstall()
|
super(configurationInteractor, self).uninstall()
|
||||||
pub.unsubscribe(self.create_tab, self.modulename+"_create_tab")
|
pub.unsubscribe(self.create_tab, self.modulename+"_create_tab")
|
||||||
pub.unsubscribe(self.set_setting, self.modulename+"_set")
|
pub.unsubscribe(self.set_setting, self.modulename+"_set")
|
||||||
pub.unsubscribe(self.restart, self.modulename+"_restart_program")
|
pub.unsubscribe(self.restart, self.modulename+"_restart_program")
|
||||||
pub.unsubscribe(self.set_language, self.modulename+"_set_language")
|
pub.unsubscribe(self.set_language, self.modulename+"_set_language")
|
||||||
|
|
||||||
def start(self):
|
def start(self):
|
||||||
self.view.realize()
|
self.view.realize()
|
||||||
result = self.view.get_response()
|
result = self.view.get_response()
|
||||||
if result == widgetUtils.OK:
|
if result == widgetUtils.OK:
|
||||||
self.on_save_settings()
|
self.on_save_settings()
|
||||||
|
|
||||||
def on_save_settings(self, *args, **kwargs):
|
def on_save_settings(self, *args, **kwargs):
|
||||||
self.presenter.update_setting(section="buffers", setting="count_for_wall_buffers", value=self.view.get_value("buffers", "wall_buffer_count"))
|
self.presenter.update_setting(section="buffers", setting="count_for_wall_buffers", value=self.view.get_value("buffers", "wall_buffer_count"))
|
||||||
self.presenter.update_setting(section="buffers", setting="count_for_video_buffers", value=self.view.get_value("buffers", "video_buffers_count"))
|
self.presenter.update_setting(section="buffers", setting="count_for_video_buffers", value=self.view.get_value("buffers", "video_buffers_count"))
|
||||||
self.presenter.update_setting(section="buffers", setting="count_for_chat_buffers", value=self.view.get_value("buffers", "chat_buffers_count"))
|
self.presenter.update_setting(section="buffers", setting="count_for_chat_buffers", value=self.view.get_value("buffers", "chat_buffers_count"))
|
||||||
self.presenter.update_setting(section="general", setting="load_images", value=self.view.get_value("general", "load_images"))
|
self.presenter.update_setting(section="general", setting="load_images", value=self.view.get_value("general", "load_images"))
|
||||||
update_channel = self.presenter.get_update_channel_type(self.view.get_value("general", "update_channel"))
|
update_channel = self.presenter.get_update_channel_type(self.view.get_value("general", "update_channel"))
|
||||||
if update_channel != self.presenter.session.settings["general"]["update_channel"]:
|
if update_channel != self.presenter.session.settings["general"]["update_channel"]:
|
||||||
if update_channel == "stable":
|
if update_channel == "stable":
|
||||||
self.presenter.update_setting(section="general", setting="update_channel", value=update_channel)
|
self.presenter.update_setting(section="general", setting="update_channel", value=update_channel)
|
||||||
elif update_channel == "weekly":
|
elif update_channel == "weekly":
|
||||||
dialog = self.view.weekly_channel()
|
dialog = self.view.weekly_channel()
|
||||||
if dialog == widgetUtils.YES:
|
if dialog == widgetUtils.YES:
|
||||||
self.presenter.update_setting(section="general", setting="update_channel", value=update_channel)
|
self.presenter.update_setting(section="general", setting="update_channel", value=update_channel)
|
||||||
elif update_channel == "alpha":
|
elif update_channel == "alpha":
|
||||||
dialog = self.view.alpha_channel()
|
dialog = self.view.alpha_channel()
|
||||||
if dialog == widgetUtils.YES:
|
if dialog == widgetUtils.YES:
|
||||||
self.presenter.update_setting(section="general", setting="update_channel", value=update_channel)
|
self.presenter.update_setting(section="general", setting="update_channel", value=update_channel)
|
||||||
self.presenter.update_setting(section="chat", setting="notify_online", value=self.view.get_value("chat", "notify_online"))
|
self.presenter.update_setting(section="chat", setting="notify_online", value=self.view.get_value("chat", "notify_online"))
|
||||||
self.presenter.update_setting(section="chat", setting="notify_offline", value=self.view.get_value("chat", "notify_offline"))
|
self.presenter.update_setting(section="chat", setting="notify_offline", value=self.view.get_value("chat", "notify_offline"))
|
||||||
self.presenter.update_setting(section="chat", setting="notifications", value=self.presenter.get_notification_type(self.view.get_value("chat", "notifications")))
|
self.presenter.update_setting(section="chat", setting="notifications", value=self.presenter.get_notification_type(self.view.get_value("chat", "notifications")))
|
||||||
self.presenter.update_setting(section="load_at_startup", setting="audio_albums", value=self.view.get_value("startup", "audio_albums"))
|
self.presenter.update_setting(section="load_at_startup", setting="audio_albums", value=self.view.get_value("startup", "audio_albums"))
|
||||||
self.presenter.update_setting(section="load_at_startup", setting="video_albums", value=self.view.get_value("startup", "video_albums"))
|
self.presenter.update_setting(section="load_at_startup", setting="video_albums", value=self.view.get_value("startup", "video_albums"))
|
||||||
self.presenter.update_setting(section="load_at_startup", setting="communities", value=self.view.get_value("startup", "communities"))
|
self.presenter.update_setting(section="load_at_startup", setting="communities", value=self.view.get_value("startup", "communities"))
|
||||||
self.presenter.update_app_setting(section="app-settings", setting="language", value=self.presenter.codes[self.view.general.language.GetSelection()])
|
self.presenter.update_app_setting(section="app-settings", setting="language", value=self.presenter.codes[self.view.general.language.GetSelection()])
|
||||||
self.presenter.update_app_setting(section="sound", setting="input_device", value=self.view.get_value("sound", "input"))
|
self.presenter.update_app_setting(section="sound", setting="input_device", value=self.view.get_value("sound", "input"))
|
||||||
self.presenter.update_app_setting(section="sound", setting="output_device", value=self.view.get_value("sound", "output"))
|
self.presenter.update_app_setting(section="sound", setting="output_device", value=self.view.get_value("sound", "output"))
|
||||||
self.presenter.update_app_setting(section="app-settings", setting="use_proxy", value=self.view.get_value("general", "use_proxy"))
|
self.presenter.update_app_setting(section="app-settings", setting="use_proxy", value=self.view.get_value("general", "use_proxy"))
|
||||||
self.presenter.update_app_setting(section="app-settings", setting="debug_logging", value=self.view.get_value("general", "debug_logging"))
|
self.presenter.update_app_setting(section="app-settings", setting="debug_logging", value=self.view.get_value("general", "debug_logging"))
|
||||||
self.presenter.save_app_settings_file()
|
self.presenter.save_app_settings_file()
|
||||||
self.presenter.save_settings_file()
|
self.presenter.save_settings_file()
|
||||||
|
@ -7,67 +7,67 @@ from .import base
|
|||||||
|
|
||||||
class createPostInteractor(base.baseInteractor):
|
class createPostInteractor(base.baseInteractor):
|
||||||
|
|
||||||
def set(self, control, value):
|
def set(self, control, value):
|
||||||
if not hasattr(self.view, control):
|
if not hasattr(self.view, control):
|
||||||
raise AttributeError("The control is not present in the view.")
|
raise AttributeError("The control is not present in the view.")
|
||||||
getattr(self.view, control).SetValue(value)
|
getattr(self.view, control).SetValue(value)
|
||||||
|
|
||||||
def add_tagged_users(self, users):
|
def add_tagged_users(self, users):
|
||||||
self.view.text.SetValue(self.view.text.GetValue()+", ".join(users))
|
self.view.text.SetValue(self.view.text.GetValue()+", ".join(users))
|
||||||
|
|
||||||
def install(self, *args, **kwargs):
|
def install(self, *args, **kwargs):
|
||||||
super(createPostInteractor, self).install(*args, **kwargs)
|
super(createPostInteractor, self).install(*args, **kwargs)
|
||||||
widgetUtils.connect_event(self.view.spellcheck, widgetUtils.BUTTON_PRESSED, self.on_spellcheck)
|
widgetUtils.connect_event(self.view.spellcheck, widgetUtils.BUTTON_PRESSED, self.on_spellcheck)
|
||||||
widgetUtils.connect_event(self.view.translateButton, widgetUtils.BUTTON_PRESSED, self.on_translate)
|
widgetUtils.connect_event(self.view.translateButton, widgetUtils.BUTTON_PRESSED, self.on_translate)
|
||||||
widgetUtils.connect_event(self.view.mention, widgetUtils.BUTTON_PRESSED, self.on_mention)
|
widgetUtils.connect_event(self.view.mention, widgetUtils.BUTTON_PRESSED, self.on_mention)
|
||||||
if hasattr(self.view, "attach"):
|
if hasattr(self.view, "attach"):
|
||||||
widgetUtils.connect_event(self.view.attach, widgetUtils.BUTTON_PRESSED, self.on_add_attachments)
|
widgetUtils.connect_event(self.view.attach, widgetUtils.BUTTON_PRESSED, self.on_add_attachments)
|
||||||
pub.subscribe(self.set, self.modulename+"_set")
|
pub.subscribe(self.set, self.modulename+"_set")
|
||||||
pub.subscribe(self.add_tagged_users, self.modulename+"_add_tagged_users")
|
pub.subscribe(self.add_tagged_users, self.modulename+"_add_tagged_users")
|
||||||
|
|
||||||
def uninstall(self):
|
def uninstall(self):
|
||||||
super(createPostInteractor, self).uninstall()
|
super(createPostInteractor, self).uninstall()
|
||||||
pub.unsubscribe(self.set, self.modulename+"_set")
|
pub.unsubscribe(self.set, self.modulename+"_set")
|
||||||
pub.unsubscribe(self.add_tagged_users, self.modulename+"_add_tagged_users")
|
pub.unsubscribe(self.add_tagged_users, self.modulename+"_add_tagged_users")
|
||||||
|
|
||||||
def start(self):
|
def start(self):
|
||||||
self.result = self.view.get_response()
|
self.result = self.view.get_response()
|
||||||
if self.result == widgetUtils.OK:
|
if self.result == widgetUtils.OK:
|
||||||
self.presenter.text = self.view.get_text()
|
self.presenter.text = self.view.get_text()
|
||||||
if hasattr(self.view, "privacy"):
|
if hasattr(self.view, "privacy"):
|
||||||
self.presenter.privacy = self.get_privacy_options()
|
self.presenter.privacy = self.get_privacy_options()
|
||||||
else:
|
else:
|
||||||
self.presenter.privacy = 0
|
self.presenter.privacy = 0
|
||||||
|
|
||||||
def get_privacy_options(self):
|
def get_privacy_options(self):
|
||||||
p = self.view.get("privacy")
|
p = self.view.get("privacy")
|
||||||
if p == _("Friends of friends"):
|
if p == _("Friends of friends"):
|
||||||
privacy = 0
|
privacy = 0
|
||||||
elif p == _("All users"):
|
elif p == _("All users"):
|
||||||
privacy = 1
|
privacy = 1
|
||||||
return privacy
|
return privacy
|
||||||
|
|
||||||
def on_mention(self, *args, **kwargs):
|
def on_mention(self, *args, **kwargs):
|
||||||
users = self.presenter.get_friends()
|
users = self.presenter.get_friends()
|
||||||
select = selector.selectPeople(users)
|
select = selector.selectPeople(users)
|
||||||
if select.get_response() == widgetUtils.OK and select.users.GetCount() > 0:
|
if select.get_response() == widgetUtils.OK and select.users.GetCount() > 0:
|
||||||
tagged_users = select.get_all_users()
|
tagged_users = select.get_all_users()
|
||||||
self.presenter.add_tagged_users(tagged_users)
|
self.presenter.add_tagged_users(tagged_users)
|
||||||
|
|
||||||
def on_translate(self, *args, **kwargs):
|
def on_translate(self, *args, **kwargs):
|
||||||
dlg = translator.gui.translateDialog()
|
dlg = translator.gui.translateDialog()
|
||||||
if dlg.get_response() == widgetUtils.OK:
|
if dlg.get_response() == widgetUtils.OK:
|
||||||
text_to_translate = self.view.get_text()
|
text_to_translate = self.view.get_text()
|
||||||
language_dict = translator.translator.available_languages()
|
language_dict = translator.translator.available_languages()
|
||||||
for k in language_dict:
|
for k in language_dict:
|
||||||
if language_dict[k] == dlg.dest_lang.GetStringSelection():
|
if language_dict[k] == dlg.dest_lang.GetStringSelection():
|
||||||
dst = k
|
dst = k
|
||||||
self.presenter.translate(text_to_translate, dst)
|
self.presenter.translate(text_to_translate, dst)
|
||||||
dlg.Destroy()
|
dlg.Destroy()
|
||||||
|
|
||||||
def on_spellcheck(self, event=None):
|
def on_spellcheck(self, event=None):
|
||||||
text = self.view.get_text()
|
text = self.view.get_text()
|
||||||
self.presenter.spellcheck(text)
|
self.presenter.spellcheck(text)
|
||||||
|
|
||||||
def on_add_attachments(self, *args, **kwargs):
|
def on_add_attachments(self, *args, **kwargs):
|
||||||
self.presenter.add_attachments()
|
self.presenter.add_attachments()
|
||||||
|
@ -10,295 +10,295 @@ from .import base
|
|||||||
|
|
||||||
class displayPostInteractor(base.baseInteractor):
|
class displayPostInteractor(base.baseInteractor):
|
||||||
|
|
||||||
def set(self, control, value):
|
def set(self, control, value):
|
||||||
if not hasattr(self.view, control):
|
if not hasattr(self.view, control):
|
||||||
raise AttributeError("The control is not present in the view.")
|
raise AttributeError("The control is not present in the view.")
|
||||||
getattr(self.view, control).SetValue(value)
|
getattr(self.view, control).SetValue(value)
|
||||||
|
|
||||||
def load_image(self, image):
|
def load_image(self, image):
|
||||||
image = wx.Image(stream=six.BytesIO(image.content))
|
image = wx.Image(stream=six.BytesIO(image.content))
|
||||||
try:
|
try:
|
||||||
self.view.image.SetBitmap(wx.Bitmap(image))
|
self.view.image.SetBitmap(wx.Bitmap(image))
|
||||||
except ValueError:
|
except ValueError:
|
||||||
return
|
return
|
||||||
self.view.panel.Layout()
|
self.view.panel.Layout()
|
||||||
|
|
||||||
def add_items(self, control, items):
|
def add_items(self, control, items):
|
||||||
if not hasattr(self.view, control):
|
if not hasattr(self.view, control):
|
||||||
raise AttributeError("The control is not present in the view.")
|
raise AttributeError("The control is not present in the view.")
|
||||||
for i in items:
|
for i in items:
|
||||||
getattr(self.view, control).insert_item(False, *i)
|
getattr(self.view, control).insert_item(False, *i)
|
||||||
|
|
||||||
def add_item(self, control, item, reversed=False):
|
def add_item(self, control, item, reversed=False):
|
||||||
if not hasattr(self.view, control):
|
if not hasattr(self.view, control):
|
||||||
raise AttributeError("The control is not present in the view.")
|
raise AttributeError("The control is not present in the view.")
|
||||||
getattr(self.view, control).insert_item(reversed, *item)
|
getattr(self.view, control).insert_item(reversed, *item)
|
||||||
|
|
||||||
def enable_attachments(self):
|
def enable_attachments(self):
|
||||||
self.view.attachments.list.Enable(True)
|
self.view.attachments.list.Enable(True)
|
||||||
|
|
||||||
def enable_photo_controls(self, navigation):
|
def enable_photo_controls(self, navigation):
|
||||||
self.view.enable_photo_controls(navigation)
|
self.view.enable_photo_controls(navigation)
|
||||||
|
|
||||||
def clean_list(self, list):
|
def clean_list(self, list):
|
||||||
if not hasattr(self.view, list):
|
if not hasattr(self.view, list):
|
||||||
raise AttributeError("The control is not present in the view.")
|
raise AttributeError("The control is not present in the view.")
|
||||||
getattr(self.view, list).clear()
|
getattr(self.view, list).clear()
|
||||||
|
|
||||||
def post_deleted(self):
|
def post_deleted(self):
|
||||||
msg = commonMessages.post_deleted()
|
msg = commonMessages.post_deleted()
|
||||||
|
|
||||||
def install(self, *args, **kwargs):
|
def install(self, *args, **kwargs):
|
||||||
super(displayPostInteractor, self).install(*args, **kwargs)
|
super(displayPostInteractor, self).install(*args, **kwargs)
|
||||||
if hasattr(self.view, "comments"):
|
if hasattr(self.view, "comments"):
|
||||||
self.view.comments.list.Bind(wx.EVT_LIST_ITEM_ACTIVATED, self.on_show_comment)
|
self.view.comments.list.Bind(wx.EVT_LIST_ITEM_ACTIVATED, self.on_show_comment)
|
||||||
self.view.comments.list.Bind(wx.EVT_LIST_ITEM_FOCUSED, self.on_comment_changed)
|
self.view.comments.list.Bind(wx.EVT_LIST_ITEM_FOCUSED, self.on_comment_changed)
|
||||||
self.view.attachments.list.Bind(wx.EVT_LIST_ITEM_ACTIVATED, self.on_open_attachment)
|
self.view.attachments.list.Bind(wx.EVT_LIST_ITEM_ACTIVATED, self.on_open_attachment)
|
||||||
widgetUtils.connect_event(self.view.like, widgetUtils.BUTTON_PRESSED, self.on_like)
|
widgetUtils.connect_event(self.view.like, widgetUtils.BUTTON_PRESSED, self.on_like)
|
||||||
widgetUtils.connect_event(self.view.comment, widgetUtils.BUTTON_PRESSED, self.on_add_comment)
|
widgetUtils.connect_event(self.view.comment, widgetUtils.BUTTON_PRESSED, self.on_add_comment)
|
||||||
widgetUtils.connect_event(self.view.tools, widgetUtils.BUTTON_PRESSED, self.on_show_tools_menu)
|
widgetUtils.connect_event(self.view.tools, widgetUtils.BUTTON_PRESSED, self.on_show_tools_menu)
|
||||||
if hasattr(self.view, "likes"):
|
if hasattr(self.view, "likes"):
|
||||||
widgetUtils.connect_event(self.view.likes, widgetUtils.BUTTON_PRESSED, self.on_show_likes_menu)
|
widgetUtils.connect_event(self.view.likes, widgetUtils.BUTTON_PRESSED, self.on_show_likes_menu)
|
||||||
if hasattr(self.view, "shares"):
|
if hasattr(self.view, "shares"):
|
||||||
widgetUtils.connect_event(self.view.shares, widgetUtils.BUTTON_PRESSED, self.on_show_shares_menu)
|
widgetUtils.connect_event(self.view.shares, widgetUtils.BUTTON_PRESSED, self.on_show_shares_menu)
|
||||||
if hasattr(self.view, "repost"):
|
if hasattr(self.view, "repost"):
|
||||||
widgetUtils.connect_event(self.view.repost, widgetUtils.BUTTON_PRESSED, self.on_repost)
|
widgetUtils.connect_event(self.view.repost, widgetUtils.BUTTON_PRESSED, self.on_repost)
|
||||||
self.view.comments.list.Bind(wx.EVT_LIST_ITEM_FOCUSED, self.on_focus)
|
self.view.comments.list.Bind(wx.EVT_LIST_ITEM_FOCUSED, self.on_focus)
|
||||||
if hasattr(self.view, "reply"):
|
if hasattr(self.view, "reply"):
|
||||||
widgetUtils.connect_event(self.view.reply, widgetUtils.BUTTON_PRESSED, self.on_reply)
|
widgetUtils.connect_event(self.view.reply, widgetUtils.BUTTON_PRESSED, self.on_reply)
|
||||||
if hasattr(self.view, "load_more_comments"):
|
if hasattr(self.view, "load_more_comments"):
|
||||||
widgetUtils.connect_event(self.view.load_more_comments, widgetUtils.BUTTON_PRESSED, self.on_load_more_comments)
|
widgetUtils.connect_event(self.view.load_more_comments, widgetUtils.BUTTON_PRESSED, self.on_load_more_comments)
|
||||||
# self.view.Bind(wx.EVT_LIST_ITEM_RIGHT_CLICK, self.on_show_menu, self.view.comments.list)
|
# self.view.Bind(wx.EVT_LIST_ITEM_RIGHT_CLICK, self.on_show_menu, self.view.comments.list)
|
||||||
# self.view.Bind(wx.EVT_LIST_KEY_DOWN, self.on_show_menu_by_key, self.view.comments.list)
|
# self.view.Bind(wx.EVT_LIST_KEY_DOWN, self.on_show_menu_by_key, self.view.comments.list)
|
||||||
pub.subscribe(self.set, self.modulename+"_set")
|
pub.subscribe(self.set, self.modulename+"_set")
|
||||||
pub.subscribe(self.load_image, self.modulename+"_load_image")
|
pub.subscribe(self.load_image, self.modulename+"_load_image")
|
||||||
pub.subscribe(self.add_items, self.modulename+"_add_items")
|
pub.subscribe(self.add_items, self.modulename+"_add_items")
|
||||||
pub.subscribe(self.add_item, self.modulename+"_add_item")
|
pub.subscribe(self.add_item, self.modulename+"_add_item")
|
||||||
pub.subscribe(self.enable_attachments, self.modulename+"_enable_attachments")
|
pub.subscribe(self.enable_attachments, self.modulename+"_enable_attachments")
|
||||||
pub.subscribe(self.enable_photo_controls, self.modulename+"_enable_photo_controls")
|
pub.subscribe(self.enable_photo_controls, self.modulename+"_enable_photo_controls")
|
||||||
pub.subscribe(self.post_deleted, self.modulename+"_post_deleted")
|
pub.subscribe(self.post_deleted, self.modulename+"_post_deleted")
|
||||||
pub.subscribe(self.clean_list, self.modulename+"_clean_list")
|
pub.subscribe(self.clean_list, self.modulename+"_clean_list")
|
||||||
|
|
||||||
def uninstall(self):
|
def uninstall(self):
|
||||||
super(displayPostInteractor, self).uninstall()
|
super(displayPostInteractor, self).uninstall()
|
||||||
pub.unsubscribe(self.set, self.modulename+"_set")
|
pub.unsubscribe(self.set, self.modulename+"_set")
|
||||||
pub.unsubscribe(self.load_image, self.modulename+"_load_image")
|
pub.unsubscribe(self.load_image, self.modulename+"_load_image")
|
||||||
pub.unsubscribe(self.add_items, self.modulename+"_add_items")
|
pub.unsubscribe(self.add_items, self.modulename+"_add_items")
|
||||||
pub.unsubscribe(self.add_item, self.modulename+"_add_item")
|
pub.unsubscribe(self.add_item, self.modulename+"_add_item")
|
||||||
pub.unsubscribe(self.enable_attachments, self.modulename+"_enable_attachments")
|
pub.unsubscribe(self.enable_attachments, self.modulename+"_enable_attachments")
|
||||||
pub.unsubscribe(self.enable_photo_controls, self.modulename+"_enable_photo_controls")
|
pub.unsubscribe(self.enable_photo_controls, self.modulename+"_enable_photo_controls")
|
||||||
pub.unsubscribe(self.post_deleted, self.modulename+"_post_deleted")
|
pub.unsubscribe(self.post_deleted, self.modulename+"_post_deleted")
|
||||||
pub.unsubscribe(self.clean_list, self.modulename+"_clean_list")
|
pub.unsubscribe(self.clean_list, self.modulename+"_clean_list")
|
||||||
|
|
||||||
def on_focus(self, *args, **kwargs):
|
def on_focus(self, *args, **kwargs):
|
||||||
item = self.view.comments.get_selected()
|
item = self.view.comments.get_selected()
|
||||||
if item == -1:
|
if item == -1:
|
||||||
self.view.reply.Enable(False)
|
self.view.reply.Enable(False)
|
||||||
else:
|
else:
|
||||||
self.view.reply.Enable(True)
|
self.view.reply.Enable(True)
|
||||||
|
|
||||||
def on_like(self, *args, **kwargs):
|
def on_like(self, *args, **kwargs):
|
||||||
self.presenter.post_like()
|
self.presenter.post_like()
|
||||||
|
|
||||||
def on_repost(self, *args, **kwargs):
|
def on_repost(self, *args, **kwargs):
|
||||||
self.presenter.post_repost()
|
self.presenter.post_repost()
|
||||||
|
|
||||||
def on_reply(self, *args, **kwargs):
|
def on_reply(self, *args, **kwargs):
|
||||||
if hasattr(self.view, "comments") and (hasattr(self.view, "repost") or not hasattr(self, "post_view")):
|
if hasattr(self.view, "comments") and (hasattr(self.view, "repost") or not hasattr(self, "post_view")):
|
||||||
comment = self.view.comments.get_selected()
|
comment = self.view.comments.get_selected()
|
||||||
self.presenter.reply(comment)
|
self.presenter.reply(comment)
|
||||||
else:
|
else:
|
||||||
self.presenter.reply()
|
self.presenter.reply()
|
||||||
|
|
||||||
def on_add_comment(self, *args, **kwargs):
|
def on_add_comment(self, *args, **kwargs):
|
||||||
self.presenter.add_comment()
|
self.presenter.add_comment()
|
||||||
|
|
||||||
def on_load_more_comments(self, *args, **kwargs):
|
def on_load_more_comments(self, *args, **kwargs):
|
||||||
if hasattr(self.presenter, "load_more_comments"):
|
if hasattr(self.presenter, "load_more_comments"):
|
||||||
self.presenter.load_more_comments()
|
self.presenter.load_more_comments()
|
||||||
|
|
||||||
def on_show_tools_menu(self, *args, **kwargs):
|
def on_show_tools_menu(self, *args, **kwargs):
|
||||||
menu = menus.toolsMenu()
|
menu = menus.toolsMenu()
|
||||||
# widgetUtils.connect_event(self.view, widgetUtils.MENU, self.on_open_url, menuitem=menu.url)
|
# widgetUtils.connect_event(self.view, widgetUtils.MENU, self.on_open_url, menuitem=menu.url)
|
||||||
widgetUtils.connect_event(self.view, widgetUtils.MENU, self.on_translate, menuitem=menu.translate)
|
widgetUtils.connect_event(self.view, widgetUtils.MENU, self.on_translate, menuitem=menu.translate)
|
||||||
widgetUtils.connect_event(self.view, widgetUtils.MENU, self.on_spellcheck, menuitem=menu.spellcheck)
|
widgetUtils.connect_event(self.view, widgetUtils.MENU, self.on_spellcheck, menuitem=menu.spellcheck)
|
||||||
self.view.PopupMenu(menu, self.view.tools.GetPosition())
|
self.view.PopupMenu(menu, self.view.tools.GetPosition())
|
||||||
|
|
||||||
def on_open_url(self, *args, **kwargs):
|
def on_open_url(self, *args, **kwargs):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def on_open_attachment(self, *args, **kwargs):
|
def on_open_attachment(self, *args, **kwargs):
|
||||||
attachment = self.view.attachments.get_selected()
|
attachment = self.view.attachments.get_selected()
|
||||||
self.presenter.open_attachment(attachment)
|
self.presenter.open_attachment(attachment)
|
||||||
|
|
||||||
def on_translate(self, *args, **kwargs):
|
def on_translate(self, *args, **kwargs):
|
||||||
dlg = translator.gui.translateDialog()
|
dlg = translator.gui.translateDialog()
|
||||||
if dlg.get_response() == widgetUtils.OK:
|
if dlg.get_response() == widgetUtils.OK:
|
||||||
text_to_translate = self.view.get("post_view")
|
text_to_translate = self.view.get("post_view")
|
||||||
language_dict = translator.translator.available_languages()
|
language_dict = translator.translator.available_languages()
|
||||||
for k in language_dict:
|
for k in language_dict:
|
||||||
if language_dict[k] == dlg.dest_lang.GetStringSelection():
|
if language_dict[k] == dlg.dest_lang.GetStringSelection():
|
||||||
dst = k
|
dst = k
|
||||||
self.presenter.translate(text_to_translate, dst)
|
self.presenter.translate(text_to_translate, dst)
|
||||||
dlg.Destroy()
|
dlg.Destroy()
|
||||||
|
|
||||||
def on_spellcheck(self, event=None):
|
def on_spellcheck(self, event=None):
|
||||||
text = self.view.get("post_view")
|
text = self.view.get("post_view")
|
||||||
self.presenter.spellcheck(text)
|
self.presenter.spellcheck(text)
|
||||||
|
|
||||||
def on_show_comment(self, *args, **kwargs):
|
def on_show_comment(self, *args, **kwargs):
|
||||||
comment = self.view.comments.get_selected()
|
comment = self.view.comments.get_selected()
|
||||||
self.presenter.show_comment(comment)
|
self.presenter.show_comment(comment)
|
||||||
|
|
||||||
def on_comment_changed(self, *args, **kwargs):
|
def on_comment_changed(self, *args, **kwargs):
|
||||||
if hasattr(self.presenter, "change_comment"):
|
if hasattr(self.presenter, "change_comment"):
|
||||||
comment = self.view.comments.get_selected()
|
comment = self.view.comments.get_selected()
|
||||||
self.presenter.change_comment(comment)
|
self.presenter.change_comment(comment)
|
||||||
|
|
||||||
def on_show_likes_menu(self, *args, **kwargs):
|
def on_show_likes_menu(self, *args, **kwargs):
|
||||||
self.presenter.show_likes()
|
self.presenter.show_likes()
|
||||||
|
|
||||||
def on_show_shares_menu(self, *args, **kwargs):
|
def on_show_shares_menu(self, *args, **kwargs):
|
||||||
self.presenter.show_shares()
|
self.presenter.show_shares()
|
||||||
|
|
||||||
class displayAudioInteractor(base.baseInteractor):
|
class displayAudioInteractor(base.baseInteractor):
|
||||||
|
|
||||||
def set(self, control, value):
|
def set(self, control, value):
|
||||||
if not hasattr(self.view, control):
|
if not hasattr(self.view, control):
|
||||||
raise AttributeError("The control is not present in the view.")
|
raise AttributeError("The control is not present in the view.")
|
||||||
getattr(self.view, control).SetValue(value)
|
getattr(self.view, control).SetValue(value)
|
||||||
|
|
||||||
def add_items(self, control, items):
|
def add_items(self, control, items):
|
||||||
if not hasattr(self.view, control):
|
if not hasattr(self.view, control):
|
||||||
raise AttributeError("The control is not present in the view.")
|
raise AttributeError("The control is not present in the view.")
|
||||||
for i in items:
|
for i in items:
|
||||||
getattr(self.view, control).Append(i)
|
getattr(self.view, control).Append(i)
|
||||||
getattr(self.view, control).SetSelection(0)
|
getattr(self.view, control).SetSelection(0)
|
||||||
|
|
||||||
def change_label(self, stopped):
|
def change_label(self, stopped):
|
||||||
|
|
||||||
if stopped == False:
|
if stopped == False:
|
||||||
self.view.play.SetLabel(_("P&ause"))
|
self.view.play.SetLabel(_("P&ause"))
|
||||||
else:
|
else:
|
||||||
self.view.play.SetLabel(_("P&lay"))
|
self.view.play.SetLabel(_("P&lay"))
|
||||||
|
|
||||||
def install(self, *args, **kwargs):
|
def install(self, *args, **kwargs):
|
||||||
super(displayAudioInteractor, self).install(*args, **kwargs)
|
super(displayAudioInteractor, self).install(*args, **kwargs)
|
||||||
widgetUtils.connect_event(self.view.list, widgetUtils.LISTBOX_CHANGED, self.on_change)
|
widgetUtils.connect_event(self.view.list, widgetUtils.LISTBOX_CHANGED, self.on_change)
|
||||||
widgetUtils.connect_event(self.view.download, widgetUtils.BUTTON_PRESSED, self.on_download)
|
widgetUtils.connect_event(self.view.download, widgetUtils.BUTTON_PRESSED, self.on_download)
|
||||||
widgetUtils.connect_event(self.view.play, widgetUtils.BUTTON_PRESSED, self.on_play)
|
widgetUtils.connect_event(self.view.play, widgetUtils.BUTTON_PRESSED, self.on_play)
|
||||||
widgetUtils.connect_event(self.view.add, widgetUtils.BUTTON_PRESSED, self.on_add_to_library)
|
widgetUtils.connect_event(self.view.add, widgetUtils.BUTTON_PRESSED, self.on_add_to_library)
|
||||||
widgetUtils.connect_event(self.view.remove, widgetUtils.BUTTON_PRESSED, self.on_remove_from_library)
|
widgetUtils.connect_event(self.view.remove, widgetUtils.BUTTON_PRESSED, self.on_remove_from_library)
|
||||||
pub.subscribe(self.set, self.modulename+"_set")
|
pub.subscribe(self.set, self.modulename+"_set")
|
||||||
pub.subscribe(self.add_items, self.modulename+"_add_items")
|
pub.subscribe(self.add_items, self.modulename+"_add_items")
|
||||||
pub.subscribe(self.change_label, "playback-changed")
|
pub.subscribe(self.change_label, "playback-changed")
|
||||||
|
|
||||||
def uninstall(self):
|
def uninstall(self):
|
||||||
super(displayAudioInteractor, self).uninstall()
|
super(displayAudioInteractor, self).uninstall()
|
||||||
pub.unsubscribe(self.set, self.modulename+"_set")
|
pub.unsubscribe(self.set, self.modulename+"_set")
|
||||||
pub.unsubscribe(self.add_items, self.modulename+"_add_items")
|
pub.unsubscribe(self.add_items, self.modulename+"_add_items")
|
||||||
pub.unsubscribe(self.change_label, "playback-changed")
|
pub.unsubscribe(self.change_label, "playback-changed")
|
||||||
|
|
||||||
def on_change(self, *args, **kwargs):
|
def on_change(self, *args, **kwargs):
|
||||||
post = self.view.get_audio()
|
post = self.view.get_audio()
|
||||||
self.presenter.handle_changes(post)
|
self.presenter.handle_changes(post)
|
||||||
|
|
||||||
def on_download(self, *args, **kwargs):
|
def on_download(self, *args, **kwargs):
|
||||||
post = self.view.get_audio()
|
post = self.view.get_audio()
|
||||||
suggested_filename = self.presenter.get_suggested_filename(post)
|
suggested_filename = self.presenter.get_suggested_filename(post)
|
||||||
path = self.view.get_destination_path(suggested_filename)
|
path = self.view.get_destination_path(suggested_filename)
|
||||||
self.presenter.download(post, path)
|
self.presenter.download(post, path)
|
||||||
|
|
||||||
def on_play(self, *args, **kwargs):
|
def on_play(self, *args, **kwargs):
|
||||||
post = self.view.get_audio()
|
post = self.view.get_audio()
|
||||||
self.presenter.play(post)
|
self.presenter.play(post)
|
||||||
|
|
||||||
def on_add_to_library(self, *args, **kwargs):
|
def on_add_to_library(self, *args, **kwargs):
|
||||||
post = self.view.get_audio()
|
post = self.view.get_audio()
|
||||||
self.presenter.add_to_library(post)
|
self.presenter.add_to_library(post)
|
||||||
|
|
||||||
def on_remove_from_library(self, *args, **kwargs):
|
def on_remove_from_library(self, *args, **kwargs):
|
||||||
post = self.view.get_audio()
|
post = self.view.get_audio()
|
||||||
self.presenter.remove_from_library(post)
|
self.presenter.remove_from_library(post)
|
||||||
|
|
||||||
class displayArticleInteractor(base.baseInteractor):
|
class displayArticleInteractor(base.baseInteractor):
|
||||||
|
|
||||||
def set(self, control, value):
|
def set(self, control, value):
|
||||||
if not hasattr(self.view, control):
|
if not hasattr(self.view, control):
|
||||||
raise AttributeError("The control is not present in the view.")
|
raise AttributeError("The control is not present in the view.")
|
||||||
getattr(self.view, control).SetValue(value)
|
getattr(self.view, control).SetValue(value)
|
||||||
|
|
||||||
def install(self, *args, **kwargs):
|
def install(self, *args, **kwargs):
|
||||||
super(displayArticleInteractor, self).install(*args, **kwargs)
|
super(displayArticleInteractor, self).install(*args, **kwargs)
|
||||||
pub.subscribe(self.set, self.modulename+"_set")
|
pub.subscribe(self.set, self.modulename+"_set")
|
||||||
|
|
||||||
def uninstall(self):
|
def uninstall(self):
|
||||||
super(displayArticleInteractor, self).uninstall()
|
super(displayArticleInteractor, self).uninstall()
|
||||||
pub.unsubscribe(self.set, self.modulename+"_set")
|
pub.unsubscribe(self.set, self.modulename+"_set")
|
||||||
|
|
||||||
class displayPollInteractor(base.baseInteractor):
|
class displayPollInteractor(base.baseInteractor):
|
||||||
|
|
||||||
def set(self, control, value):
|
def set(self, control, value):
|
||||||
if not hasattr(self.view, control):
|
if not hasattr(self.view, control):
|
||||||
raise AttributeError("The control is not present in the view.")
|
raise AttributeError("The control is not present in the view.")
|
||||||
getattr(self.view, control).SetValue(value)
|
getattr(self.view, control).SetValue(value)
|
||||||
|
|
||||||
def done(self):
|
def done(self):
|
||||||
self.view.done()
|
self.view.done()
|
||||||
|
|
||||||
def add_options(self, options, multiple):
|
def add_options(self, options, multiple):
|
||||||
self.view.add_options(options, multiple)
|
self.view.add_options(options, multiple)
|
||||||
|
|
||||||
def install(self, *args, **kwargs):
|
def install(self, *args, **kwargs):
|
||||||
super(displayPollInteractor, self).install(*args, **kwargs)
|
super(displayPollInteractor, self).install(*args, **kwargs)
|
||||||
pub.subscribe(self.set, self.modulename+"_set")
|
pub.subscribe(self.set, self.modulename+"_set")
|
||||||
pub.subscribe(self.done, self.modulename+"_done")
|
pub.subscribe(self.done, self.modulename+"_done")
|
||||||
pub.subscribe(self.add_options, self.modulename+"_add_options")
|
pub.subscribe(self.add_options, self.modulename+"_add_options")
|
||||||
|
|
||||||
def uninstall(self):
|
def uninstall(self):
|
||||||
super(displayPollInteractor, self).uninstall()
|
super(displayPollInteractor, self).uninstall()
|
||||||
pub.unsubscribe(self.set, self.modulename+"_set")
|
pub.unsubscribe(self.set, self.modulename+"_set")
|
||||||
pub.unsubscribe(self.done, self.modulename+"_done")
|
pub.unsubscribe(self.done, self.modulename+"_done")
|
||||||
pub.unsubscribe(self.add_options, self.modulename+"_add_options")
|
pub.unsubscribe(self.add_options, self.modulename+"_add_options")
|
||||||
|
|
||||||
def start(self, *args, **kwargs):
|
def start(self, *args, **kwargs):
|
||||||
super(displayPollInteractor, self).start(*args, **kwargs)
|
super(displayPollInteractor, self).start(*args, **kwargs)
|
||||||
if self.result == widgetUtils.OK: # USer votd.
|
if self.result == widgetUtils.OK: # USer votd.
|
||||||
answers = self.view.get_answers()
|
answers = self.view.get_answers()
|
||||||
self.presenter.vote(answers)
|
self.presenter.vote(answers)
|
||||||
|
|
||||||
class displayFriendshipInteractor(base.baseInteractor):
|
class displayFriendshipInteractor(base.baseInteractor):
|
||||||
|
|
||||||
def add_items(self, control, items):
|
def add_items(self, control, items):
|
||||||
if not hasattr(self.view, control):
|
if not hasattr(self.view, control):
|
||||||
raise AttributeError("The control is not present in the view.")
|
raise AttributeError("The control is not present in the view.")
|
||||||
for i in items:
|
for i in items:
|
||||||
getattr(self.view, control).insert_item(False, *[i])
|
getattr(self.view, control).insert_item(False, *[i])
|
||||||
|
|
||||||
def install(self, *args, **kwargs):
|
def install(self, *args, **kwargs):
|
||||||
super(displayFriendshipInteractor, self).install(*args, **kwargs)
|
super(displayFriendshipInteractor, self).install(*args, **kwargs)
|
||||||
pub.subscribe(self.add_items, self.modulename+"_add_items")
|
pub.subscribe(self.add_items, self.modulename+"_add_items")
|
||||||
self.view.friends.list.Bind(wx.EVT_CONTEXT_MENU, self.on_context_menu)
|
self.view.friends.list.Bind(wx.EVT_CONTEXT_MENU, self.on_context_menu)
|
||||||
|
|
||||||
def uninstall(self):
|
def uninstall(self):
|
||||||
super(displayFriendshipInteractor, self).uninstall()
|
super(displayFriendshipInteractor, self).uninstall()
|
||||||
pub.unsubscribe(self.add_items, self.modulename+"_add_items")
|
pub.unsubscribe(self.add_items, self.modulename+"_add_items")
|
||||||
|
|
||||||
def on_context_menu(self, *args, **kwargs):
|
def on_context_menu(self, *args, **kwargs):
|
||||||
item = self.view.friends.get_selected()
|
item = self.view.friends.get_selected()
|
||||||
if item < 0:
|
if item < 0:
|
||||||
return
|
return
|
||||||
menu = menus.peopleMenu(False, False, True)
|
menu = menus.peopleMenu(False, False, True)
|
||||||
widgetUtils.connect_event(menu, widgetUtils.MENU, self.on_view_profile, menuitem=menu.view_profile)
|
widgetUtils.connect_event(menu, widgetUtils.MENU, self.on_view_profile, menuitem=menu.view_profile)
|
||||||
widgetUtils.connect_event(menu, widgetUtils.MENU, self.on_open_in_browser, menuitem=menu.open_in_browser)
|
widgetUtils.connect_event(menu, widgetUtils.MENU, self.on_open_in_browser, menuitem=menu.open_in_browser)
|
||||||
# Generally message sending is blocked.
|
# Generally message sending is blocked.
|
||||||
menu.message.Enable(False)
|
menu.message.Enable(False)
|
||||||
self.view.PopupMenu(menu, self.view.friends.list.GetPosition())
|
self.view.PopupMenu(menu, self.view.friends.list.GetPosition())
|
||||||
|
|
||||||
def on_view_profile(self, *args, **kwargs):
|
def on_view_profile(self, *args, **kwargs):
|
||||||
item = self.view.friends.get_selected()
|
item = self.view.friends.get_selected()
|
||||||
self.presenter.view_profile(item)
|
self.presenter.view_profile(item)
|
||||||
|
|
||||||
def on_open_in_browser(self, *args, **kwargs):
|
def on_open_in_browser(self, *args, **kwargs):
|
||||||
item = self.view.friends.get_selected()
|
item = self.view.friends.get_selected()
|
||||||
self.presenter.open_in_browser(item)
|
self.presenter.open_in_browser(item)
|
||||||
|
@ -9,62 +9,62 @@ from . import base
|
|||||||
|
|
||||||
class userProfileInteractor(base.baseInteractor):
|
class userProfileInteractor(base.baseInteractor):
|
||||||
|
|
||||||
def enable_control(self, tab, control):
|
def enable_control(self, tab, control):
|
||||||
if not hasattr(self.view, tab):
|
if not hasattr(self.view, tab):
|
||||||
raise AttributeError("The viw does not contain the specified tab.")
|
raise AttributeError("The viw does not contain the specified tab.")
|
||||||
tab = getattr(self.view, tab)
|
tab = getattr(self.view, tab)
|
||||||
if not hasattr(tab, control):
|
if not hasattr(tab, control):
|
||||||
raise AttributeError("The control is not present in the tab.")
|
raise AttributeError("The control is not present in the tab.")
|
||||||
getattr(tab, control).Enable(True)
|
getattr(tab, control).Enable(True)
|
||||||
|
|
||||||
def set(self, tab, control, value):
|
def set(self, tab, control, value):
|
||||||
if not hasattr(self.view, tab):
|
if not hasattr(self.view, tab):
|
||||||
raise AttributeError("The view does not contain the specified tab.")
|
raise AttributeError("The view does not contain the specified tab.")
|
||||||
tab = getattr(self.view, tab)
|
tab = getattr(self.view, tab)
|
||||||
if not hasattr(tab, control):
|
if not hasattr(tab, control):
|
||||||
raise AttributeError("The control is not present in the tab.")
|
raise AttributeError("The control is not present in the tab.")
|
||||||
control = getattr(tab, control)
|
control = getattr(tab, control)
|
||||||
control.SetValue(value)
|
control.SetValue(value)
|
||||||
|
|
||||||
def set_label(self, tab, control, value):
|
def set_label(self, tab, control, value):
|
||||||
if not hasattr(self.view, tab):
|
if not hasattr(self.view, tab):
|
||||||
raise AttributeError("The viw does not contain the specified tab.")
|
raise AttributeError("The viw does not contain the specified tab.")
|
||||||
tab = getattr(self.view, tab)
|
tab = getattr(self.view, tab)
|
||||||
if not hasattr(tab, control):
|
if not hasattr(tab, control):
|
||||||
raise AttributeError("The control is not present in the tab.")
|
raise AttributeError("The control is not present in the tab.")
|
||||||
control = getattr(tab, control)
|
control = getattr(tab, control)
|
||||||
control.SetLabel(value)
|
control.SetLabel(value)
|
||||||
|
|
||||||
def load_image(self, image):
|
def load_image(self, image):
|
||||||
image = wx.Image(stream=six.BytesIO(image.content))
|
image = wx.Image(stream=six.BytesIO(image.content))
|
||||||
try:
|
try:
|
||||||
self.view.image.SetBitmap(wx.Bitmap(image))
|
self.view.image.SetBitmap(wx.Bitmap(image))
|
||||||
except ValueError:
|
except ValueError:
|
||||||
return
|
return
|
||||||
self.view.panel.Layout()
|
self.view.panel.Layout()
|
||||||
|
|
||||||
def install(self, *args, **kwargs):
|
def install(self, *args, **kwargs):
|
||||||
super(userProfileInteractor, self).install(*args, **kwargs)
|
super(userProfileInteractor, self).install(*args, **kwargs)
|
||||||
pub.subscribe(self.set, self.modulename+"_set")
|
pub.subscribe(self.set, self.modulename+"_set")
|
||||||
pub.subscribe(self.load_image, self.modulename+"_load_image")
|
pub.subscribe(self.load_image, self.modulename+"_load_image")
|
||||||
self.view.create_controls("main_info")
|
self.view.create_controls("main_info")
|
||||||
self.view.realice()
|
self.view.realice()
|
||||||
widgetUtils.connect_event(self.view.main_info.go_site, widgetUtils.BUTTON_PRESSED, self.on_visit_website)
|
widgetUtils.connect_event(self.view.main_info.go_site, widgetUtils.BUTTON_PRESSED, self.on_visit_website)
|
||||||
|
|
||||||
def uninstall(self):
|
def uninstall(self):
|
||||||
super(userProfileInteractor, self).uninstall()
|
super(userProfileInteractor, self).uninstall()
|
||||||
pub.unsubscribe(self.set, self.modulename+"_set")
|
pub.unsubscribe(self.set, self.modulename+"_set")
|
||||||
pub.unsubscribe(self.load_image, self.modulename+"_load_image")
|
pub.unsubscribe(self.load_image, self.modulename+"_load_image")
|
||||||
|
|
||||||
|
|
||||||
def on_visit_website(self, *args, **kwargs):
|
def on_visit_website(self, *args, **kwargs):
|
||||||
urls = self.presenter.get_urls()
|
urls = self.presenter.get_urls()
|
||||||
if len(urls) == 1:
|
if len(urls) == 1:
|
||||||
self.presenter.visit_url(urls[0])
|
self.presenter.visit_url(urls[0])
|
||||||
else:
|
else:
|
||||||
dialog = urlList.urlList()
|
dialog = urlList.urlList()
|
||||||
dialog.populate_list(urls)
|
dialog.populate_list(urls)
|
||||||
if dialog.get_response() != widgetUtils.OK:
|
if dialog.get_response() != widgetUtils.OK:
|
||||||
return
|
return
|
||||||
selected_url = urls[dialog.get_item()]
|
selected_url = urls[dialog.get_item()]
|
||||||
self.presenter.visit_url(selected_url)
|
self.presenter.visit_url(selected_url)
|
||||||
|
@ -28,37 +28,37 @@ from mysc.thread_utils import call_threaded
|
|||||||
from . import wx_ui
|
from . import wx_ui
|
||||||
|
|
||||||
class reportBug(object):
|
class reportBug(object):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.dialog = wx_ui.reportBugDialog()
|
self.dialog = wx_ui.reportBugDialog()
|
||||||
widgetUtils.connect_event(self.dialog.ok, widgetUtils.BUTTON_PRESSED, self.send)
|
widgetUtils.connect_event(self.dialog.ok, widgetUtils.BUTTON_PRESSED, self.send)
|
||||||
self.dialog.get_response()
|
self.dialog.get_response()
|
||||||
|
|
||||||
def do_report(self, *args, **kwargs):
|
def do_report(self, *args, **kwargs):
|
||||||
r = requests.post(*args, **kwargs)
|
r = requests.post(*args, **kwargs)
|
||||||
if r.status_code > 300:
|
if r.status_code > 300:
|
||||||
wx.CallAfter(self.dialog.error)
|
wx.CallAfter(self.dialog.error)
|
||||||
wx.CallAfter(self.dialog.progress.Destroy)
|
wx.CallAfter(self.dialog.progress.Destroy)
|
||||||
wx.CallAfter(self.dialog.success, r.json()["data"]["issue"]["id"])
|
wx.CallAfter(self.dialog.success, r.json()["data"]["issue"]["id"])
|
||||||
|
|
||||||
def send(self, *args, **kwargs):
|
def send(self, *args, **kwargs):
|
||||||
if self.dialog.get("summary") == "" or self.dialog.get("description") == "" or self.dialog.get("first_name") == "" or self.dialog.get("last_name") == "":
|
if self.dialog.get("summary") == "" or self.dialog.get("description") == "" or self.dialog.get("first_name") == "" or self.dialog.get("last_name") == "":
|
||||||
self.dialog.no_filled()
|
self.dialog.no_filled()
|
||||||
return
|
return
|
||||||
if self.dialog.get("agree") == False:
|
if self.dialog.get("agree") == False:
|
||||||
self.dialog.no_checkbox()
|
self.dialog.no_checkbox()
|
||||||
return
|
return
|
||||||
title = self.dialog.get("summary")
|
title = self.dialog.get("summary")
|
||||||
body = self.dialog.get("description")
|
body = self.dialog.get("description")
|
||||||
issue_type = "issue" # for now just have issue
|
issue_type = "issue" # for now just have issue
|
||||||
app_type = paths.mode
|
app_type = paths.mode
|
||||||
app_version = application.version
|
app_version = application.version
|
||||||
reporter_name = "{first_name} {last_name}".format(first_name=self.dialog.get("first_name"), last_name=self.dialog.get("last_name"))
|
reporter_name = "{first_name} {last_name}".format(first_name=self.dialog.get("first_name"), last_name=self.dialog.get("last_name"))
|
||||||
reporter_contact_type = "email" # For now just email is supported in the issue reporter
|
reporter_contact_type = "email" # For now just email is supported in the issue reporter
|
||||||
reporter_contact_handle = self.dialog.get("email")
|
reporter_contact_handle = self.dialog.get("email")
|
||||||
operating_system = platform.platform()
|
operating_system = platform.platform()
|
||||||
json = dict(title=title, issue_type=issue_type, body=body, operating_system=operating_system, app_type=app_type, app_version=app_version, reporter_name=reporter_name, reporter_contact_handle=reporter_contact_handle, reporter_contact_type=reporter_contact_type)
|
json = dict(title=title, issue_type=issue_type, body=body, operating_system=operating_system, app_type=app_type, app_version=app_version, reporter_name=reporter_name, reporter_contact_handle=reporter_contact_handle, reporter_contact_type=reporter_contact_type)
|
||||||
auth=HTTPBasicAuth(application.bts_name, application.bts_access_token)
|
auth=HTTPBasicAuth(application.bts_name, application.bts_access_token)
|
||||||
url = "{bts_url}/issue/new".format(bts_url=application.bts_url)
|
url = "{bts_url}/issue/new".format(bts_url=application.bts_url)
|
||||||
call_threaded(self.do_report, url, json=json, auth=auth)
|
call_threaded(self.do_report, url, json=json, auth=auth)
|
||||||
self.dialog.show_progress()
|
self.dialog.show_progress()
|
||||||
self.dialog.EndModal(wx.ID_OK)
|
self.dialog.EndModal(wx.ID_OK)
|
||||||
|
@ -22,89 +22,89 @@ import widgetUtils
|
|||||||
import application
|
import application
|
||||||
|
|
||||||
class reportBugDialog(widgetUtils.BaseDialog):
|
class reportBugDialog(widgetUtils.BaseDialog):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super(reportBugDialog, self).__init__(parent=None, id=wx.NewId())
|
super(reportBugDialog, self).__init__(parent=None, id=wx.NewId())
|
||||||
self.SetTitle(_("Report an error"))
|
self.SetTitle(_("Report an error"))
|
||||||
panel = wx.Panel(self)
|
panel = wx.Panel(self)
|
||||||
sizer = wx.BoxSizer(wx.VERTICAL)
|
sizer = wx.BoxSizer(wx.VERTICAL)
|
||||||
|
|
||||||
summaryLabel = wx.StaticText(panel, -1, _("Briefly describe what happened. You will be able to thoroughly explain it later"), size=wx.DefaultSize)
|
summaryLabel = wx.StaticText(panel, -1, _("Briefly describe what happened. You will be able to thoroughly explain it later"), size=wx.DefaultSize)
|
||||||
self.summary = wx.TextCtrl(panel, -1)
|
self.summary = wx.TextCtrl(panel, -1)
|
||||||
dc = wx.WindowDC(self.summary)
|
dc = wx.WindowDC(self.summary)
|
||||||
dc.SetFont(self.summary.GetFont())
|
dc.SetFont(self.summary.GetFont())
|
||||||
self.summary.SetSize(dc.GetTextExtent("a"*80))
|
self.summary.SetSize(dc.GetTextExtent("a"*80))
|
||||||
summaryB = wx.BoxSizer(wx.HORIZONTAL)
|
summaryB = wx.BoxSizer(wx.HORIZONTAL)
|
||||||
summaryB.Add(summaryLabel, 0, wx.ALL, 5)
|
summaryB.Add(summaryLabel, 0, wx.ALL, 5)
|
||||||
summaryB.Add(self.summary, 0, wx.ALL, 5)
|
summaryB.Add(self.summary, 0, wx.ALL, 5)
|
||||||
sizer.Add(summaryB, 0, wx.ALL, 5)
|
sizer.Add(summaryB, 0, wx.ALL, 5)
|
||||||
|
|
||||||
first_nameLabel = wx.StaticText(panel, -1, _("First Name"), size=wx.DefaultSize)
|
first_nameLabel = wx.StaticText(panel, -1, _("First Name"), size=wx.DefaultSize)
|
||||||
self.first_name = wx.TextCtrl(panel, -1)
|
self.first_name = wx.TextCtrl(panel, -1)
|
||||||
dc = wx.WindowDC(self.first_name)
|
dc = wx.WindowDC(self.first_name)
|
||||||
dc.SetFont(self.first_name.GetFont())
|
dc.SetFont(self.first_name.GetFont())
|
||||||
self.first_name.SetSize(dc.GetTextExtent("a"*40))
|
self.first_name.SetSize(dc.GetTextExtent("a"*40))
|
||||||
first_nameB = wx.BoxSizer(wx.HORIZONTAL)
|
first_nameB = wx.BoxSizer(wx.HORIZONTAL)
|
||||||
first_nameB.Add(first_nameLabel, 0, wx.ALL, 5)
|
first_nameB.Add(first_nameLabel, 0, wx.ALL, 5)
|
||||||
first_nameB.Add(self.first_name, 0, wx.ALL, 5)
|
first_nameB.Add(self.first_name, 0, wx.ALL, 5)
|
||||||
sizer.Add(first_nameB, 0, wx.ALL, 5)
|
sizer.Add(first_nameB, 0, wx.ALL, 5)
|
||||||
|
|
||||||
last_nameLabel = wx.StaticText(panel, -1, _("Last Name"), size=wx.DefaultSize)
|
last_nameLabel = wx.StaticText(panel, -1, _("Last Name"), size=wx.DefaultSize)
|
||||||
self.last_name = wx.TextCtrl(panel, -1)
|
self.last_name = wx.TextCtrl(panel, -1)
|
||||||
dc = wx.WindowDC(self.last_name)
|
dc = wx.WindowDC(self.last_name)
|
||||||
dc.SetFont(self.last_name.GetFont())
|
dc.SetFont(self.last_name.GetFont())
|
||||||
self.last_name.SetSize(dc.GetTextExtent("a"*40))
|
self.last_name.SetSize(dc.GetTextExtent("a"*40))
|
||||||
last_nameB = wx.BoxSizer(wx.HORIZONTAL)
|
last_nameB = wx.BoxSizer(wx.HORIZONTAL)
|
||||||
last_nameB.Add(last_nameLabel, 0, wx.ALL, 5)
|
last_nameB.Add(last_nameLabel, 0, wx.ALL, 5)
|
||||||
last_nameB.Add(self.last_name, 0, wx.ALL, 5)
|
last_nameB.Add(self.last_name, 0, wx.ALL, 5)
|
||||||
sizer.Add(last_nameB, 0, wx.ALL, 5)
|
sizer.Add(last_nameB, 0, wx.ALL, 5)
|
||||||
|
|
||||||
emailLabel = wx.StaticText(panel, -1, _("Email address (Will not be public)"), size=wx.DefaultSize)
|
emailLabel = wx.StaticText(panel, -1, _("Email address (Will not be public)"), size=wx.DefaultSize)
|
||||||
self.email = wx.TextCtrl(panel, -1)
|
self.email = wx.TextCtrl(panel, -1)
|
||||||
dc = wx.WindowDC(self.email)
|
dc = wx.WindowDC(self.email)
|
||||||
dc.SetFont(self.email.GetFont())
|
dc.SetFont(self.email.GetFont())
|
||||||
self.email.SetSize(dc.GetTextExtent("a"*30))
|
self.email.SetSize(dc.GetTextExtent("a"*30))
|
||||||
emailB = wx.BoxSizer(wx.HORIZONTAL)
|
emailB = wx.BoxSizer(wx.HORIZONTAL)
|
||||||
emailB.Add(emailLabel, 0, wx.ALL, 5)
|
emailB.Add(emailLabel, 0, wx.ALL, 5)
|
||||||
emailB.Add(self.email, 0, wx.ALL, 5)
|
emailB.Add(self.email, 0, wx.ALL, 5)
|
||||||
sizer.Add(emailB, 0, wx.ALL, 5)
|
sizer.Add(emailB, 0, wx.ALL, 5)
|
||||||
|
|
||||||
descriptionLabel = wx.StaticText(panel, -1, _("Here, you can describe the bug in detail"), size=wx.DefaultSize)
|
descriptionLabel = wx.StaticText(panel, -1, _("Here, you can describe the bug in detail"), size=wx.DefaultSize)
|
||||||
self.description = wx.TextCtrl(panel, -1, style=wx.TE_MULTILINE)
|
self.description = wx.TextCtrl(panel, -1, style=wx.TE_MULTILINE)
|
||||||
dc = wx.WindowDC(self.description)
|
dc = wx.WindowDC(self.description)
|
||||||
dc.SetFont(self.description.GetFont())
|
dc.SetFont(self.description.GetFont())
|
||||||
(x, y) = dc.GetMultiLineTextExtent("0"*2000)
|
(x, y) = dc.GetMultiLineTextExtent("0"*2000)
|
||||||
self.description.SetSize((x, y))
|
self.description.SetSize((x, y))
|
||||||
descBox = wx.BoxSizer(wx.HORIZONTAL)
|
descBox = wx.BoxSizer(wx.HORIZONTAL)
|
||||||
descBox.Add(descriptionLabel, 0, wx.ALL, 5)
|
descBox.Add(descriptionLabel, 0, wx.ALL, 5)
|
||||||
descBox.Add(self.description, 0, wx.ALL, 5)
|
descBox.Add(self.description, 0, wx.ALL, 5)
|
||||||
sizer.Add(descBox, 0, wx.ALL, 5)
|
sizer.Add(descBox, 0, wx.ALL, 5)
|
||||||
self.agree = wx.CheckBox(panel, -1, _("I know that the {0} bug system will get my email address to contact me and fix the bug quickly").format(application.name,))
|
self.agree = wx.CheckBox(panel, -1, _("I know that the {0} bug system will get my email address to contact me and fix the bug quickly").format(application.name,))
|
||||||
self.agree.SetValue(False)
|
self.agree.SetValue(False)
|
||||||
sizer.Add(self.agree, 0, wx.ALL, 5)
|
sizer.Add(self.agree, 0, wx.ALL, 5)
|
||||||
self.ok = wx.Button(panel, wx.ID_OK, _("Send report"))
|
self.ok = wx.Button(panel, wx.ID_OK, _("Send report"))
|
||||||
self.ok.SetDefault()
|
self.ok.SetDefault()
|
||||||
cancel = wx.Button(panel, wx.ID_CANCEL, _("Cancel"))
|
cancel = wx.Button(panel, wx.ID_CANCEL, _("Cancel"))
|
||||||
btnBox = wx.BoxSizer(wx.HORIZONTAL)
|
btnBox = wx.BoxSizer(wx.HORIZONTAL)
|
||||||
btnBox.Add(self.ok, 0, wx.ALL, 5)
|
btnBox.Add(self.ok, 0, wx.ALL, 5)
|
||||||
btnBox.Add(cancel, 0, wx.ALL, 5)
|
btnBox.Add(cancel, 0, wx.ALL, 5)
|
||||||
sizer.Add(btnBox, 0, wx.ALL, 5)
|
sizer.Add(btnBox, 0, wx.ALL, 5)
|
||||||
panel.SetSizer(sizer)
|
panel.SetSizer(sizer)
|
||||||
self.SetClientSize(sizer.CalcMin())
|
self.SetClientSize(sizer.CalcMin())
|
||||||
|
|
||||||
def no_filled(self):
|
def no_filled(self):
|
||||||
wx.MessageDialog(self, _("You must fill out the following fields: first name, last name, email address and issue information."), _("Error"), wx.OK|wx.ICON_ERROR).ShowModal()
|
wx.MessageDialog(self, _("You must fill out the following fields: first name, last name, email address and issue information."), _("Error"), wx.OK|wx.ICON_ERROR).ShowModal()
|
||||||
|
|
||||||
def no_checkbox(self):
|
def no_checkbox(self):
|
||||||
wx.MessageDialog(self, _("You need to mark the checkbox to provide us your email address to contact you if it is necessary."), _("Error"), wx.ICON_ERROR).ShowModal()
|
wx.MessageDialog(self, _("You need to mark the checkbox to provide us your email address to contact you if it is necessary."), _("Error"), wx.ICON_ERROR).ShowModal()
|
||||||
|
|
||||||
def success(self, id):
|
def success(self, id):
|
||||||
wx.MessageDialog(self, _("Thanks for reporting this bug! In future versions, you may be able to find it in the changes list. You have received an email with more information regarding your report. You've reported the bug number %i") % (id), _("reported"), wx.OK).ShowModal()
|
wx.MessageDialog(self, _("Thanks for reporting this bug! In future versions, you may be able to find it in the changes list. You have received an email with more information regarding your report. You've reported the bug number %i") % (id), _("reported"), wx.OK).ShowModal()
|
||||||
self.Destroy()
|
self.Destroy()
|
||||||
|
|
||||||
def error(self):
|
def error(self):
|
||||||
wx.MessageDialog(self, _("Something unexpected occurred while trying to report the bug. Please, try again later"), _("Error while reporting"), wx.ICON_ERROR|wx.OK).ShowModal()
|
wx.MessageDialog(self, _("Something unexpected occurred while trying to report the bug. Please, try again later"), _("Error while reporting"), wx.ICON_ERROR|wx.OK).ShowModal()
|
||||||
self.Destroy()
|
self.Destroy()
|
||||||
|
|
||||||
def show_progress(self):
|
def show_progress(self):
|
||||||
self.progress = wx.ProgressDialog(title=_("Sending report..."), message=_("Please wait while your report is being send."), maximum=100, parent=self)
|
self.progress = wx.ProgressDialog(title=_("Sending report..."), message=_("Please wait while your report is being send."), maximum=100, parent=self)
|
||||||
self.progress.ShowModal()
|
self.progress.ShowModal()
|
||||||
|
@ -5,12 +5,12 @@ log = logging.getLogger("keyring")
|
|||||||
keyring = None
|
keyring = None
|
||||||
|
|
||||||
def setup():
|
def setup():
|
||||||
global keyring
|
global keyring
|
||||||
if keyring == None:
|
if keyring == None:
|
||||||
keyring = Keyring()
|
keyring = Keyring()
|
||||||
log.debug("Keyring started")
|
log.debug("Keyring started")
|
||||||
|
|
||||||
class Keyring(object):
|
class Keyring(object):
|
||||||
|
|
||||||
def get_api_key(self):
|
def get_api_key(self):
|
||||||
return "5093442"
|
return "5093442"
|
||||||
|
@ -20,195 +20,195 @@ LOCALE_SLANGDISPLAYNAME=0x6f
|
|||||||
curLang="en"
|
curLang="en"
|
||||||
|
|
||||||
def localeNameToWindowsLCID(localeName):
|
def localeNameToWindowsLCID(localeName):
|
||||||
"""Retreave the Windows locale identifier (LCID) for the given locale name
|
"""Retreave the Windows locale identifier (LCID) for the given locale name
|
||||||
@param localeName: a string of 2letterLanguage_2letterCountry or or just 2letterLanguage
|
@param localeName: a string of 2letterLanguage_2letterCountry or or just 2letterLanguage
|
||||||
@type localeName: string
|
@type localeName: string
|
||||||
@returns: a Windows LCID
|
@returns: a Windows LCID
|
||||||
@rtype: integer
|
@rtype: integer
|
||||||
"""
|
"""
|
||||||
#Windows Vista is able to convert locale names to LCIDs
|
#Windows Vista is able to convert locale names to LCIDs
|
||||||
func_LocaleNameToLCID=getattr(ctypes.windll.kernel32,'LocaleNameToLCID',None)
|
func_LocaleNameToLCID=getattr(ctypes.windll.kernel32,'LocaleNameToLCID',None)
|
||||||
if func_LocaleNameToLCID is not None:
|
if func_LocaleNameToLCID is not None:
|
||||||
localeName=localeName.replace('_','-')
|
localeName=localeName.replace('_','-')
|
||||||
LCID=func_LocaleNameToLCID(str(localeName),0)
|
LCID=func_LocaleNameToLCID(str(localeName),0)
|
||||||
else: #Windows doesn't have this functionality, manually search Python's windows_locale dictionary for the LCID
|
else: #Windows doesn't have this functionality, manually search Python's windows_locale dictionary for the LCID
|
||||||
localeName=locale.normalize(localeName)
|
localeName=locale.normalize(localeName)
|
||||||
if '.' in localeName:
|
if '.' in localeName:
|
||||||
localeName=localeName.split('.')[0]
|
localeName=localeName.split('.')[0]
|
||||||
LCList=[x[0] for x in locale.windows_locale.items() if x[1]==localeName]
|
LCList=[x[0] for x in locale.windows_locale.items() if x[1]==localeName]
|
||||||
if len(LCList)>0:
|
if len(LCList)>0:
|
||||||
LCID=LCList[0]
|
LCID=LCList[0]
|
||||||
else:
|
else:
|
||||||
LCID=0
|
LCID=0
|
||||||
return LCID
|
return LCID
|
||||||
|
|
||||||
def getLanguageDescription(language):
|
def getLanguageDescription(language):
|
||||||
"""Finds out the description (localized full name) of a given local name"""
|
"""Finds out the description (localized full name) of a given local name"""
|
||||||
desc=None
|
desc=None
|
||||||
if platform.system() == "Windows":
|
if platform.system() == "Windows":
|
||||||
LCID=localeNameToWindowsLCID(language)
|
LCID=localeNameToWindowsLCID(language)
|
||||||
if LCID!=0:
|
if LCID!=0:
|
||||||
buf=ctypes.create_unicode_buffer(1024)
|
buf=ctypes.create_unicode_buffer(1024)
|
||||||
if '_' not in language:
|
if '_' not in language:
|
||||||
res=ctypes.windll.kernel32.GetLocaleInfoW(LCID,LOCALE_SLANGDISPLAYNAME,buf,1024)
|
res=ctypes.windll.kernel32.GetLocaleInfoW(LCID,LOCALE_SLANGDISPLAYNAME,buf,1024)
|
||||||
else:
|
else:
|
||||||
res=0
|
res=0
|
||||||
if res==0:
|
if res==0:
|
||||||
res=ctypes.windll.kernel32.GetLocaleInfoW(LCID,LOCALE_SLANGUAGE,buf,1024)
|
res=ctypes.windll.kernel32.GetLocaleInfoW(LCID,LOCALE_SLANGUAGE,buf,1024)
|
||||||
desc=buf.value
|
desc=buf.value
|
||||||
elif platform.system() == "Linux" or not desc:
|
elif platform.system() == "Linux" or not desc:
|
||||||
desc={
|
desc={
|
||||||
"am":pgettext("languageName","Amharic"),
|
"am":pgettext("languageName","Amharic"),
|
||||||
"an":pgettext("languageName","Aragonese"),
|
"an":pgettext("languageName","Aragonese"),
|
||||||
"es":pgettext("languageName","Spanish"),
|
"es":pgettext("languageName","Spanish"),
|
||||||
"pt":pgettext("languageName","Portuguese"),
|
"pt":pgettext("languageName","Portuguese"),
|
||||||
"ru":pgettext("languageName","Russian"),
|
"ru":pgettext("languageName","Russian"),
|
||||||
"it":pgettext("languageName","italian"),
|
"it":pgettext("languageName","italian"),
|
||||||
"tr":pgettext("languageName","Turkey"),
|
"tr":pgettext("languageName","Turkey"),
|
||||||
"gl":pgettext("languageName","Galician"),
|
"gl":pgettext("languageName","Galician"),
|
||||||
"ca":pgettext("languageName","Catala"),
|
"ca":pgettext("languageName","Catala"),
|
||||||
"eu":pgettext("languageName","Vasque"),
|
"eu":pgettext("languageName","Vasque"),
|
||||||
"pl":pgettext("languageName","polish"),
|
"pl":pgettext("languageName","polish"),
|
||||||
"ar":pgettext("languageName","Arabic"),
|
"ar":pgettext("languageName","Arabic"),
|
||||||
"ne":pgettext("languageName","Nepali"),
|
"ne":pgettext("languageName","Nepali"),
|
||||||
"sr":pgettext("languageName","Serbian (Latin)"),
|
"sr":pgettext("languageName","Serbian (Latin)"),
|
||||||
"ja":pgettext("languageName","Japanese"),
|
"ja":pgettext("languageName","Japanese"),
|
||||||
}.get(language,None)
|
}.get(language,None)
|
||||||
return desc
|
return desc
|
||||||
|
|
||||||
def getAvailableLanguages():
|
def getAvailableLanguages():
|
||||||
"""generates a list of locale names, plus their full localized language and country names.
|
"""generates a list of locale names, plus their full localized language and country names.
|
||||||
@rtype: list of tuples
|
@rtype: list of tuples
|
||||||
"""
|
"""
|
||||||
#Make a list of all the locales found in NVDA's locale dir
|
#Make a list of all the locales found in NVDA's locale dir
|
||||||
l=[x for x in os.listdir(paths.locale_path()) if not x.startswith('.')]
|
l=[x for x in os.listdir(paths.locale_path()) if not x.startswith('.')]
|
||||||
l=[x for x in l if os.path.isfile(os.path.join(paths.locale_path(), '%s/LC_MESSAGES/%s.po' % (x, application.short_name)))]
|
l=[x for x in l if os.path.isfile(os.path.join(paths.locale_path(), '%s/LC_MESSAGES/%s.po' % (x, application.short_name)))]
|
||||||
#Make sure that en (english) is in the list as it may not have any locale files, but is default
|
#Make sure that en (english) is in the list as it may not have any locale files, but is default
|
||||||
if 'en' not in l:
|
if 'en' not in l:
|
||||||
l.append('en')
|
l.append('en')
|
||||||
l.sort()
|
l.sort()
|
||||||
#For each locale, ask Windows for its human readable display name
|
#For each locale, ask Windows for its human readable display name
|
||||||
d=[]
|
d=[]
|
||||||
for i in l:
|
for i in l:
|
||||||
desc=getLanguageDescription(i)
|
desc=getLanguageDescription(i)
|
||||||
label="%s, %s"%(desc,i) if desc else i
|
label="%s, %s"%(desc,i) if desc else i
|
||||||
d.append(label)
|
d.append(label)
|
||||||
#include a 'user default, windows' language, which just represents the default language for this user account
|
#include a 'user default, windows' language, which just represents the default language for this user account
|
||||||
l.append("system")
|
l.append("system")
|
||||||
# Translators: the label for the Windows default NVDA interface language.
|
# Translators: the label for the Windows default NVDA interface language.
|
||||||
d.append(_("User default"))
|
d.append(_("User default"))
|
||||||
#return a zipped up version of both the lists (a list with tuples of locale,label)
|
#return a zipped up version of both the lists (a list with tuples of locale,label)
|
||||||
return list(zip(l,d))
|
return list(zip(l,d))
|
||||||
|
|
||||||
def makePgettext(translations):
|
def makePgettext(translations):
|
||||||
"""Obtaina pgettext function for use with a gettext translations instance.
|
"""Obtaina pgettext function for use with a gettext translations instance.
|
||||||
pgettext is used to support message contexts,
|
pgettext is used to support message contexts,
|
||||||
but Python 2.7's gettext module doesn't support this,
|
but Python 2.7's gettext module doesn't support this,
|
||||||
so NVDA must provide its own implementation.
|
so NVDA must provide its own implementation.
|
||||||
"""
|
"""
|
||||||
if isinstance(translations, gettext.GNUTranslations):
|
if isinstance(translations, gettext.GNUTranslations):
|
||||||
def pgettext(context, message):
|
def pgettext(context, message):
|
||||||
message = str(message)
|
message = str(message)
|
||||||
try:
|
try:
|
||||||
# Look up the message with its context.
|
# Look up the message with its context.
|
||||||
return translations._catalog["%s\x04%s" % (context, message)]
|
return translations._catalog["%s\x04%s" % (context, message)]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
return message
|
return message
|
||||||
else:
|
else:
|
||||||
def pgettext(context, message):
|
def pgettext(context, message):
|
||||||
return str(message)
|
return str(message)
|
||||||
return pgettext
|
return pgettext
|
||||||
|
|
||||||
def setLanguage(lang):
|
def setLanguage(lang):
|
||||||
system = platform.system()
|
system = platform.system()
|
||||||
global curLang
|
global curLang
|
||||||
try:
|
try:
|
||||||
if lang=="system":
|
if lang=="system":
|
||||||
if system == "Windows":
|
if system == "Windows":
|
||||||
windowsLCID=ctypes.windll.kernel32.GetUserDefaultUILanguage()
|
windowsLCID=ctypes.windll.kernel32.GetUserDefaultUILanguage()
|
||||||
localeName=locale.windows_locale[windowsLCID]
|
localeName=locale.windows_locale[windowsLCID]
|
||||||
elif system == "Darwin":
|
elif system == "Darwin":
|
||||||
import Foundation
|
import Foundation
|
||||||
localeName = Foundation.NSLocale.currentLocale().identifier()
|
localeName = Foundation.NSLocale.currentLocale().identifier()
|
||||||
elif system == "Linux":
|
elif system == "Linux":
|
||||||
localeName = locale.getdefaultlocale()[0]
|
localeName = locale.getdefaultlocale()[0]
|
||||||
trans=gettext.translation(application.short_name, localedir=paths.locale_path(), languages=[localeName])
|
trans=gettext.translation(application.short_name, localedir=paths.locale_path(), languages=[localeName])
|
||||||
curLang=localeName
|
curLang=localeName
|
||||||
# else:
|
# else:
|
||||||
# localeName=locale.getdefaultlocale()[0]
|
# localeName=locale.getdefaultlocale()[0]
|
||||||
# trans=gettext.translation('twblue', localedir=paths.locale_path(), languages=[localeName])
|
# trans=gettext.translation('twblue', localedir=paths.locale_path(), languages=[localeName])
|
||||||
# curLang=localeName
|
# curLang=localeName
|
||||||
|
|
||||||
else:
|
else:
|
||||||
trans=gettext.translation(application.short_name, localedir=paths.locale_path(), languages=[lang])
|
trans=gettext.translation(application.short_name, localedir=paths.locale_path(), languages=[lang])
|
||||||
curLang=lang
|
curLang=lang
|
||||||
localeChanged=False
|
localeChanged=False
|
||||||
#Try setting Python's locale to lang
|
#Try setting Python's locale to lang
|
||||||
# try:
|
# try:
|
||||||
if system == "Windows":
|
if system == "Windows":
|
||||||
locale.setlocale(locale.LC_ALL, langToWindowsLocale(lang))
|
locale.setlocale(locale.LC_ALL, langToWindowsLocale(lang))
|
||||||
localeChanged=True
|
localeChanged=True
|
||||||
else:
|
else:
|
||||||
locale.setlocale(locale.LC_ALL, lang)
|
locale.setlocale(locale.LC_ALL, lang)
|
||||||
localeChanged=True
|
localeChanged=True
|
||||||
# except:
|
# except:
|
||||||
# pass
|
# pass
|
||||||
if not localeChanged and '_' in lang:
|
if not localeChanged and '_' in lang:
|
||||||
#Python couldn'tsupport the language_country locale, just try language.
|
#Python couldn'tsupport the language_country locale, just try language.
|
||||||
try:
|
try:
|
||||||
locale.setlocale(locale.LC_ALL, lang.split('_')[0])
|
locale.setlocale(locale.LC_ALL, lang.split('_')[0])
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
#Set the windows locale for this thread (NVDA core) to this locale.
|
#Set the windows locale for this thread (NVDA core) to this locale.
|
||||||
if system == "Windows":
|
if system == "Windows":
|
||||||
LCID=localeNameToWindowsLCID(lang)
|
LCID=localeNameToWindowsLCID(lang)
|
||||||
ctypes.windll.kernel32.SetThreadLocale(LCID)
|
ctypes.windll.kernel32.SetThreadLocale(LCID)
|
||||||
except IOError:
|
except IOError:
|
||||||
trans=gettext.translation(application.short_name, fallback=True)
|
trans=gettext.translation(application.short_name, fallback=True)
|
||||||
curLang="en"
|
curLang="en"
|
||||||
if sys.version[0] == "3":
|
if sys.version[0] == "3":
|
||||||
trans.install()
|
trans.install()
|
||||||
else:
|
else:
|
||||||
trans.install(unicode=True)
|
trans.install(unicode=True)
|
||||||
# Install our pgettext function.
|
# Install our pgettext function.
|
||||||
# __builtin__.__dict__["pgettext"] = makePgettext(trans)
|
# __builtin__.__dict__["pgettext"] = makePgettext(trans)
|
||||||
|
|
||||||
def getLanguage():
|
def getLanguage():
|
||||||
return curLang
|
return curLang
|
||||||
|
|
||||||
def normalizeLanguage(lang):
|
def normalizeLanguage(lang):
|
||||||
"""
|
"""
|
||||||
Normalizes a language-dialect string in to a standard form we can deal with.
|
Normalizes a language-dialect string in to a standard form we can deal with.
|
||||||
Converts any dash to underline, and makes sure that language is lowercase and dialect is upercase.
|
Converts any dash to underline, and makes sure that language is lowercase and dialect is upercase.
|
||||||
"""
|
"""
|
||||||
lang=lang.replace('-','_')
|
lang=lang.replace('-','_')
|
||||||
ld=lang.split('_')
|
ld=lang.split('_')
|
||||||
ld[0]=ld[0].lower()
|
ld[0]=ld[0].lower()
|
||||||
#Filter out meta languages such as x-western
|
#Filter out meta languages such as x-western
|
||||||
if ld[0]=='x':
|
if ld[0]=='x':
|
||||||
return None
|
return None
|
||||||
if len(ld)>=2:
|
if len(ld)>=2:
|
||||||
ld[1]=ld[1].upper()
|
ld[1]=ld[1].upper()
|
||||||
return "_".join(ld)
|
return "_".join(ld)
|
||||||
|
|
||||||
def langToWindowsLocale(lang):
|
def langToWindowsLocale(lang):
|
||||||
languages = {"en": "eng",
|
languages = {"en": "eng",
|
||||||
"ar": "ara",
|
"ar": "ara",
|
||||||
"ca": "cat",
|
"ca": "cat",
|
||||||
"de": "deu",
|
"de": "deu",
|
||||||
"es": "esp",
|
"es": "esp",
|
||||||
"fi": "fin",
|
"fi": "fin",
|
||||||
"fr": "fre_FRA",
|
"fr": "fre_FRA",
|
||||||
"gl": "glc",
|
"gl": "glc",
|
||||||
"eu": "euq",
|
"eu": "euq",
|
||||||
"hu": "hun",
|
"hu": "hun",
|
||||||
"hr": "hrv",
|
"hr": "hrv",
|
||||||
"it": "ita",
|
"it": "ita",
|
||||||
"ja": "jpn",
|
"ja": "jpn",
|
||||||
"pl": "plk",
|
"pl": "plk",
|
||||||
"pt": "ptb",
|
"pt": "ptb",
|
||||||
"ru": "rus",
|
"ru": "rus",
|
||||||
"tr": "trk",
|
"tr": "trk",
|
||||||
"sr": "eng",
|
"sr": "eng",
|
||||||
}
|
}
|
||||||
return languages[lang]
|
return languages[lang]
|
||||||
|
82
src/main.py
82
src/main.py
@ -15,7 +15,7 @@ import logging
|
|||||||
import keys
|
import keys
|
||||||
import application
|
import application
|
||||||
if hasattr(sys, "frozen"):
|
if hasattr(sys, "frozen"):
|
||||||
sys.excepthook = lambda x, y, z: logging.critical(''.join(traceback.format_exception(x, y, z)))
|
sys.excepthook = lambda x, y, z: logging.critical(''.join(traceback.format_exception(x, y, z)))
|
||||||
from mysc.thread_utils import call_threaded
|
from mysc.thread_utils import call_threaded
|
||||||
from wxUI import commonMessages
|
from wxUI import commonMessages
|
||||||
|
|
||||||
@ -24,48 +24,48 @@ log = logging.getLogger("main")
|
|||||||
orig_session_init = None
|
orig_session_init = None
|
||||||
|
|
||||||
def setup():
|
def setup():
|
||||||
global orig_session_init
|
global orig_session_init
|
||||||
log.debug("Starting Socializer %s" % (application.version,))
|
log.debug("Starting Socializer %s" % (application.version,))
|
||||||
config.setup()
|
config.setup()
|
||||||
if config.app["app-settings"]["debug_logging"] == True:
|
if config.app["app-settings"]["debug_logging"] == True:
|
||||||
logger.app_handler.setLevel(logging.DEBUG)
|
logger.app_handler.setLevel(logging.DEBUG)
|
||||||
log.info("Using %s %s" % (platform.system(), platform.architecture()[0]))
|
log.info("Using %s %s" % (platform.system(), platform.architecture()[0]))
|
||||||
log.debug("Application path is %s" % (paths.app_path(),))
|
log.debug("Application path is %s" % (paths.app_path(),))
|
||||||
log.debug("config path is %s" % (paths.config_path(),))
|
log.debug("config path is %s" % (paths.config_path(),))
|
||||||
output.setup()
|
output.setup()
|
||||||
languageHandler.setLanguage(config.app["app-settings"]["language"])
|
languageHandler.setLanguage(config.app["app-settings"]["language"])
|
||||||
log.debug("Language set to %s" % (languageHandler.getLanguage()))
|
log.debug("Language set to %s" % (languageHandler.getLanguage()))
|
||||||
keys.setup()
|
keys.setup()
|
||||||
app = widgetUtils.mainLoopObject()
|
app = widgetUtils.mainLoopObject()
|
||||||
if config.app["app-settings"]["first_start"]:
|
if config.app["app-settings"]["first_start"]:
|
||||||
log.debug("Detected first time execution.")
|
log.debug("Detected first time execution.")
|
||||||
proxy_option = commonMessages.proxy_question()
|
proxy_option = commonMessages.proxy_question()
|
||||||
if proxy_option == widgetUtils.YES:
|
if proxy_option == widgetUtils.YES:
|
||||||
config.app["app-settings"]["use_proxy"] = True
|
config.app["app-settings"]["use_proxy"] = True
|
||||||
log.debug("User has requested to use proxy for connecting to VK.")
|
log.debug("User has requested to use proxy for connecting to VK.")
|
||||||
config.app["app-settings"]["first_start"] = False
|
config.app["app-settings"]["first_start"] = False
|
||||||
config.app.write()
|
config.app.write()
|
||||||
if config.app["app-settings"]["use_proxy"]:
|
if config.app["app-settings"]["use_proxy"]:
|
||||||
log.debug("Enabling proxy support... ")
|
log.debug("Enabling proxy support... ")
|
||||||
import requests
|
import requests
|
||||||
orig_session_init=requests.sessions.Session.__init__
|
orig_session_init=requests.sessions.Session.__init__
|
||||||
requests.sessions.Session.__init__=patched_session_init
|
requests.sessions.Session.__init__=patched_session_init
|
||||||
requests.Session.__init__=patched_session_init
|
requests.Session.__init__=patched_session_init
|
||||||
from controller import mainController
|
from controller import mainController
|
||||||
from sessionmanager import sessionManager
|
from sessionmanager import sessionManager
|
||||||
|
|
||||||
log.debug("Created Application mainloop object")
|
log.debug("Created Application mainloop object")
|
||||||
sm = sessionManager.sessionManagerController()
|
sm = sessionManager.sessionManagerController()
|
||||||
sm.show()
|
sm.show()
|
||||||
del sm
|
del sm
|
||||||
r = mainController.Controller()
|
r = mainController.Controller()
|
||||||
call_threaded(r.login)
|
call_threaded(r.login)
|
||||||
app.run()
|
app.run()
|
||||||
|
|
||||||
def patched_session_init(self):
|
def patched_session_init(self):
|
||||||
global orig_session_init
|
global orig_session_init
|
||||||
orig_session_init(self)
|
orig_session_init(self)
|
||||||
self.proxies={"http": "http://socializer:socializer@socializer.su:3128",
|
self.proxies={"http": "http://socializer:socializer@socializer.su:3128",
|
||||||
"https": "http://socializer:socializer@socializer.su:3128"}
|
"https": "http://socializer:socializer@socializer.su:3128"}
|
||||||
|
|
||||||
setup()
|
setup()
|
||||||
|
@ -5,14 +5,13 @@ import logging
|
|||||||
log = logging.getLogger("mysc.localization")
|
log = logging.getLogger("mysc.localization")
|
||||||
|
|
||||||
def get(rootFolder):
|
def get(rootFolder):
|
||||||
log.debug("Getting documentation folder. RootFolder: %s" % (rootFolder,))
|
log.debug("Getting documentation folder. RootFolder: %s" % (rootFolder,))
|
||||||
defaultLocale = languageHandler.curLang
|
defaultLocale = languageHandler.curLang
|
||||||
if len(defaultLocale) > 2:
|
if len(defaultLocale) > 2:
|
||||||
defaultLocale = defaultLocale[:2]
|
defaultLocale = defaultLocale[:2]
|
||||||
log.debug("Locale: %s" % (defaultLocale,))
|
log.debug("Locale: %s" % (defaultLocale,))
|
||||||
if os.path.exists(rootFolder+"/"+defaultLocale):
|
if os.path.exists(rootFolder+"/"+defaultLocale):
|
||||||
return defaultLocale
|
return defaultLocale
|
||||||
else:
|
else:
|
||||||
log.debug("The folder does not exist, using the English folder...")
|
log.debug("The folder does not exist, using the English folder...")
|
||||||
return "en"
|
return "en"
|
||||||
|
|
||||||
|
@ -4,34 +4,34 @@ import logging
|
|||||||
log = logging.getLogger("mysc.repeating_timer")
|
log = logging.getLogger("mysc.repeating_timer")
|
||||||
|
|
||||||
class RepeatingTimer(threading.Thread):
|
class RepeatingTimer(threading.Thread):
|
||||||
"""Call a function after a specified number of seconds, it will then repeat again after the specified number of seconds
|
"""Call a function after a specified number of seconds, it will then repeat again after the specified number of seconds
|
||||||
Note: If the function provided takes time to execute, this time is NOT taken from the next wait period
|
Note: If the function provided takes time to execute, this time is NOT taken from the next wait period
|
||||||
|
|
||||||
t = RepeatingTimer(30.0, f, args=[], kwargs={})
|
t = RepeatingTimer(30.0, f, args=[], kwargs={})
|
||||||
t.start()
|
t.start()
|
||||||
t.cancel() # stop the timer's actions
|
t.cancel() # stop the timer's actions
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, interval, function, daemon=True, *args, **kwargs):
|
def __init__(self, interval, function, daemon=True, *args, **kwargs):
|
||||||
threading.Thread.__init__(self)
|
threading.Thread.__init__(self)
|
||||||
self.daemon = daemon
|
self.daemon = daemon
|
||||||
self.interval = float(interval)
|
self.interval = float(interval)
|
||||||
self.function = function
|
self.function = function
|
||||||
self.args = args
|
self.args = args
|
||||||
self.kwargs = kwargs
|
self.kwargs = kwargs
|
||||||
self.finished = threading.Event()
|
self.finished = threading.Event()
|
||||||
|
|
||||||
def cancel(self):
|
def cancel(self):
|
||||||
"""Stop the timer if it hasn't finished yet"""
|
"""Stop the timer if it hasn't finished yet"""
|
||||||
log.debug("Stopping repeater for %s" % (self.function,))
|
log.debug("Stopping repeater for %s" % (self.function,))
|
||||||
self.finished.set()
|
self.finished.set()
|
||||||
stop = cancel
|
stop = cancel
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
while not self.finished.is_set():
|
while not self.finished.is_set():
|
||||||
self.finished.wait(self.interval)
|
self.finished.wait(self.interval)
|
||||||
if not self.finished.is_set(): #In case someone has canceled while waiting
|
if not self.finished.is_set(): #In case someone has canceled while waiting
|
||||||
try:
|
try:
|
||||||
self.function(*self.args, **self.kwargs)
|
self.function(*self.args, **self.kwargs)
|
||||||
except:
|
except:
|
||||||
log.exception("Execution failed. Function: %r args: %r and kwargs: %r" % (self.function, self.args, self.kwargs))
|
log.exception("Execution failed. Function: %r args: %r and kwargs: %r" % (self.function, self.args, self.kwargs))
|
||||||
|
@ -3,10 +3,10 @@ from __future__ import unicode_literals
|
|||||||
import sys, os
|
import sys, os
|
||||||
|
|
||||||
def restart_program():
|
def restart_program():
|
||||||
""" Function that restarts the application if is executed."""
|
""" Function that restarts the application if is executed."""
|
||||||
args = sys.argv[:]
|
args = sys.argv[:]
|
||||||
if not hasattr(sys, "frozen"):
|
if not hasattr(sys, "frozen"):
|
||||||
args.insert(0, sys.executable)
|
args.insert(0, sys.executable)
|
||||||
if sys.platform == 'win32':
|
if sys.platform == 'win32':
|
||||||
args = ['"%s"' % arg for arg in args]
|
args = ['"%s"' % arg for arg in args]
|
||||||
os.execv(sys.executable, args)
|
os.execv(sys.executable, args)
|
||||||
|
@ -5,13 +5,13 @@ standard_library.install_aliases()
|
|||||||
import threading
|
import threading
|
||||||
|
|
||||||
def call_threaded(func, *args, **kwargs):
|
def call_threaded(func, *args, **kwargs):
|
||||||
#Call the given function in a daemonized thread and return the thread.
|
#Call the given function in a daemonized thread and return the thread.
|
||||||
def new_func(*a, **k):
|
def new_func(*a, **k):
|
||||||
# try:
|
# try:
|
||||||
func(*a, **k)
|
func(*a, **k)
|
||||||
# except:
|
# except:
|
||||||
# pass
|
# pass
|
||||||
thread = threading.Thread(target=new_func, args=args, kwargs=kwargs)
|
thread = threading.Thread(target=new_func, args=args, kwargs=kwargs)
|
||||||
thread.daemon = True
|
thread.daemon = True
|
||||||
thread.start()
|
thread.start()
|
||||||
return thread
|
return thread
|
||||||
|
@ -9,34 +9,34 @@ speaker = None
|
|||||||
retries = 0
|
retries = 0
|
||||||
|
|
||||||
def speak(text, interrupt=0):
|
def speak(text, interrupt=0):
|
||||||
global speaker, retries
|
global speaker, retries
|
||||||
if not speaker:
|
if not speaker:
|
||||||
setup()
|
setup()
|
||||||
try:
|
try:
|
||||||
speaker.speak(text, interrupt)
|
speaker.speak(text, interrupt)
|
||||||
except:
|
except:
|
||||||
if retries < 5:
|
if retries < 5:
|
||||||
retries = retries + 1
|
retries = retries + 1
|
||||||
speak(text)
|
speak(text)
|
||||||
# speaker.braille(text)
|
# speaker.braille(text)
|
||||||
|
|
||||||
def setup ():
|
def setup ():
|
||||||
global speaker
|
global speaker
|
||||||
logger.debug("Initializing output subsystem.")
|
logger.debug("Initializing output subsystem.")
|
||||||
try:
|
try:
|
||||||
# speaker = speech.Speaker(speech.outputs.Sapi5())
|
# speaker = speech.Speaker(speech.outputs.Sapi5())
|
||||||
# else:
|
# else:
|
||||||
speaker = outputs.auto.Auto()
|
speaker = outputs.auto.Auto()
|
||||||
except:
|
except:
|
||||||
logger.exception("Output: Error during initialization.")
|
logger.exception("Output: Error during initialization.")
|
||||||
|
|
||||||
def enable_sapi():
|
def enable_sapi():
|
||||||
speaker = outputs.sapi.SAPI5()
|
speaker = outputs.sapi.SAPI5()
|
||||||
|
|
||||||
def copy(text):
|
def copy(text):
|
||||||
import win32clipboard
|
import win32clipboard
|
||||||
#Copies text to the clipboard.
|
#Copies text to the clipboard.
|
||||||
win32clipboard.OpenClipboard()
|
win32clipboard.OpenClipboard()
|
||||||
win32clipboard.EmptyClipboard()
|
win32clipboard.EmptyClipboard()
|
||||||
win32clipboard.SetClipboardText(text)
|
win32clipboard.SetClipboardText(text)
|
||||||
win32clipboard.CloseClipboard()
|
win32clipboard.CloseClipboard()
|
||||||
|
82
src/paths.py
82
src/paths.py
@ -15,58 +15,58 @@ fsencoding = sys.getfilesystemencoding()
|
|||||||
|
|
||||||
#log = logging.getLogger("paths")
|
#log = logging.getLogger("paths")
|
||||||
if len(glob.glob("Uninstall.exe")) > 0: # installed copy
|
if len(glob.glob("Uninstall.exe")) > 0: # installed copy
|
||||||
mode= "installed"
|
mode= "installed"
|
||||||
|
|
||||||
def app_path():
|
def app_path():
|
||||||
return paths_.app_path()
|
return paths_.app_path()
|
||||||
|
|
||||||
def config_path():
|
def config_path():
|
||||||
global mode, directory
|
global mode, directory
|
||||||
if mode == "portable":
|
if mode == "portable":
|
||||||
if directory != None: path = os.path.join(directory, "config")
|
if directory != None: path = os.path.join(directory, "config")
|
||||||
elif directory == None: path = os.path.join(app_path(), "config")
|
elif directory == None: path = os.path.join(app_path(), "config")
|
||||||
elif mode == "installed":
|
elif mode == "installed":
|
||||||
path = os.path.join(data_path(), "config")
|
path = os.path.join(data_path(), "config")
|
||||||
if not os.path.exists(path):
|
if not os.path.exists(path):
|
||||||
# log.debug("%s path does not exist, creating..." % (path,))
|
# log.debug("%s path does not exist, creating..." % (path,))
|
||||||
os.mkdir(path)
|
os.mkdir(path)
|
||||||
return path
|
return path
|
||||||
|
|
||||||
def logs_path():
|
def logs_path():
|
||||||
global mode, directory
|
global mode, directory
|
||||||
if mode == "portable":
|
if mode == "portable":
|
||||||
if directory != None: path = os.path.join(directory, "logs")
|
if directory != None: path = os.path.join(directory, "logs")
|
||||||
elif directory == None: path = os.path.join(app_path(), "logs")
|
elif directory == None: path = os.path.join(app_path(), "logs")
|
||||||
elif mode == "installed":
|
elif mode == "installed":
|
||||||
path = os.path.join(data_path(), "logs")
|
path = os.path.join(data_path(), "logs")
|
||||||
if not os.path.exists(path):
|
if not os.path.exists(path):
|
||||||
# log.debug("%s path does not exist, creating..." % (path,))
|
# log.debug("%s path does not exist, creating..." % (path,))
|
||||||
os.mkdir(path)
|
os.mkdir(path)
|
||||||
return path
|
return path
|
||||||
|
|
||||||
def data_path(app_name='socializer'):
|
def data_path(app_name='socializer'):
|
||||||
if platform.system() == "Windows":
|
if platform.system() == "Windows":
|
||||||
data_path = os.path.join(os.getenv("AppData"), app_name)
|
data_path = os.path.join(os.getenv("AppData"), app_name)
|
||||||
else:
|
else:
|
||||||
data_path = os.path.join(os.environ['HOME'], ".%s" % app_name)
|
data_path = os.path.join(os.environ['HOME'], ".%s" % app_name)
|
||||||
if not os.path.exists(data_path):
|
if not os.path.exists(data_path):
|
||||||
os.mkdir(data_path)
|
os.mkdir(data_path)
|
||||||
return data_path
|
return data_path
|
||||||
|
|
||||||
def locale_path():
|
def locale_path():
|
||||||
return os.path.join(app_path(), "locales")
|
return os.path.join(app_path(), "locales")
|
||||||
|
|
||||||
def sound_path():
|
def sound_path():
|
||||||
return os.path.join(app_path(), "sounds")
|
return os.path.join(app_path(), "sounds")
|
||||||
|
|
||||||
def com_path():
|
def com_path():
|
||||||
global mode, directory
|
global mode, directory
|
||||||
if mode == "portable":
|
if mode == "portable":
|
||||||
if directory != None: path = os.path.join(directory, "com_cache")
|
if directory != None: path = os.path.join(directory, "com_cache")
|
||||||
elif directory == None: path = os.path.join(app_path(), "com_cache")
|
elif directory == None: path = os.path.join(app_path(), "com_cache")
|
||||||
elif mode == "installed":
|
elif mode == "installed":
|
||||||
path = os.path.join(data_path(), "com_cache")
|
path = os.path.join(data_path(), "com_cache")
|
||||||
if not os.path.exists(path):
|
if not os.path.exists(path):
|
||||||
# log.debug("%s path does not exist, creating..." % (path,))
|
# log.debug("%s path does not exist, creating..." % (path,))
|
||||||
os.mkdir(path)
|
os.mkdir(path)
|
||||||
return path
|
return path
|
||||||
|
@ -1,15 +1,15 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
""" A "presenter" in the socializer's terminology is a module that handles business logic in the application's workflow.
|
""" A "presenter" in the socializer's terminology is a module that handles business logic in the application's workflow.
|
||||||
All presenter classes should derive from base.basePresenter and will be completely abstracted from views (the GUI elements). It means presenters and views don't know anything about the each other.
|
All presenter classes should derive from base.basePresenter and will be completely abstracted from views (the GUI elements). It means presenters and views don't know anything about the each other.
|
||||||
Both Presenters and views can communicate through the interactors. Interactors are responsible to receive user input and send requests to the presenters, aswell as receiving presenter requests and render those in the view.
|
Both Presenters and views can communicate through the interactors. Interactors are responsible to receive user input and send requests to the presenters, aswell as receiving presenter requests and render those in the view.
|
||||||
So, in a tipical user interaction made in socializer, the following could happen when someone decides to do something:
|
So, in a tipical user interaction made in socializer, the following could happen when someone decides to do something:
|
||||||
1. A new presenter is created, with two mandatory arguments: The corresponding view and interactor.
|
1. A new presenter is created, with two mandatory arguments: The corresponding view and interactor.
|
||||||
2. The presenter will call to the install() method in the interactor, to connect all GUI events to their corresponding methods. All of these functions will be present in the interactor only.
|
2. The presenter will call to the install() method in the interactor, to connect all GUI events to their corresponding methods. All of these functions will be present in the interactor only.
|
||||||
3. After install(), the presenter will run the View, which will display the graphical user interface that users can see and interact with. The view is the only layer directly accessible from the user world and does not handle any kind of logic.
|
3. After install(), the presenter will run the View, which will display the graphical user interface that users can see and interact with. The view is the only layer directly accessible from the user world and does not handle any kind of logic.
|
||||||
4. If the user presses a button or generates an event connected to a function in the interactor side, the function will be executed in the interactor. The interactor is aware of the View, and holds a reference to the presenter. The interactor should call other GUI elements if necessary and handle some logic (related to GUI, like yes/no dialogs). The interactor can call the presenter to retrieve some information, though the interactor cannot perform any business logic (like altering the cache database, retrieving usernames and so on).
|
4. If the user presses a button or generates an event connected to a function in the interactor side, the function will be executed in the interactor. The interactor is aware of the View, and holds a reference to the presenter. The interactor should call other GUI elements if necessary and handle some logic (related to GUI, like yes/no dialogs). The interactor can call the presenter to retrieve some information, though the interactor cannot perform any business logic (like altering the cache database, retrieving usernames and so on).
|
||||||
5. If the interactor calls something in the presenter, it will be executed. The presenter knows everything about VK and the session object, so it will fetch data, save it in the cache, call other methods from VK and what not. If the presenter wants to change something in the GUI elements (for example, hiding a control or displaying something else), it will send a pubsub event that the interactor will receive and act on accordingly.
|
5. If the interactor calls something in the presenter, it will be executed. The presenter knows everything about VK and the session object, so it will fetch data, save it in the cache, call other methods from VK and what not. If the presenter wants to change something in the GUI elements (for example, hiding a control or displaying something else), it will send a pubsub event that the interactor will receive and act on accordingly.
|
||||||
|
|
||||||
By using this design pattern it allows more decoupled code, easier testing (as we don't need to instantiate the views) and easy to switch (or add) a new graphical user interface by replacing interactors and views.
|
By using this design pattern it allows more decoupled code, easier testing (as we don't need to instantiate the views) and easy to switch (or add) a new graphical user interface by replacing interactors and views.
|
||||||
"""
|
"""
|
||||||
from . import player
|
from . import player
|
||||||
from .base import *
|
from .base import *
|
||||||
|
@ -1,15 +1,15 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
""" A "presenter" in the socializer's terminology is a module that handles business logic in the application's workflow.
|
""" A "presenter" in the socializer's terminology is a module that handles business logic in the application's workflow.
|
||||||
All presenter classes should derive from base.basePresenter and will be completely abstracted from views (the GUI elements). It means presenters and views don't know anything about the each other.
|
All presenter classes should derive from base.basePresenter and will be completely abstracted from views (the GUI elements). It means presenters and views don't know anything about the each other.
|
||||||
Both Presenters and views can communicate through the interactors. Interactors are responsible to receive user input and send requests to the presenters, aswell as receiving presenter requests and render those in the view.
|
Both Presenters and views can communicate through the interactors. Interactors are responsible to receive user input and send requests to the presenters, aswell as receiving presenter requests and render those in the view.
|
||||||
So, in a tipical user interaction made in socializer, the following could happen when someone decides to do something:
|
So, in a tipical user interaction made in socializer, the following could happen when someone decides to do something:
|
||||||
1. A new presenter is created, with two mandatory arguments: The corresponding view and interactor.
|
1. A new presenter is created, with two mandatory arguments: The corresponding view and interactor.
|
||||||
2. The presenter will call to the install() method in the interactor, to connect all GUI events to their corresponding methods. All of these functions will be present in the interactor only.
|
2. The presenter will call to the install() method in the interactor, to connect all GUI events to their corresponding methods. All of these functions will be present in the interactor only.
|
||||||
3. After install(), the presenter will run the View, which will display the graphical user interface that users can see and interact with. The view is the only layer directly accessible from the user world and does not handle any kind of logic.
|
3. After install(), the presenter will run the View, which will display the graphical user interface that users can see and interact with. The view is the only layer directly accessible from the user world and does not handle any kind of logic.
|
||||||
4. If the user presses a button or generates an event connected to a function in the interactor side, the function will be executed in the interactor. The interactor is aware of the View, and holds a reference to the presenter. The interactor should call other GUI elements if necessary and handle some logic (related to GUI, like yes/no dialogs). The interactor can call the presenter to retrieve some information, though the interactor cannot perform any business logic (like altering the cache database, retrieving usernames and so on).
|
4. If the user presses a button or generates an event connected to a function in the interactor side, the function will be executed in the interactor. The interactor is aware of the View, and holds a reference to the presenter. The interactor should call other GUI elements if necessary and handle some logic (related to GUI, like yes/no dialogs). The interactor can call the presenter to retrieve some information, though the interactor cannot perform any business logic (like altering the cache database, retrieving usernames and so on).
|
||||||
5. If the interactor calls something in the presenter, it will be executed. The presenter knows everything about VK and the session object, so it will fetch data, save it in the cache, call other methods from VK and what not. If the presenter wants to change something in the GUI elements (for example, hiding a control or displaying something else), it will send a pubsub event that the interactor will receive and act on accordingly.
|
5. If the interactor calls something in the presenter, it will be executed. The presenter knows everything about VK and the session object, so it will fetch data, save it in the cache, call other methods from VK and what not. If the presenter wants to change something in the GUI elements (for example, hiding a control or displaying something else), it will send a pubsub event that the interactor will receive and act on accordingly.
|
||||||
|
|
||||||
By using this design pattern it allows more decoupled code, easier testing (as we don't need to instantiate the views) and easy to switch (or add) a new graphical user interface by replacing interactors and views.
|
By using this design pattern it allows more decoupled code, easier testing (as we don't need to instantiate the views) and easy to switch (or add) a new graphical user interface by replacing interactors and views.
|
||||||
"""
|
"""
|
||||||
from .attach import *
|
from .attach import *
|
||||||
from .audioRecorder import *
|
from .audioRecorder import *
|
||||||
|
@ -15,109 +15,109 @@ from . import audioRecorder, base
|
|||||||
log = logging.getLogger(__file__)
|
log = logging.getLogger(__file__)
|
||||||
|
|
||||||
class attachPresenter(base.basePresenter):
|
class attachPresenter(base.basePresenter):
|
||||||
""" Controller used in some sections of the application, it can do the following:
|
""" Controller used in some sections of the application, it can do the following:
|
||||||
|
|
||||||
* Handle all user input related to adding local or online files (online files are those already uploaded in vk).
|
* Handle all user input related to adding local or online files (online files are those already uploaded in vk).
|
||||||
* Prepare local files to be uploaded once a post will be sent (no uploading work is done here, but structured dicts will be generated).
|
* Prepare local files to be uploaded once a post will be sent (no uploading work is done here, but structured dicts will be generated).
|
||||||
* Parse online files and allow addition of them as attachments, so this controller will add both local and online files in the same dialog.
|
* Parse online files and allow addition of them as attachments, so this controller will add both local and online files in the same dialog.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, session, view, interactor, voice_messages=False):
|
def __init__(self, session, view, interactor, voice_messages=False):
|
||||||
""" Constructor.
|
""" Constructor.
|
||||||
@ session sessionmanager.session object: an object capable of calling all VK methods and accessing the session database.
|
@ session sessionmanager.session object: an object capable of calling all VK methods and accessing the session database.
|
||||||
@voice_messages bool: If True, will add a button for sending voice messages.
|
@voice_messages bool: If True, will add a button for sending voice messages.
|
||||||
"""
|
"""
|
||||||
super(attachPresenter, self).__init__(view=view, interactor=interactor, modulename="attach")
|
super(attachPresenter, self).__init__(view=view, interactor=interactor, modulename="attach")
|
||||||
self.session = session
|
self.session = session
|
||||||
# Self.attachments will hold a reference to all attachments added to the dialog.
|
# Self.attachments will hold a reference to all attachments added to the dialog.
|
||||||
self.attachments = list()
|
self.attachments = list()
|
||||||
self.run()
|
self.run()
|
||||||
|
|
||||||
def upload_image(self, image, description):
|
def upload_image(self, image, description):
|
||||||
""" allows uploading an image from the computer. Description will be used when posting to VK.
|
""" allows uploading an image from the computer. Description will be used when posting to VK.
|
||||||
"""
|
"""
|
||||||
imageInfo = {"type": "photo", "file": image, "description": description, "from": "local"}
|
imageInfo = {"type": "photo", "file": image, "description": description, "from": "local"}
|
||||||
self.attachments.append(imageInfo)
|
self.attachments.append(imageInfo)
|
||||||
# Translators: This is the text displayed in the attachments dialog, when the user adds a photo.
|
# Translators: This is the text displayed in the attachments dialog, when the user adds a photo.
|
||||||
info = [_("Photo"), description]
|
info = [_("Photo"), description]
|
||||||
self.send_message("insert_attachment", attachment=info)
|
self.send_message("insert_attachment", attachment=info)
|
||||||
self.send_message("enable_control", control="remove")
|
self.send_message("enable_control", control="remove")
|
||||||
|
|
||||||
def upload_audio(self, audio):
|
def upload_audio(self, audio):
|
||||||
""" Allows uploading an audio file from the computer. Only mp3 files are supported. """
|
""" Allows uploading an audio file from the computer. Only mp3 files are supported. """
|
||||||
if audio != None:
|
if audio != None:
|
||||||
# Define data structure for this attachment, as will be required by VK API later.
|
# Define data structure for this attachment, as will be required by VK API later.
|
||||||
# Let's extract the ID3 tags to show them in the list and send them to VK, too.
|
# Let's extract the ID3 tags to show them in the list and send them to VK, too.
|
||||||
try:
|
try:
|
||||||
audio_tags = ID3(audio)
|
audio_tags = ID3(audio)
|
||||||
if "TIT2" in audio_tags:
|
if "TIT2" in audio_tags:
|
||||||
title = audio_tags["TIT2"].text[0]
|
title = audio_tags["TIT2"].text[0]
|
||||||
else:
|
else:
|
||||||
title = _("Untitled")
|
title = _("Untitled")
|
||||||
if "TPE1" in audio_tags:
|
if "TPE1" in audio_tags:
|
||||||
artist = audio_tags["TPE1"].text[0]
|
artist = audio_tags["TPE1"].text[0]
|
||||||
else:
|
else:
|
||||||
artist = _("Unknown artist")
|
artist = _("Unknown artist")
|
||||||
except ID3NoHeaderError: # File doesn't include ID3 tags so let's assume unknown artist.
|
except ID3NoHeaderError: # File doesn't include ID3 tags so let's assume unknown artist.
|
||||||
artist = _("Unknown artist")
|
artist = _("Unknown artist")
|
||||||
title = os.path.basename(audio).replace(".mp3", "")
|
title = os.path.basename(audio).replace(".mp3", "")
|
||||||
audioInfo = {"type": "audio", "file": audio, "from": "local", "title": title, "artist": artist}
|
audioInfo = {"type": "audio", "file": audio, "from": "local", "title": title, "artist": artist}
|
||||||
self.attachments.append(audioInfo)
|
self.attachments.append(audioInfo)
|
||||||
# Translators: This is the text displayed in the attachments dialog, when the user adds an audio file.
|
# Translators: This is the text displayed in the attachments dialog, when the user adds an audio file.
|
||||||
info = [_("Audio file"), "{title} - {artist}".format(title=title, artist=artist)]
|
info = [_("Audio file"), "{title} - {artist}".format(title=title, artist=artist)]
|
||||||
self.send_message("insert_attachment", attachment=info)
|
self.send_message("insert_attachment", attachment=info)
|
||||||
self.send_message("enable_control", control="remove")
|
self.send_message("enable_control", control="remove")
|
||||||
|
|
||||||
def upload_document(self, document):
|
def upload_document(self, document):
|
||||||
""" allows uploading a document from the computer.
|
""" allows uploading a document from the computer.
|
||||||
"""
|
"""
|
||||||
doc_info = {"type": "document", "file": document, "from": "local", "title": os.path.basename(os.path.splitext(document)[0])}
|
doc_info = {"type": "document", "file": document, "from": "local", "title": os.path.basename(os.path.splitext(document)[0])}
|
||||||
self.attachments.append(doc_info)
|
self.attachments.append(doc_info)
|
||||||
# Translators: This is the text displayed in the attachments dialog, when the user adds a document.
|
# Translators: This is the text displayed in the attachments dialog, when the user adds a document.
|
||||||
info = [_("Document"), os.path.basename(document)]
|
info = [_("Document"), os.path.basename(document)]
|
||||||
self.send_message("insert_attachment", attachment=info)
|
self.send_message("insert_attachment", attachment=info)
|
||||||
self.send_message("enable_control", control="remove")
|
self.send_message("enable_control", control="remove")
|
||||||
|
|
||||||
def upload_voice_message(self):
|
def upload_voice_message(self):
|
||||||
a = audioRecorder.audioRecorderPresenter(view=views.audioRecorderDialog(), interactor=interactors.audioRecorderInteractor())
|
a = audioRecorder.audioRecorderPresenter(view=views.audioRecorderDialog(), interactor=interactors.audioRecorderInteractor())
|
||||||
if a.file != None and a.duration != 0:
|
if a.file != None and a.duration != 0:
|
||||||
audioInfo = {"type": "voice_message", "file": a.file, "from": "local"}
|
audioInfo = {"type": "voice_message", "file": a.file, "from": "local"}
|
||||||
self.attachments.append(audioInfo)
|
self.attachments.append(audioInfo)
|
||||||
# Translators: This is the text displayed in the attachments dialog, when the user adds an audio file.
|
# Translators: This is the text displayed in the attachments dialog, when the user adds an audio file.
|
||||||
info = [_("Voice message"), seconds_to_string(a.duration,)]
|
info = [_("Voice message"), seconds_to_string(a.duration,)]
|
||||||
self.send_message("insert_attachment", attachment=info)
|
self.send_message("insert_attachment", attachment=info)
|
||||||
self.send_message("enable_control", control="remove")
|
self.send_message("enable_control", control="remove")
|
||||||
|
|
||||||
####### ToDo: replace this with selector presenter when finished.
|
####### ToDo: replace this with selector presenter when finished.
|
||||||
def get_available_audios(self):
|
def get_available_audios(self):
|
||||||
# Let's reuse the already downloaded audios.
|
# Let's reuse the already downloaded audios.
|
||||||
list_of_audios = self.session.db["me_audio"]["items"]
|
list_of_audios = self.session.db["me_audio"]["items"]
|
||||||
audios = []
|
audios = []
|
||||||
for i in list_of_audios:
|
for i in list_of_audios:
|
||||||
audios.append("{0}, {1}".format(i["title"], i["artist"]))
|
audios.append("{0}, {1}".format(i["title"], i["artist"]))
|
||||||
return audios
|
return audios
|
||||||
|
|
||||||
def take_audios(self, audios_list):
|
def take_audios(self, audios_list):
|
||||||
list_of_audios = self.session.db["me_audio"]["items"]
|
list_of_audios = self.session.db["me_audio"]["items"]
|
||||||
for i in audios_list:
|
for i in audios_list:
|
||||||
info = dict(type="audio", id=list_of_audios[i]["id"], owner_id=list_of_audios[i]["owner_id"])
|
info = dict(type="audio", id=list_of_audios[i]["id"], owner_id=list_of_audios[i]["owner_id"])
|
||||||
info["from"] = "online"
|
info["from"] = "online"
|
||||||
self.attachments.append(info)
|
self.attachments.append(info)
|
||||||
# Translators: This is the text displayed in the attachments dialog, when the user adds an audio file.
|
# Translators: This is the text displayed in the attachments dialog, when the user adds an audio file.
|
||||||
info2 = [_("Audio file"), "{0} - {1}".format(list_of_audios[i]["title"], list_of_audios[i]["artist"])]
|
info2 = [_("Audio file"), "{0} - {1}".format(list_of_audios[i]["title"], list_of_audios[i]["artist"])]
|
||||||
self.send_message("insert_attachment", attachment=info2)
|
self.send_message("insert_attachment", attachment=info2)
|
||||||
self.check_remove_status()
|
self.check_remove_status()
|
||||||
|
|
||||||
def remove_attachment(self, item_index):
|
def remove_attachment(self, item_index):
|
||||||
""" Remove the currently focused item from the attachments list."""
|
""" Remove the currently focused item from the attachments list."""
|
||||||
log.debug("Removing item %d" % (item_index,))
|
log.debug("Removing item %d" % (item_index,))
|
||||||
if item_index == -1: item_index = 0
|
if item_index == -1: item_index = 0
|
||||||
self.attachments.pop(item_index)
|
self.attachments.pop(item_index)
|
||||||
self.send_message("remove_attachment", attachment=item_index)
|
self.send_message("remove_attachment", attachment=item_index)
|
||||||
self.check_remove_status()
|
self.check_remove_status()
|
||||||
log.debug("Removed")
|
log.debug("Removed")
|
||||||
|
|
||||||
def check_remove_status(self):
|
def check_remove_status(self):
|
||||||
""" Checks whether the remove button should remain enabled."""
|
""" Checks whether the remove button should remain enabled."""
|
||||||
if len(self.attachments) == 0:
|
if len(self.attachments) == 0:
|
||||||
self.send_message("disable_control", control="remove")
|
self.send_message("disable_control", control="remove")
|
||||||
|
@ -10,102 +10,102 @@ from mysc.thread_utils import call_threaded
|
|||||||
from . import base
|
from . import base
|
||||||
|
|
||||||
class audioRecorderPresenter(base.basePresenter):
|
class audioRecorderPresenter(base.basePresenter):
|
||||||
def __init__(self, view, interactor):
|
def __init__(self, view, interactor):
|
||||||
super(audioRecorderPresenter, self).__init__(view=view, interactor=interactor, modulename="audiorecorder")
|
super(audioRecorderPresenter, self).__init__(view=view, interactor=interactor, modulename="audiorecorder")
|
||||||
self.recorded = False
|
self.recorded = False
|
||||||
self.recording = None
|
self.recording = None
|
||||||
self.duration = 0
|
self.duration = 0
|
||||||
self.playing = None
|
self.playing = None
|
||||||
self.file = None
|
self.file = None
|
||||||
self.run()
|
self.run()
|
||||||
|
|
||||||
def toggle_recording(self, *args, **kwargs):
|
def toggle_recording(self, *args, **kwargs):
|
||||||
if self.recording != None:
|
if self.recording != None:
|
||||||
self.stop_recording()
|
self.stop_recording()
|
||||||
else:
|
else:
|
||||||
self.start_recording()
|
self.start_recording()
|
||||||
|
|
||||||
def start_recording(self):
|
def start_recording(self):
|
||||||
self.file = tempfile.mktemp(suffix='.wav')
|
self.file = tempfile.mktemp(suffix='.wav')
|
||||||
self.recording = sound.get_recording(self.file)
|
self.recording = sound.get_recording(self.file)
|
||||||
self.duration = time.time()
|
self.duration = time.time()
|
||||||
self.recording.play()
|
self.recording.play()
|
||||||
self.send_message("set_label", control="record", label=_("&Stop"))
|
self.send_message("set_label", control="record", label=_("&Stop"))
|
||||||
output.speak(_("Recording"))
|
output.speak(_("Recording"))
|
||||||
self.send_message("disable_control", control="ok")
|
self.send_message("disable_control", control="ok")
|
||||||
|
|
||||||
def stop_recording(self):
|
def stop_recording(self):
|
||||||
self.recording.stop()
|
self.recording.stop()
|
||||||
self.duration = int(time.time()-self.duration)
|
self.duration = int(time.time()-self.duration)
|
||||||
self.recording.free()
|
self.recording.free()
|
||||||
output.speak(_("Stopped"))
|
output.speak(_("Stopped"))
|
||||||
self.recorded = True
|
self.recorded = True
|
||||||
self.send_message("set_label", control="record", label=_("&Record"))
|
self.send_message("set_label", control="record", label=_("&Record"))
|
||||||
self.send_message("disable_control", control="record")
|
self.send_message("disable_control", control="record")
|
||||||
self.send_message("enable_control", control="play")
|
self.send_message("enable_control", control="play")
|
||||||
self.send_message("enable_control", control="discard")
|
self.send_message("enable_control", control="discard")
|
||||||
self.send_message("enable_control", control="ok")
|
self.send_message("enable_control", control="ok")
|
||||||
self.send_message("focus_control", control="play")
|
self.send_message("focus_control", control="play")
|
||||||
|
|
||||||
def discard_recording(self, *args, **kwargs):
|
def discard_recording(self, *args, **kwargs):
|
||||||
if self.playing:
|
if self.playing:
|
||||||
self._stop()
|
self._stop()
|
||||||
if self.recording != None:
|
if self.recording != None:
|
||||||
self.cleanup()
|
self.cleanup()
|
||||||
self.send_message("disable_control", control="play")
|
self.send_message("disable_control", control="play")
|
||||||
self.send_message("disable_control", control="ok")
|
self.send_message("disable_control", control="ok")
|
||||||
self.file = None
|
self.file = None
|
||||||
self.send_message("enable_control", control="record")
|
self.send_message("enable_control", control="record")
|
||||||
self.send_message("focus_control", control="record")
|
self.send_message("focus_control", control="record")
|
||||||
self.send_message("disable_control", control="discard")
|
self.send_message("disable_control", control="discard")
|
||||||
self.recording = None
|
self.recording = None
|
||||||
output.speak(_("Discarded"))
|
output.speak(_("Discarded"))
|
||||||
|
|
||||||
def play(self, *args, **kwargs):
|
def play(self, *args, **kwargs):
|
||||||
if not self.playing:
|
if not self.playing:
|
||||||
call_threaded(self._play)
|
call_threaded(self._play)
|
||||||
else:
|
else:
|
||||||
self._stop()
|
self._stop()
|
||||||
|
|
||||||
def _play(self):
|
def _play(self):
|
||||||
output.speak(_("Playing..."))
|
output.speak(_("Playing..."))
|
||||||
# try:
|
# try:
|
||||||
self.playing = sound_lib.stream.FileStream(file=str(self.file), flags=sound_lib.stream.BASS_UNICODE)
|
self.playing = sound_lib.stream.FileStream(file=str(self.file), flags=sound_lib.stream.BASS_UNICODE)
|
||||||
self.playing.play()
|
self.playing.play()
|
||||||
self.send_message("set_label", control="play", label=_("&Stop"))
|
self.send_message("set_label", control="play", label=_("&Stop"))
|
||||||
try:
|
try:
|
||||||
while self.playing.is_playing:
|
while self.playing.is_playing:
|
||||||
pass
|
pass
|
||||||
self.send_message("set_label", control="play", label=_("&Play"))
|
self.send_message("set_label", control="play", label=_("&Play"))
|
||||||
self.playing.free()
|
self.playing.free()
|
||||||
self.playing = None
|
self.playing = None
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def _stop(self):
|
def _stop(self):
|
||||||
output.speak(_("Stopped"))
|
output.speak(_("Stopped"))
|
||||||
self.playing.stop()
|
self.playing.stop()
|
||||||
self.playing.free()
|
self.playing.free()
|
||||||
self.send_message("set_label", control="play", label=_("&Play"))
|
self.send_message("set_label", control="play", label=_("&Play"))
|
||||||
self.playing = None
|
self.playing = None
|
||||||
|
|
||||||
def postprocess(self):
|
def postprocess(self):
|
||||||
if self.file.lower().endswith('.wav'):
|
if self.file.lower().endswith('.wav'):
|
||||||
output.speak(_("Recoding audio..."))
|
output.speak(_("Recoding audio..."))
|
||||||
sound.recode_audio(self.file)
|
sound.recode_audio(self.file)
|
||||||
self.wav_file = self.file
|
self.wav_file = self.file
|
||||||
self.file = '%s.ogg' % self.file[:-4]
|
self.file = '%s.ogg' % self.file[:-4]
|
||||||
self.cleanup()
|
self.cleanup()
|
||||||
|
|
||||||
def cleanup(self):
|
def cleanup(self):
|
||||||
if self.playing and self.playing.is_playing:
|
if self.playing and self.playing.is_playing:
|
||||||
self.playing.stop()
|
self.playing.stop()
|
||||||
if self.recording != None:
|
if self.recording != None:
|
||||||
if self.recording.is_playing:
|
if self.recording.is_playing:
|
||||||
self.recording.stop()
|
self.recording.stop()
|
||||||
try:
|
try:
|
||||||
self.recording.free()
|
self.recording.free()
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
if hasattr(self, 'wav_file'):
|
if hasattr(self, 'wav_file'):
|
||||||
os.remove(self.wav_file)
|
os.remove(self.wav_file)
|
||||||
|
@ -5,15 +5,15 @@ from interactors import configuration as interactor
|
|||||||
|
|
||||||
class basePresenter(object):
|
class basePresenter(object):
|
||||||
|
|
||||||
def __init__(self, view, interactor, modulename):
|
def __init__(self, view, interactor, modulename):
|
||||||
self.modulename = modulename
|
self.modulename = modulename
|
||||||
self.interactor = interactor
|
self.interactor = interactor
|
||||||
self.view = view
|
self.view = view
|
||||||
self.interactor.install(view=view, presenter=self, modulename=modulename)
|
self.interactor.install(view=view, presenter=self, modulename=modulename)
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
self.interactor.start()
|
self.interactor.start()
|
||||||
self.interactor.uninstall()
|
self.interactor.uninstall()
|
||||||
|
|
||||||
def send_message(self, msg, *args, **kwargs):
|
def send_message(self, msg, *args, **kwargs):
|
||||||
pub.sendMessage(self.modulename+"_"+msg, *args, **kwargs)
|
pub.sendMessage(self.modulename+"_"+msg, *args, **kwargs)
|
||||||
|
@ -5,26 +5,26 @@ from . import base
|
|||||||
|
|
||||||
class blacklistPresenter(base.basePresenter):
|
class blacklistPresenter(base.basePresenter):
|
||||||
|
|
||||||
def __init__(self, session, view, interactor):
|
def __init__(self, session, view, interactor):
|
||||||
self.session = session
|
self.session = session
|
||||||
super(blacklistPresenter, self).__init__(view=view, interactor=interactor, modulename="blacklist")
|
super(blacklistPresenter, self).__init__(view=view, interactor=interactor, modulename="blacklist")
|
||||||
self.worker = threading.Thread(target=self.load_information)
|
self.worker = threading.Thread(target=self.load_information)
|
||||||
self.worker.finished = threading.Event()
|
self.worker.finished = threading.Event()
|
||||||
self.worker.start()
|
self.worker.start()
|
||||||
self.run()
|
self.run()
|
||||||
|
|
||||||
def load_information(self):
|
def load_information(self):
|
||||||
banned_users = self.session.vk.client.account.getBanned(count=200)
|
banned_users = self.session.vk.client.account.getBanned(count=200)
|
||||||
self.users = banned_users["profiles"]
|
self.users = banned_users["profiles"]
|
||||||
items = []
|
items = []
|
||||||
for i in self.users:
|
for i in self.users:
|
||||||
str_user = "{first_name} {last_name}".format(first_name=i["first_name"], last_name=i["last_name"])
|
str_user = "{first_name} {last_name}".format(first_name=i["first_name"], last_name=i["last_name"])
|
||||||
items.append([str_user])
|
items.append([str_user])
|
||||||
self.send_message("add_items", control="persons", items=items)
|
self.send_message("add_items", control="persons", items=items)
|
||||||
|
|
||||||
def unblock_person(self, item):
|
def unblock_person(self, item):
|
||||||
result = self.session.vk.client.account.unban(owner_id=self.users[item]["id"])
|
result = self.session.vk.client.account.unban(owner_id=self.users[item]["id"])
|
||||||
if result == 1:
|
if result == 1:
|
||||||
msg = _("You've unblocked {user1_nom} from your friends.").format(**self.session.get_user(self.users[item]["id"]),)
|
msg = _("You've unblocked {user1_nom} from your friends.").format(**self.session.get_user(self.users[item]["id"]),)
|
||||||
pub.sendMessage("notify", message=msg)
|
pub.sendMessage("notify", message=msg)
|
||||||
return result
|
return result
|
||||||
|
@ -8,97 +8,97 @@ from . import base
|
|||||||
|
|
||||||
class configurationPresenter(base.basePresenter):
|
class configurationPresenter(base.basePresenter):
|
||||||
|
|
||||||
def __init__(self, session, view, interactor):
|
def __init__(self, session, view, interactor):
|
||||||
self.session = session
|
self.session = session
|
||||||
super(configurationPresenter, self).__init__(view=view, interactor=interactor, modulename="configuration")
|
super(configurationPresenter, self).__init__(view=view, interactor=interactor, modulename="configuration")
|
||||||
# Control requirement for a restart of the application.
|
# Control requirement for a restart of the application.
|
||||||
self.needs_restart = False
|
self.needs_restart = False
|
||||||
self.create_config()
|
self.create_config()
|
||||||
self.run()
|
self.run()
|
||||||
|
|
||||||
def get_notification_label(self, value):
|
def get_notification_label(self, value):
|
||||||
if value == "native":
|
if value == "native":
|
||||||
return _("Native")
|
return _("Native")
|
||||||
else:
|
else:
|
||||||
return _("Custom")
|
return _("Custom")
|
||||||
|
|
||||||
def get_update_channel_label(self, value):
|
def get_update_channel_label(self, value):
|
||||||
if value == "stable":
|
if value == "stable":
|
||||||
return _("Stable")
|
return _("Stable")
|
||||||
elif value == "weekly":
|
elif value == "weekly":
|
||||||
return _("Weekly")
|
return _("Weekly")
|
||||||
else:
|
else:
|
||||||
return _("Alpha")
|
return _("Alpha")
|
||||||
|
|
||||||
def get_notification_type(self, value):
|
def get_notification_type(self, value):
|
||||||
if value == _("Native"):
|
if value == _("Native"):
|
||||||
return "native"
|
return "native"
|
||||||
else:
|
else:
|
||||||
return "custom"
|
return "custom"
|
||||||
|
|
||||||
def get_update_channel_type(self, value):
|
def get_update_channel_type(self, value):
|
||||||
if value == _("Stable"):
|
if value == _("Stable"):
|
||||||
return "stable"
|
return "stable"
|
||||||
elif value == _("Weekly"):
|
elif value == _("Weekly"):
|
||||||
return "weekly"
|
return "weekly"
|
||||||
else:
|
else:
|
||||||
return "alpha"
|
return "alpha"
|
||||||
|
|
||||||
def create_config(self):
|
def create_config(self):
|
||||||
self.langs = languageHandler.getAvailableLanguages()
|
self.langs = languageHandler.getAvailableLanguages()
|
||||||
langs = [i[1] for i in self.langs]
|
langs = [i[1] for i in self.langs]
|
||||||
self.codes = [i[0] for i in self.langs]
|
self.codes = [i[0] for i in self.langs]
|
||||||
id = self.codes.index(config.app["app-settings"]["language"])
|
id = self.codes.index(config.app["app-settings"]["language"])
|
||||||
self.send_message("create_tab", tab="general", arglist=dict(languages=langs))
|
self.send_message("create_tab", tab="general", arglist=dict(languages=langs))
|
||||||
self.send_message("set_language", language=id)
|
self.send_message("set_language", language=id)
|
||||||
self.send_message("set", tab="general", setting="load_images", value=self.session.settings["general"]["load_images"])
|
self.send_message("set", tab="general", setting="load_images", value=self.session.settings["general"]["load_images"])
|
||||||
self.send_message("set", tab="general", setting="use_proxy", value=config.app["app-settings"]["use_proxy"])
|
self.send_message("set", tab="general", setting="use_proxy", value=config.app["app-settings"]["use_proxy"])
|
||||||
self.send_message("set", tab="general", setting="debug_logging", value=config.app["app-settings"]["debug_logging"])
|
self.send_message("set", tab="general", setting="debug_logging", value=config.app["app-settings"]["debug_logging"])
|
||||||
self.send_message("set", tab="general", setting="update_channel", value=self.get_update_channel_label(self.session.settings["general"]["update_channel"]))
|
self.send_message("set", tab="general", setting="update_channel", value=self.get_update_channel_label(self.session.settings["general"]["update_channel"]))
|
||||||
self.send_message("create_tab", tab="buffers")
|
self.send_message("create_tab", tab="buffers")
|
||||||
self.send_message("set", tab="buffers", setting="wall_buffer_count", value=self.session.settings["buffers"]["count_for_wall_buffers"])
|
self.send_message("set", tab="buffers", setting="wall_buffer_count", value=self.session.settings["buffers"]["count_for_wall_buffers"])
|
||||||
self.send_message("set", tab="buffers", setting="video_buffers_count", value=self.session.settings["buffers"]["count_for_video_buffers"])
|
self.send_message("set", tab="buffers", setting="video_buffers_count", value=self.session.settings["buffers"]["count_for_video_buffers"])
|
||||||
self.send_message("set", tab="buffers", setting="chat_buffers_count", value=self.session.settings["buffers"]["count_for_chat_buffers"])
|
self.send_message("set", tab="buffers", setting="chat_buffers_count", value=self.session.settings["buffers"]["count_for_chat_buffers"])
|
||||||
self.send_message("create_tab", tab="chat")
|
self.send_message("create_tab", tab="chat")
|
||||||
self.send_message("set", tab="chat", setting="notify_online", value=self.session.settings["chat"]["notify_online"])
|
self.send_message("set", tab="chat", setting="notify_online", value=self.session.settings["chat"]["notify_online"])
|
||||||
self.send_message("set", tab="chat", setting="notify_offline", value=self.session.settings["chat"]["notify_offline"])
|
self.send_message("set", tab="chat", setting="notify_offline", value=self.session.settings["chat"]["notify_offline"])
|
||||||
self.send_message("set", tab="chat", setting="notifications", value=self.get_notification_label(self.session.settings["chat"]["notifications"]))
|
self.send_message("set", tab="chat", setting="notifications", value=self.get_notification_label(self.session.settings["chat"]["notifications"]))
|
||||||
self.send_message("create_tab", tab="startup_options")
|
self.send_message("create_tab", tab="startup_options")
|
||||||
self.send_message("set", tab="startup", setting="audio_albums", value=self.session.settings["load_at_startup"]["audio_albums"])
|
self.send_message("set", tab="startup", setting="audio_albums", value=self.session.settings["load_at_startup"]["audio_albums"])
|
||||||
self.send_message("set", tab="startup", setting="video_albums", value=self.session.settings["load_at_startup"]["video_albums"])
|
self.send_message("set", tab="startup", setting="video_albums", value=self.session.settings["load_at_startup"]["video_albums"])
|
||||||
self.send_message("set", tab="startup", setting="communities", value=self.session.settings["load_at_startup"]["communities"])
|
self.send_message("set", tab="startup", setting="communities", value=self.session.settings["load_at_startup"]["communities"])
|
||||||
self.input_devices = sound_lib.input.Input.get_device_names()
|
self.input_devices = sound_lib.input.Input.get_device_names()
|
||||||
self.output_devices = sound_lib.output.Output.get_device_names()
|
self.output_devices = sound_lib.output.Output.get_device_names()
|
||||||
self.send_message("create_tab", tab="sound", arglist=dict(input_devices=self.input_devices, output_devices=self.output_devices, soundpacks=[]))
|
self.send_message("create_tab", tab="sound", arglist=dict(input_devices=self.input_devices, output_devices=self.output_devices, soundpacks=[]))
|
||||||
self.send_message("set", tab="sound", setting="input", value=config.app["sound"]["input_device"])
|
self.send_message("set", tab="sound", setting="input", value=config.app["sound"]["input_device"])
|
||||||
self.send_message("set", tab="sound", setting="output", value=config.app["sound"]["output_device"])
|
self.send_message("set", tab="sound", setting="output", value=config.app["sound"]["output_device"])
|
||||||
|
|
||||||
def update_setting(self, section, setting, value):
|
def update_setting(self, section, setting, value):
|
||||||
if section not in self.session.settings:
|
if section not in self.session.settings:
|
||||||
raise AttributeError("The configuration section is not present in the spec file.")
|
raise AttributeError("The configuration section is not present in the spec file.")
|
||||||
if setting not in self.session.settings[section]:
|
if setting not in self.session.settings[section]:
|
||||||
raise AttributeError("The setting you specified is not present in the config file.")
|
raise AttributeError("The setting you specified is not present in the config file.")
|
||||||
self.session.settings[section][setting] = value
|
self.session.settings[section][setting] = value
|
||||||
|
|
||||||
def save_settings_file(self):
|
def save_settings_file(self):
|
||||||
self.session.settings.write()
|
self.session.settings.write()
|
||||||
|
|
||||||
def update_app_setting(self, section, setting, value):
|
def update_app_setting(self, section, setting, value):
|
||||||
if section not in config.app:
|
if section not in config.app:
|
||||||
raise AttributeError("The configuration section is not present in the spec file.")
|
raise AttributeError("The configuration section is not present in the spec file.")
|
||||||
if setting not in config.app[section]:
|
if setting not in config.app[section]:
|
||||||
raise AttributeError("The setting you specified is not present in the config file.")
|
raise AttributeError("The setting you specified is not present in the config file.")
|
||||||
# check if certain settings have been changed so we'd restart the client.
|
# check if certain settings have been changed so we'd restart the client.
|
||||||
# List of app settings that require a restart after being changed.
|
# List of app settings that require a restart after being changed.
|
||||||
settings_needing_restart = ["language", "use_proxy", "input_device", "output_device", "debug_logging"]
|
settings_needing_restart = ["language", "use_proxy", "input_device", "output_device", "debug_logging"]
|
||||||
if value != config.app[section][setting] and setting in settings_needing_restart:
|
if value != config.app[section][setting] and setting in settings_needing_restart:
|
||||||
self.needs_restart = True
|
self.needs_restart = True
|
||||||
config.app[section][setting] = value
|
config.app[section][setting] = value
|
||||||
|
|
||||||
def save_app_settings_file(self):
|
def save_app_settings_file(self):
|
||||||
config.app.write()
|
config.app.write()
|
||||||
if self.needs_restart:
|
if self.needs_restart:
|
||||||
self.send_message("restart_program")
|
self.send_message("restart_program")
|
||||||
|
|
||||||
def restart_application(self):
|
def restart_application(self):
|
||||||
restart.restart_program()
|
restart.restart_program()
|
||||||
|
@ -14,45 +14,45 @@ log = getLogger("controller.message")
|
|||||||
|
|
||||||
class createPostPresenter(base.basePresenter):
|
class createPostPresenter(base.basePresenter):
|
||||||
|
|
||||||
def __init__(self, session, view, interactor):
|
def __init__(self, session, view, interactor):
|
||||||
super(createPostPresenter, self).__init__(view=view, interactor=interactor, modulename="create_post")
|
super(createPostPresenter, self).__init__(view=view, interactor=interactor, modulename="create_post")
|
||||||
self.session = session
|
self.session = session
|
||||||
self.images = []
|
self.images = []
|
||||||
self.tagged_people = []
|
self.tagged_people = []
|
||||||
self.run()
|
self.run()
|
||||||
|
|
||||||
def get_friends(self):
|
def get_friends(self):
|
||||||
try:
|
try:
|
||||||
fields = "id, first_name, last_name"
|
fields = "id, first_name, last_name"
|
||||||
self.friends = self.session.vk.client.friends.get(count=5000, fields=fields)
|
self.friends = self.session.vk.client.friends.get(count=5000, fields=fields)
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
time.sleep(2)
|
time.sleep(2)
|
||||||
log.exception("Error retrieving friends...")
|
log.exception("Error retrieving friends...")
|
||||||
return []
|
return []
|
||||||
self.users = []
|
self.users = []
|
||||||
for i in self.friends["items"]:
|
for i in self.friends["items"]:
|
||||||
self.users.append("{0} {1}".format(i["first_name"], i["last_name"]))
|
self.users.append("{0} {1}".format(i["first_name"], i["last_name"]))
|
||||||
return self.users
|
return self.users
|
||||||
|
|
||||||
def add_tagged_users(self, tagged_users):
|
def add_tagged_users(self, tagged_users):
|
||||||
self.tagged_people = []
|
self.tagged_people = []
|
||||||
for i in tagged_users:
|
for i in tagged_users:
|
||||||
self.tagged_people.append("[id%s|%s]" % (str(self.friends["items"][i]["id"]), self.friends["items"][i]["first_name"]))
|
self.tagged_people.append("[id%s|%s]" % (str(self.friends["items"][i]["id"]), self.friends["items"][i]["first_name"]))
|
||||||
self.send_message("add_tagged_users", users=self.tagged_people)
|
self.send_message("add_tagged_users", users=self.tagged_people)
|
||||||
|
|
||||||
def translate(self, text, language):
|
def translate(self, text, language):
|
||||||
msg = translator.translator.translate(text, language)
|
msg = translator.translator.translate(text, language)
|
||||||
self.send_message("set", control="text", value=msg)
|
self.send_message("set", control="text", value=msg)
|
||||||
self.send_message("focus_control", control="text")
|
self.send_message("focus_control", control="text")
|
||||||
output.speak(_("Translated"))
|
output.speak(_("Translated"))
|
||||||
|
|
||||||
def spellcheck(self, text):
|
def spellcheck(self, text):
|
||||||
checker = SpellChecker.spellchecker.spellChecker(text)
|
checker = SpellChecker.spellchecker.spellChecker(text)
|
||||||
if hasattr(checker, "fixed_text"):
|
if hasattr(checker, "fixed_text"):
|
||||||
self.send_message("set", control="text", value=checker.fixed_text)
|
self.send_message("set", control="text", value=checker.fixed_text)
|
||||||
self.send_message("focus_control", control="text")
|
self.send_message("focus_control", control="text")
|
||||||
|
|
||||||
def add_attachments(self):
|
def add_attachments(self):
|
||||||
a = attach.attachPresenter(session=self.session, view=views.attachDialog(), interactor=interactors.attachInteractor())
|
a = attach.attachPresenter(session=self.session, view=views.attachDialog(), interactor=interactors.attachInteractor())
|
||||||
if len(a.attachments) != 0:
|
if len(a.attachments) != 0:
|
||||||
self.attachments = a.attachments
|
self.attachments = a.attachments
|
||||||
|
@ -10,38 +10,38 @@ from presenters import base
|
|||||||
log = logging.getLogger(__file__)
|
log = logging.getLogger(__file__)
|
||||||
|
|
||||||
class displayArticlePresenter(base.basePresenter):
|
class displayArticlePresenter(base.basePresenter):
|
||||||
def __init__(self, session, postObject, view, interactor):
|
def __init__(self, session, postObject, view, interactor):
|
||||||
super(displayArticlePresenter, self).__init__(view=view, interactor=interactor, modulename="display_article")
|
super(displayArticlePresenter, self).__init__(view=view, interactor=interactor, modulename="display_article")
|
||||||
self.session = session
|
self.session = session
|
||||||
self.post = postObject
|
self.post = postObject
|
||||||
self.load_article()
|
self.load_article()
|
||||||
self.run()
|
self.run()
|
||||||
|
|
||||||
def load_article(self):
|
def load_article(self):
|
||||||
""" Loads the article in the interactor.
|
""" Loads the article in the interactor.
|
||||||
This function retrieves, by using the params defined in the VK API, the web version of the article and extracts some info from it.
|
This function retrieves, by using the params defined in the VK API, the web version of the article and extracts some info from it.
|
||||||
this is needed because there are no public API for articles so far.
|
this is needed because there are no public API for articles so far.
|
||||||
"""
|
"""
|
||||||
article = self.post[0]
|
article = self.post[0]
|
||||||
# By using the vk_api's session, proxy settings are applied, thus might work in blocked countries.
|
# By using the vk_api's session, proxy settings are applied, thus might work in blocked countries.
|
||||||
article_body = self.session.vk.session_object.http.get(article["view_url"])
|
article_body = self.session.vk.session_object.http.get(article["view_url"])
|
||||||
# Parse and extract text from all paragraphs.
|
# Parse and extract text from all paragraphs.
|
||||||
# ToDo: Extract all links and set those as attachments.
|
# ToDo: Extract all links and set those as attachments.
|
||||||
soup = BeautifulSoup(article_body.text, "lxml")
|
soup = BeautifulSoup(article_body.text, "lxml")
|
||||||
# ToDo: Article extraction require testing to see if you can add more tags beside paragraphs.
|
# ToDo: Article extraction require testing to see if you can add more tags beside paragraphs.
|
||||||
msg = [p.get_text() for p in soup.find_all("p")]
|
msg = [p.get_text() for p in soup.find_all("p")]
|
||||||
msg = "\n\n".join(msg)
|
msg = "\n\n".join(msg)
|
||||||
self.send_message("set", control="article_view", value=msg)
|
self.send_message("set", control="article_view", value=msg)
|
||||||
self.send_message("set_title", value=article["title"])
|
self.send_message("set_title", value=article["title"])
|
||||||
# Retrieve views count
|
# Retrieve views count
|
||||||
views = soup.find("div", class_="articleView__views_info")
|
views = soup.find("div", class_="articleView__views_info")
|
||||||
# This might return None if VK changes anything, so let's avoid errors.
|
# This might return None if VK changes anything, so let's avoid errors.
|
||||||
if views == None:
|
if views == None:
|
||||||
views = str(-1)
|
views = str(-1)
|
||||||
else:
|
else:
|
||||||
views = views.text
|
views = views.text
|
||||||
# Find the integer and remove the words from the string.
|
# Find the integer and remove the words from the string.
|
||||||
numbers = re.findall(r'\d+', views)
|
numbers = re.findall(r'\d+', views)
|
||||||
if len(numbers) != 0:
|
if len(numbers) != 0:
|
||||||
views = numbers[0]
|
views = numbers[0]
|
||||||
self.send_message("set", control="views", value=views)
|
self.send_message("set", control="views", value=views)
|
||||||
|
@ -8,93 +8,93 @@ from presenters import base, player
|
|||||||
log = logging.getLogger(__file__)
|
log = logging.getLogger(__file__)
|
||||||
|
|
||||||
class displayAudioPresenter(base.basePresenter):
|
class displayAudioPresenter(base.basePresenter):
|
||||||
def __init__(self, session, postObject, view, interactor):
|
def __init__(self, session, postObject, view, interactor):
|
||||||
super(displayAudioPresenter, self).__init__(view=view, interactor=interactor, modulename="display_audio")
|
super(displayAudioPresenter, self).__init__(view=view, interactor=interactor, modulename="display_audio")
|
||||||
self.added_audios = {}
|
self.added_audios = {}
|
||||||
self.session = session
|
self.session = session
|
||||||
self.post = postObject
|
self.post = postObject
|
||||||
self.load_audios()
|
self.load_audios()
|
||||||
self.fill_information(0)
|
self.fill_information(0)
|
||||||
self.run()
|
self.run()
|
||||||
|
|
||||||
def add_to_library(self, audio_index):
|
def add_to_library(self, audio_index):
|
||||||
post = self.post[audio_index]
|
post = self.post[audio_index]
|
||||||
args = {}
|
args = {}
|
||||||
args["audio_id"] = post["id"]
|
args["audio_id"] = post["id"]
|
||||||
if "album_id" in post:
|
if "album_id" in post:
|
||||||
args["album_id"] = post["album_id"]
|
args["album_id"] = post["album_id"]
|
||||||
args["owner_id"] = post["owner_id"]
|
args["owner_id"] = post["owner_id"]
|
||||||
audio = self.session.vk.client.audio.add(**args)
|
audio = self.session.vk.client.audio.add(**args)
|
||||||
if audio != None and int(audio) > 21:
|
if audio != None and int(audio) > 21:
|
||||||
self.added_audios[post["id"]] = audio
|
self.added_audios[post["id"]] = audio
|
||||||
self.send_message("disable_control", control="add")
|
self.send_message("disable_control", control="add")
|
||||||
self.send_message("enable_control", control="remove")
|
self.send_message("enable_control", control="remove")
|
||||||
|
|
||||||
def remove_from_library(self, audio_index):
|
def remove_from_library(self, audio_index):
|
||||||
post = self.post[audio_index]
|
post = self.post[audio_index]
|
||||||
args = {}
|
args = {}
|
||||||
if post["id"] in self.added_audios:
|
if post["id"] in self.added_audios:
|
||||||
args["audio_id"] = self.added_audios[post["id"]]
|
args["audio_id"] = self.added_audios[post["id"]]
|
||||||
args["owner_id"] = self.session.user_id
|
args["owner_id"] = self.session.user_id
|
||||||
else:
|
else:
|
||||||
args["audio_id"] = post["id"]
|
args["audio_id"] = post["id"]
|
||||||
args["owner_id"] = post["owner_id"]
|
args["owner_id"] = post["owner_id"]
|
||||||
result = self.session.vk.client.audio.delete(**args)
|
result = self.session.vk.client.audio.delete(**args)
|
||||||
if int(result) == 1:
|
if int(result) == 1:
|
||||||
self.send_message("enable_control", control="add")
|
self.send_message("enable_control", control="add")
|
||||||
self.send_message("disable_control", control="remove")
|
self.send_message("disable_control", control="remove")
|
||||||
if post["id"] in self.added_audios:
|
if post["id"] in self.added_audios:
|
||||||
self.added_audios.pop(post["id"])
|
self.added_audios.pop(post["id"])
|
||||||
|
|
||||||
def fill_information(self, index):
|
def fill_information(self, index):
|
||||||
post = self.post[index]
|
post = self.post[index]
|
||||||
if "artist" in post:
|
if "artist" in post:
|
||||||
self.send_message("set", control="artist", value=post["artist"])
|
self.send_message("set", control="artist", value=post["artist"])
|
||||||
if "title" in post:
|
if "title" in post:
|
||||||
self.send_message("set", control="title", value=post["title"])
|
self.send_message("set", control="title", value=post["title"])
|
||||||
if "duration" in post:
|
if "duration" in post:
|
||||||
self.send_message("set", control="duration", value=utils.seconds_to_string(post["duration"]))
|
self.send_message("set", control="duration", value=utils.seconds_to_string(post["duration"]))
|
||||||
self.send_message("set_title", value="{0} - {1}".format(post["title"], post["artist"]))
|
self.send_message("set_title", value="{0} - {1}".format(post["title"], post["artist"]))
|
||||||
call_threaded(self.get_lyrics, index)
|
call_threaded(self.get_lyrics, index)
|
||||||
if post["owner_id"] == self.session.user_id or (post["id"] in self.added_audios) == True:
|
if post["owner_id"] == self.session.user_id or (post["id"] in self.added_audios) == True:
|
||||||
self.send_message("enable_control", control="remove")
|
self.send_message("enable_control", control="remove")
|
||||||
self.send_message("disable_control", control="add")
|
self.send_message("disable_control", control="add")
|
||||||
else:
|
else:
|
||||||
self.send_message("enable_control", control="add")
|
self.send_message("enable_control", control="add")
|
||||||
self.send_message("disable_control", control="remove")
|
self.send_message("disable_control", control="remove")
|
||||||
|
|
||||||
def get_lyrics(self, audio_index):
|
def get_lyrics(self, audio_index):
|
||||||
post = self.post[audio_index]
|
post = self.post[audio_index]
|
||||||
if "lyrics_id" in post:
|
if "lyrics_id" in post:
|
||||||
l = self.session.vk.client.audio.getLyrics(lyrics_id=int(post["lyrics_id"]))
|
l = self.session.vk.client.audio.getLyrics(lyrics_id=int(post["lyrics_id"]))
|
||||||
self.send_message("set", control="lyric", value=l["text"])
|
self.send_message("set", control="lyric", value=l["text"])
|
||||||
else:
|
else:
|
||||||
self.send_message("disable_control", control="lyric")
|
self.send_message("disable_control", control="lyric")
|
||||||
|
|
||||||
def get_suggested_filename(self, audio_index):
|
def get_suggested_filename(self, audio_index):
|
||||||
post = self.post[audio_index]
|
post = self.post[audio_index]
|
||||||
return utils.safe_filename("{0} - {1}.mp3".format(post["title"], post["artist"]))
|
return utils.safe_filename("{0} - {1}.mp3".format(post["title"], post["artist"]))
|
||||||
|
|
||||||
def download(self, audio_index, path):
|
def download(self, audio_index, path):
|
||||||
post = self.post[audio_index]
|
post = self.post[audio_index]
|
||||||
if path != None:
|
if path != None:
|
||||||
pub.sendMessage("download-file", url=post["url"], filename=path)
|
pub.sendMessage("download-file", url=post["url"], filename=path)
|
||||||
|
|
||||||
def play(self, audio_index):
|
def play(self, audio_index):
|
||||||
post = self.post[audio_index]
|
post = self.post[audio_index]
|
||||||
if player.player.check_is_playing() == True:
|
if player.player.check_is_playing() == True:
|
||||||
return pub.sendMessage("stop")
|
return pub.sendMessage("stop")
|
||||||
pub.sendMessage("play", object=post)
|
pub.sendMessage("play", object=post)
|
||||||
|
|
||||||
def load_audios(self):
|
def load_audios(self):
|
||||||
audios = []
|
audios = []
|
||||||
for i in self.post:
|
for i in self.post:
|
||||||
s = "{0} - {1}. {2}".format(i["title"], i["artist"], utils.seconds_to_string(i["duration"]))
|
s = "{0} - {1}. {2}".format(i["title"], i["artist"], utils.seconds_to_string(i["duration"]))
|
||||||
audios.append(s)
|
audios.append(s)
|
||||||
self.send_message("add_items", control="list", items=audios)
|
self.send_message("add_items", control="list", items=audios)
|
||||||
if len(self.post) == 1:
|
if len(self.post) == 1:
|
||||||
self.send_message("disable_control", control="list")
|
self.send_message("disable_control", control="list")
|
||||||
self.send_message("focus_control", control="title")
|
self.send_message("focus_control", control="title")
|
||||||
|
|
||||||
def handle_changes(self, audio_index):
|
def handle_changes(self, audio_index):
|
||||||
self.fill_information(audio_index)
|
self.fill_information(audio_index)
|
||||||
|
@ -20,359 +20,359 @@ from . import audio, poll, article
|
|||||||
log = logging.getLogger(__file__)
|
log = logging.getLogger(__file__)
|
||||||
|
|
||||||
def get_message(status):
|
def get_message(status):
|
||||||
message = ""
|
message = ""
|
||||||
if "text" in status:
|
if "text" in status:
|
||||||
message = utils.clean_text(status["text"])
|
message = utils.clean_text(status["text"])
|
||||||
return message
|
return message
|
||||||
|
|
||||||
class displayPostPresenter(base.basePresenter):
|
class displayPostPresenter(base.basePresenter):
|
||||||
""" Base class for post representation."""
|
""" Base class for post representation."""
|
||||||
|
|
||||||
def __init__(self, session, postObject, view, interactor):
|
def __init__(self, session, postObject, view, interactor):
|
||||||
super(displayPostPresenter, self).__init__(view=view, interactor=interactor, modulename="display_post")
|
super(displayPostPresenter, self).__init__(view=view, interactor=interactor, modulename="display_post")
|
||||||
self.type = "post"
|
self.type = "post"
|
||||||
self.session = session
|
self.session = session
|
||||||
self.post = postObject
|
self.post = postObject
|
||||||
# Posts from newsfeed contains this source_id instead from_id in walls. Also it uses post_id and walls use just id.
|
# Posts from newsfeed contains this source_id instead from_id in walls. Also it uses post_id and walls use just id.
|
||||||
if "source_id" in self.post:
|
if "source_id" in self.post:
|
||||||
self.user_identifier = "source_id"
|
self.user_identifier = "source_id"
|
||||||
self.post_identifier = "post_id"
|
self.post_identifier = "post_id"
|
||||||
else:
|
else:
|
||||||
# In wall's posts, if someone has posted in user's wall, owner_id should be used instead from_id
|
# In wall's posts, if someone has posted in user's wall, owner_id should be used instead from_id
|
||||||
# This will help for retrieving comments, do likes, etc.
|
# This will help for retrieving comments, do likes, etc.
|
||||||
if "owner_id" not in self.post:
|
if "owner_id" not in self.post:
|
||||||
self.user_identifier = "from_id"
|
self.user_identifier = "from_id"
|
||||||
else:
|
else:
|
||||||
self.user_identifier = "owner_id"
|
self.user_identifier = "owner_id"
|
||||||
self.post_identifier = "id"
|
self.post_identifier = "id"
|
||||||
self.attachments = []
|
self.attachments = []
|
||||||
self.load_images = False
|
self.load_images = False
|
||||||
# We'll put images here, so it will be easier to work with them.
|
# We'll put images here, so it will be easier to work with them.
|
||||||
self.images = []
|
self.images = []
|
||||||
self.imageIndex = 0
|
self.imageIndex = 0
|
||||||
result = self.get_post_information()
|
result = self.get_post_information()
|
||||||
# Stop loading everything else if post was deleted.
|
# Stop loading everything else if post was deleted.
|
||||||
if result == False:
|
if result == False:
|
||||||
self.interactor.uninstall()
|
self.interactor.uninstall()
|
||||||
return
|
return
|
||||||
self.worker = threading.Thread(target=self.load_all_components)
|
self.worker = threading.Thread(target=self.load_all_components)
|
||||||
self.worker.finished = threading.Event()
|
self.worker.finished = threading.Event()
|
||||||
self.worker.start()
|
self.worker.start()
|
||||||
# connect here the pubsub event for successful posting of comments.
|
# connect here the pubsub event for successful posting of comments.
|
||||||
pub.subscribe(self.posted, "posted")
|
pub.subscribe(self.posted, "posted")
|
||||||
self.run()
|
self.run()
|
||||||
pub.unsubscribe(self.posted, "posted")
|
pub.unsubscribe(self.posted, "posted")
|
||||||
|
|
||||||
def posted(self, from_buffer=None):
|
def posted(self, from_buffer=None):
|
||||||
self.clear_comments_list()
|
self.clear_comments_list()
|
||||||
|
|
||||||
def get_comments(self):
|
def get_comments(self):
|
||||||
""" Get comments and insert them in a list."""
|
""" Get comments and insert them in a list."""
|
||||||
user = self.post[self.user_identifier]
|
user = self.post[self.user_identifier]
|
||||||
id = self.post[self.post_identifier]
|
id = self.post[self.post_identifier]
|
||||||
comments_data = self.session.vk.client.wall.getComments(owner_id=user, post_id=id, need_likes=1, count=100, extended=1, preview_length=0, thread_items_count=10)
|
comments_data = self.session.vk.client.wall.getComments(owner_id=user, post_id=id, need_likes=1, count=100, extended=1, preview_length=0, thread_items_count=10)
|
||||||
self.comments = dict(items=[], profiles=comments_data["profiles"])
|
self.comments = dict(items=[], profiles=comments_data["profiles"])
|
||||||
for i in comments_data["items"]:
|
for i in comments_data["items"]:
|
||||||
self.comments["items"].append(i)
|
self.comments["items"].append(i)
|
||||||
if i.get("thread") != None and i["thread"].get("count") > 0:
|
if i.get("thread") != None and i["thread"].get("count") > 0:
|
||||||
for newI in i["thread"]["items"]:
|
for newI in i["thread"]["items"]:
|
||||||
self.comments["items"].append(newI)
|
self.comments["items"].append(newI)
|
||||||
comments_ = []
|
comments_ = []
|
||||||
# Save profiles in session local storage for a future usage.
|
# Save profiles in session local storage for a future usage.
|
||||||
# Although community objects are returned here, we should not add those because their names are changed.
|
# Although community objects are returned here, we should not add those because their names are changed.
|
||||||
# For example, self reference to a group is marked as "Administrator", which would ruin this profile to be rendered somewhere else.
|
# For example, self reference to a group is marked as "Administrator", which would ruin this profile to be rendered somewhere else.
|
||||||
data = dict(groups=[], profiles=self.comments["profiles"])
|
data = dict(groups=[], profiles=self.comments["profiles"])
|
||||||
self.session.process_usernames(data)
|
self.session.process_usernames(data)
|
||||||
for i in self.comments["items"]:
|
for i in self.comments["items"]:
|
||||||
# If comment has a "deleted" key it should not be displayed, obviously.
|
# If comment has a "deleted" key it should not be displayed, obviously.
|
||||||
if "deleted" in i:
|
if "deleted" in i:
|
||||||
continue
|
continue
|
||||||
from_ = self.session.get_user(i["from_id"])["user1_nom"]
|
from_ = self.session.get_user(i["from_id"])["user1_nom"]
|
||||||
if "reply_to_user" in i:
|
if "reply_to_user" in i:
|
||||||
extra_info = self.session.get_user(i["reply_to_user"])["user1_nom"]
|
extra_info = self.session.get_user(i["reply_to_user"])["user1_nom"]
|
||||||
from_ = _("{0} > {1}").format(from_, extra_info)
|
from_ = _("{0} > {1}").format(from_, extra_info)
|
||||||
# As we set the comment reply properly in the from_ field, let's remove the first username from here if it exists.
|
# As we set the comment reply properly in the from_ field, let's remove the first username from here if it exists.
|
||||||
fixed_text = utils.clean_text(i["text"])
|
fixed_text = utils.clean_text(i["text"])
|
||||||
if len(fixed_text) > 140:
|
if len(fixed_text) > 140:
|
||||||
text = fixed_text[:141]
|
text = fixed_text[:141]
|
||||||
else:
|
else:
|
||||||
text = fixed_text
|
text = fixed_text
|
||||||
original_date = arrow.get(i["date"])
|
original_date = arrow.get(i["date"])
|
||||||
created_at = original_date.humanize(locale=languageHandler.curLang[:2])
|
created_at = original_date.humanize(locale=languageHandler.curLang[:2])
|
||||||
likes = str(i["likes"]["count"])
|
likes = str(i["likes"]["count"])
|
||||||
comments_.append((from_, text, created_at, likes))
|
comments_.append((from_, text, created_at, likes))
|
||||||
self.send_message("add_items", control="comments", items=comments_)
|
self.send_message("add_items", control="comments", items=comments_)
|
||||||
|
|
||||||
def get_post_information(self):
|
def get_post_information(self):
|
||||||
from_ = self.session.get_user(self.post[self.user_identifier])
|
from_ = self.session.get_user(self.post[self.user_identifier])
|
||||||
if "copy_history" in self.post:
|
if "copy_history" in self.post:
|
||||||
title = _("repost from {user1_nom}").format(**from_)
|
title = _("repost from {user1_nom}").format(**from_)
|
||||||
else:
|
else:
|
||||||
if ("from_id" in self.post and "owner_id" in self.post) and (self.post["from_id"] != self.post["owner_id"]):
|
if ("from_id" in self.post and "owner_id" in self.post) and (self.post["from_id"] != self.post["owner_id"]):
|
||||||
# Translators: {0} will be replaced with the user who is posting, and {1} with the wall owner.
|
# Translators: {0} will be replaced with the user who is posting, and {1} with the wall owner.
|
||||||
user2 = self.session.get_user(self.post["owner_id"], "user2")
|
user2 = self.session.get_user(self.post["owner_id"], "user2")
|
||||||
user2.update(from_)
|
user2.update(from_)
|
||||||
title = _("Post from {user1_nom} in the {user2_nom}'s wall").format(**user2)
|
title = _("Post from {user1_nom} in the {user2_nom}'s wall").format(**user2)
|
||||||
else:
|
else:
|
||||||
title = _("Post from {user1_nom}").format(**from_)
|
title = _("Post from {user1_nom}").format(**from_)
|
||||||
self.send_message("set_title", value=title)
|
self.send_message("set_title", value=title)
|
||||||
message = ""
|
message = ""
|
||||||
# Retrieve again the post, so we'll make sure to get the most up to date information.
|
# Retrieve again the post, so we'll make sure to get the most up to date information.
|
||||||
# And we add a counter for views.
|
# And we add a counter for views.
|
||||||
post = self.session.vk.client.wall.getById(posts="{owner_id}_{post_id}".format(owner_id=self.post[self.user_identifier], post_id=self.post[self.post_identifier]))
|
post = self.session.vk.client.wall.getById(posts="{owner_id}_{post_id}".format(owner_id=self.post[self.user_identifier], post_id=self.post[self.post_identifier]))
|
||||||
# If this post has been deleted, let's send an event to the interactor so it won't be displayed.
|
# If this post has been deleted, let's send an event to the interactor so it won't be displayed.
|
||||||
if len(post) == 0:
|
if len(post) == 0:
|
||||||
self.send_message("post_deleted")
|
self.send_message("post_deleted")
|
||||||
return False
|
return False
|
||||||
self.post = post[0]
|
self.post = post[0]
|
||||||
if "views" in self.post and self.post["views"]["count"] > 0:
|
if "views" in self.post and self.post["views"]["count"] > 0:
|
||||||
self.send_message("set", control="views", value=str(self.post["views"]["count"]))
|
self.send_message("set", control="views", value=str(self.post["views"]["count"]))
|
||||||
else:
|
else:
|
||||||
self.send_message("disable_control", control="views")
|
self.send_message("disable_control", control="views")
|
||||||
if "owner_id" not in self.post:
|
if "owner_id" not in self.post:
|
||||||
self.user_identifier = "from_id"
|
self.user_identifier = "from_id"
|
||||||
else:
|
else:
|
||||||
self.user_identifier = "owner_id"
|
self.user_identifier = "owner_id"
|
||||||
self.post_identifier = "id"
|
self.post_identifier = "id"
|
||||||
message = get_message(self.post)
|
message = get_message(self.post)
|
||||||
if "copy_history" in self.post:
|
if "copy_history" in self.post:
|
||||||
nm = "\n"
|
nm = "\n"
|
||||||
for i in self.post["copy_history"]:
|
for i in self.post["copy_history"]:
|
||||||
u = self.session.get_user(i["from_id"])
|
u = self.session.get_user(i["from_id"])
|
||||||
u.update(message=get_message(i))
|
u.update(message=get_message(i))
|
||||||
nm += "{user1_nom}: {message}\n\n".format(**u)
|
nm += "{user1_nom}: {message}\n\n".format(**u)
|
||||||
self.get_attachments(i, get_message(i))
|
self.get_attachments(i, get_message(i))
|
||||||
message += nm
|
message += nm
|
||||||
self.send_message("set", control="post_view", value=message)
|
self.send_message("set", control="post_view", value=message)
|
||||||
self.get_attachments(self.post, message)
|
self.get_attachments(self.post, message)
|
||||||
self.check_image_load()
|
self.check_image_load()
|
||||||
|
|
||||||
def get_attachments(self, post, text):
|
def get_attachments(self, post, text):
|
||||||
attachments = []
|
attachments = []
|
||||||
self.attachments = []
|
self.attachments = []
|
||||||
if "attachments" in post:
|
if "attachments" in post:
|
||||||
for i in post["attachments"]:
|
for i in post["attachments"]:
|
||||||
# We don't need the photos_list attachment, so skip it.
|
# We don't need the photos_list attachment, so skip it.
|
||||||
if i["type"] == "photos_list":
|
if i["type"] == "photos_list":
|
||||||
continue
|
continue
|
||||||
if i["type"] == "photo":
|
if i["type"] == "photo":
|
||||||
if self.load_images == False: self.load_images = True
|
if self.load_images == False: self.load_images = True
|
||||||
self.images.append(i)
|
self.images.append(i)
|
||||||
attachments.append(renderers.add_attachment(i))
|
attachments.append(renderers.add_attachment(i))
|
||||||
self.attachments.append(i)
|
self.attachments.append(i)
|
||||||
# Links in text are not treated like normal attachments, so we'll have to catch and add those to the list without title
|
# Links in text are not treated like normal attachments, so we'll have to catch and add those to the list without title
|
||||||
# We can't get a title because title is provided by the VK API and it will not work for links as simple text.
|
# We can't get a title because title is provided by the VK API and it will not work for links as simple text.
|
||||||
urls = utils.find_urls_in_text(text)
|
urls = utils.find_urls_in_text(text)
|
||||||
if len(urls) > 0:
|
if len(urls) > 0:
|
||||||
links = []
|
links = []
|
||||||
for i in urls:
|
for i in urls:
|
||||||
links.append({"link": {"title": _("Untitled link"), "url": i}, "type": "link"})
|
links.append({"link": {"title": _("Untitled link"), "url": i}, "type": "link"})
|
||||||
for i in links:
|
for i in links:
|
||||||
attachments.append(renderers.add_attachment(i))
|
attachments.append(renderers.add_attachment(i))
|
||||||
self.attachments.append(i)
|
self.attachments.append(i)
|
||||||
if len(self.attachments) > 0:
|
if len(self.attachments) > 0:
|
||||||
self.send_message("enable_attachments")
|
self.send_message("enable_attachments")
|
||||||
self.send_message("add_items", control="attachments", items=attachments)
|
self.send_message("add_items", control="attachments", items=attachments)
|
||||||
else:
|
else:
|
||||||
self.interactor.view.attachments.list.Enable(False)
|
self.interactor.view.attachments.list.Enable(False)
|
||||||
|
|
||||||
def check_image_load(self):
|
def check_image_load(self):
|
||||||
if self.load_images and len(self.images) > 0 and self.session.settings["general"]["load_images"]:
|
if self.load_images and len(self.images) > 0 and self.session.settings["general"]["load_images"]:
|
||||||
self.send_message("enable_control", control="image")
|
self.send_message("enable_control", control="image")
|
||||||
nav = False # Disable navigation controls in photos
|
nav = False # Disable navigation controls in photos
|
||||||
if len(self.images) > 1:
|
if len(self.images) > 1:
|
||||||
nav = True
|
nav = True
|
||||||
self.send_message("enable_photo_controls", navigation=nav)
|
self.send_message("enable_photo_controls", navigation=nav)
|
||||||
self.set_image(0)
|
self.set_image(0)
|
||||||
|
|
||||||
def set_next_image(self, *args, **kwargs):
|
def set_next_image(self, *args, **kwargs):
|
||||||
if self.imageIndex < -1 or self.imageIndex == len(self.images)-1:
|
if self.imageIndex < -1 or self.imageIndex == len(self.images)-1:
|
||||||
self.imageIndex = -1
|
self.imageIndex = -1
|
||||||
if len(self.images) <= self.imageIndex+1:
|
if len(self.images) <= self.imageIndex+1:
|
||||||
self.imageIndex = 0
|
self.imageIndex = 0
|
||||||
else:
|
else:
|
||||||
self.imageIndex = self.imageIndex + 1
|
self.imageIndex = self.imageIndex + 1
|
||||||
self.set_image(self.imageIndex)
|
self.set_image(self.imageIndex)
|
||||||
|
|
||||||
def set_previous_image(self, *args, **kwargs):
|
def set_previous_image(self, *args, **kwargs):
|
||||||
if self.imageIndex <= 0:
|
if self.imageIndex <= 0:
|
||||||
self.imageIndex = len(self.images)
|
self.imageIndex = len(self.images)
|
||||||
self.imageIndex = self.imageIndex - 1
|
self.imageIndex = self.imageIndex - 1
|
||||||
self.set_image(self.imageIndex)
|
self.set_image(self.imageIndex)
|
||||||
|
|
||||||
def set_image(self, index):
|
def set_image(self, index):
|
||||||
if len(self.images) < index-1:
|
if len(self.images) < index-1:
|
||||||
return
|
return
|
||||||
# Get's photo URL.
|
# Get's photo URL.
|
||||||
url = self.get_photo_url(self.images[index]["photo"], "x")
|
url = self.get_photo_url(self.images[index]["photo"], "x")
|
||||||
if url != "":
|
if url != "":
|
||||||
img = requests.get(url)
|
img = requests.get(url)
|
||||||
self.send_message("load_image", image=img)
|
self.send_message("load_image", image=img)
|
||||||
# Translators: {0} is the number of the current photo and {1} is the total number of photos.
|
# Translators: {0} is the number of the current photo and {1} is the total number of photos.
|
||||||
output.speak(_("Loaded photo {0} of {1}").format(index+1, len(self.images)))
|
output.speak(_("Loaded photo {0} of {1}").format(index+1, len(self.images)))
|
||||||
return
|
return
|
||||||
|
|
||||||
def get_photo_url(self, photo, size="x"):
|
def get_photo_url(self, photo, size="x"):
|
||||||
url = ""
|
url = ""
|
||||||
for i in photo["sizes"]:
|
for i in photo["sizes"]:
|
||||||
if i["type"] == size:
|
if i["type"] == size:
|
||||||
url = i["url"]
|
url = i["url"]
|
||||||
break
|
break
|
||||||
return url
|
return url
|
||||||
|
|
||||||
def load_all_components(self):
|
def load_all_components(self):
|
||||||
self.get_likes()
|
self.get_likes()
|
||||||
self.get_reposts()
|
self.get_reposts()
|
||||||
self.get_comments()
|
self.get_comments()
|
||||||
if self.post["comments"]["can_post"] == 0:
|
if self.post["comments"]["can_post"] == 0:
|
||||||
self.send_message("disable_control", control="comment")
|
self.send_message("disable_control", control="comment")
|
||||||
if self.post["likes"]["can_like"] == 0 and self.post["likes"]["user_likes"] == 0:
|
if self.post["likes"]["can_like"] == 0 and self.post["likes"]["user_likes"] == 0:
|
||||||
self.send_message("disable_control", "like")
|
self.send_message("disable_control", "like")
|
||||||
elif self.post["likes"]["user_likes"] == 1:
|
elif self.post["likes"]["user_likes"] == 1:
|
||||||
self.send_message("set_label", control="like", label=_("&Dislike"))
|
self.send_message("set_label", control="like", label=_("&Dislike"))
|
||||||
if self.post["likes"]["can_publish"] == 0:
|
if self.post["likes"]["can_publish"] == 0:
|
||||||
self.send_message("disable_control", control="repost")
|
self.send_message("disable_control", control="repost")
|
||||||
|
|
||||||
def post_like(self):
|
def post_like(self):
|
||||||
if ("owner_id" in self.post) == False:
|
if ("owner_id" in self.post) == False:
|
||||||
user = int(self.post[self.user_identifier])
|
user = int(self.post[self.user_identifier])
|
||||||
else:
|
else:
|
||||||
user = int(self.post["owner_id"])
|
user = int(self.post["owner_id"])
|
||||||
id = int(self.post[self.post_identifier])
|
id = int(self.post[self.post_identifier])
|
||||||
if "type" in self.post:
|
if "type" in self.post:
|
||||||
type_ = self.post["type"]
|
type_ = self.post["type"]
|
||||||
else:
|
else:
|
||||||
type_ = self.type
|
type_ = self.type
|
||||||
if self.post["likes"]["user_likes"] == 1:
|
if self.post["likes"]["user_likes"] == 1:
|
||||||
l = self.session.vk.client.likes.delete(owner_id=user, item_id=id, type=type_)
|
l = self.session.vk.client.likes.delete(owner_id=user, item_id=id, type=type_)
|
||||||
output.speak(_("You don't like this"))
|
output.speak(_("You don't like this"))
|
||||||
self.post["likes"]["count"] = l["likes"]
|
self.post["likes"]["count"] = l["likes"]
|
||||||
self.post["likes"]["user_likes"] = 2
|
self.post["likes"]["user_likes"] = 2
|
||||||
self.get_likes()
|
self.get_likes()
|
||||||
self.send_message("set_label", control="like", label=_("&Like"))
|
self.send_message("set_label", control="like", label=_("&Like"))
|
||||||
else:
|
else:
|
||||||
l = self.session.vk.client.likes.add(owner_id=user, item_id=id, type=type_)
|
l = self.session.vk.client.likes.add(owner_id=user, item_id=id, type=type_)
|
||||||
output.speak(_("You liked this"))
|
output.speak(_("You liked this"))
|
||||||
self.send_message("set_label", control="like", label=_("&Dislike"))
|
self.send_message("set_label", control="like", label=_("&Dislike"))
|
||||||
self.post["likes"]["count"] = l["likes"]
|
self.post["likes"]["count"] = l["likes"]
|
||||||
self.post["likes"]["user_likes"] = 1
|
self.post["likes"]["user_likes"] = 1
|
||||||
self.get_likes()
|
self.get_likes()
|
||||||
|
|
||||||
def post_repost(self):
|
def post_repost(self):
|
||||||
object_id = "wall{0}_{1}".format(self.post[self.user_identifier], self.post[self.post_identifier])
|
object_id = "wall{0}_{1}".format(self.post[self.user_identifier], self.post[self.post_identifier])
|
||||||
p = createPostPresenter(session=self.session, interactor=interactors.createPostInteractor(), view=views.createPostDialog(title=_("Repost"), message=_("Add your comment here"), text="", mode="comment"))
|
p = createPostPresenter(session=self.session, interactor=interactors.createPostInteractor(), view=views.createPostDialog(title=_("Repost"), message=_("Add your comment here"), text="", mode="comment"))
|
||||||
if hasattr(p, "text") or hasattr(p, "privacy"):
|
if hasattr(p, "text") or hasattr(p, "privacy"):
|
||||||
post_arguments = dict(object=object_id, message=p.text)
|
post_arguments = dict(object=object_id, message=p.text)
|
||||||
attachments = []
|
attachments = []
|
||||||
if hasattr(p, "attachments"):
|
if hasattr(p, "attachments"):
|
||||||
attachments = p.attachments
|
attachments = p.attachments
|
||||||
call_threaded(pub.sendMessage, "post", parent_endpoint="wall", child_endpoint="repost", attachments_list=attachments, post_arguments=post_arguments)
|
call_threaded(pub.sendMessage, "post", parent_endpoint="wall", child_endpoint="repost", attachments_list=attachments, post_arguments=post_arguments)
|
||||||
|
|
||||||
def get_likes(self):
|
def get_likes(self):
|
||||||
self.send_message("set_label", control="likes", label=_("{0} people like this").format(self.post["likes"]["count"],))
|
self.send_message("set_label", control="likes", label=_("{0} people like this").format(self.post["likes"]["count"],))
|
||||||
|
|
||||||
def get_reposts(self):
|
def get_reposts(self):
|
||||||
self.send_message("set_label", control="shares", label=_("Shared {0} times").format(self.post["reposts"]["count"],))
|
self.send_message("set_label", control="shares", label=_("Shared {0} times").format(self.post["reposts"]["count"],))
|
||||||
|
|
||||||
def add_comment(self):
|
def add_comment(self):
|
||||||
comment = createPostPresenter(session=self.session, interactor=interactors.createPostInteractor(), view=views.createPostDialog(title=_("Add a comment"), message="", text="", mode="comment"))
|
comment = createPostPresenter(session=self.session, interactor=interactors.createPostInteractor(), view=views.createPostDialog(title=_("Add a comment"), message="", text="", mode="comment"))
|
||||||
if hasattr(comment, "text") or hasattr(comment, "privacy"):
|
if hasattr(comment, "text") or hasattr(comment, "privacy"):
|
||||||
owner_id = self.post[self.user_identifier]
|
owner_id = self.post[self.user_identifier]
|
||||||
post_id = self.post[self.post_identifier]
|
post_id = self.post[self.post_identifier]
|
||||||
post_arguments=dict(message=comment.text, owner_id=owner_id, post_id=post_id)
|
post_arguments=dict(message=comment.text, owner_id=owner_id, post_id=post_id)
|
||||||
attachments = []
|
attachments = []
|
||||||
if hasattr(comment, "attachments"):
|
if hasattr(comment, "attachments"):
|
||||||
attachments = comment.attachments
|
attachments = comment.attachments
|
||||||
call_threaded(pub.sendMessage, "post", parent_endpoint="wall", child_endpoint="createComment", attachments_list=attachments, post_arguments=post_arguments)
|
call_threaded(pub.sendMessage, "post", parent_endpoint="wall", child_endpoint="createComment", attachments_list=attachments, post_arguments=post_arguments)
|
||||||
|
|
||||||
def reply(self, comment):
|
def reply(self, comment):
|
||||||
c = self.comments["items"][comment]
|
c = self.comments["items"][comment]
|
||||||
comment = createPostPresenter(session=self.session, interactor=interactors.createPostInteractor(), view=views.createPostDialog(title=_("Reply to {user1_nom}").format(**self.session.get_user(c["from_id"])), message="", text="", mode="comment"))
|
comment = createPostPresenter(session=self.session, interactor=interactors.createPostInteractor(), view=views.createPostDialog(title=_("Reply to {user1_nom}").format(**self.session.get_user(c["from_id"])), message="", text="", mode="comment"))
|
||||||
if hasattr(comment, "text") or hasattr(comment, "privacy"):
|
if hasattr(comment, "text") or hasattr(comment, "privacy"):
|
||||||
post_id = self.post[self.post_identifier]
|
post_id = self.post[self.post_identifier]
|
||||||
post_arguments=dict(message=comment.text, owner_id=c["owner_id"], reply_to_comment=c["id"], post_id=c["post_id"], reply_to_user=c["owner_id"])
|
post_arguments=dict(message=comment.text, owner_id=c["owner_id"], reply_to_comment=c["id"], post_id=c["post_id"], reply_to_user=c["owner_id"])
|
||||||
attachments = []
|
attachments = []
|
||||||
if hasattr(comment, "attachments"):
|
if hasattr(comment, "attachments"):
|
||||||
attachments = comment.attachments
|
attachments = comment.attachments
|
||||||
call_threaded(pub.sendMessage, "post", parent_endpoint="wall", child_endpoint="createComment", attachments_list=attachments, post_arguments=post_arguments)
|
call_threaded(pub.sendMessage, "post", parent_endpoint="wall", child_endpoint="createComment", attachments_list=attachments, post_arguments=post_arguments)
|
||||||
|
|
||||||
def show_comment(self, comment_index):
|
def show_comment(self, comment_index):
|
||||||
from . import comment
|
from . import comment
|
||||||
c = self.comments["items"][comment_index]
|
c = self.comments["items"][comment_index]
|
||||||
c["post_id"] = self.post[self.post_identifier]
|
c["post_id"] = self.post[self.post_identifier]
|
||||||
a = comment.displayCommentPresenter(session=self.session, postObject=c, interactor=interactors.displayPostInteractor(), view=views.displayComment())
|
a = comment.displayCommentPresenter(session=self.session, postObject=c, interactor=interactors.displayPostInteractor(), view=views.displayComment())
|
||||||
|
|
||||||
def translate(self, text, language):
|
def translate(self, text, language):
|
||||||
msg = translator.translator.translate(text, language)
|
msg = translator.translator.translate(text, language)
|
||||||
self.send_message("set", control="post_view", value=msg)
|
self.send_message("set", control="post_view", value=msg)
|
||||||
self.send_message("focus_control", control="post_view")
|
self.send_message("focus_control", control="post_view")
|
||||||
output.speak(_("Translated"))
|
output.speak(_("Translated"))
|
||||||
|
|
||||||
def spellcheck(self, text):
|
def spellcheck(self, text):
|
||||||
checker = SpellChecker.spellchecker.spellChecker(text)
|
checker = SpellChecker.spellchecker.spellChecker(text)
|
||||||
if hasattr(checker, "fixed_text"):
|
if hasattr(checker, "fixed_text"):
|
||||||
self.send_message("set", control="post_view", value=checker.fixed_text)
|
self.send_message("set", control="post_view", value=checker.fixed_text)
|
||||||
self.send_message("focus_control", control="post_view")
|
self.send_message("focus_control", control="post_view")
|
||||||
|
|
||||||
def open_attachment(self, index):
|
def open_attachment(self, index):
|
||||||
attachment = self.attachments[index]
|
attachment = self.attachments[index]
|
||||||
if attachment["type"] == "audio":
|
if attachment["type"] == "audio":
|
||||||
a = audio.displayAudioPresenter(session=self.session, postObject=[attachment["audio"]], interactor=interactors.displayAudioInteractor(), view=views.displayAudio())
|
a = audio.displayAudioPresenter(session=self.session, postObject=[attachment["audio"]], interactor=interactors.displayAudioInteractor(), view=views.displayAudio())
|
||||||
elif attachment["type"] == "link":
|
elif attachment["type"] == "link":
|
||||||
output.speak(_("Opening URL..."), True)
|
output.speak(_("Opening URL..."), True)
|
||||||
webbrowser.open_new_tab(attachment["link"]["url"])
|
webbrowser.open_new_tab(attachment["link"]["url"])
|
||||||
elif attachment["type"] == "doc":
|
elif attachment["type"] == "doc":
|
||||||
output.speak(_("Opening document in web browser..."))
|
output.speak(_("Opening document in web browser..."))
|
||||||
webbrowser.open(attachment["doc"]["url"])
|
webbrowser.open(attachment["doc"]["url"])
|
||||||
elif attachment["type"] == "video":
|
elif attachment["type"] == "video":
|
||||||
# it seems VK doesn't like to attach video links as normal URLS, so we'll have to
|
# it seems VK doesn't like to attach video links as normal URLS, so we'll have to
|
||||||
# get the full video object and use its "player" key which will open a webbrowser in their site with a player for the video.
|
# get the full video object and use its "player" key which will open a webbrowser in their site with a player for the video.
|
||||||
# see https://vk.com/dev/attachments_w and and https://vk.com/dev/video.get
|
# see https://vk.com/dev/attachments_w and and https://vk.com/dev/video.get
|
||||||
# However, the flash player isn't good for visually impaired people (when you press play you won't be able to close the window with alt+f4), so it could be good to use the HTML5 player.
|
# However, the flash player isn't good for visually impaired people (when you press play you won't be able to close the window with alt+f4), so it could be good to use the HTML5 player.
|
||||||
# For firefox, see https://addons.mozilla.org/ru/firefox/addon/force-html5-video-player-at-vk/
|
# For firefox, see https://addons.mozilla.org/ru/firefox/addon/force-html5-video-player-at-vk/
|
||||||
# May be I could use a dialogue here for inviting people to use this addon in firefox. It seems it isn't possible to use this html5 player from the player URL.
|
# May be I could use a dialogue here for inviting people to use this addon in firefox. It seems it isn't possible to use this html5 player from the player URL.
|
||||||
object_id = "{0}_{1}".format(attachment["video"]["owner_id"], attachment["video"]["id"])
|
object_id = "{0}_{1}".format(attachment["video"]["owner_id"], attachment["video"]["id"])
|
||||||
video_object = self.session.vk.client.video.get(owner_id=attachment["video"]["owner_id"], videos=object_id)
|
video_object = self.session.vk.client.video.get(owner_id=attachment["video"]["owner_id"], videos=object_id)
|
||||||
video_object = video_object["items"][0]
|
video_object = video_object["items"][0]
|
||||||
output.speak(_("Opening video in web browser..."), True)
|
output.speak(_("Opening video in web browser..."), True)
|
||||||
webbrowser.open_new_tab(video_object["player"])
|
webbrowser.open_new_tab(video_object["player"])
|
||||||
elif attachment["type"] == "photo":
|
elif attachment["type"] == "photo":
|
||||||
output.speak(_("Opening photo in web browser..."), True)
|
output.speak(_("Opening photo in web browser..."), True)
|
||||||
# Possible photo sizes for looking in the attachment information. Try to use the biggest photo available.
|
# Possible photo sizes for looking in the attachment information. Try to use the biggest photo available.
|
||||||
possible_sizes = [1280, 604, 130, 75]
|
possible_sizes = [1280, 604, 130, 75]
|
||||||
url = ""
|
url = ""
|
||||||
for i in possible_sizes:
|
for i in possible_sizes:
|
||||||
if "photo_{0}".format(i,) in attachment["photo"]:
|
if "photo_{0}".format(i,) in attachment["photo"]:
|
||||||
url = attachment["photo"]["photo_{0}".format(i,)]
|
url = attachment["photo"]["photo_{0}".format(i,)]
|
||||||
break
|
break
|
||||||
if url != "":
|
if url != "":
|
||||||
webbrowser.open_new_tab(url)
|
webbrowser.open_new_tab(url)
|
||||||
elif attachment["type"] == "poll":
|
elif attachment["type"] == "poll":
|
||||||
a = poll.displayPollPresenter(session=self.session, poll=attachment, interactor=interactors.displayPollInteractor(), view=views.displayPoll())
|
a = poll.displayPollPresenter(session=self.session, poll=attachment, interactor=interactors.displayPollInteractor(), view=views.displayPoll())
|
||||||
elif attachment["type"] == "article":
|
elif attachment["type"] == "article":
|
||||||
a = article.displayArticlePresenter(session=self.session, postObject=[attachment["article"]], interactor=interactors.displayArticleInteractor(), view=views.displayArticle())
|
a = article.displayArticlePresenter(session=self.session, postObject=[attachment["article"]], interactor=interactors.displayArticleInteractor(), view=views.displayArticle())
|
||||||
else:
|
else:
|
||||||
log.error("Unhandled attachment: %r" % (attachment,))
|
log.error("Unhandled attachment: %r" % (attachment,))
|
||||||
|
|
||||||
def __del__(self):
|
def __del__(self):
|
||||||
if hasattr(self, "worker"):
|
if hasattr(self, "worker"):
|
||||||
self.worker.finished.set()
|
self.worker.finished.set()
|
||||||
|
|
||||||
def clear_comments_list(self):
|
def clear_comments_list(self):
|
||||||
self.send_message("clean_list", list="comments")
|
self.send_message("clean_list", list="comments")
|
||||||
self.get_comments()
|
self.get_comments()
|
||||||
|
|
||||||
def show_likes(self):
|
def show_likes(self):
|
||||||
""" show likes for the specified post."""
|
""" show likes for the specified post."""
|
||||||
data = dict(type="post", owner_id=self.post[self.user_identifier], item_id=self.post["id"], extended=True, count=100, skip_own=True)
|
data = dict(type="post", owner_id=self.post[self.user_identifier], item_id=self.post["id"], extended=True, count=100, skip_own=True)
|
||||||
result = self.session.vk.client.likes.getList(**data)
|
result = self.session.vk.client.likes.getList(**data)
|
||||||
if result["count"] > 0:
|
if result["count"] > 0:
|
||||||
post = {"source_id": self.post[self.user_identifier], "friends": {"items": result["items"]}}
|
post = {"source_id": self.post[self.user_identifier], "friends": {"items": result["items"]}}
|
||||||
pub.sendMessage("open-post", post_object=post, controller_="displayFriendship", vars=dict(caption=_("people who liked this")))
|
pub.sendMessage("open-post", post_object=post, controller_="displayFriendship", vars=dict(caption=_("people who liked this")))
|
||||||
|
|
||||||
def show_shares(self):
|
def show_shares(self):
|
||||||
data = dict(type="post", owner_id=self.post[self.user_identifier], item_id=self.post["id"], extended=True, count=1000, skip_own=True, filter="copies")
|
data = dict(type="post", owner_id=self.post[self.user_identifier], item_id=self.post["id"], extended=True, count=1000, skip_own=True, filter="copies")
|
||||||
result = self.session.vk.client.likes.getList(**data)
|
result = self.session.vk.client.likes.getList(**data)
|
||||||
if result["count"] > 0:
|
if result["count"] > 0:
|
||||||
post = {"source_id": self.post[self.user_identifier], "friends": {"items": result["items"]}}
|
post = {"source_id": self.post[self.user_identifier], "friends": {"items": result["items"]}}
|
||||||
pub.sendMessage("open-post", post_object=post, controller_="displayFriendship", vars=dict(caption=_("people who shared this")))
|
pub.sendMessage("open-post", post_object=post, controller_="displayFriendship", vars=dict(caption=_("people who shared this")))
|
||||||
|
@ -15,75 +15,75 @@ from . import basePost
|
|||||||
log = logging.getLogger(__file__)
|
log = logging.getLogger(__file__)
|
||||||
|
|
||||||
def get_message(status):
|
def get_message(status):
|
||||||
message = ""
|
message = ""
|
||||||
if "text" in status:
|
if "text" in status:
|
||||||
message = utils.clean_text(status["text"])
|
message = utils.clean_text(status["text"])
|
||||||
return message
|
return message
|
||||||
|
|
||||||
class displayCommentPresenter(basePost.displayPostPresenter):
|
class displayCommentPresenter(basePost.displayPostPresenter):
|
||||||
|
|
||||||
def __init__(self, session, postObject, view, interactor):
|
def __init__(self, session, postObject, view, interactor):
|
||||||
self.type = "comment"
|
self.type = "comment"
|
||||||
self.modulename = "display_comment"
|
self.modulename = "display_comment"
|
||||||
self.interactor = interactor
|
self.interactor = interactor
|
||||||
self.view = view
|
self.view = view
|
||||||
self.interactor.install(view=view, presenter=self, modulename=self.modulename)
|
self.interactor.install(view=view, presenter=self, modulename=self.modulename)
|
||||||
self.session = session
|
self.session = session
|
||||||
self.post = postObject
|
self.post = postObject
|
||||||
self.user_identifier = "from_id"
|
self.user_identifier = "from_id"
|
||||||
self.post_identifier = "id"
|
self.post_identifier = "id"
|
||||||
self.worker = threading.Thread(target=self.load_all_components)
|
self.worker = threading.Thread(target=self.load_all_components)
|
||||||
self.worker.finished = threading.Event()
|
self.worker.finished = threading.Event()
|
||||||
self.worker.start()
|
self.worker.start()
|
||||||
self.attachments = []
|
self.attachments = []
|
||||||
self.load_images = False
|
self.load_images = False
|
||||||
# We'll put images here, so it will be easier to work with them.
|
# We'll put images here, so it will be easier to work with them.
|
||||||
self.images = []
|
self.images = []
|
||||||
self.imageIndex = 0
|
self.imageIndex = 0
|
||||||
# connect here the pubsub event for successful posting of comments.
|
# connect here the pubsub event for successful posting of comments.
|
||||||
pub.subscribe(self.posted, "posted")
|
pub.subscribe(self.posted, "posted")
|
||||||
self.run()
|
self.run()
|
||||||
pub.unsubscribe(self.posted, "posted")
|
pub.unsubscribe(self.posted, "posted")
|
||||||
|
|
||||||
def load_all_components(self):
|
def load_all_components(self):
|
||||||
self.get_post_information()
|
self.get_post_information()
|
||||||
self.get_likes()
|
self.get_likes()
|
||||||
self.send_message("disable_control", control="comment")
|
self.send_message("disable_control", control="comment")
|
||||||
if self.post["likes"]["can_like"] == 0 and self.post["likes"]["user_likes"] == 0:
|
if self.post["likes"]["can_like"] == 0 and self.post["likes"]["user_likes"] == 0:
|
||||||
self.send_message("disable_control", "like")
|
self.send_message("disable_control", "like")
|
||||||
elif self.post["likes"]["user_likes"] == 1:
|
elif self.post["likes"]["user_likes"] == 1:
|
||||||
self.send_message("set_label", control="like", label=_("&Dislike"))
|
self.send_message("set_label", control="like", label=_("&Dislike"))
|
||||||
|
|
||||||
def get_post_information(self):
|
def get_post_information(self):
|
||||||
from_ = self.session.get_user(self.post[self.user_identifier])
|
from_ = self.session.get_user(self.post[self.user_identifier])
|
||||||
if ("from_id" in self.post and "owner_id" in self.post):
|
if ("from_id" in self.post and "owner_id" in self.post):
|
||||||
user2 = self.session.get_user(self.post["owner_id"], "user2")
|
user2 = self.session.get_user(self.post["owner_id"], "user2")
|
||||||
user2.update(from_)
|
user2.update(from_)
|
||||||
title = _("Comment from {user1_nom} in the {user2_nom}'s post").format(**user2)
|
title = _("Comment from {user1_nom} in the {user2_nom}'s post").format(**user2)
|
||||||
self.send_message("set_title", value=title)
|
self.send_message("set_title", value=title)
|
||||||
message = ""
|
message = ""
|
||||||
message = get_message(self.post)
|
message = get_message(self.post)
|
||||||
self.send_message("set", control="post_view", value=message)
|
self.send_message("set", control="post_view", value=message)
|
||||||
self.get_attachments(self.post, message)
|
self.get_attachments(self.post, message)
|
||||||
self.check_image_load()
|
self.check_image_load()
|
||||||
|
|
||||||
def reply(self, *args, **kwargs):
|
def reply(self, *args, **kwargs):
|
||||||
comment = createPostPresenter(session=self.session, interactor=interactors.createPostInteractor(), view=views.createPostDialog(title=_("Reply to {user1_nom}").format(**self.session.get_user(self.post["from_id"])), message="", text="", mode="comment"))
|
comment = createPostPresenter(session=self.session, interactor=interactors.createPostInteractor(), view=views.createPostDialog(title=_("Reply to {user1_nom}").format(**self.session.get_user(self.post["from_id"])), message="", text="", mode="comment"))
|
||||||
if hasattr(comment, "text") or hasattr(comment, "privacy"):
|
if hasattr(comment, "text") or hasattr(comment, "privacy"):
|
||||||
post_arguments = dict(owner_id=self.post["owner_id"], reply_to_comment=self.post["id"], post_id=self.post["post_id"], reply_to_user=self.post["owner_id"], message=comment.text)
|
post_arguments = dict(owner_id=self.post["owner_id"], reply_to_comment=self.post["id"], post_id=self.post["post_id"], reply_to_user=self.post["owner_id"], message=comment.text)
|
||||||
attachments = []
|
attachments = []
|
||||||
if hasattr(comment, "attachments"):
|
if hasattr(comment, "attachments"):
|
||||||
attachments = comment.attachments
|
attachments = comment.attachments
|
||||||
call_threaded(pub.sendMessage, "post", parent_endpoint="wall", child_endpoint="createComment", attachments_list=attachments, post_arguments=post_arguments)
|
call_threaded(pub.sendMessage, "post", parent_endpoint="wall", child_endpoint="createComment", attachments_list=attachments, post_arguments=post_arguments)
|
||||||
|
|
||||||
def show_likes(self):
|
def show_likes(self):
|
||||||
""" show likes for the specified post."""
|
""" show likes for the specified post."""
|
||||||
data = dict(type="comment", owner_id=self.post["owner_id"], item_id=self.post["id"], extended=True, count=100, skip_own=True)
|
data = dict(type="comment", owner_id=self.post["owner_id"], item_id=self.post["id"], extended=True, count=100, skip_own=True)
|
||||||
result = self.session.vk.client.likes.getList(**data)
|
result = self.session.vk.client.likes.getList(**data)
|
||||||
if result["count"] > 0:
|
if result["count"] > 0:
|
||||||
post = {"source_id": self.post[self.user_identifier], "friends": {"items": result["items"]}}
|
post = {"source_id": self.post[self.user_identifier], "friends": {"items": result["items"]}}
|
||||||
pub.sendMessage("open-post", post_object=post, controller_="displayFriendship", vars=dict(caption=_("people who liked this")))
|
pub.sendMessage("open-post", post_object=post, controller_="displayFriendship", vars=dict(caption=_("people who liked this")))
|
||||||
|
|
||||||
def posted(self, from_buffer=None):
|
def posted(self, from_buffer=None):
|
||||||
self.interactor.uninstall()
|
self.interactor.uninstall()
|
||||||
return
|
return
|
||||||
|
@ -8,43 +8,43 @@ log = logging.getLogger(__file__)
|
|||||||
|
|
||||||
class displayFriendshipPresenter(base.basePresenter):
|
class displayFriendshipPresenter(base.basePresenter):
|
||||||
|
|
||||||
def __init__(self, session, postObject, view, interactor, caption=""):
|
def __init__(self, session, postObject, view, interactor, caption=""):
|
||||||
self.session = session
|
self.session = session
|
||||||
self.post = postObject
|
self.post = postObject
|
||||||
super(displayFriendshipPresenter, self).__init__(view=view, interactor=interactor, modulename="display_friendship")
|
super(displayFriendshipPresenter, self).__init__(view=view, interactor=interactor, modulename="display_friendship")
|
||||||
list_of_friends = self.get_friend_names()
|
list_of_friends = self.get_friend_names()
|
||||||
from_ = self.session.get_user(self.post["source_id"])
|
from_ = self.session.get_user(self.post["source_id"])
|
||||||
title = caption.format(**from_)
|
title = caption.format(**from_)
|
||||||
self.send_message("set_title", value=title)
|
self.send_message("set_title", value=title)
|
||||||
self.set_friends_list(list_of_friends)
|
self.set_friends_list(list_of_friends)
|
||||||
self.run()
|
self.run()
|
||||||
|
|
||||||
def get_friend_names(self):
|
def get_friend_names(self):
|
||||||
self.friends = self.post["friends"]["items"]
|
self.friends = self.post["friends"]["items"]
|
||||||
friends = list()
|
friends = list()
|
||||||
for i in self.friends:
|
for i in self.friends:
|
||||||
if "user_id" in i:
|
if "user_id" in i:
|
||||||
friends.append(self.session.get_user(i["user_id"])["user1_nom"])
|
friends.append(self.session.get_user(i["user_id"])["user1_nom"])
|
||||||
else:
|
else:
|
||||||
friends.append(self.session.get_user(i["id"])["user1_nom"])
|
friends.append(self.session.get_user(i["id"])["user1_nom"])
|
||||||
return friends
|
return friends
|
||||||
|
|
||||||
def set_friends_list(self, friendslist):
|
def set_friends_list(self, friendslist):
|
||||||
self.send_message("add_items", control="friends", items=friendslist)
|
self.send_message("add_items", control="friends", items=friendslist)
|
||||||
|
|
||||||
def view_profile(self, item):
|
def view_profile(self, item):
|
||||||
user = self.friends[item]
|
user = self.friends[item]
|
||||||
if "user_id" in user:
|
if "user_id" in user:
|
||||||
id = user["user_id"]
|
id = user["user_id"]
|
||||||
else:
|
else:
|
||||||
id = user["id"]
|
id = user["id"]
|
||||||
pub.sendMessage("user-profile", person=id)
|
pub.sendMessage("user-profile", person=id)
|
||||||
|
|
||||||
def open_in_browser(self, item):
|
def open_in_browser(self, item):
|
||||||
user = self.friends[item]
|
user = self.friends[item]
|
||||||
if "user_id" in user:
|
if "user_id" in user:
|
||||||
id = user["user_id"]
|
id = user["user_id"]
|
||||||
else:
|
else:
|
||||||
id = user["id"]
|
id = user["id"]
|
||||||
url = "https://vk.com/id{user_id}".format(user_id=id)
|
url = "https://vk.com/id{user_id}".format(user_id=id)
|
||||||
webbrowser.open_new_tab(url)
|
webbrowser.open_new_tab(url)
|
||||||
|
@ -7,49 +7,49 @@ log = logging.getLogger(__file__)
|
|||||||
|
|
||||||
class displayPollPresenter(base.basePresenter):
|
class displayPollPresenter(base.basePresenter):
|
||||||
|
|
||||||
def __init__(self, session, poll, view, interactor, show_results=False):
|
def __init__(self, session, poll, view, interactor, show_results=False):
|
||||||
super(displayPollPresenter, self).__init__(view=view, interactor=interactor, modulename="display_poll")
|
super(displayPollPresenter, self).__init__(view=view, interactor=interactor, modulename="display_poll")
|
||||||
self.poll = poll["poll"]
|
self.poll = poll["poll"]
|
||||||
self.session = session
|
self.session = session
|
||||||
self.get_poll()
|
self.get_poll()
|
||||||
self.load_poll(show_results)
|
self.load_poll(show_results)
|
||||||
self.run()
|
self.run()
|
||||||
|
|
||||||
def get_poll(self):
|
def get_poll(self):
|
||||||
# Retrieve the poll again so we will have a fresh and updated object.
|
# Retrieve the poll again so we will have a fresh and updated object.
|
||||||
data = dict(owner_id=self.poll["owner_id"], is_board=int(self.poll["is_board"]), poll_id=self.poll["id"])
|
data = dict(owner_id=self.poll["owner_id"], is_board=int(self.poll["is_board"]), poll_id=self.poll["id"])
|
||||||
self.poll = self.session.vk.client.polls.getById(**data)
|
self.poll = self.session.vk.client.polls.getById(**data)
|
||||||
|
|
||||||
def load_poll(self, load_results=False):
|
def load_poll(self, load_results=False):
|
||||||
user = self.session.get_user(self.poll["author_id"])
|
user = self.session.get_user(self.poll["author_id"])
|
||||||
title = _("Poll from {user1_nom}").format(**user)
|
title = _("Poll from {user1_nom}").format(**user)
|
||||||
self.send_message("set_title", value=title)
|
self.send_message("set_title", value=title)
|
||||||
self.send_message("set", control="question", value=self.poll["question"])
|
self.send_message("set", control="question", value=self.poll["question"])
|
||||||
if len(self.poll["answer_ids"]) > 0 or ("is_closed" in self.poll and self.poll["is_closed"] == True) or load_results == True or ("can_vote" in self.poll and self.poll["can_vote"] == False):
|
if len(self.poll["answer_ids"]) > 0 or ("is_closed" in self.poll and self.poll["is_closed"] == True) or load_results == True or ("can_vote" in self.poll and self.poll["can_vote"] == False):
|
||||||
options = []
|
options = []
|
||||||
for i in self.poll["answers"]:
|
for i in self.poll["answers"]:
|
||||||
options.append((i["text"], i["votes"], i["rate"]))
|
options.append((i["text"], i["votes"], i["rate"]))
|
||||||
self.send_message("add_options", options=options, multiple=self.poll["multiple"])
|
self.send_message("add_options", options=options, multiple=self.poll["multiple"])
|
||||||
self.send_message("done")
|
self.send_message("done")
|
||||||
self.send_message("disable_control", control="ok")
|
self.send_message("disable_control", control="ok")
|
||||||
else:
|
else:
|
||||||
options = []
|
options = []
|
||||||
for i in self.poll["answers"]:
|
for i in self.poll["answers"]:
|
||||||
options.append(i["text"])
|
options.append(i["text"])
|
||||||
self.send_message("add_options", options=options, multiple=self.poll["multiple"])
|
self.send_message("add_options", options=options, multiple=self.poll["multiple"])
|
||||||
self.send_message("done")
|
self.send_message("done")
|
||||||
|
|
||||||
def vote(self, answers):
|
def vote(self, answers):
|
||||||
ids = ""
|
ids = ""
|
||||||
for i in range(0, len(self.poll["answers"])):
|
for i in range(0, len(self.poll["answers"])):
|
||||||
if answers[i] == True:
|
if answers[i] == True:
|
||||||
ids = ids+"{answer_id},".format(answer_id=self.poll["answers"][i]["id"])
|
ids = ids+"{answer_id},".format(answer_id=self.poll["answers"][i]["id"])
|
||||||
if self.poll["multiple"] == False:
|
if self.poll["multiple"] == False:
|
||||||
break
|
break
|
||||||
if ids == "":
|
if ids == "":
|
||||||
log.exception("An error occurred when retrieving answer IDS for the following poll: %r. Provided answer list: %r" % (self.poll, answers))
|
log.exception("An error occurred when retrieving answer IDS for the following poll: %r. Provided answer list: %r" % (self.poll, answers))
|
||||||
return
|
return
|
||||||
data = dict(owner_id=self.poll["owner_id"], poll_id=self.poll["id"], answer_ids=ids, is_board=int(self.poll["is_board"]))
|
data = dict(owner_id=self.poll["owner_id"], poll_id=self.poll["id"], answer_ids=ids, is_board=int(self.poll["is_board"]))
|
||||||
result = self.session.vk.client.polls.addVote(**data)
|
result = self.session.vk.client.polls.addVote(**data)
|
||||||
if result == 1:
|
if result == 1:
|
||||||
output.speak(_("Your vote has been added to this poll."))
|
output.speak(_("Your vote has been added to this poll."))
|
||||||
|
@ -18,151 +18,151 @@ log = logging.getLogger(__file__)
|
|||||||
|
|
||||||
class displayTopicPresenter(basePost.displayPostPresenter):
|
class displayTopicPresenter(basePost.displayPostPresenter):
|
||||||
|
|
||||||
def __init__(self, session, postObject, group_id, view, interactor):
|
def __init__(self, session, postObject, group_id, view, interactor):
|
||||||
self.type = "topic"
|
self.type = "topic"
|
||||||
self.modulename = "display_topic"
|
self.modulename = "display_topic"
|
||||||
self.interactor = interactor
|
self.interactor = interactor
|
||||||
self.view = view
|
self.view = view
|
||||||
self.interactor.install(view=view, presenter=self, modulename=self.modulename)
|
self.interactor.install(view=view, presenter=self, modulename=self.modulename)
|
||||||
self.session = session
|
self.session = session
|
||||||
self.post = postObject
|
self.post = postObject
|
||||||
self.group_id = group_id
|
self.group_id = group_id
|
||||||
self.load_images = False
|
self.load_images = False
|
||||||
# We'll put images here, so it will be easier to work with them.
|
# We'll put images here, so it will be easier to work with them.
|
||||||
self.images = []
|
self.images = []
|
||||||
self.imageIndex = 0
|
self.imageIndex = 0
|
||||||
result = self.get_post_information()
|
result = self.get_post_information()
|
||||||
# Stop loading everything else if post was deleted.
|
# Stop loading everything else if post was deleted.
|
||||||
if result == False:
|
if result == False:
|
||||||
self.interactor.uninstall()
|
self.interactor.uninstall()
|
||||||
return
|
return
|
||||||
self.worker = threading.Thread(target=self.load_all_components)
|
self.worker = threading.Thread(target=self.load_all_components)
|
||||||
self.worker.finished = threading.Event()
|
self.worker.finished = threading.Event()
|
||||||
self.worker.start()
|
self.worker.start()
|
||||||
self.attachments = []
|
self.attachments = []
|
||||||
# connect pubsub event for posted comments.
|
# connect pubsub event for posted comments.
|
||||||
pub.subscribe(self.posted, "posted")
|
pub.subscribe(self.posted, "posted")
|
||||||
self.run()
|
self.run()
|
||||||
pub.unsubscribe(self.posted, "posted")
|
pub.unsubscribe(self.posted, "posted")
|
||||||
|
|
||||||
def load_all_components(self):
|
def load_all_components(self):
|
||||||
self.get_comments()
|
self.get_comments()
|
||||||
|
|
||||||
def get_post_information(self):
|
def get_post_information(self):
|
||||||
title = self.post["title"]
|
title = self.post["title"]
|
||||||
self.send_message("set_title", value=title)
|
self.send_message("set_title", value=title)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def get_comments(self):
|
def get_comments(self):
|
||||||
""" Get comments and insert them in a list."""
|
""" Get comments and insert them in a list."""
|
||||||
self.comments = self.session.vk.client.board.getComments(group_id=self.group_id, topic_id=self.post["id"], need_likes=1, count=100, extended=1, sort="desc")
|
self.comments = self.session.vk.client.board.getComments(group_id=self.group_id, topic_id=self.post["id"], need_likes=1, count=100, extended=1, sort="desc")
|
||||||
comments_ = []
|
comments_ = []
|
||||||
data = dict(profiles=self.comments["profiles"], groups=[])
|
data = dict(profiles=self.comments["profiles"], groups=[])
|
||||||
self.session.process_usernames(data)
|
self.session.process_usernames(data)
|
||||||
self.comments["items"].reverse()
|
self.comments["items"].reverse()
|
||||||
# If there are less than 100 comments in the topic we should disable the "load previous" button.
|
# If there are less than 100 comments in the topic we should disable the "load previous" button.
|
||||||
if self.comments["count"] <= 100:
|
if self.comments["count"] <= 100:
|
||||||
self.send_message("disable_control", control="load_more_comments")
|
self.send_message("disable_control", control="load_more_comments")
|
||||||
else:
|
else:
|
||||||
left_comments = self.comments["count"]-len(self.comments["items"])
|
left_comments = self.comments["count"]-len(self.comments["items"])
|
||||||
if left_comments > 100:
|
if left_comments > 100:
|
||||||
left_comments = 100
|
left_comments = 100
|
||||||
self.send_message("set_label", control="load_more_comments", label=_("Load {comments} previous comments").format(comments=left_comments))
|
self.send_message("set_label", control="load_more_comments", label=_("Load {comments} previous comments").format(comments=left_comments))
|
||||||
for i in self.comments["items"]:
|
for i in self.comments["items"]:
|
||||||
# If comment has a "deleted" key it should not be displayed, obviously.
|
# If comment has a "deleted" key it should not be displayed, obviously.
|
||||||
if "deleted" in i:
|
if "deleted" in i:
|
||||||
continue
|
continue
|
||||||
from_ = self.session.get_user(i["from_id"])["user1_nom"]
|
from_ = self.session.get_user(i["from_id"])["user1_nom"]
|
||||||
# match user mentions inside text comment.
|
# match user mentions inside text comment.
|
||||||
original_date = arrow.get(i["date"])
|
original_date = arrow.get(i["date"])
|
||||||
created_at = original_date.humanize(locale=languageHandler.curLang[:2])
|
created_at = original_date.humanize(locale=languageHandler.curLang[:2])
|
||||||
likes = str(i["likes"]["count"])
|
likes = str(i["likes"]["count"])
|
||||||
text = utils.clean_text(text=i["text"])
|
text = utils.clean_text(text=i["text"])
|
||||||
comments_.append((from_, text, created_at, likes))
|
comments_.append((from_, text, created_at, likes))
|
||||||
self.send_message("add_items", control="comments", items=comments_)
|
self.send_message("add_items", control="comments", items=comments_)
|
||||||
|
|
||||||
def post_like(self):
|
def post_like(self):
|
||||||
c = self.interactor.view.comments.get_selected()
|
c = self.interactor.view.comments.get_selected()
|
||||||
id = self.comments["items"][c]["id"]
|
id = self.comments["items"][c]["id"]
|
||||||
if self.comments["items"][c]["likes"]["user_likes"] == 1:
|
if self.comments["items"][c]["likes"]["user_likes"] == 1:
|
||||||
l = self.session.vk.client.likes.delete(owner_id=-1*self.group_id, item_id=id, type="topic_comment")
|
l = self.session.vk.client.likes.delete(owner_id=-1*self.group_id, item_id=id, type="topic_comment")
|
||||||
output.speak(_("You don't like this"))
|
output.speak(_("You don't like this"))
|
||||||
self.comments["items"][c]["likes"]["count"] = l["likes"]
|
self.comments["items"][c]["likes"]["count"] = l["likes"]
|
||||||
self.comments["items"][c]["likes"]["user_likes"] = 2
|
self.comments["items"][c]["likes"]["user_likes"] = 2
|
||||||
self.send_message("set_label", control="like", label=_("&Like"))
|
self.send_message("set_label", control="like", label=_("&Like"))
|
||||||
else:
|
else:
|
||||||
l = self.session.vk.client.likes.add(owner_id=-1*self.group_id, item_id=id, type="topic_comment")
|
l = self.session.vk.client.likes.add(owner_id=-1*self.group_id, item_id=id, type="topic_comment")
|
||||||
output.speak(_("You liked this"))
|
output.speak(_("You liked this"))
|
||||||
self.send_message("set_label", control="like", label=_("&Dislike"))
|
self.send_message("set_label", control="like", label=_("&Dislike"))
|
||||||
self.comments["items"][c]["likes"]["count"] = l["likes"]
|
self.comments["items"][c]["likes"]["count"] = l["likes"]
|
||||||
self.comments["items"][c]["likes"]["user_likes"] = 1
|
self.comments["items"][c]["likes"]["user_likes"] = 1
|
||||||
self.clear_comments_list()
|
self.clear_comments_list()
|
||||||
|
|
||||||
def change_comment(self, comment):
|
def change_comment(self, comment):
|
||||||
comment = self.comments["items"][comment]
|
comment = self.comments["items"][comment]
|
||||||
self.send_message("clean_list", list="attachments")
|
self.send_message("clean_list", list="attachments")
|
||||||
self.get_attachments(comment, "")
|
self.get_attachments(comment, "")
|
||||||
if comment["likes"]["user_likes"] == 1:
|
if comment["likes"]["user_likes"] == 1:
|
||||||
self.send_message("set_label", control="like", label=_("&Dislike"))
|
self.send_message("set_label", control="like", label=_("&Dislike"))
|
||||||
else:
|
else:
|
||||||
self.send_message("set_label", control="like", label=_("&Like"))
|
self.send_message("set_label", control="like", label=_("&Like"))
|
||||||
|
|
||||||
def add_comment(self):
|
def add_comment(self):
|
||||||
comment = createPostPresenter(session=self.session, interactor=interactors.createPostInteractor(), view=views.createPostDialog(title=_("Add a comment"), message="", text="", mode="comment"))
|
comment = createPostPresenter(session=self.session, interactor=interactors.createPostInteractor(), view=views.createPostDialog(title=_("Add a comment"), message="", text="", mode="comment"))
|
||||||
if hasattr(comment, "text") or hasattr(comment, "privacy"):
|
if hasattr(comment, "text") or hasattr(comment, "privacy"):
|
||||||
post_arguments = dict(group_id=self.group_id, topic_id=self.post["id"], message=comment.text)
|
post_arguments = dict(group_id=self.group_id, topic_id=self.post["id"], message=comment.text)
|
||||||
attachments = []
|
attachments = []
|
||||||
if hasattr(comment, "attachments"):
|
if hasattr(comment, "attachments"):
|
||||||
attachments = comment.attachments
|
attachments = comment.attachments
|
||||||
call_threaded(pub.sendMessage, "post", parent_endpoint="board", child_endpoint="createComment", attachments_list=attachments, post_arguments=post_arguments)
|
call_threaded(pub.sendMessage, "post", parent_endpoint="board", child_endpoint="createComment", attachments_list=attachments, post_arguments=post_arguments)
|
||||||
|
|
||||||
def reply(self, comment):
|
def reply(self, comment):
|
||||||
c = self.comments["items"][comment]
|
c = self.comments["items"][comment]
|
||||||
comment = createPostPresenter(session=self.session, interactor=interactors.createPostInteractor(), view=views.createPostDialog(title=_("Reply to {user1_nom}").format(**self.session.get_user(c["from_id"])), message="", text="", mode="comment"))
|
comment = createPostPresenter(session=self.session, interactor=interactors.createPostInteractor(), view=views.createPostDialog(title=_("Reply to {user1_nom}").format(**self.session.get_user(c["from_id"])), message="", text="", mode="comment"))
|
||||||
if hasattr(comment, "text") or hasattr(comment, "privacy"):
|
if hasattr(comment, "text") or hasattr(comment, "privacy"):
|
||||||
user = self.session.get_user(c["from_id"])
|
user = self.session.get_user(c["from_id"])
|
||||||
name = user["user1_nom"].split(" ")[0]
|
name = user["user1_nom"].split(" ")[0]
|
||||||
comment.text = "[post{post_id}|{name}], {text}".format(post_id=c["id"], text=comment.text, name=name)
|
comment.text = "[post{post_id}|{name}], {text}".format(post_id=c["id"], text=comment.text, name=name)
|
||||||
group_id = self.group_id
|
group_id = self.group_id
|
||||||
topic_id = self.post["id"]
|
topic_id = self.post["id"]
|
||||||
post_arguments = dict(group_id=group_id, topic_id=topic_id, reply_to_comment=c["id"], message=comment.text)
|
post_arguments = dict(group_id=group_id, topic_id=topic_id, reply_to_comment=c["id"], message=comment.text)
|
||||||
attachments = []
|
attachments = []
|
||||||
if hasattr(comment, "attachments"):
|
if hasattr(comment, "attachments"):
|
||||||
attachments = comment.attachments
|
attachments = comment.attachments
|
||||||
call_threaded(pub.sendMessage, "post", parent_endpoint="board", child_endpoint="createComment", attachments_list=attachments, post_arguments=post_arguments)
|
call_threaded(pub.sendMessage, "post", parent_endpoint="board", child_endpoint="createComment", attachments_list=attachments, post_arguments=post_arguments)
|
||||||
|
|
||||||
def show_comment(self, comment_index):
|
def show_comment(self, comment_index):
|
||||||
c = self.comments["items"][comment_index]
|
c = self.comments["items"][comment_index]
|
||||||
c["post_id"] = self.post["id"]
|
c["post_id"] = self.post["id"]
|
||||||
c["group_id"] = -1*self.group_id
|
c["group_id"] = -1*self.group_id
|
||||||
a = displayTopicCommentPresenter(session=self.session, postObject=c, interactor=interactors.displayPostInteractor(), view=views.displayComment())
|
a = displayTopicCommentPresenter(session=self.session, postObject=c, interactor=interactors.displayPostInteractor(), view=views.displayComment())
|
||||||
|
|
||||||
def load_more_comments(self):
|
def load_more_comments(self):
|
||||||
offset = len(self.comments["items"])
|
offset = len(self.comments["items"])
|
||||||
comments = self.session.vk.client.board.getComments(group_id=self.group_id, topic_id=self.post["id"], need_likes=1, count=100, extended=1, sort="desc", offset=offset)
|
comments = self.session.vk.client.board.getComments(group_id=self.group_id, topic_id=self.post["id"], need_likes=1, count=100, extended=1, sort="desc", offset=offset)
|
||||||
data = dict(profiles=comments["profiles"], groups=[])
|
data = dict(profiles=comments["profiles"], groups=[])
|
||||||
self.session.process_usernames(data)
|
self.session.process_usernames(data)
|
||||||
# If there are less than 100 comments in the topic we should disable the "load previous" button.
|
# If there are less than 100 comments in the topic we should disable the "load previous" button.
|
||||||
for i in comments["items"]:
|
for i in comments["items"]:
|
||||||
self.comments["items"].insert(0, i)
|
self.comments["items"].insert(0, i)
|
||||||
for i in comments["items"]:
|
for i in comments["items"]:
|
||||||
# If comment has a "deleted" key it should not be displayed, obviously.
|
# If comment has a "deleted" key it should not be displayed, obviously.
|
||||||
if "deleted" in i:
|
if "deleted" in i:
|
||||||
continue
|
continue
|
||||||
from_ = self.session.get_user(i["from_id"])["user1_nom"]
|
from_ = self.session.get_user(i["from_id"])["user1_nom"]
|
||||||
# match user mentions inside text comment.
|
# match user mentions inside text comment.
|
||||||
original_date = arrow.get(i["date"])
|
original_date = arrow.get(i["date"])
|
||||||
created_at = original_date.humanize(locale=languageHandler.curLang[:2])
|
created_at = original_date.humanize(locale=languageHandler.curLang[:2])
|
||||||
likes = str(i["likes"]["count"])
|
likes = str(i["likes"]["count"])
|
||||||
text = utils.clean_text(text=i["text"])
|
text = utils.clean_text(text=i["text"])
|
||||||
self.send_message("add_item", control="comments", item=(from_, text, created_at, likes), reversed=True)
|
self.send_message("add_item", control="comments", item=(from_, text, created_at, likes), reversed=True)
|
||||||
if len(self.comments["items"]) == self.comments["count"]:
|
if len(self.comments["items"]) == self.comments["count"]:
|
||||||
self.send_message("disable_control", control="load_more_comments")
|
self.send_message("disable_control", control="load_more_comments")
|
||||||
else:
|
else:
|
||||||
left_comments = self.comments["count"]-len(self.comments["items"])
|
left_comments = self.comments["count"]-len(self.comments["items"])
|
||||||
if left_comments > 100:
|
if left_comments > 100:
|
||||||
left_comments = 100
|
left_comments = 100
|
||||||
self.send_message("set_label", control="load_more_comments", label=_("Load {comments} previous comments").format(comments=left_comments))
|
self.send_message("set_label", control="load_more_comments", label=_("Load {comments} previous comments").format(comments=left_comments))
|
||||||
|
|
||||||
def posted(self, from_buffer=None):
|
def posted(self, from_buffer=None):
|
||||||
self.clear_comments_list()
|
self.clear_comments_list()
|
||||||
|
@ -10,44 +10,44 @@ from . import comment
|
|||||||
log = logging.getLogger(__file__)
|
log = logging.getLogger(__file__)
|
||||||
|
|
||||||
def get_message(status):
|
def get_message(status):
|
||||||
message = ""
|
message = ""
|
||||||
if "text" in status:
|
if "text" in status:
|
||||||
message = utils.clean_text(status["text"])
|
message = utils.clean_text(status["text"])
|
||||||
return message
|
return message
|
||||||
|
|
||||||
class displayTopicCommentPresenter(comment.displayCommentPresenter):
|
class displayTopicCommentPresenter(comment.displayCommentPresenter):
|
||||||
|
|
||||||
def get_post_information(self):
|
def get_post_information(self):
|
||||||
from_ = self.session.get_user(self.post[self.user_identifier])
|
from_ = self.session.get_user(self.post[self.user_identifier])
|
||||||
title = from_["user1_nom"]
|
title = from_["user1_nom"]
|
||||||
self.send_message("set_title", value=title)
|
self.send_message("set_title", value=title)
|
||||||
message = ""
|
message = ""
|
||||||
message = get_message(self.post)
|
message = get_message(self.post)
|
||||||
self.send_message("set", control="post_view", value=message)
|
self.send_message("set", control="post_view", value=message)
|
||||||
self.get_attachments(self.post, message)
|
self.get_attachments(self.post, message)
|
||||||
self.check_image_load()
|
self.check_image_load()
|
||||||
self.send_message("disable_control", control="reply")
|
self.send_message("disable_control", control="reply")
|
||||||
|
|
||||||
def post_like(self):
|
def post_like(self):
|
||||||
id = self.post["id"]
|
id = self.post["id"]
|
||||||
if self.post["likes"]["user_likes"] == 1:
|
if self.post["likes"]["user_likes"] == 1:
|
||||||
l = self.session.vk.client.likes.delete(owner_id=self.post["group_id"], item_id=id, type="topic_comment")
|
l = self.session.vk.client.likes.delete(owner_id=self.post["group_id"], item_id=id, type="topic_comment")
|
||||||
output.speak(_("You don't like this"))
|
output.speak(_("You don't like this"))
|
||||||
self.post["likes"]["count"] = l["likes"]
|
self.post["likes"]["count"] = l["likes"]
|
||||||
self.post["likes"]["user_likes"] = 2
|
self.post["likes"]["user_likes"] = 2
|
||||||
self.send_message("set_label", control="like", label=_("&Like"))
|
self.send_message("set_label", control="like", label=_("&Like"))
|
||||||
else:
|
else:
|
||||||
l = self.session.vk.client.likes.add(owner_id=self.post["group_id"], item_id=id, type="topic_comment")
|
l = self.session.vk.client.likes.add(owner_id=self.post["group_id"], item_id=id, type="topic_comment")
|
||||||
output.speak(_("You liked this"))
|
output.speak(_("You liked this"))
|
||||||
self.send_message("set_label", control="like", label=_("&Dislike"))
|
self.send_message("set_label", control="like", label=_("&Dislike"))
|
||||||
self.post["likes"]["count"] = l["likes"]
|
self.post["likes"]["count"] = l["likes"]
|
||||||
self.post["likes"]["user_likes"] = 1
|
self.post["likes"]["user_likes"] = 1
|
||||||
self.get_likes()
|
self.get_likes()
|
||||||
|
|
||||||
def show_likes(self):
|
def show_likes(self):
|
||||||
""" show likes for the specified post."""
|
""" show likes for the specified post."""
|
||||||
data = dict(type="topic_comment", owner_id=self.post["group_id"], item_id=self.post["id"], extended=True, count=100, skip_own=True)
|
data = dict(type="topic_comment", owner_id=self.post["group_id"], item_id=self.post["id"], extended=True, count=100, skip_own=True)
|
||||||
result = self.session.vk.client.likes.getList(**data)
|
result = self.session.vk.client.likes.getList(**data)
|
||||||
if result["count"] > 0:
|
if result["count"] > 0:
|
||||||
post = {"source_id": self.post["group_id"], "friends": {"items": result["items"]}}
|
post = {"source_id": self.post["group_id"], "friends": {"items": result["items"]}}
|
||||||
pub.sendMessage("open-post", post_object=post, controller_="displayFriendship", vars=dict(caption=_("people who liked this")))
|
pub.sendMessage("open-post", post_object=post, controller_="displayFriendship", vars=dict(caption=_("people who liked this")))
|
||||||
|
@ -8,22 +8,22 @@ from logging import getLogger
|
|||||||
log = getLogger("controller.longpolThread")
|
log = getLogger("controller.longpolThread")
|
||||||
|
|
||||||
class worker(threading.Thread):
|
class worker(threading.Thread):
|
||||||
def __init__(self, session):
|
def __init__(self, session):
|
||||||
super(worker, self).__init__()
|
super(worker, self).__init__()
|
||||||
log.debug("Instantiating longPoll server")
|
log.debug("Instantiating longPoll server")
|
||||||
self.session = session
|
self.session = session
|
||||||
self.longpoll = VkLongPoll(self.session.vk.session_object)
|
self.longpoll = VkLongPoll(self.session.vk.session_object)
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
try:
|
try:
|
||||||
for event in self.longpoll.listen():
|
for event in self.longpoll.listen():
|
||||||
if event.type == VkEventType.MESSAGE_NEW:
|
if event.type == VkEventType.MESSAGE_NEW:
|
||||||
pub.sendMessage("order-sent-message", obj=event)
|
pub.sendMessage("order-sent-message", obj=event)
|
||||||
elif event.type == VkEventType.USER_ONLINE:
|
elif event.type == VkEventType.USER_ONLINE:
|
||||||
pub.sendMessage("user-online", event=event)
|
pub.sendMessage("user-online", event=event)
|
||||||
elif event.type == VkEventType.USER_OFFLINE:
|
elif event.type == VkEventType.USER_OFFLINE:
|
||||||
pub.sendMessage("user-offline", event=event)
|
pub.sendMessage("user-offline", event=event)
|
||||||
elif event.type == VkEventType.USER_TYPING:
|
elif event.type == VkEventType.USER_TYPING:
|
||||||
pub.sendMessage("user-typing", obj=event)
|
pub.sendMessage("user-typing", obj=event)
|
||||||
except:
|
except:
|
||||||
pub.sendMessage("longpoll-read-timeout")
|
pub.sendMessage("longpoll-read-timeout")
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -21,234 +21,234 @@ player = None
|
|||||||
log = logging.getLogger("player")
|
log = logging.getLogger("player")
|
||||||
|
|
||||||
def setup():
|
def setup():
|
||||||
global player
|
global player
|
||||||
if player == None:
|
if player == None:
|
||||||
player = audioPlayer()
|
player = audioPlayer()
|
||||||
|
|
||||||
class audioPlayer(object):
|
class audioPlayer(object):
|
||||||
""" A media player which will play all passed URLS."""
|
""" A media player which will play all passed URLS."""
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
# control variable for checking if another file has been sent to the player before,
|
# control variable for checking if another file has been sent to the player before,
|
||||||
# thus avoiding double file playback and other oddities happening in sound_lib from time to time.
|
# thus avoiding double file playback and other oddities happening in sound_lib from time to time.
|
||||||
self.is_playing = False
|
self.is_playing = False
|
||||||
# This will be the URLStream handler
|
# This will be the URLStream handler
|
||||||
self.stream = None
|
self.stream = None
|
||||||
self.message = None
|
self.message = None
|
||||||
self.vol = config.app["sound"]["volume"]
|
self.vol = config.app["sound"]["volume"]
|
||||||
# this variable is set to true when the URLPlayer is decoding something, thus it will block other calls to the play method.
|
# this variable is set to true when the URLPlayer is decoding something, thus it will block other calls to the play method.
|
||||||
self.is_working = False
|
self.is_working = False
|
||||||
# Playback queue.
|
# Playback queue.
|
||||||
self.queue = []
|
self.queue = []
|
||||||
# Index of the currently playing track.
|
# Index of the currently playing track.
|
||||||
self.playing_track = 0
|
self.playing_track = 0
|
||||||
self.playing_all = False
|
self.playing_all = False
|
||||||
self.worker = RepeatingTimer(5, self.player_function)
|
self.worker = RepeatingTimer(5, self.player_function)
|
||||||
self.worker.start()
|
self.worker.start()
|
||||||
# Status of the player.
|
# Status of the player.
|
||||||
self.stopped = True
|
self.stopped = True
|
||||||
# Modify some default settings present in Bass so it will increase timeout connection, thus causing less "connection timed out" errors when playing.
|
# Modify some default settings present in Bass so it will increase timeout connection, thus causing less "connection timed out" errors when playing.
|
||||||
bassconfig = BassConfig()
|
bassconfig = BassConfig()
|
||||||
# Set timeout connection to 30 seconds.
|
# Set timeout connection to 30 seconds.
|
||||||
bassconfig["net_timeout"] = 30000
|
bassconfig["net_timeout"] = 30000
|
||||||
# subscribe all pubsub events.
|
# subscribe all pubsub events.
|
||||||
pub.subscribe(self.play, "play")
|
pub.subscribe(self.play, "play")
|
||||||
pub.subscribe(self.play_message, "play-message")
|
pub.subscribe(self.play_message, "play-message")
|
||||||
pub.subscribe(self.play_all, "play-all")
|
pub.subscribe(self.play_all, "play-all")
|
||||||
pub.subscribe(self.pause, "pause")
|
pub.subscribe(self.pause, "pause")
|
||||||
pub.subscribe(self.stop, "stop")
|
pub.subscribe(self.stop, "stop")
|
||||||
pub.subscribe(self.play_next, "play-next")
|
pub.subscribe(self.play_next, "play-next")
|
||||||
pub.subscribe(self.play_previous, "play-previous")
|
pub.subscribe(self.play_previous, "play-previous")
|
||||||
pub.subscribe(self.seek, "seek")
|
pub.subscribe(self.seek, "seek")
|
||||||
|
|
||||||
# Stopped has a special function here, hence the decorator
|
# Stopped has a special function here, hence the decorator
|
||||||
# when stopped will be set to True, it will send a pubsub event to inform other parts of the application about the status change.
|
# when stopped will be set to True, it will send a pubsub event to inform other parts of the application about the status change.
|
||||||
# this is useful for changing labels between play and pause, and so on, in buttons.
|
# this is useful for changing labels between play and pause, and so on, in buttons.
|
||||||
@property
|
@property
|
||||||
def stopped(self):
|
def stopped(self):
|
||||||
return self._stopped
|
return self._stopped
|
||||||
|
|
||||||
@stopped.setter
|
@stopped.setter
|
||||||
def stopped(self, value):
|
def stopped(self, value):
|
||||||
self._stopped = value
|
self._stopped = value
|
||||||
pub.sendMessage("playback-changed", stopped=value)
|
pub.sendMessage("playback-changed", stopped=value)
|
||||||
|
|
||||||
def play(self, object, set_info=True, fresh=False):
|
def play(self, object, set_info=True, fresh=False):
|
||||||
""" Play an URl Stream.
|
""" Play an URl Stream.
|
||||||
@object dict: typically an audio object as returned by VK, with a "url" component which must be a valid URL to a media file.
|
@object dict: typically an audio object as returned by VK, with a "url" component which must be a valid URL to a media file.
|
||||||
@set_info bool: If true, will set information about the currently playing audio in the application status bar.
|
@set_info bool: If true, will set information about the currently playing audio in the application status bar.
|
||||||
@fresh bool: If True, will remove everything playing in the queue and start this file only. otherwise it will play the new file but not remove the current queue."""
|
@fresh bool: If True, will remove everything playing in the queue and start this file only. otherwise it will play the new file but not remove the current queue."""
|
||||||
if "url" in object and object["url"] =="":
|
if "url" in object and object["url"] =="":
|
||||||
pub.sendMessage("notify", message=_("This file could not be played because it is not allowed in your country"))
|
pub.sendMessage("notify", message=_("This file could not be played because it is not allowed in your country"))
|
||||||
return
|
return
|
||||||
if self.stream != None and (self.stream.is_playing == True or self.stream.is_stalled == True):
|
if self.stream != None and (self.stream.is_playing == True or self.stream.is_stalled == True):
|
||||||
try:
|
try:
|
||||||
self.stream.stop()
|
self.stream.stop()
|
||||||
except BassError:
|
except BassError:
|
||||||
log.exception("error when stopping the file")
|
log.exception("error when stopping the file")
|
||||||
self.stream = None
|
self.stream = None
|
||||||
self.stopped = True
|
self.stopped = True
|
||||||
if fresh == True:
|
if fresh == True:
|
||||||
self.queue = []
|
self.queue = []
|
||||||
# Make sure that there are no other sounds trying to be played.
|
# Make sure that there are no other sounds trying to be played.
|
||||||
if self.is_working == False:
|
if self.is_working == False:
|
||||||
self.is_working = True
|
self.is_working = True
|
||||||
url_ = utils.transform_audio_url(object["url"])
|
url_ = utils.transform_audio_url(object["url"])
|
||||||
try:
|
try:
|
||||||
self.stream = URLStream(url=url_)
|
self.stream = URLStream(url=url_)
|
||||||
except:
|
except:
|
||||||
log.error("Unable to play URL %s" % (url_))
|
log.error("Unable to play URL %s" % (url_))
|
||||||
return
|
return
|
||||||
# Translators: {0} will be replaced with a song's title and {1} with the artist.
|
# Translators: {0} will be replaced with a song's title and {1} with the artist.
|
||||||
if set_info:
|
if set_info:
|
||||||
msg = _("Playing {0} by {1}").format(object["title"], object["artist"])
|
msg = _("Playing {0} by {1}").format(object["title"], object["artist"])
|
||||||
pub.sendMessage("update-status-bar", status=msg)
|
pub.sendMessage("update-status-bar", status=msg)
|
||||||
self.stream.volume = self.vol/100.0
|
self.stream.volume = self.vol/100.0
|
||||||
self.stream.play()
|
self.stream.play()
|
||||||
self.stopped = False
|
self.stopped = False
|
||||||
self.is_working = False
|
self.is_working = False
|
||||||
|
|
||||||
def play_message(self, message_url):
|
def play_message(self, message_url):
|
||||||
if self.message != None and (self.message.is_playing == True or self.message.is_stalled == True):
|
if self.message != None and (self.message.is_playing == True or self.message.is_stalled == True):
|
||||||
return self.stop_message()
|
return self.stop_message()
|
||||||
output.speak(_("Playing..."))
|
output.speak(_("Playing..."))
|
||||||
url_ = utils.transform_audio_url(message_url)
|
url_ = utils.transform_audio_url(message_url)
|
||||||
try:
|
try:
|
||||||
self.message = URLStream(url=url_)
|
self.message = URLStream(url=url_)
|
||||||
except:
|
except:
|
||||||
log.error("Unable to play URL %s" % (url_))
|
log.error("Unable to play URL %s" % (url_))
|
||||||
return
|
return
|
||||||
self.message.volume = self.vol/100.0
|
self.message.volume = self.vol/100.0
|
||||||
self.message.play()
|
self.message.play()
|
||||||
volume_percent = self.volume*0.25
|
volume_percent = self.volume*0.25
|
||||||
volume_step = self.volume*0.15
|
volume_step = self.volume*0.15
|
||||||
while self.stream.volume*100 > volume_percent:
|
while self.stream.volume*100 > volume_percent:
|
||||||
self.stream.volume = self.stream.volume-(volume_step/100)
|
self.stream.volume = self.stream.volume-(volume_step/100)
|
||||||
time.sleep(0.1)
|
time.sleep(0.1)
|
||||||
|
|
||||||
def stop(self):
|
def stop(self):
|
||||||
""" Stop audio playback. """
|
""" Stop audio playback. """
|
||||||
if self.stream != None and self.stream.is_playing == True:
|
if self.stream != None and self.stream.is_playing == True:
|
||||||
self.stream.stop()
|
self.stream.stop()
|
||||||
self.stopped = True
|
self.stopped = True
|
||||||
self.queue = []
|
self.queue = []
|
||||||
|
|
||||||
def stop_message(self):
|
def stop_message(self):
|
||||||
if hasattr(self, "message") and self.message != None and self.message.is_playing == True:
|
if hasattr(self, "message") and self.message != None and self.message.is_playing == True:
|
||||||
self.message.stop()
|
self.message.stop()
|
||||||
volume_step = self.volume*0.15
|
volume_step = self.volume*0.15
|
||||||
while self.stream.volume*100 < self.volume:
|
while self.stream.volume*100 < self.volume:
|
||||||
self.stream.volume = self.stream.volume+(volume_step/100)
|
self.stream.volume = self.stream.volume+(volume_step/100)
|
||||||
time.sleep(0.1)
|
time.sleep(0.1)
|
||||||
self.message = None
|
self.message = None
|
||||||
|
|
||||||
def pause(self):
|
def pause(self):
|
||||||
""" pause the current playback, without destroying the queue or the current stream. If the stream is already paused this function will resume the playback. """
|
""" pause the current playback, without destroying the queue or the current stream. If the stream is already paused this function will resume the playback. """
|
||||||
if self.stream != None:
|
if self.stream != None:
|
||||||
if self.stream.is_playing == True:
|
if self.stream.is_playing == True:
|
||||||
self.stream.pause()
|
self.stream.pause()
|
||||||
self.stopped = True
|
self.stopped = True
|
||||||
else:
|
else:
|
||||||
try:
|
try:
|
||||||
self.stream.play()
|
self.stream.play()
|
||||||
self.stopped = False
|
self.stopped = False
|
||||||
except BassError:
|
except BassError:
|
||||||
pass
|
pass
|
||||||
if self.playing_all == False and len(self.queue) > 0:
|
if self.playing_all == False and len(self.queue) > 0:
|
||||||
self.playing_all = True
|
self.playing_all = True
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def volume(self):
|
def volume(self):
|
||||||
return self.vol
|
return self.vol
|
||||||
|
|
||||||
@volume.setter
|
@volume.setter
|
||||||
def volume(self, vol):
|
def volume(self, vol):
|
||||||
if vol <= 100 and vol >= 0:
|
if vol <= 100 and vol >= 0:
|
||||||
self.vol = vol
|
self.vol = vol
|
||||||
elif vol < 0:
|
elif vol < 0:
|
||||||
self.vol = 0
|
self.vol = 0
|
||||||
elif vol > 100:
|
elif vol > 100:
|
||||||
self.vol = 100
|
self.vol = 100
|
||||||
if self.stream != None:
|
if self.stream != None:
|
||||||
if self.message != None and self.message.is_playing:
|
if self.message != None and self.message.is_playing:
|
||||||
self.stream.volume = (self.vol*0.25)/100.0
|
self.stream.volume = (self.vol*0.25)/100.0
|
||||||
self.message.volume = self.vol/100.0
|
self.message.volume = self.vol/100.0
|
||||||
else:
|
else:
|
||||||
self.stream.volume = self.vol/100.0
|
self.stream.volume = self.vol/100.0
|
||||||
|
|
||||||
def play_all(self, list_of_songs, shuffle=False):
|
def play_all(self, list_of_songs, shuffle=False):
|
||||||
""" Play all passed songs and adds all of those to the queue.
|
""" Play all passed songs and adds all of those to the queue.
|
||||||
@list_of_songs list: A list of audio objects returned by VK.
|
@list_of_songs list: A list of audio objects returned by VK.
|
||||||
@shuffle bool: If True, the files will be played randomly."""
|
@shuffle bool: If True, the files will be played randomly."""
|
||||||
if self.is_working:
|
if self.is_working:
|
||||||
return
|
return
|
||||||
self.playing_track = 0
|
self.playing_track = 0
|
||||||
self.stop()
|
self.stop()
|
||||||
# Skip all country restricted tracks as they are not playable here.
|
# Skip all country restricted tracks as they are not playable here.
|
||||||
self.queue = [i for i in list_of_songs if i["url"] != ""]
|
self.queue = [i for i in list_of_songs if i["url"] != ""]
|
||||||
if shuffle:
|
if shuffle:
|
||||||
random.shuffle(self.queue)
|
random.shuffle(self.queue)
|
||||||
call_threaded(self.play, self.queue[self.playing_track])
|
call_threaded(self.play, self.queue[self.playing_track])
|
||||||
self.playing_all = True
|
self.playing_all = True
|
||||||
|
|
||||||
def player_function(self):
|
def player_function(self):
|
||||||
""" Check if the stream has reached the end of the file so it will play the next song. """
|
""" Check if the stream has reached the end of the file so it will play the next song. """
|
||||||
if self.message != None and self.message.is_playing == False and len(self.message) == self.message.position:
|
if self.message != None and self.message.is_playing == False and len(self.message) == self.message.position:
|
||||||
volume_step = self.volume*0.15
|
volume_step = self.volume*0.15
|
||||||
while self.stream != None and self.stream.volume*100 < self.volume:
|
while self.stream != None and self.stream.volume*100 < self.volume:
|
||||||
self.stream.volume = self.stream.volume+(volume_step/100)
|
self.stream.volume = self.stream.volume+(volume_step/100)
|
||||||
time.sleep(0.1)
|
time.sleep(0.1)
|
||||||
if self.stream != None and self.stream.is_playing == False and self.stopped == False and len(self.stream) == self.stream.position:
|
if self.stream != None and self.stream.is_playing == False and self.stopped == False and len(self.stream) == self.stream.position:
|
||||||
if self.playing_track >= len(self.queue):
|
if self.playing_track >= len(self.queue):
|
||||||
self.stopped = True
|
self.stopped = True
|
||||||
self.playing_all = False
|
self.playing_all = False
|
||||||
return
|
return
|
||||||
elif self.playing_all == False:
|
elif self.playing_all == False:
|
||||||
self.stopped = True
|
self.stopped = True
|
||||||
return
|
return
|
||||||
elif self.playing_track < len(self.queue):
|
elif self.playing_track < len(self.queue):
|
||||||
self.playing_track += 1
|
self.playing_track += 1
|
||||||
self.play(self.queue[self.playing_track])
|
self.play(self.queue[self.playing_track])
|
||||||
|
|
||||||
def play_next(self):
|
def play_next(self):
|
||||||
""" Play the next song in the queue. """
|
""" Play the next song in the queue. """
|
||||||
if len(self.queue) == 0:
|
if len(self.queue) == 0:
|
||||||
return
|
return
|
||||||
if self.is_working:
|
if self.is_working:
|
||||||
return
|
return
|
||||||
if self.playing_track < len(self.queue)-1:
|
if self.playing_track < len(self.queue)-1:
|
||||||
self.playing_track += 1
|
self.playing_track += 1
|
||||||
else:
|
else:
|
||||||
self.playing_track = 0
|
self.playing_track = 0
|
||||||
call_threaded(self.play, self.queue[self.playing_track])
|
call_threaded(self.play, self.queue[self.playing_track])
|
||||||
|
|
||||||
def play_previous(self):
|
def play_previous(self):
|
||||||
""" Play the previous song in the queue. """
|
""" Play the previous song in the queue. """
|
||||||
if len(self.queue) == 0:
|
if len(self.queue) == 0:
|
||||||
return
|
return
|
||||||
if self.is_working:
|
if self.is_working:
|
||||||
return
|
return
|
||||||
if self.playing_track <= 0:
|
if self.playing_track <= 0:
|
||||||
self.playing_track = len(self.queue)-1
|
self.playing_track = len(self.queue)-1
|
||||||
else:
|
else:
|
||||||
self.playing_track -= 1
|
self.playing_track -= 1
|
||||||
call_threaded(self.play, self.queue[self.playing_track])
|
call_threaded(self.play, self.queue[self.playing_track])
|
||||||
|
|
||||||
def seek(self, ms=0):
|
def seek(self, ms=0):
|
||||||
if self.check_is_playing():
|
if self.check_is_playing():
|
||||||
if self.stream.position < 500000 and ms < 0:
|
if self.stream.position < 500000 and ms < 0:
|
||||||
self.stream.position = 0
|
self.stream.position = 0
|
||||||
else:
|
else:
|
||||||
try:
|
try:
|
||||||
self.stream.position = self.stream.position+ms
|
self.stream.position = self.stream.position+ms
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def check_is_playing(self):
|
def check_is_playing(self):
|
||||||
""" check if the player is already playing a stream. """
|
""" check if the player is already playing a stream. """
|
||||||
if self.stream == None:
|
if self.stream == None:
|
||||||
return False
|
return False
|
||||||
if self.stream != None and self.stream.is_playing == False and self.stream.is_stalled == False:
|
if self.stream != None and self.stream.is_playing == False and self.stream.is_stalled == False:
|
||||||
return False
|
return False
|
||||||
else:
|
else:
|
||||||
return True
|
return True
|
||||||
|
@ -15,154 +15,154 @@ log = logging.getLogger("controller.profiles")
|
|||||||
|
|
||||||
class userProfilePresenter(base.basePresenter):
|
class userProfilePresenter(base.basePresenter):
|
||||||
|
|
||||||
def __init__(self, session, user_id, view, interactor):
|
def __init__(self, session, user_id, view, interactor):
|
||||||
""" Default constructor:
|
""" Default constructor:
|
||||||
@session vk.session: The main session object, capable of calling VK methods.
|
@session vk.session: The main session object, capable of calling VK methods.
|
||||||
@user_id integer: User ID to retrieve information of.
|
@user_id integer: User ID to retrieve information of.
|
||||||
At the current time, only users (and not communities) are supported.
|
At the current time, only users (and not communities) are supported.
|
||||||
"""
|
"""
|
||||||
super(userProfilePresenter, self).__init__(view=view, interactor=interactor, modulename="user_profile")
|
super(userProfilePresenter, self).__init__(view=view, interactor=interactor, modulename="user_profile")
|
||||||
# self.person will hold a reference to the user object when retrieved from VK.
|
# self.person will hold a reference to the user object when retrieved from VK.
|
||||||
self.person = None
|
self.person = None
|
||||||
self.session = session
|
self.session = session
|
||||||
self.user_id = user_id
|
self.user_id = user_id
|
||||||
# Get information in a threaded way here.
|
# Get information in a threaded way here.
|
||||||
# Note: We do not handle any race condition here because due to the presenter only sending pubsub messages,
|
# Note: We do not handle any race condition here because due to the presenter only sending pubsub messages,
|
||||||
# Nothing happens if the pubsub send messages to the interactor after the latter has been destroyed.
|
# Nothing happens if the pubsub send messages to the interactor after the latter has been destroyed.
|
||||||
# Pubsub messages are just skipped if there are no listeners for them.
|
# Pubsub messages are just skipped if there are no listeners for them.
|
||||||
call_threaded(self.get_basic_information)
|
call_threaded(self.get_basic_information)
|
||||||
self.run()
|
self.run()
|
||||||
|
|
||||||
def get_basic_information(self):
|
def get_basic_information(self):
|
||||||
""" Gets and inserts basic user information.
|
""" Gets and inserts basic user information.
|
||||||
See https://vk.com/dev/users.get"""
|
See https://vk.com/dev/users.get"""
|
||||||
# List of fields (information) to retrieve. For a list of fields available for user objects,
|
# List of fields (information) to retrieve. For a list of fields available for user objects,
|
||||||
# see https://vk.com/dev/fields
|
# see https://vk.com/dev/fields
|
||||||
fields = "first_name, last_name, bdate, city, country, home_town, photo_200_orig, online, site, status, last_seen, occupation, relation, relatives, personal, connections, activities, interests, music, movies, tv, books, games, about, quotes, can_write_private_message, contacts, has_mobile, universities, education, schools"
|
fields = "first_name, last_name, bdate, city, country, home_town, photo_200_orig, online, site, status, last_seen, occupation, relation, relatives, personal, connections, activities, interests, music, movies, tv, books, games, about, quotes, can_write_private_message, contacts, has_mobile, universities, education, schools"
|
||||||
# ToDo: this method supports multiple user IDS, I'm not sure if this may be of any help for profile viewer.
|
# ToDo: this method supports multiple user IDS, I'm not sure if this may be of any help for profile viewer.
|
||||||
person = self.session.vk.client.users.get(user_ids=self.user_id, fields=fields)
|
person = self.session.vk.client.users.get(user_ids=self.user_id, fields=fields)
|
||||||
# If VK does not return anything it is very likely we have found a community.
|
# If VK does not return anything it is very likely we have found a community.
|
||||||
if len(person) == 0:
|
if len(person) == 0:
|
||||||
return output.speak(_("Information for groups is not supported, yet."))
|
return output.speak(_("Information for groups is not supported, yet."))
|
||||||
person = person[0]
|
person = person[0]
|
||||||
# toDo: remove this print when I will be done with creation of profile viewer logic.
|
# toDo: remove this print when I will be done with creation of profile viewer logic.
|
||||||
# print(person)
|
# print(person)
|
||||||
# From this part we will format data from VK so users will see it in the GUI control.
|
# From this part we will format data from VK so users will see it in the GUI control.
|
||||||
# Format full name.
|
# Format full name.
|
||||||
n = "{0} {1}".format(person["first_name"], person["last_name"])
|
n = "{0} {1}".format(person["first_name"], person["last_name"])
|
||||||
# format phones
|
# format phones
|
||||||
if person.get("mobile_phone") != None and person.get("mobile_phone") != "":
|
if person.get("mobile_phone") != None and person.get("mobile_phone") != "":
|
||||||
self.send_message("enable_control", tab="main_info", control="mobile_phone")
|
self.send_message("enable_control", tab="main_info", control="mobile_phone")
|
||||||
self.send_message("set", tab="main_info", control="mobile_phone", value=person["mobile_phone"])
|
self.send_message("set", tab="main_info", control="mobile_phone", value=person["mobile_phone"])
|
||||||
if person.get("home_phone") != None and person.get("home_phone") != "":
|
if person.get("home_phone") != None and person.get("home_phone") != "":
|
||||||
self.send_message("enable_control", tab="main_info", control="home_phone")
|
self.send_message("enable_control", tab="main_info", control="home_phone")
|
||||||
self.send_message("set", tab="main_info", control="home_phone", value=person["home_phone"])
|
self.send_message("set", tab="main_info", control="home_phone", value=person["home_phone"])
|
||||||
# Format birthdate.
|
# Format birthdate.
|
||||||
if "bdate" in person and person["bdate"] != "":
|
if "bdate" in person and person["bdate"] != "":
|
||||||
self.send_message("enable_control", tab="main_info", control="bdate")
|
self.send_message("enable_control", tab="main_info", control="bdate")
|
||||||
# VK can display dd.mm or dd.mm.yyyy birthdates. So let's compare the string lenght to handle both cases accordingly.
|
# VK can display dd.mm or dd.mm.yyyy birthdates. So let's compare the string lenght to handle both cases accordingly.
|
||||||
if len(person["bdate"]) <= 5: # dd.mm
|
if len(person["bdate"]) <= 5: # dd.mm
|
||||||
d = arrow.get(person["bdate"], "D.M")
|
d = arrow.get(person["bdate"], "D.M")
|
||||||
self.send_message("set", tab="main_info", control="bdate", value=d.format(_("MMMM D"), locale=languageHandler.curLang[:2]))
|
self.send_message("set", tab="main_info", control="bdate", value=d.format(_("MMMM D"), locale=languageHandler.curLang[:2]))
|
||||||
else: # mm.dd.yyyy
|
else: # mm.dd.yyyy
|
||||||
d = arrow.get(person["bdate"], "D.M.YYYY")
|
d = arrow.get(person["bdate"], "D.M.YYYY")
|
||||||
# Calculate user's years.
|
# Calculate user's years.
|
||||||
now = arrow.get()
|
now = arrow.get()
|
||||||
timedelta = now-d
|
timedelta = now-d
|
||||||
years = int(timedelta.days/365)
|
years = int(timedelta.days/365)
|
||||||
date = d.format(_("MMMM D, YYYY"), locale=languageHandler.curLang[:2])
|
date = d.format(_("MMMM D, YYYY"), locale=languageHandler.curLang[:2])
|
||||||
msg = _("{date} ({age} years)").format(date=date, age=years)
|
msg = _("{date} ({age} years)").format(date=date, age=years)
|
||||||
self.send_message("set", tab="main_info", control="bdate", value=msg)
|
self.send_message("set", tab="main_info", control="bdate", value=msg)
|
||||||
# Format current city and home town
|
# Format current city and home town
|
||||||
city = ""
|
city = ""
|
||||||
if "home_town" in person and person["home_town"] != "":
|
if "home_town" in person and person["home_town"] != "":
|
||||||
home_town = person["home_town"]
|
home_town = person["home_town"]
|
||||||
self.send_message("enable_control", tab="main_info", control="home_town")
|
self.send_message("enable_control", tab="main_info", control="home_town")
|
||||||
self.send_message("set", tab="main_info", control="home_town", value=home_town)
|
self.send_message("set", tab="main_info", control="home_town", value=home_town)
|
||||||
if "city" in person and len(person["city"]) > 0:
|
if "city" in person and len(person["city"]) > 0:
|
||||||
city = person["city"]["title"]
|
city = person["city"]["title"]
|
||||||
if "country" in person and person["country"] != "":
|
if "country" in person and person["country"] != "":
|
||||||
if city != "":
|
if city != "":
|
||||||
city = city+", {0}".format(person["country"]["title"])
|
city = city+", {0}".format(person["country"]["title"])
|
||||||
else:
|
else:
|
||||||
city = person["country"]["title"]
|
city = person["country"]["title"]
|
||||||
self.send_message("enable_control", tab="main_info", control="city")
|
self.send_message("enable_control", tab="main_info", control="city")
|
||||||
self.send_message("set", tab="main_info", control="city", value=city)
|
self.send_message("set", tab="main_info", control="city", value=city)
|
||||||
self.send_message("set", tab="main_info", control="name", value=n)
|
self.send_message("set", tab="main_info", control="name", value=n)
|
||||||
# Format title
|
# Format title
|
||||||
user = self.session.get_user(person["id"])
|
user = self.session.get_user(person["id"])
|
||||||
self.send_message("set_title", value=_("{user1_nom}'s profile").format(**user))
|
self.send_message("set_title", value=_("{user1_nom}'s profile").format(**user))
|
||||||
# Format website (or websites, if there are multiple of them).
|
# Format website (or websites, if there are multiple of them).
|
||||||
if "site" in person and person["site"] != "":
|
if "site" in person and person["site"] != "":
|
||||||
self.send_message("enable_control", tab="main_info", control="website")
|
self.send_message("enable_control", tab="main_info", control="website")
|
||||||
self.send_message("set", tab="main_info", control="website", value=person["site"])
|
self.send_message("set", tab="main_info", control="website", value=person["site"])
|
||||||
self.send_message("enable_control", tab="main_info", control="go_site")
|
self.send_message("enable_control", tab="main_info", control="go_site")
|
||||||
# Format status message.
|
# Format status message.
|
||||||
if "status" in person and person["status"] != "":
|
if "status" in person and person["status"] != "":
|
||||||
self.send_message("enable_control", tab="main_info", control="status")
|
self.send_message("enable_control", tab="main_info", control="status")
|
||||||
self.send_message("set", tab="main_info", control="status", value=person["status"])
|
self.send_message("set", tab="main_info", control="status", value=person["status"])
|
||||||
# Format occupation.
|
# Format occupation.
|
||||||
# toDo: Research in this field is needed. Sometimes it returns university information even if users have active work places.
|
# toDo: Research in this field is needed. Sometimes it returns university information even if users have active work places.
|
||||||
if "occupation" in person and person["occupation"] != None:
|
if "occupation" in person and person["occupation"] != None:
|
||||||
if person["occupation"]["type"] == "work": c1 = _("Work ")
|
if person["occupation"]["type"] == "work": c1 = _("Work ")
|
||||||
elif person["occupation"]["type"] == "school": c1 = _("Student ")
|
elif person["occupation"]["type"] == "school": c1 = _("Student ")
|
||||||
elif person["occupation"]["type"] == "university": c1 = _("Student ")
|
elif person["occupation"]["type"] == "university": c1 = _("Student ")
|
||||||
if "name" in person["occupation"] and person["occupation"]["name"] != "":
|
if "name" in person["occupation"] and person["occupation"]["name"] != "":
|
||||||
c2 = _("In {0}").format(person["occupation"]["name"],)
|
c2 = _("In {0}").format(person["occupation"]["name"],)
|
||||||
else:
|
else:
|
||||||
c2 = ""
|
c2 = ""
|
||||||
self.send_message("enable_control", tab="main_info", control="occupation")
|
self.send_message("enable_control", tab="main_info", control="occupation")
|
||||||
self.send_message("set", tab="main_info", control="occupation", value=c1+c2)
|
self.send_message("set", tab="main_info", control="occupation", value=c1+c2)
|
||||||
# format relationship status.
|
# format relationship status.
|
||||||
# ToDo: When dating someone, the button associated to the information should point to the profile of the user.
|
# ToDo: When dating someone, the button associated to the information should point to the profile of the user.
|
||||||
if "relation" in person and person["relation"] != 0:
|
if "relation" in person and person["relation"] != 0:
|
||||||
if person["relation"] == 1:
|
if person["relation"] == 1:
|
||||||
r = _("Single")
|
r = _("Single")
|
||||||
elif person["relation"] == 2:
|
elif person["relation"] == 2:
|
||||||
if "relation_partner" in person:
|
if "relation_partner" in person:
|
||||||
r = _("Dating with {0} {1}").format(person["relation_partner"]["first_name"], person["relation_partner"]["last_name"])
|
r = _("Dating with {0} {1}").format(person["relation_partner"]["first_name"], person["relation_partner"]["last_name"])
|
||||||
else:
|
else:
|
||||||
r = _("Dating")
|
r = _("Dating")
|
||||||
elif person["relation"] == 3:
|
elif person["relation"] == 3:
|
||||||
r = _("Engaged with {0} {1}").format(person["relation_partner"]["first_name"], person["relation_partner"]["last_name"])
|
r = _("Engaged with {0} {1}").format(person["relation_partner"]["first_name"], person["relation_partner"]["last_name"])
|
||||||
elif person["relation"] == 4:
|
elif person["relation"] == 4:
|
||||||
if "relation_partner" in person:
|
if "relation_partner" in person:
|
||||||
r = _("Married to {0} {1}").format(person["relation_partner"]["first_name"], person["relation_partner"]["last_name"])
|
r = _("Married to {0} {1}").format(person["relation_partner"]["first_name"], person["relation_partner"]["last_name"])
|
||||||
else:
|
else:
|
||||||
r = _("Married")
|
r = _("Married")
|
||||||
elif person["relation"] == 5:
|
elif person["relation"] == 5:
|
||||||
r = _("It's complicated")
|
r = _("It's complicated")
|
||||||
elif person["relation"] == 6:
|
elif person["relation"] == 6:
|
||||||
r = _("Actively searching")
|
r = _("Actively searching")
|
||||||
elif person["relation"] == 7:
|
elif person["relation"] == 7:
|
||||||
r = _("In love")
|
r = _("In love")
|
||||||
self.send_message("enable_control", tab="main_info", control="relation")
|
self.send_message("enable_control", tab="main_info", control="relation")
|
||||||
self.send_message("set_label", tab="main_info", control="relation", value=_("Relationship: ")+r)
|
self.send_message("set_label", tab="main_info", control="relation", value=_("Relationship: ")+r)
|
||||||
# format last seen.
|
# format last seen.
|
||||||
if "last_seen" in person and person["last_seen"] != False:
|
if "last_seen" in person and person["last_seen"] != False:
|
||||||
original_date = arrow.get(person["last_seen"]["time"])
|
original_date = arrow.get(person["last_seen"]["time"])
|
||||||
# Translators: This is the date of last seen
|
# Translators: This is the date of last seen
|
||||||
last_seen = _("{0}").format(original_date.humanize(locale=languageHandler.curLang[:2]),)
|
last_seen = _("{0}").format(original_date.humanize(locale=languageHandler.curLang[:2]),)
|
||||||
self.send_message("enable_control", tab="main_info", control="last_seen")
|
self.send_message("enable_control", tab="main_info", control="last_seen")
|
||||||
self.send_message("set", tab="main_info", control="last_seen", value=last_seen)
|
self.send_message("set", tab="main_info", control="last_seen", value=last_seen)
|
||||||
self.person = person
|
self.person = person
|
||||||
# Adds photo to the dialog.
|
# Adds photo to the dialog.
|
||||||
# ToDo: Need to ask if this has a visible effect in the dialog.
|
# ToDo: Need to ask if this has a visible effect in the dialog.
|
||||||
if "photo_200_orig" in person:
|
if "photo_200_orig" in person:
|
||||||
img = requests.get(person["photo_200_orig"])
|
img = requests.get(person["photo_200_orig"])
|
||||||
self.send_message("load_image", image=requests.get(person["photo_200_orig"]))
|
self.send_message("load_image", image=requests.get(person["photo_200_orig"]))
|
||||||
output.speak(_("Profile loaded"))
|
output.speak(_("Profile loaded"))
|
||||||
|
|
||||||
def get_urls(self, *args, **kwargs):
|
def get_urls(self, *args, **kwargs):
|
||||||
""" Allows to visit an user's website. """
|
""" Allows to visit an user's website. """
|
||||||
text = self.person["site"]
|
text = self.person["site"]
|
||||||
# Let's search for URLS with a regexp, as there are users with multiple websites in their profiles.
|
# Let's search for URLS with a regexp, as there are users with multiple websites in their profiles.
|
||||||
urls = utils.find_urls_in_text(text)
|
urls = utils.find_urls_in_text(text)
|
||||||
if len(urls) == 0:
|
if len(urls) == 0:
|
||||||
output.speak(_("No URL addresses were detected."))
|
output.speak(_("No URL addresses were detected."))
|
||||||
return
|
return
|
||||||
return urls
|
return urls
|
||||||
|
|
||||||
def visit_url(self, url):
|
def visit_url(self, url):
|
||||||
output.speak(_("Opening URL..."))
|
output.speak(_("Opening URL..."))
|
||||||
webbrowser.open_new_tab(url)
|
webbrowser.open_new_tab(url)
|
||||||
|
@ -5,42 +5,42 @@ from validate import Validator, VdtValueError
|
|||||||
import os
|
import os
|
||||||
|
|
||||||
class ConfigurationResetException(Exception):
|
class ConfigurationResetException(Exception):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
class Configuration (UserDict):
|
class Configuration (UserDict):
|
||||||
|
|
||||||
def __init__ (self, file=None, spec=None, *args, **kwargs):
|
def __init__ (self, file=None, spec=None, *args, **kwargs):
|
||||||
self.file = file
|
self.file = file
|
||||||
self.spec = spec
|
self.spec = spec
|
||||||
self.validator = Validator()
|
self.validator = Validator()
|
||||||
self.setup_config(file=file, spec=spec)
|
self.setup_config(file=file, spec=spec)
|
||||||
self.validated = self.config.validate(self.validator, copy=True)
|
self.validated = self.config.validate(self.validator, copy=True)
|
||||||
if self.validated:
|
if self.validated:
|
||||||
self.write()
|
self.write()
|
||||||
UserDict.__init__(self, self.config)
|
UserDict.__init__(self, self.config)
|
||||||
|
|
||||||
def setup_config (self, file, spec):
|
def setup_config (self, file, spec):
|
||||||
spec = ConfigObj(spec, list_values=False, encoding="utf-8")
|
spec = ConfigObj(spec, list_values=False, encoding="utf-8")
|
||||||
try:
|
try:
|
||||||
self.config = ConfigObj(infile=file, configspec=spec, create_empty=True, stringify=True, encoding="utf-8")
|
self.config = ConfigObj(infile=file, configspec=spec, create_empty=True, stringify=True, encoding="utf-8")
|
||||||
except ParseError:
|
except ParseError:
|
||||||
os.remove(file)
|
os.remove(file)
|
||||||
self.config = ConfigObj(infile=file, configspec=spec, create_empty=True, stringify=True)
|
self.config = ConfigObj(infile=file, configspec=spec, create_empty=True, stringify=True)
|
||||||
raise ConfigurationResetException
|
raise ConfigurationResetException
|
||||||
|
|
||||||
def __getitem__ (self, *args, **kwargs):
|
def __getitem__ (self, *args, **kwargs):
|
||||||
return dict(self.config).__getitem__(*args, **kwargs)
|
return dict(self.config).__getitem__(*args, **kwargs)
|
||||||
|
|
||||||
def __setitem__ (self, *args, **kwargs):
|
def __setitem__ (self, *args, **kwargs):
|
||||||
self.config.__setitem__(*args, **kwargs)
|
self.config.__setitem__(*args, **kwargs)
|
||||||
UserDict.__setitem__(self, *args, **kwargs)
|
UserDict.__setitem__(self, *args, **kwargs)
|
||||||
|
|
||||||
def write (self):
|
def write (self):
|
||||||
if hasattr(self.config, 'write'):
|
if hasattr(self.config, 'write'):
|
||||||
self.config.write()
|
self.config.write()
|
||||||
|
|
||||||
class SessionConfiguration (Configuration):
|
class SessionConfiguration (Configuration):
|
||||||
def setup_config (self, file, spec):
|
def setup_config (self, file, spec):
|
||||||
#No infile required.
|
#No infile required.
|
||||||
spec = ConfigObj(spec, list_values=False)
|
spec = ConfigObj(spec, list_values=False)
|
||||||
self.config = ConfigObj(configspec=spec, stringify=True)
|
self.config = ConfigObj(configspec=spec, stringify=True)
|
||||||
|
@ -12,296 +12,296 @@ log = logging.getLogger(__file__)
|
|||||||
### Some util functions
|
### Some util functions
|
||||||
|
|
||||||
def extract_attachment(attachment):
|
def extract_attachment(attachment):
|
||||||
""" Adds information about attachment files in posts. It only adds the text, I mean, no attachment file is added here.
|
""" Adds information about attachment files in posts. It only adds the text, I mean, no attachment file is added here.
|
||||||
This will produce a result like:
|
This will produce a result like:
|
||||||
'website: http://url.com'.
|
'website: http://url.com'.
|
||||||
'photo: A forest'."""
|
'photo: A forest'."""
|
||||||
msg = ""
|
msg = ""
|
||||||
if attachment["type"] == "link":
|
if attachment["type"] == "link":
|
||||||
msg = "{0}: {1}".format(attachment["link"]["title"], attachment["link"]["url"])
|
msg = "{0}: {1}".format(attachment["link"]["title"], attachment["link"]["url"])
|
||||||
elif attachment["type"] == "photo":
|
elif attachment["type"] == "photo":
|
||||||
msg = attachment["photo"]["text"]
|
msg = attachment["photo"]["text"]
|
||||||
if msg == "":
|
if msg == "":
|
||||||
return _("photo with no description available")
|
return _("photo with no description available")
|
||||||
elif attachment["type"] == "video":
|
elif attachment["type"] == "video":
|
||||||
msg = _("video: {0}").format(attachment["video"]["title"],)
|
msg = _("video: {0}").format(attachment["video"]["title"],)
|
||||||
return msg
|
return msg
|
||||||
|
|
||||||
def short_text(status):
|
def short_text(status):
|
||||||
""" This shorts the text to 140 characters for displaying it in the list control of buffers."""
|
""" This shorts the text to 140 characters for displaying it in the list control of buffers."""
|
||||||
message = ""
|
message = ""
|
||||||
# copy_story indicates that the post is a shared repost.
|
# copy_story indicates that the post is a shared repost.
|
||||||
if "copy_history" in status:
|
if "copy_history" in status:
|
||||||
txt = status["copy_history"][0]["text"]
|
txt = status["copy_history"][0]["text"]
|
||||||
else:
|
else:
|
||||||
txt = status["text"]
|
txt = status["text"]
|
||||||
if len(txt) < 140:
|
if len(txt) < 140:
|
||||||
message = clean_text(txt)
|
message = clean_text(txt)
|
||||||
else:
|
else:
|
||||||
message = clean_text(txt[:139])
|
message = clean_text(txt[:139])
|
||||||
return message
|
return message
|
||||||
|
|
||||||
def clean_audio(audio):
|
def clean_audio(audio):
|
||||||
""" Remove unavailable songs due to different reasons. This is used to clean the audio list when people adds audios and need to be displayed in the buffer."""
|
""" Remove unavailable songs due to different reasons. This is used to clean the audio list when people adds audios and need to be displayed in the buffer."""
|
||||||
for i in audio["items"][:]:
|
for i in audio["items"][:]:
|
||||||
if type(i) == bool:
|
if type(i) == bool:
|
||||||
audio["items"].remove(i)
|
audio["items"].remove(i)
|
||||||
audio["count"] = audio["count"] -1
|
audio["count"] = audio["count"] -1
|
||||||
return audio
|
return audio
|
||||||
|
|
||||||
def add_attachment(attachment):
|
def add_attachment(attachment):
|
||||||
msg = ""
|
msg = ""
|
||||||
tpe = ""
|
tpe = ""
|
||||||
if attachment["type"] == "link":
|
if attachment["type"] == "link":
|
||||||
msg = "{0}: {1}".format(attachment["link"]["title"], attachment["link"]["url"])
|
msg = "{0}: {1}".format(attachment["link"]["title"], attachment["link"]["url"])
|
||||||
tpe = _("Link")
|
tpe = _("Link")
|
||||||
elif attachment["type"] == "photo":
|
elif attachment["type"] == "photo":
|
||||||
tpe = _("Photo")
|
tpe = _("Photo")
|
||||||
msg = attachment["photo"]["text"]
|
msg = attachment["photo"]["text"]
|
||||||
if msg == "":
|
if msg == "":
|
||||||
msg = _("no description available")
|
msg = _("no description available")
|
||||||
elif attachment["type"] == "video":
|
elif attachment["type"] == "video":
|
||||||
msg = "{0}".format(attachment["video"]["title"],)
|
msg = "{0}".format(attachment["video"]["title"],)
|
||||||
tpe = _("Video")
|
tpe = _("Video")
|
||||||
elif attachment["type"] == "audio":
|
elif attachment["type"] == "audio":
|
||||||
msg = "{0}".format(" ".join(render_audio(attachment["audio"])))
|
msg = "{0}".format(" ".join(render_audio(attachment["audio"])))
|
||||||
tpe = _("Audio")
|
tpe = _("Audio")
|
||||||
elif attachment["type"] == "doc":
|
elif attachment["type"] == "doc":
|
||||||
msg = "{0}".format(attachment["doc"]["title"])
|
msg = "{0}".format(attachment["doc"]["title"])
|
||||||
tpe = _("{0} file").format(attachment["doc"]["ext"])
|
tpe = _("{0} file").format(attachment["doc"]["ext"])
|
||||||
elif attachment["type"] == "audio_message":
|
elif attachment["type"] == "audio_message":
|
||||||
msg = "{0}".format(" ".join(render_audio_message(attachment["audio_message"])))
|
msg = "{0}".format(" ".join(render_audio_message(attachment["audio_message"])))
|
||||||
tpe = _("Voice message")
|
tpe = _("Voice message")
|
||||||
elif attachment["type"] == "poll":
|
elif attachment["type"] == "poll":
|
||||||
tpe = _("Poll")
|
tpe = _("Poll")
|
||||||
msg = attachment["poll"]["question"]
|
msg = attachment["poll"]["question"]
|
||||||
elif attachment["type"] == "wall":
|
elif attachment["type"] == "wall":
|
||||||
tpe = _("Post")
|
tpe = _("Post")
|
||||||
user = attachment["wall"]["from"]["name"]
|
user = attachment["wall"]["from"]["name"]
|
||||||
if len(attachment["wall"]["text"]) > 140:
|
if len(attachment["wall"]["text"]) > 140:
|
||||||
text = attachment["wall"]["text"][:145]+"..."
|
text = attachment["wall"]["text"][:145]+"..."
|
||||||
else:
|
else:
|
||||||
text = attachment["wall"]["text"]
|
text = attachment["wall"]["text"]
|
||||||
msg = _("{user}: {post}").format(user=user, post=text)
|
msg = _("{user}: {post}").format(user=user, post=text)
|
||||||
elif attachment["type"] == "article":
|
elif attachment["type"] == "article":
|
||||||
tpe = _("Article")
|
tpe = _("Article")
|
||||||
msg = "{author}: {article}".format(author=attachment["article"]["owner_name"], article=attachment["article"]["title"])
|
msg = "{author}: {article}".format(author=attachment["article"]["owner_name"], article=attachment["article"]["title"])
|
||||||
else:
|
else:
|
||||||
print(attachment)
|
print(attachment)
|
||||||
return [tpe, msg]
|
return [tpe, msg]
|
||||||
|
|
||||||
### Render functions
|
### Render functions
|
||||||
|
|
||||||
def render_person(status, session):
|
def render_person(status, session):
|
||||||
""" Render users in people buffers such as everything related to friendships or buffers created with only people.
|
""" Render users in people buffers such as everything related to friendships or buffers created with only people.
|
||||||
Example result: ["John Doe", "An hour ago"]
|
Example result: ["John Doe", "An hour ago"]
|
||||||
Reference: https://vk.com/dev/fields"""
|
Reference: https://vk.com/dev/fields"""
|
||||||
# In case the user decided to not show his/her last seen information we must provide a default.
|
# In case the user decided to not show his/her last seen information we must provide a default.
|
||||||
# ToDo: Shall we indicate this with a message?
|
# ToDo: Shall we indicate this with a message?
|
||||||
online_status = ""
|
online_status = ""
|
||||||
if "last_seen" in status:
|
if "last_seen" in status:
|
||||||
original_date = arrow.get(status["last_seen"]["time"])
|
original_date = arrow.get(status["last_seen"]["time"])
|
||||||
now = arrow.now()
|
now = arrow.now()
|
||||||
original_date.to(now.tzinfo)
|
original_date.to(now.tzinfo)
|
||||||
diffdate = now-original_date
|
diffdate = now-original_date
|
||||||
if diffdate.days == 0 and diffdate.seconds <= 360:
|
if diffdate.days == 0 and diffdate.seconds <= 360:
|
||||||
online_status = _("Online")
|
online_status = _("Online")
|
||||||
else:
|
else:
|
||||||
# Translators: This is the date of last seen
|
# Translators: This is the date of last seen
|
||||||
online_status = _("Last seen {0}").format(original_date.humanize(locale=languageHandler.curLang[:2]),)
|
online_status = _("Last seen {0}").format(original_date.humanize(locale=languageHandler.curLang[:2]),)
|
||||||
# Account suspended or deleted.
|
# Account suspended or deleted.
|
||||||
elif ("last_seen" in status) == False and "deactivated" in status:
|
elif ("last_seen" in status) == False and "deactivated" in status:
|
||||||
online_status = _("Account deactivated")
|
online_status = _("Account deactivated")
|
||||||
return ["{0} {1}".format(status["first_name"], status["last_name"]), online_status]
|
return ["{0} {1}".format(status["first_name"], status["last_name"]), online_status]
|
||||||
|
|
||||||
def render_newsfeed_item(status, session):
|
def render_newsfeed_item(status, session):
|
||||||
""" This me☻thod is used to render an item of the news feed.
|
""" This me☻thod is used to render an item of the news feed.
|
||||||
References:
|
References:
|
||||||
https://vk.com/dev/newsfeed.get
|
https://vk.com/dev/newsfeed.get
|
||||||
https://vk.com/dev/post_source
|
https://vk.com/dev/post_source
|
||||||
https://vk.com/dev/post
|
https://vk.com/dev/post
|
||||||
"""
|
"""
|
||||||
user = session.get_user(status["source_id"], key="user1")
|
user = session.get_user(status["source_id"], key="user1")
|
||||||
# See if this is a post or repost.
|
# See if this is a post or repost.
|
||||||
if "copy_history" in status:
|
if "copy_history" in status:
|
||||||
# Get the second user (whose post is been shared).
|
# Get the second user (whose post is been shared).
|
||||||
user2 = session.get_user(status["copy_history"][0]["owner_id"], key="user2")
|
user2 = session.get_user(status["copy_history"][0]["owner_id"], key="user2")
|
||||||
# Add contents of poster to the new dict, it will create both user1_nom and user2_nom.
|
# Add contents of poster to the new dict, it will create both user1_nom and user2_nom.
|
||||||
user2.update(user)
|
user2.update(user)
|
||||||
user = dict(user1_nom=_("{user1_nom} has shared the {user2_nom}'s post").format(**user2))
|
user = dict(user1_nom=_("{user1_nom} has shared the {user2_nom}'s post").format(**user2))
|
||||||
message = ""
|
message = ""
|
||||||
original_date = arrow.get(status["date"])
|
original_date = arrow.get(status["date"])
|
||||||
created_at = original_date.humanize(locale=languageHandler.curLang[:2])
|
created_at = original_date.humanize(locale=languageHandler.curLang[:2])
|
||||||
# handle status updates.
|
# handle status updates.
|
||||||
if status["type"] == "post":
|
if status["type"] == "post":
|
||||||
message += short_text(status)
|
message += short_text(status)
|
||||||
if "attachment" in status and len(status["attachment"]) > 0:
|
if "attachment" in status and len(status["attachment"]) > 0:
|
||||||
message += extract_attachment(status["attachment"])
|
message += extract_attachment(status["attachment"])
|
||||||
# If there is no message after adding text, it's because a pphoto with no description has been found.
|
# If there is no message after adding text, it's because a pphoto with no description has been found.
|
||||||
# so let's manually add the "no description" tag here.
|
# so let's manually add the "no description" tag here.
|
||||||
if message == "":
|
if message == "":
|
||||||
message = "no description available"
|
message = "no description available"
|
||||||
# Handle audio rendering.
|
# Handle audio rendering.
|
||||||
elif status["type"] == "audio" and "audio" in status:
|
elif status["type"] == "audio" and "audio" in status:
|
||||||
# removes deleted audios.
|
# removes deleted audios.
|
||||||
status["audio"] = clean_audio(status["audio"])
|
status["audio"] = clean_audio(status["audio"])
|
||||||
if status["audio"]["count"] == 1:
|
if status["audio"]["count"] == 1:
|
||||||
data = dict(audio_file=", ".join(render_audio(status["audio"]["items"][0], session)))
|
data = dict(audio_file=", ".join(render_audio(status["audio"]["items"][0], session)))
|
||||||
data.update(user)
|
data.update(user)
|
||||||
message = _("{user1_nom} has added an audio: {audio_file}").format(**data)
|
message = _("{user1_nom} has added an audio: {audio_file}").format(**data)
|
||||||
else:
|
else:
|
||||||
prem = ""
|
prem = ""
|
||||||
for i in range(0, status["audio"]["count"]):
|
for i in range(0, status["audio"]["count"]):
|
||||||
composed_audio = render_audio(status["audio"]["items"][i], session)
|
composed_audio = render_audio(status["audio"]["items"][i], session)
|
||||||
prem += "{0} - {1}, ".format(composed_audio[0], composed_audio[1])
|
prem += "{0} - {1}, ".format(composed_audio[0], composed_audio[1])
|
||||||
data = dict(audio_files=prem, total_audio_files=status["audio"]["count"])
|
data = dict(audio_files=prem, total_audio_files=status["audio"]["count"])
|
||||||
data.update(user)
|
data.update(user)
|
||||||
message = _("{user1_nom} has added {total_audio_files} audios: {audio_files}").format(**data)
|
message = _("{user1_nom} has added {total_audio_files} audios: {audio_files}").format(**data)
|
||||||
# Handle audio playlists
|
# Handle audio playlists
|
||||||
elif status["type"] == "audio_playlist":
|
elif status["type"] == "audio_playlist":
|
||||||
if status["audio_playlist"]["count"] == 1:
|
if status["audio_playlist"]["count"] == 1:
|
||||||
data = dict(audio_album=status["audio_playlist"]["items"][0]["title"], audio_album_description=status["audio_playlist"]["items"][0]["description"])
|
data = dict(audio_album=status["audio_playlist"]["items"][0]["title"], audio_album_description=status["audio_playlist"]["items"][0]["description"])
|
||||||
data.update(user)
|
data.update(user)
|
||||||
message = _("{user1_nom} has added an audio album: {audio_album}, {audio_album_description}").format(**data)
|
message = _("{user1_nom} has added an audio album: {audio_album}, {audio_album_description}").format(**data)
|
||||||
else:
|
else:
|
||||||
prestring = ""
|
prestring = ""
|
||||||
for i in range(0, status["audio_playlist"]["count"]):
|
for i in range(0, status["audio_playlist"]["count"]):
|
||||||
prestring += "{0} - {1}, ".format(status["audio_playlist"]["items"][i]["title"], status["audio_playlist"]["items"][i]["description"])
|
prestring += "{0} - {1}, ".format(status["audio_playlist"]["items"][i]["title"], status["audio_playlist"]["items"][i]["description"])
|
||||||
data = dict(audio_albums=prestring, total_audio_albums=status["audio_playlist"]["count"])
|
data = dict(audio_albums=prestring, total_audio_albums=status["audio_playlist"]["count"])
|
||||||
data.update(user)
|
data.update(user)
|
||||||
message = _("{user1_nom} has added {total_audio_albums} audio albums: {audio_albums}").format(**data)
|
message = _("{user1_nom} has added {total_audio_albums} audio albums: {audio_albums}").format(**data)
|
||||||
# handle new friends for people in the news buffer.
|
# handle new friends for people in the news buffer.
|
||||||
elif status["type"] == "friend":
|
elif status["type"] == "friend":
|
||||||
msg_users = ""
|
msg_users = ""
|
||||||
if "friends" in status:
|
if "friends" in status:
|
||||||
for i in status["friends"]["items"]:
|
for i in status["friends"]["items"]:
|
||||||
msg_users = msg_users + "{0}, ".format(session.get_user(i["user_id"])["user1_nom"])
|
msg_users = msg_users + "{0}, ".format(session.get_user(i["user_id"])["user1_nom"])
|
||||||
else:
|
else:
|
||||||
print(list(status.keys()))
|
print(list(status.keys()))
|
||||||
data = dict(friends=msg_users)
|
data = dict(friends=msg_users)
|
||||||
data.update(user)
|
data.update(user)
|
||||||
message = _("{user1_nom} added friends: {friends}").format(**data)
|
message = _("{user1_nom} added friends: {friends}").format(**data)
|
||||||
elif status["type"] == "video":
|
elif status["type"] == "video":
|
||||||
if status["video"]["count"] == 1:
|
if status["video"]["count"] == 1:
|
||||||
data = dict(video=", ".join(render_video(status["video"]["items"][0], session)))
|
data = dict(video=", ".join(render_video(status["video"]["items"][0], session)))
|
||||||
data.update(user)
|
data.update(user)
|
||||||
message = _("{user1_nom} has added a video: {video}").format(**data)
|
message = _("{user1_nom} has added a video: {video}").format(**data)
|
||||||
else:
|
else:
|
||||||
prem = ""
|
prem = ""
|
||||||
for i in range(0, status["video"]["count"]):
|
for i in range(0, status["video"]["count"]):
|
||||||
composed_video = render_video(status["video"]["items"][i], session)
|
composed_video = render_video(status["video"]["items"][i], session)
|
||||||
prem += "{0} - {1}, ".format(composed_video[0], composed_video[1])
|
prem += "{0} - {1}, ".format(composed_video[0], composed_video[1])
|
||||||
data = dict(videos=prem, total_videos=status["video"]["count"])
|
data = dict(videos=prem, total_videos=status["video"]["count"])
|
||||||
data.update(user)
|
data.update(user)
|
||||||
message = _("{user1_nom} has added {total_videos} videos: {videos}").format(**data)
|
message = _("{user1_nom} has added {total_videos} videos: {videos}").format(**data)
|
||||||
else:
|
else:
|
||||||
if status["type"] != "post": print(status)
|
if status["type"] != "post": print(status)
|
||||||
return [user["user1_nom"], message, created_at]
|
return [user["user1_nom"], message, created_at]
|
||||||
|
|
||||||
def render_message(message, session):
|
def render_message(message, session):
|
||||||
""" Render a message posted in a private conversation.
|
""" Render a message posted in a private conversation.
|
||||||
Reference: https://vk.com/dev/message"""
|
Reference: https://vk.com/dev/message"""
|
||||||
user = session.get_user(message["from_id"], key="user1")
|
user = session.get_user(message["from_id"], key="user1")
|
||||||
original_date = arrow.get(message["date"])
|
original_date = arrow.get(message["date"])
|
||||||
now = arrow.now()
|
now = arrow.now()
|
||||||
original_date = original_date.to(now.tzinfo)
|
original_date = original_date.to(now.tzinfo)
|
||||||
# Format the date here differently depending in if this is the same day for both dates or not.
|
# Format the date here differently depending in if this is the same day for both dates or not.
|
||||||
if original_date.day == now.day:
|
if original_date.day == now.day:
|
||||||
created_at = original_date.format(_("H:mm."), locale=languageHandler.curLang[:2])
|
created_at = original_date.format(_("H:mm."), locale=languageHandler.curLang[:2])
|
||||||
else:
|
else:
|
||||||
created_at = original_date.format(_("H:mm. dddd, MMMM D, YYYY"), locale=languageHandler.curLang[:2])
|
created_at = original_date.format(_("H:mm. dddd, MMMM D, YYYY"), locale=languageHandler.curLang[:2])
|
||||||
# No idea why some messages send "text" instead "body"
|
# No idea why some messages send "text" instead "body"
|
||||||
if "body" in message:
|
if "body" in message:
|
||||||
body = message["body"]
|
body = message["body"]
|
||||||
else:
|
else:
|
||||||
body = message["text"]
|
body = message["text"]
|
||||||
data = dict(body=body, created_at=created_at)
|
data = dict(body=body, created_at=created_at)
|
||||||
data.update(user)
|
data.update(user)
|
||||||
return ["{user1_nom}, {body} {created_at}".format(**data)]
|
return ["{user1_nom}, {body} {created_at}".format(**data)]
|
||||||
|
|
||||||
def render_status(status, session):
|
def render_status(status, session):
|
||||||
""" Render a wall post (shown in user's wall, not in newsfeed).
|
""" Render a wall post (shown in user's wall, not in newsfeed).
|
||||||
Reference: https://vk.com/dev/post"""
|
Reference: https://vk.com/dev/post"""
|
||||||
user = session.get_user(status["from_id"], key="user1")
|
user = session.get_user(status["from_id"], key="user1")
|
||||||
if "copy_history" in status:
|
if "copy_history" in status:
|
||||||
user2 = session.get_user(status["copy_history"][0]["owner_id"], key="user2")
|
user2 = session.get_user(status["copy_history"][0]["owner_id"], key="user2")
|
||||||
user2.update(user)
|
user2.update(user)
|
||||||
user = dict(user1_nom=_("{user1_nom} has shared the {user2_nom}'s post").format(**user2))
|
user = dict(user1_nom=_("{user1_nom} has shared the {user2_nom}'s post").format(**user2))
|
||||||
message = ""
|
message = ""
|
||||||
original_date = arrow.get(status["date"])
|
original_date = arrow.get(status["date"])
|
||||||
created_at = original_date.humanize(locale=languageHandler.curLang[:2])
|
created_at = original_date.humanize(locale=languageHandler.curLang[:2])
|
||||||
if "copy_owner_id" in status:
|
if "copy_owner_id" in status:
|
||||||
user2 = session.get_user(status["copy_owner_id"], key="user2")
|
user2 = session.get_user(status["copy_owner_id"], key="user2")
|
||||||
user2.update(user)
|
user2.update(user)
|
||||||
user = _("{user1_nom} has shared the {user2_nom}'s post").format(**user2)
|
user = _("{user1_nom} has shared the {user2_nom}'s post").format(**user2)
|
||||||
if status["post_type"] == "post" or status["post_type"] == "copy":
|
if status["post_type"] == "post" or status["post_type"] == "copy":
|
||||||
message += short_text(status)
|
message += short_text(status)
|
||||||
if "attachment" in status and len(status["attachment"]) > 0:
|
if "attachment" in status and len(status["attachment"]) > 0:
|
||||||
message += extract_attachment(status["attachment"])
|
message += extract_attachment(status["attachment"])
|
||||||
if message == "":
|
if message == "":
|
||||||
message = "no description available"
|
message = "no description available"
|
||||||
return [user["user1_nom"], message, created_at]
|
return [user["user1_nom"], message, created_at]
|
||||||
|
|
||||||
def render_audio(audio, session=None):
|
def render_audio(audio, session=None):
|
||||||
""" Render audio files added to VK.
|
""" Render audio files added to VK.
|
||||||
Example result:
|
Example result:
|
||||||
["Song title", "Artist", "03:15"]
|
["Song title", "Artist", "03:15"]
|
||||||
reference: https://vk.com/dev/audio_object"""
|
reference: https://vk.com/dev/audio_object"""
|
||||||
if audio == False: return [_("Audio removed from library"), "", ""]
|
if audio == False: return [_("Audio removed from library"), "", ""]
|
||||||
return [audio["title"], audio["artist"], seconds_to_string(audio["duration"])]
|
return [audio["title"], audio["artist"], seconds_to_string(audio["duration"])]
|
||||||
|
|
||||||
def render_video(video, session=None):
|
def render_video(video, session=None):
|
||||||
""" Render a video file from VK.
|
""" Render a video file from VK.
|
||||||
Example result:
|
Example result:
|
||||||
["Video title", "Video description", "01:30:28"]
|
["Video title", "Video description", "01:30:28"]
|
||||||
Reference: https://vk.com/dev/video_object"""
|
Reference: https://vk.com/dev/video_object"""
|
||||||
if video == False:
|
if video == False:
|
||||||
return [_("Video not available"), "", ""]
|
return [_("Video not available"), "", ""]
|
||||||
return [video["title"], video["description"], seconds_to_string(video["duration"])]
|
return [video["title"], video["description"], seconds_to_string(video["duration"])]
|
||||||
|
|
||||||
def render_audio_message(audio_message, session=None):
|
def render_audio_message(audio_message, session=None):
|
||||||
""" Render a voice message from VK
|
""" Render a voice message from VK
|
||||||
Example result:
|
Example result:
|
||||||
["Voice message", "01:30:28"]"""
|
["Voice message", "01:30:28"]"""
|
||||||
if audio_message == False:
|
if audio_message == False:
|
||||||
return [_("Voice message not available"), "", ""]
|
return [_("Voice message not available"), "", ""]
|
||||||
return [seconds_to_string(audio_message["duration"])]
|
return [seconds_to_string(audio_message["duration"])]
|
||||||
|
|
||||||
def render_topic(topic, session):
|
def render_topic(topic, session):
|
||||||
""" Render topics for a community.
|
""" Render topics for a community.
|
||||||
Reference: https://vk.com/dev/objects/topic"""
|
Reference: https://vk.com/dev/objects/topic"""
|
||||||
user = session.get_user(topic["created_by"])
|
user = session.get_user(topic["created_by"])
|
||||||
title = topic["title"]
|
title = topic["title"]
|
||||||
comments = topic["comments"]
|
comments = topic["comments"]
|
||||||
last_commenter = session.get_user(topic["updated_by"])
|
last_commenter = session.get_user(topic["updated_by"])
|
||||||
last_update = arrow.get(topic["updated"]).humanize(locale=languageHandler.curLang[:2])
|
last_update = arrow.get(topic["updated"]).humanize(locale=languageHandler.curLang[:2])
|
||||||
last_commenter.update(date=last_update)
|
last_commenter.update(date=last_update)
|
||||||
lastupdate = _("Last post by {user1_nom} {date}").format(**last_commenter)
|
lastupdate = _("Last post by {user1_nom} {date}").format(**last_commenter)
|
||||||
return [user["user1_nom"], title, str(comments), lastupdate]
|
return [user["user1_nom"], title, str(comments), lastupdate]
|
||||||
|
|
||||||
def render_document(document, session):
|
def render_document(document, session):
|
||||||
doc_types = {1: _("Text document"), 2: _("Archive"), 3: _("Gif"), 4: _("Image"), 5: _("Audio"), 6: _("Video"), 7: _("Ebook"), 8: _("Unknown document")}
|
doc_types = {1: _("Text document"), 2: _("Archive"), 3: _("Gif"), 4: _("Image"), 5: _("Audio"), 6: _("Video"), 7: _("Ebook"), 8: _("Unknown document")}
|
||||||
user = session.get_user(document["owner_id"])
|
user = session.get_user(document["owner_id"])
|
||||||
title = document["title"]
|
title = document["title"]
|
||||||
size = convert_bytes(document["size"])
|
size = convert_bytes(document["size"])
|
||||||
date = arrow.get(document["date"]).humanize(locale=languageHandler.curLang[:2])
|
date = arrow.get(document["date"]).humanize(locale=languageHandler.curLang[:2])
|
||||||
doc_type = doc_types[document["type"]]
|
doc_type = doc_types[document["type"]]
|
||||||
return [user["user1_nom"], title, doc_type, size, date]
|
return [user["user1_nom"], title, doc_type, size, date]
|
||||||
|
|
||||||
def render_notification(notification, session):
|
def render_notification(notification, session):
|
||||||
notification.pop("hide_buttons")
|
notification.pop("hide_buttons")
|
||||||
print(notification["icon_type"])
|
print(notification["icon_type"])
|
||||||
# print(notification["header"])
|
# print(notification["header"])
|
||||||
print(notification)
|
print(notification)
|
||||||
date = arrow.get(notification["date"]).humanize(locale=languageHandler.curLang[:2])
|
date = arrow.get(notification["date"]).humanize(locale=languageHandler.curLang[:2])
|
||||||
msg = notification["header"]
|
msg = notification["header"]
|
||||||
# msg = notification["header"]
|
# msg = notification["header"]
|
||||||
# if notification["type"] == "follow":
|
# if notification["type"] == "follow":
|
||||||
# if len(notification["feedback"]) == 1:
|
# if len(notification["feedback"]) == 1:
|
||||||
# user = session.get_user(notification["feedback"][0])
|
# user = session.get_user(notification["feedback"][0])
|
||||||
# msg = _("{user1_nom} subscribed to your account").format(**user)
|
# msg = _("{user1_nom} subscribed to your account").format(**user)
|
||||||
# else:
|
# else:
|
||||||
# users = ["{first_name} {last_name},".format(first_name=user["first_name"], last_name=user["last_name"]) for user in notification["feedback"]]
|
# users = ["{first_name} {last_name},".format(first_name=user["first_name"], last_name=user["last_name"]) for user in notification["feedback"]]
|
||||||
# msg = " ".join(users)
|
# msg = " ".join(users)
|
||||||
# print(msg)
|
# print(msg)
|
||||||
return [msg, date]
|
return [msg, date]
|
||||||
|
@ -29,370 +29,370 @@ identifiers = ["aid", "gid", "uid", "pid", "id", "post_id", "nid", "date"]
|
|||||||
post_types = dict(audio="audio", friend="friends", video="files", post="post_type", audio_playlist="audio_playlist")
|
post_types = dict(audio="audio", friend="friends", video="files", post="post_type", audio_playlist="audio_playlist")
|
||||||
|
|
||||||
def find_item(list, item):
|
def find_item(list, item):
|
||||||
""" Find an item in a list by taking an identifier.
|
""" Find an item in a list by taking an identifier.
|
||||||
@list list: A list of dict objects.
|
@list list: A list of dict objects.
|
||||||
@ item dict: A dictionary containing at least an identifier.
|
@ item dict: A dictionary containing at least an identifier.
|
||||||
"""
|
"""
|
||||||
# determine the kind of identifier that we are using
|
# determine the kind of identifier that we are using
|
||||||
global identifiers
|
global identifiers
|
||||||
identifier = None
|
identifier = None
|
||||||
for i in identifiers:
|
for i in identifiers:
|
||||||
if i in item:
|
if i in item:
|
||||||
identifier = i
|
identifier = i
|
||||||
break
|
break
|
||||||
if identifier == None:
|
if identifier == None:
|
||||||
# if there are objects that can't be processed by lack of identifier, let's print keys for finding one.
|
# if there are objects that can't be processed by lack of identifier, let's print keys for finding one.
|
||||||
log.exception("Can't find an identifier for the following object: %r" % (item,))
|
log.exception("Can't find an identifier for the following object: %r" % (item,))
|
||||||
return False
|
return False
|
||||||
for i in list:
|
for i in list:
|
||||||
if identifier in i and i[identifier] == item[identifier]:
|
if identifier in i and i[identifier] == item[identifier]:
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
class vkSession(object):
|
class vkSession(object):
|
||||||
""" The only session available in socializer. Manages everything related to a model in an MVC app: calls to VK, sound handling, settings and a cache database."""
|
""" The only session available in socializer. Manages everything related to a model in an MVC app: calls to VK, sound handling, settings and a cache database."""
|
||||||
|
|
||||||
def order_buffer(self, name, data, show_nextpage):
|
def order_buffer(self, name, data, show_nextpage):
|
||||||
""" Put new items on the local cache database.
|
""" Put new items on the local cache database.
|
||||||
@name str: The name for the buffer stored in the dictionary.
|
@name str: The name for the buffer stored in the dictionary.
|
||||||
@data list: A list with items and some information about cursors.
|
@data list: A list with items and some information about cursors.
|
||||||
returns the number of items that have been added in this execution"""
|
returns the number of items that have been added in this execution"""
|
||||||
global post_types
|
global post_types
|
||||||
# When this method is called by friends.getOnlyne, it gives only friend IDS so we need to retrieve full objects from VK.
|
# When this method is called by friends.getOnlyne, it gives only friend IDS so we need to retrieve full objects from VK.
|
||||||
# ToDo: It would be nice to investigate whether reusing some existing objects would be a good idea, whenever possible.
|
# ToDo: It would be nice to investigate whether reusing some existing objects would be a good idea, whenever possible.
|
||||||
if name == "online_friends":
|
if name == "online_friends":
|
||||||
newdata = self.vk.client.users.get(user_ids=",".join([str(z) for z in data]), fields="last_seen")
|
newdata = self.vk.client.users.get(user_ids=",".join([str(z) for z in data]), fields="last_seen")
|
||||||
data = newdata
|
data = newdata
|
||||||
first_addition = False
|
first_addition = False
|
||||||
num = 0
|
num = 0
|
||||||
if (name in self.db) == False:
|
if (name in self.db) == False:
|
||||||
self.db[name] = {}
|
self.db[name] = {}
|
||||||
self.db[name]["items"] = []
|
self.db[name]["items"] = []
|
||||||
first_addition = True
|
first_addition = True
|
||||||
# Handles chat messages case, as the buffer is inverted
|
# Handles chat messages case, as the buffer is inverted
|
||||||
if name.endswith("_messages") and show_nextpage == True:
|
if name.endswith("_messages") and show_nextpage == True:
|
||||||
show_nextpage = False
|
show_nextpage = False
|
||||||
for i in data:
|
for i in data:
|
||||||
if "type" in i and (i["type"] == "wall_photo" or i["type"] == "photo_tag" or i["type"] == "photo" or i["type"] == False or i["type"] == True):
|
if "type" in i and (i["type"] == "wall_photo" or i["type"] == "photo_tag" or i["type"] == "photo" or i["type"] == False or i["type"] == True):
|
||||||
log.debug("Skipping unsupported item... %r" % (i,))
|
log.debug("Skipping unsupported item... %r" % (i,))
|
||||||
continue
|
continue
|
||||||
# for some reason, VK sends post data if the post has been deleted already.
|
# for some reason, VK sends post data if the post has been deleted already.
|
||||||
# Example of this behaviour is when you upload an audio and inmediately delete the audio, VK still sends the post stating that you uploaded an audio file,
|
# Example of this behaviour is when you upload an audio and inmediately delete the audio, VK still sends the post stating that you uploaded an audio file,
|
||||||
# But without the audio data, making socializer to render an empty post.
|
# But without the audio data, making socializer to render an empty post.
|
||||||
# Here we check if the post contains data of the type it advertises.
|
# Here we check if the post contains data of the type it advertises.
|
||||||
if i.get("type") != None and isinstance(i["type"], str) and post_types.get(i["type"]) not in i:
|
if i.get("type") != None and isinstance(i["type"], str) and post_types.get(i["type"]) not in i:
|
||||||
log.error("Detected invalid or unsupported post. Skipping...")
|
log.error("Detected invalid or unsupported post. Skipping...")
|
||||||
log.error(i)
|
log.error(i)
|
||||||
continue
|
continue
|
||||||
if find_item(self.db[name]["items"], i) == False:
|
if find_item(self.db[name]["items"], i) == False:
|
||||||
# if i not in self.db[name]["items"]:
|
# if i not in self.db[name]["items"]:
|
||||||
if first_addition == True or show_nextpage == True:
|
if first_addition == True or show_nextpage == True:
|
||||||
if self.settings["general"]["reverse_timelines"] == False: self.db[name]["items"].append(i)
|
if self.settings["general"]["reverse_timelines"] == False: self.db[name]["items"].append(i)
|
||||||
else: self.db[name]["items"].insert(0, i)
|
else: self.db[name]["items"].insert(0, i)
|
||||||
else:
|
else:
|
||||||
if self.settings["general"]["reverse_timelines"] == False: self.db[name]["items"].insert(0, i)
|
if self.settings["general"]["reverse_timelines"] == False: self.db[name]["items"].insert(0, i)
|
||||||
else: self.db[name]["items"].append(i)
|
else: self.db[name]["items"].append(i)
|
||||||
num = num+1
|
num = num+1
|
||||||
log.debug("There are %d items in the %s buffer" % (len(self.db[name]["items"]), name))
|
log.debug("There are %d items in the %s buffer" % (len(self.db[name]["items"]), name))
|
||||||
return num
|
return num
|
||||||
|
|
||||||
def __init__(self, session_id):
|
def __init__(self, session_id):
|
||||||
self.session_id = session_id
|
self.session_id = session_id
|
||||||
self.logged = False
|
self.logged = False
|
||||||
self.settings = None
|
self.settings = None
|
||||||
self.vk = vkSessionHandler.vkObject()
|
self.vk = vkSessionHandler.vkObject()
|
||||||
self.db = {}
|
self.db = {}
|
||||||
self.db["users"] = {}
|
self.db["users"] = {}
|
||||||
self.db["groups"] = {}
|
self.db["groups"] = {}
|
||||||
self.db["group_info"] = {}
|
self.db["group_info"] = {}
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def is_logged(self):
|
def is_logged(self):
|
||||||
return self.logged
|
return self.logged
|
||||||
|
|
||||||
def get_configuration(self, nosound=False):
|
def get_configuration(self, nosound=False):
|
||||||
|
|
||||||
""" Gets settings for a session."""
|
""" Gets settings for a session."""
|
||||||
|
|
||||||
file_ = "%s/session.conf" % (self.session_id,)
|
file_ = "%s/session.conf" % (self.session_id,)
|
||||||
# try:
|
# try:
|
||||||
log.debug("Creating config file %s" % (file_,))
|
log.debug("Creating config file %s" % (file_,))
|
||||||
self.settings = Configuration(os.path.join(paths.config_path(), file_), os.path.join(paths.app_path(), "session.defaults"))
|
self.settings = Configuration(os.path.join(paths.config_path(), file_), os.path.join(paths.app_path(), "session.defaults"))
|
||||||
if nosound == False:
|
if nosound == False:
|
||||||
self.soundplayer = sound.soundSystem(config.app["sound"])
|
self.soundplayer = sound.soundSystem(config.app["sound"])
|
||||||
pub.subscribe(self.play_sound, "play-sound")
|
pub.subscribe(self.play_sound, "play-sound")
|
||||||
pub.subscribe(self.post, "post")
|
pub.subscribe(self.post, "post")
|
||||||
# except:
|
# except:
|
||||||
# log.exception("The session configuration has failed.")
|
# log.exception("The session configuration has failed.")
|
||||||
|
|
||||||
def play_sound(self, sound):
|
def play_sound(self, sound):
|
||||||
self.soundplayer.play(sound)
|
self.soundplayer.play(sound)
|
||||||
|
|
||||||
def login(self):
|
def login(self):
|
||||||
""" Logging in VK.com. This is basically the first method interacting with VK. """
|
""" Logging in VK.com. This is basically the first method interacting with VK. """
|
||||||
# If user is already logged in, we should skip this method.
|
# If user is already logged in, we should skip this method.
|
||||||
if self.logged == True:
|
if self.logged == True:
|
||||||
return
|
return
|
||||||
try:
|
try:
|
||||||
config_filename = os.path.join(paths.config_path(), self.session_id, "vkconfig.json")
|
config_filename = os.path.join(paths.config_path(), self.session_id, "vkconfig.json")
|
||||||
self.vk.login(self.settings["vk"]["user"], self.settings["vk"]["password"], token=self.settings["vk"]["token"], alt_token=self.settings["vk"]["use_alternative_tokens"], filename=config_filename)
|
self.vk.login(self.settings["vk"]["user"], self.settings["vk"]["password"], token=self.settings["vk"]["token"], alt_token=self.settings["vk"]["use_alternative_tokens"], filename=config_filename)
|
||||||
self.settings["vk"]["token"] = self.vk.session_object.token["access_token"]
|
self.settings["vk"]["token"] = self.vk.session_object.token["access_token"]
|
||||||
self.settings.write()
|
self.settings.write()
|
||||||
self.logged = True
|
self.logged = True
|
||||||
self.get_my_data()
|
self.get_my_data()
|
||||||
except VkApiError as error:
|
except VkApiError as error:
|
||||||
print(error)
|
print(error)
|
||||||
if error.code == 5: # this means invalid access token.
|
if error.code == 5: # this means invalid access token.
|
||||||
self.settings["vk"]["user"] = ""
|
self.settings["vk"]["user"] = ""
|
||||||
self.settings["vk"]["password"] = ""
|
self.settings["vk"]["password"] = ""
|
||||||
self.settings["vk"]["token"] = ""
|
self.settings["vk"]["token"] = ""
|
||||||
self.settings.write()
|
self.settings.write()
|
||||||
pub.sendMessage("authorisation-failed")
|
pub.sendMessage("authorisation-failed")
|
||||||
else: # print out error so we we will handle it in future versions.
|
else: # print out error so we we will handle it in future versions.
|
||||||
log.exception("Fatal error when authenticating the application.")
|
log.exception("Fatal error when authenticating the application.")
|
||||||
log.exception(error.code)
|
log.exception(error.code)
|
||||||
log.exception(error.message)
|
log.exception(error.message)
|
||||||
except (ProxyError, ConnectionError):
|
except (ProxyError, ConnectionError):
|
||||||
pub.sendMessage("connection_error")
|
pub.sendMessage("connection_error")
|
||||||
|
|
||||||
def post_wall_status(self, message, *args, **kwargs):
|
def post_wall_status(self, message, *args, **kwargs):
|
||||||
""" Sends a post to an user, group or community wall."""
|
""" Sends a post to an user, group or community wall."""
|
||||||
log.debug("Making a post to the user's wall with the following params: %r" % (kwargs,))
|
log.debug("Making a post to the user's wall with the following params: %r" % (kwargs,))
|
||||||
response = self.vk.client.wall.post(message=message, *args, **kwargs)
|
response = self.vk.client.wall.post(message=message, *args, **kwargs)
|
||||||
|
|
||||||
def get_newsfeed(self, name="newsfeed", show_nextpage=False, endpoint="", *args, **kwargs):
|
def get_newsfeed(self, name="newsfeed", show_nextpage=False, endpoint="", *args, **kwargs):
|
||||||
log.debug("Updating news feed...")
|
log.debug("Updating news feed...")
|
||||||
if show_nextpage == True and "cursor" in self.db[name]:
|
if show_nextpage == True and "cursor" in self.db[name]:
|
||||||
log.debug("user has requested previous items")
|
log.debug("user has requested previous items")
|
||||||
kwargs["start_from"] = self.db[name]["cursor"]
|
kwargs["start_from"] = self.db[name]["cursor"]
|
||||||
log.debug("Params for sending to vk: %r" % (kwargs,))
|
log.debug("Params for sending to vk: %r" % (kwargs,))
|
||||||
data = getattr(self.vk.client.newsfeed, "get")(*args, **kwargs)
|
data = getattr(self.vk.client.newsfeed, "get")(*args, **kwargs)
|
||||||
if data != None:
|
if data != None:
|
||||||
self.process_usernames(data)
|
self.process_usernames(data)
|
||||||
num = self.order_buffer(name, data["items"], show_nextpage)
|
num = self.order_buffer(name, data["items"], show_nextpage)
|
||||||
log.debug("Keys of the returned data for debug purposes: %r" % (list(data.keys()),))
|
log.debug("Keys of the returned data for debug purposes: %r" % (list(data.keys()),))
|
||||||
if "next_from" in data:
|
if "next_from" in data:
|
||||||
self.db[name]["cursor"] = data["next_from"]
|
self.db[name]["cursor"] = data["next_from"]
|
||||||
log.debug("Next cursor saved for data: {cursor}".format(cursor=data["next_from"]))
|
log.debug("Next cursor saved for data: {cursor}".format(cursor=data["next_from"]))
|
||||||
return num
|
return num
|
||||||
|
|
||||||
def get_page(self, name="", show_nextpage=False, endpoint="", *args, **kwargs):
|
def get_page(self, name="", show_nextpage=False, endpoint="", *args, **kwargs):
|
||||||
data = None
|
data = None
|
||||||
if "audio" in endpoint and self.settings["vk"]["use_alternative_tokens"]:
|
if "audio" in endpoint and self.settings["vk"]["use_alternative_tokens"]:
|
||||||
log.info("Using alternative audio methods.")
|
log.info("Using alternative audio methods.")
|
||||||
c = self.vk.client_audio
|
c = self.vk.client_audio
|
||||||
else:
|
else:
|
||||||
c = self.vk.client
|
c = self.vk.client
|
||||||
formatted_endpoint = ""
|
formatted_endpoint = ""
|
||||||
if "parent_endpoint" in kwargs:
|
if "parent_endpoint" in kwargs:
|
||||||
p = kwargs["parent_endpoint"]
|
p = kwargs["parent_endpoint"]
|
||||||
formatted_endpoint = kwargs["parent_endpoint"]
|
formatted_endpoint = kwargs["parent_endpoint"]
|
||||||
if "audio" in p and self.settings["vk"]["use_alternative_tokens"]:
|
if "audio" in p and self.settings["vk"]["use_alternative_tokens"]:
|
||||||
log.info("Using alternative audio methods.")
|
log.info("Using alternative audio methods.")
|
||||||
c = self.vk.client_audio
|
c = self.vk.client_audio
|
||||||
kwargs.pop("parent_endpoint")
|
kwargs.pop("parent_endpoint")
|
||||||
try:
|
try:
|
||||||
p = getattr(c, p)
|
p = getattr(c, p)
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
p = c
|
p = c
|
||||||
if name in self.db and "offset" in self.db[name] and show_nextpage == True:
|
if name in self.db and "offset" in self.db[name] and show_nextpage == True:
|
||||||
kwargs.update(offset=self.db[name]["offset"])
|
kwargs.update(offset=self.db[name]["offset"])
|
||||||
else:
|
else:
|
||||||
kwargs.update(offset=0)
|
kwargs.update(offset=0)
|
||||||
formatted_endpoint = "{formatted_endpoint}.{new_path}".format(formatted_endpoint=formatted_endpoint, new_path=endpoint)
|
formatted_endpoint = "{formatted_endpoint}.{new_path}".format(formatted_endpoint=formatted_endpoint, new_path=endpoint)
|
||||||
offset_deprecated = ["notifications.get"]
|
offset_deprecated = ["notifications.get"]
|
||||||
if formatted_endpoint in offset_deprecated:
|
if formatted_endpoint in offset_deprecated:
|
||||||
kwargs.update(offset=None)
|
kwargs.update(offset=None)
|
||||||
log.debug("Calling endpoint %s with params %r" % (formatted_endpoint, kwargs,))
|
log.debug("Calling endpoint %s with params %r" % (formatted_endpoint, kwargs,))
|
||||||
data = getattr(p, endpoint)(*args, **kwargs)
|
data = getattr(p, endpoint)(*args, **kwargs)
|
||||||
if data != None:
|
if data != None:
|
||||||
if "count" not in kwargs:
|
if "count" not in kwargs:
|
||||||
kwargs["count"] = 100
|
kwargs["count"] = 100
|
||||||
# Let's handle a little exception when dealing with conversation buffers.
|
# Let's handle a little exception when dealing with conversation buffers.
|
||||||
# the first results of the query should be reversed before being sent to order_buffer.
|
# the first results of the query should be reversed before being sent to order_buffer.
|
||||||
if type(data) == dict and "items" in data and endpoint == "getHistory" and kwargs["offset"] == 0:
|
if type(data) == dict and "items" in data and endpoint == "getHistory" and kwargs["offset"] == 0:
|
||||||
data["items"].reverse()
|
data["items"].reverse()
|
||||||
if type(data) == dict:
|
if type(data) == dict:
|
||||||
num = self.order_buffer(name, data["items"], show_nextpage)
|
num = self.order_buffer(name, data["items"], show_nextpage)
|
||||||
if formatted_endpoint not in offset_deprecated:
|
if formatted_endpoint not in offset_deprecated:
|
||||||
self.db[name]["offset"] = kwargs["offset"]+kwargs["count"]
|
self.db[name]["offset"] = kwargs["offset"]+kwargs["count"]
|
||||||
if len(data["items"]) > 0 and "first_name" in data["items"][0]:
|
if len(data["items"]) > 0 and "first_name" in data["items"][0]:
|
||||||
data2 = {"profiles": [], "groups": []}
|
data2 = {"profiles": [], "groups": []}
|
||||||
for i in data["items"]:
|
for i in data["items"]:
|
||||||
data2["profiles"].append(i)
|
data2["profiles"].append(i)
|
||||||
self.process_usernames(data2)
|
self.process_usernames(data2)
|
||||||
if "profiles" in data and "groups" in data:
|
if "profiles" in data and "groups" in data:
|
||||||
self.process_usernames(data)
|
self.process_usernames(data)
|
||||||
else:
|
else:
|
||||||
num = self.order_buffer(name, data, show_nextpage)
|
num = self.order_buffer(name, data, show_nextpage)
|
||||||
self.db[name]["offset"] = kwargs["offset"]+kwargs["count"]
|
self.db[name]["offset"] = kwargs["offset"]+kwargs["count"]
|
||||||
return num
|
return num
|
||||||
|
|
||||||
def get_messages(self, name="", *args, **kwargs):
|
def get_messages(self, name="", *args, **kwargs):
|
||||||
data = self.vk.client.messages.getHistory(*args, **kwargs)
|
data = self.vk.client.messages.getHistory(*args, **kwargs)
|
||||||
data["items"].reverse()
|
data["items"].reverse()
|
||||||
if data != None:
|
if data != None:
|
||||||
num = self.order_buffer(name, data["items"], False)
|
num = self.order_buffer(name, data["items"], False)
|
||||||
return num
|
return num
|
||||||
|
|
||||||
def get_users(self, user_ids=None, group_ids=None):
|
def get_users(self, user_ids=None, group_ids=None):
|
||||||
log.debug("Getting user information from the VK servers")
|
log.debug("Getting user information from the VK servers")
|
||||||
if user_ids != None:
|
if user_ids != None:
|
||||||
u = self.vk.client.users.get(user_ids=user_ids, fields="uid, first_name, last_name")
|
u = self.vk.client.users.get(user_ids=user_ids, fields="uid, first_name, last_name")
|
||||||
for i in u:
|
for i in u:
|
||||||
self.db["users"][i["id"]] = dict(nom="{0} {1}".format(i["first_name"], i["last_name"]))
|
self.db["users"][i["id"]] = dict(nom="{0} {1}".format(i["first_name"], i["last_name"]))
|
||||||
if group_ids != None:
|
if group_ids != None:
|
||||||
g = self.vk.client.groups.getById(group_ids=group_ids, fields="name")
|
g = self.vk.client.groups.getById(group_ids=group_ids, fields="name")
|
||||||
for i in g:
|
for i in g:
|
||||||
self.db["groups"][i["id"]] = dict(nom=i["name"], gen=i["name"], dat=i["name"], acc=i["name"], ins=i["name"], abl=i["name"])
|
self.db["groups"][i["id"]] = dict(nom=i["name"], gen=i["name"], dat=i["name"], acc=i["name"], ins=i["name"], abl=i["name"])
|
||||||
|
|
||||||
def get_user(self, user_id, key="user1"):
|
def get_user(self, user_id, key="user1"):
|
||||||
if user_id > 0:
|
if user_id > 0:
|
||||||
if user_id in self.db["users"]:
|
if user_id in self.db["users"]:
|
||||||
user_data = {}
|
user_data = {}
|
||||||
user_fields = "nom, gen, ins, dat, abl, acc".split(", ")
|
user_fields = "nom, gen, ins, dat, abl, acc".split(", ")
|
||||||
for i in user_fields:
|
for i in user_fields:
|
||||||
k = "{key}_{case}".format(key=key, case=i)
|
k = "{key}_{case}".format(key=key, case=i)
|
||||||
v = "{first_name} {last_name}".format(first_name=self.db["users"][user_id]["first_name_"+i], last_name=self.db["users"][user_id]["last_name_"+i])
|
v = "{first_name} {last_name}".format(first_name=self.db["users"][user_id]["first_name_"+i], last_name=self.db["users"][user_id]["last_name_"+i])
|
||||||
user_data[k] = v
|
user_data[k] = v
|
||||||
return user_data
|
return user_data
|
||||||
# if User_id is not present in db.
|
# if User_id is not present in db.
|
||||||
else:
|
else:
|
||||||
user = dict(id=user_id)
|
user = dict(id=user_id)
|
||||||
self.process_usernames(data=dict(profiles=[user], groups=[]))
|
self.process_usernames(data=dict(profiles=[user], groups=[]))
|
||||||
return self.get_user(user_id)
|
return self.get_user(user_id)
|
||||||
else:
|
else:
|
||||||
if abs(user_id) in self.db["groups"]:
|
if abs(user_id) in self.db["groups"]:
|
||||||
user_data = {}
|
user_data = {}
|
||||||
user_fields = "nom, gen, ins, dat, abl, acc".split(", ")
|
user_fields = "nom, gen, ins, dat, abl, acc".split(", ")
|
||||||
for i in user_fields:
|
for i in user_fields:
|
||||||
k = "{key}_{case}".format(key=key, case=i)
|
k = "{key}_{case}".format(key=key, case=i)
|
||||||
v = self.db["groups"][abs(user_id)][i]
|
v = self.db["groups"][abs(user_id)][i]
|
||||||
user_data[k] = v
|
user_data[k] = v
|
||||||
else:
|
else:
|
||||||
group = self.vk.client.groups.getById(group_ids=-1*user_id)[0]
|
group = self.vk.client.groups.getById(group_ids=-1*user_id)[0]
|
||||||
self.process_usernames(data=dict(profiles=[], groups=[group]))
|
self.process_usernames(data=dict(profiles=[], groups=[group]))
|
||||||
return self.get_user(user_id=user_id, key=key)
|
return self.get_user(user_id=user_id, key=key)
|
||||||
return user_data
|
return user_data
|
||||||
|
|
||||||
def process_usernames(self, data):
|
def process_usernames(self, data):
|
||||||
""" processes user IDS and saves them in a local storage system.
|
""" processes user IDS and saves them in a local storage system.
|
||||||
Every function wich needs to convert from an ID to user or community name will have to call the get_user_name function in this session object.
|
Every function wich needs to convert from an ID to user or community name will have to call the get_user_name function in this session object.
|
||||||
Every function that needs to save a set ot user ids for a future use needs to pass a data dictionary with a profiles key being a list of user objects.
|
Every function that needs to save a set ot user ids for a future use needs to pass a data dictionary with a profiles key being a list of user objects.
|
||||||
It gets first and last name for people in the 6 russian cases and saves them for future reference."""
|
It gets first and last name for people in the 6 russian cases and saves them for future reference."""
|
||||||
log.debug("Adding usernames to the local database...")
|
log.debug("Adding usernames to the local database...")
|
||||||
ids = ""
|
ids = ""
|
||||||
for i in data["profiles"]:
|
for i in data["profiles"]:
|
||||||
if (i["id"] in self.db["users"]) == False:
|
if (i["id"] in self.db["users"]) == False:
|
||||||
ids = ids + "{0},".format(i["id"],)
|
ids = ids + "{0},".format(i["id"],)
|
||||||
gids = ""
|
gids = ""
|
||||||
for i in data["groups"]:
|
for i in data["groups"]:
|
||||||
if i["id"] not in self.db["groups"]:
|
if i["id"] not in self.db["groups"]:
|
||||||
self.db["groups"][i["id"]] = dict(nom=i["name"], gen=i["name"], dat=i["name"], acc=i["name"], ins=i["name"], abl=i["name"])
|
self.db["groups"][i["id"]] = dict(nom=i["name"], gen=i["name"], dat=i["name"], acc=i["name"], ins=i["name"], abl=i["name"])
|
||||||
gids = "{0},".format(i["id"],)
|
gids = "{0},".format(i["id"],)
|
||||||
user_fields = "first_name_nom, last_name_nom, first_name_gen, last_name_gen, first_name_ins, last_name_ins, first_name_dat, last_name_dat, first_name_abl, last_name_abl, first_name_acc, last_name_acc, sex"
|
user_fields = "first_name_nom, last_name_nom, first_name_gen, last_name_gen, first_name_ins, last_name_ins, first_name_dat, last_name_dat, first_name_abl, last_name_abl, first_name_acc, last_name_acc, sex"
|
||||||
user_fields_list = user_fields.split(", ")
|
user_fields_list = user_fields.split(", ")
|
||||||
if ids != "":
|
if ids != "":
|
||||||
users = self.vk.client.users.get(user_ids=ids, fields=user_fields)
|
users = self.vk.client.users.get(user_ids=ids, fields=user_fields)
|
||||||
for i in users:
|
for i in users:
|
||||||
if i["id"] not in self.db["users"]:
|
if i["id"] not in self.db["users"]:
|
||||||
userdata = {}
|
userdata = {}
|
||||||
for field in user_fields_list:
|
for field in user_fields_list:
|
||||||
if field in i:
|
if field in i:
|
||||||
userdata[field] = i[field]
|
userdata[field] = i[field]
|
||||||
self.db["users"][i["id"]] = userdata
|
self.db["users"][i["id"]] = userdata
|
||||||
|
|
||||||
def get_my_data(self):
|
def get_my_data(self):
|
||||||
log.debug("Getting user identifier...")
|
log.debug("Getting user identifier...")
|
||||||
user = self.vk.client.users.get(fields="uid, first_name, last_name")
|
user = self.vk.client.users.get(fields="uid, first_name, last_name")
|
||||||
self.user_id = user[0]["id"]
|
self.user_id = user[0]["id"]
|
||||||
|
|
||||||
def post(self, parent_endpoint, child_endpoint, from_buffer=None, attachments_list=[], post_arguments={}):
|
def post(self, parent_endpoint, child_endpoint, from_buffer=None, attachments_list=[], post_arguments={}):
|
||||||
""" Generic function to be called whenever user wants to post something to VK.
|
""" Generic function to be called whenever user wants to post something to VK.
|
||||||
This function should be capable of uploading all attachments before posting, and send a special event in case the post has failed,
|
This function should be capable of uploading all attachments before posting, and send a special event in case the post has failed,
|
||||||
So the program can recreate the post and show it back to the user."""
|
So the program can recreate the post and show it back to the user."""
|
||||||
# Define a list of error codes that are handled by the application.
|
# Define a list of error codes that are handled by the application.
|
||||||
handled_errors = [7, 900]
|
handled_errors = [7, 900]
|
||||||
# ToDo: this function will occasionally be called with attachments already set to post_arguments, example if the user could upload the files but was unable to send the post due to a connection problem.
|
# ToDo: this function will occasionally be called with attachments already set to post_arguments, example if the user could upload the files but was unable to send the post due to a connection problem.
|
||||||
# We should see what can be done (reuploading everything vs using the already added attachments).
|
# We should see what can be done (reuploading everything vs using the already added attachments).
|
||||||
attachments = ""
|
attachments = ""
|
||||||
# Firstly, let's try to upload the attachments here. If peer_id exists in post_arguments,
|
# Firstly, let's try to upload the attachments here. If peer_id exists in post_arguments,
|
||||||
# It means we are talking about private messages, whose attachment procedures have their own methods.
|
# It means we are talking about private messages, whose attachment procedures have their own methods.
|
||||||
if len(attachments_list) > 0:
|
if len(attachments_list) > 0:
|
||||||
try:
|
try:
|
||||||
attachments = self.upload_attachments(attachments_list, post_arguments.get("peer_id"))
|
attachments = self.upload_attachments(attachments_list, post_arguments.get("peer_id"))
|
||||||
except Exception as error:
|
except Exception as error:
|
||||||
log.error("Error calling method %s.%s with arguments: %r. Failed during loading attachments. Error: %s" % (parent_endpoint, child_endpoint, post_arguments, str(error)))
|
log.error("Error calling method %s.%s with arguments: %r. Failed during loading attachments. Error: %s" % (parent_endpoint, child_endpoint, post_arguments, str(error)))
|
||||||
# Report a failed function here too with same arguments so the client should be able to recreate it again.
|
# Report a failed function here too with same arguments so the client should be able to recreate it again.
|
||||||
wx.CallAfter(pub.sendMessage, "postFailed", parent_endpoint=parent_endpoint, child_endpoint=child_endpoint, from_buffer=from_buffer, attachments_list=attachments_list, post_arguments=post_arguments)
|
wx.CallAfter(pub.sendMessage, "postFailed", parent_endpoint=parent_endpoint, child_endpoint=child_endpoint, from_buffer=from_buffer, attachments_list=attachments_list, post_arguments=post_arguments)
|
||||||
# After modifying everything, let's update the post arguments if needed.
|
# After modifying everything, let's update the post arguments if needed.
|
||||||
if len(attachments) > 0:
|
if len(attachments) > 0:
|
||||||
if parent_endpoint == "messages":
|
if parent_endpoint == "messages":
|
||||||
post_arguments.update(attachment=attachments)
|
post_arguments.update(attachment=attachments)
|
||||||
else:
|
else:
|
||||||
post_arguments.update(attachments=attachments)
|
post_arguments.update(attachments=attachments)
|
||||||
# Determines the correct functions to call here.
|
# Determines the correct functions to call here.
|
||||||
endpoint = getattr(self.vk.client, parent_endpoint)
|
endpoint = getattr(self.vk.client, parent_endpoint)
|
||||||
endpoint = getattr(endpoint, child_endpoint)
|
endpoint = getattr(endpoint, child_endpoint)
|
||||||
try:
|
try:
|
||||||
post = endpoint(**post_arguments)
|
post = endpoint(**post_arguments)
|
||||||
# Once the post has been send, let's report it to the interested objects.
|
# Once the post has been send, let's report it to the interested objects.
|
||||||
pub.sendMessage("posted", from_buffer=from_buffer)
|
pub.sendMessage("posted", from_buffer=from_buffer)
|
||||||
except Exception as error:
|
except Exception as error:
|
||||||
log.exception("Error calling method %s.%s with arguments: %r. Error: %s" % (parent_endpoint, child_endpoint, post_arguments, str(error)))
|
log.exception("Error calling method %s.%s with arguments: %r. Error: %s" % (parent_endpoint, child_endpoint, post_arguments, str(error)))
|
||||||
# Send handled errors to the corresponding function, call the default handler otherwise.
|
# Send handled errors to the corresponding function, call the default handler otherwise.
|
||||||
if error.code in handled_errors:
|
if error.code in handled_errors:
|
||||||
wx.CallAfter(pub.sendMessage, "api-error", code=error.code)
|
wx.CallAfter(pub.sendMessage, "api-error", code=error.code)
|
||||||
else:
|
else:
|
||||||
# Report a failed function here too with same arguments so the client should be able to recreate it again.
|
# Report a failed function here too with same arguments so the client should be able to recreate it again.
|
||||||
wx.CallAfter(pub.sendMessage, "postFailed", parent_endpoint=parent_endpoint, child_endpoint=child_endpoint, from_buffer=from_buffer, attachments_list=attachments_list, post_arguments=post_arguments)
|
wx.CallAfter(pub.sendMessage, "postFailed", parent_endpoint=parent_endpoint, child_endpoint=child_endpoint, from_buffer=from_buffer, attachments_list=attachments_list, post_arguments=post_arguments)
|
||||||
|
|
||||||
def upload_attachments(self, attachments, peer_id=None):
|
def upload_attachments(self, attachments, peer_id=None):
|
||||||
""" Upload attachments to VK before posting them.
|
""" Upload attachments to VK before posting them.
|
||||||
Returns attachments formatted as string, as required by VK API.
|
Returns attachments formatted as string, as required by VK API.
|
||||||
@ peer_id int: if this value is passed, let's assume attachments will be send in private messages.
|
@ peer_id int: if this value is passed, let's assume attachments will be send in private messages.
|
||||||
"""
|
"""
|
||||||
# To do: Check the caption and description fields for this kind of attachments.
|
# To do: Check the caption and description fields for this kind of attachments.
|
||||||
local_attachments = ""
|
local_attachments = ""
|
||||||
uploader = upload.VkUpload(self.vk.session_object)
|
uploader = upload.VkUpload(self.vk.session_object)
|
||||||
for i in attachments:
|
for i in attachments:
|
||||||
if i["from"] == "online":
|
if i["from"] == "online":
|
||||||
local_attachments += "{0}{1}_{2},".format(i["type"], i["owner_id"], i["id"])
|
local_attachments += "{0}{1}_{2},".format(i["type"], i["owner_id"], i["id"])
|
||||||
elif i["from"] == "local" and i["type"] == "photo":
|
elif i["from"] == "local" and i["type"] == "photo":
|
||||||
photos = i["file"]
|
photos = i["file"]
|
||||||
description = i["description"]
|
description = i["description"]
|
||||||
if peer_id == None:
|
if peer_id == None:
|
||||||
r = uploader.photo_wall(photos, caption=description)
|
r = uploader.photo_wall(photos, caption=description)
|
||||||
else:
|
else:
|
||||||
r = uploader.photo_messages(photos)
|
r = uploader.photo_messages(photos)
|
||||||
id = r[0]["id"]
|
id = r[0]["id"]
|
||||||
owner_id = r[0]["owner_id"]
|
owner_id = r[0]["owner_id"]
|
||||||
local_attachments += "photo{0}_{1},".format(owner_id, id)
|
local_attachments += "photo{0}_{1},".format(owner_id, id)
|
||||||
elif i["from"] == "local" and i["type"] == "audio":
|
elif i["from"] == "local" and i["type"] == "audio":
|
||||||
audio = i["file"]
|
audio = i["file"]
|
||||||
title = "untitled"
|
title = "untitled"
|
||||||
artist = "unnamed"
|
artist = "unnamed"
|
||||||
if "artist" in i:
|
if "artist" in i:
|
||||||
artist = i["artist"]
|
artist = i["artist"]
|
||||||
if "title" in i:
|
if "title" in i:
|
||||||
title = i["title"]
|
title = i["title"]
|
||||||
r = uploader.audio(audio, title=title, artist=artist)
|
r = uploader.audio(audio, title=title, artist=artist)
|
||||||
id = r["id"]
|
id = r["id"]
|
||||||
owner_id = r["owner_id"]
|
owner_id = r["owner_id"]
|
||||||
local_attachments += "audio{0}_{1},".format(owner_id, id)
|
local_attachments += "audio{0}_{1},".format(owner_id, id)
|
||||||
elif i["from"] == "local" and i["type"] == "voice_message":
|
elif i["from"] == "local" and i["type"] == "voice_message":
|
||||||
r = uploader.audio_message(i["file"], peer_id=peer_id)
|
r = uploader.audio_message(i["file"], peer_id=peer_id)
|
||||||
id = r["audio_message"]["id"]
|
id = r["audio_message"]["id"]
|
||||||
owner_id = r["audio_message"]["owner_id"]
|
owner_id = r["audio_message"]["owner_id"]
|
||||||
local_attachments += "audio_message{0}_{1},".format(owner_id, id)
|
local_attachments += "audio_message{0}_{1},".format(owner_id, id)
|
||||||
elif i["from"] == "local" and i["type"] == "document":
|
elif i["from"] == "local" and i["type"] == "document":
|
||||||
document = i["file"]
|
document = i["file"]
|
||||||
title = i["title"]
|
title = i["title"]
|
||||||
if peer_id == None:
|
if peer_id == None:
|
||||||
r = uploader.document(document, title=title, to_wall=True)
|
r = uploader.document(document, title=title, to_wall=True)
|
||||||
else:
|
else:
|
||||||
r = uploader.document(document, title=title, message_peer_id=peer_id)
|
r = uploader.document(document, title=title, message_peer_id=peer_id)
|
||||||
id = r["doc"]["id"]
|
id = r["doc"]["id"]
|
||||||
owner_id = r["doc"]["owner_id"]
|
owner_id = r["doc"]["owner_id"]
|
||||||
local_attachments += "doc{0}_{1},".format(owner_id, id)
|
local_attachments += "doc{0}_{1},".format(owner_id, id)
|
||||||
return local_attachments
|
return local_attachments
|
||||||
|
@ -14,83 +14,83 @@ from .config_utils import Configuration
|
|||||||
log = logging.getLogger("sessionmanager.sessionManager")
|
log = logging.getLogger("sessionmanager.sessionManager")
|
||||||
|
|
||||||
class sessionManagerController(object):
|
class sessionManagerController(object):
|
||||||
def __init__(self, starting=True):
|
def __init__(self, starting=True):
|
||||||
super(sessionManagerController, self).__init__()
|
super(sessionManagerController, self).__init__()
|
||||||
log.debug("Setting up the session manager.")
|
log.debug("Setting up the session manager.")
|
||||||
if starting:
|
if starting:
|
||||||
title=_("Select an account")
|
title=_("Select an account")
|
||||||
else:
|
else:
|
||||||
title = _("Manage accounts")
|
title = _("Manage accounts")
|
||||||
self.view = view.sessionManagerWindow(starting=starting, title=title)
|
self.view = view.sessionManagerWindow(starting=starting, title=title)
|
||||||
widgetUtils.connect_event(self.view.new, widgetUtils.BUTTON_PRESSED, self.manage_new_account)
|
widgetUtils.connect_event(self.view.new, widgetUtils.BUTTON_PRESSED, self.manage_new_account)
|
||||||
widgetUtils.connect_event(self.view.remove, widgetUtils.BUTTON_PRESSED, self.remove)
|
widgetUtils.connect_event(self.view.remove, widgetUtils.BUTTON_PRESSED, self.remove)
|
||||||
self.fill_list()
|
self.fill_list()
|
||||||
if len(self.sessions) == 0:
|
if len(self.sessions) == 0:
|
||||||
log.debug("the session list is empty, creating a new one...")
|
log.debug("the session list is empty, creating a new one...")
|
||||||
self.manage_new_account()
|
self.manage_new_account()
|
||||||
|
|
||||||
def fill_list(self):
|
def fill_list(self):
|
||||||
self.sessions = []
|
self.sessions = []
|
||||||
log.debug("Filling the session list...")
|
log.debug("Filling the session list...")
|
||||||
for i in os.listdir(paths.config_path()):
|
for i in os.listdir(paths.config_path()):
|
||||||
if i != "dicts" and os.path.isdir(os.path.join(paths.config_path(), i)):
|
if i != "dicts" and os.path.isdir(os.path.join(paths.config_path(), i)):
|
||||||
log.debug("Adding session %s" % (i,))
|
log.debug("Adding session %s" % (i,))
|
||||||
config_test = Configuration(os.path.join(paths.config_path(), i, "session.conf"))
|
config_test = Configuration(os.path.join(paths.config_path(), i, "session.conf"))
|
||||||
name = config_test["vk"]["user"]
|
name = config_test["vk"]["user"]
|
||||||
if name != "" and config_test["vk"]["password"] != "":
|
if name != "" and config_test["vk"]["password"] != "":
|
||||||
self.sessions.append((i, name))
|
self.sessions.append((i, name))
|
||||||
self.view.list.insert_item(False, *[name])
|
self.view.list.insert_item(False, *[name])
|
||||||
|
|
||||||
def manage_new_account(self, *args, **kwargs):
|
def manage_new_account(self, *args, **kwargs):
|
||||||
if view.new_account_dialog() == widgetUtils.YES:
|
if view.new_account_dialog() == widgetUtils.YES:
|
||||||
location = (str(time.time())[-6:])
|
location = (str(time.time())[-6:])
|
||||||
log.debug("Creating session in the %s path" % (location,))
|
log.debug("Creating session in the %s path" % (location,))
|
||||||
s = session.vkSession(location)
|
s = session.vkSession(location)
|
||||||
path = os.path.join(paths.config_path(), location)
|
path = os.path.join(paths.config_path(), location)
|
||||||
if not os.path.exists(path):
|
if not os.path.exists(path):
|
||||||
os.mkdir(path)
|
os.mkdir(path)
|
||||||
s.get_configuration(True)
|
s.get_configuration(True)
|
||||||
self.get_authorisation(s)
|
self.get_authorisation(s)
|
||||||
name = s.settings["vk"]["user"]
|
name = s.settings["vk"]["user"]
|
||||||
self.sessions.append((location, name))
|
self.sessions.append((location, name))
|
||||||
self.view.list.insert_item(False, *[name])
|
self.view.list.insert_item(False, *[name])
|
||||||
self.modified = True
|
self.modified = True
|
||||||
|
|
||||||
def get_authorisation(self, c):
|
def get_authorisation(self, c):
|
||||||
log.debug("Starting the authorisation process...")
|
log.debug("Starting the authorisation process...")
|
||||||
dl = view.newSessionDialog()
|
dl = view.newSessionDialog()
|
||||||
if dl.ShowModal() == widgetUtils.OK:
|
if dl.ShowModal() == widgetUtils.OK:
|
||||||
c.settings["vk"]["user"] = dl.get_email()
|
c.settings["vk"]["user"] = dl.get_email()
|
||||||
c.settings["vk"]["password"] = dl.get_password()
|
c.settings["vk"]["password"] = dl.get_password()
|
||||||
try:
|
try:
|
||||||
c.login()
|
c.login()
|
||||||
except AuthenticationError:
|
except AuthenticationError:
|
||||||
c.settings["vk"]["password"] = ""
|
c.settings["vk"]["password"] = ""
|
||||||
c.settings["vk"]["user"]
|
c.settings["vk"]["user"]
|
||||||
return self.get_authorisation(c)
|
return self.get_authorisation(c)
|
||||||
|
|
||||||
def do_ok(self):
|
def do_ok(self):
|
||||||
selected_session = self.sessions[self.view.list.get_selected()]
|
selected_session = self.sessions[self.view.list.get_selected()]
|
||||||
self.session = selected_session[0]
|
self.session = selected_session[0]
|
||||||
self.session = session.vkSession(self.session)
|
self.session = session.vkSession(self.session)
|
||||||
self.session.get_configuration()
|
self.session.get_configuration()
|
||||||
session.sessions[selected_session[1]] = self.session
|
session.sessions[selected_session[1]] = self.session
|
||||||
|
|
||||||
def show(self):
|
def show(self):
|
||||||
if len(self.sessions) > 1:
|
if len(self.sessions) > 1:
|
||||||
answer = self.view.get_response()
|
answer = self.view.get_response()
|
||||||
else:
|
else:
|
||||||
answer = widgetUtils.OK
|
answer = widgetUtils.OK
|
||||||
if answer == widgetUtils.OK:
|
if answer == widgetUtils.OK:
|
||||||
self.do_ok()
|
self.do_ok()
|
||||||
else:
|
else:
|
||||||
sys.exit()
|
sys.exit()
|
||||||
self.view.destroy()
|
self.view.destroy()
|
||||||
|
|
||||||
def remove(self, *args, **kwargs):
|
def remove(self, *args, **kwargs):
|
||||||
if self.view.remove_account_dialog() == widgetUtils.YES:
|
if self.view.remove_account_dialog() == widgetUtils.YES:
|
||||||
selected_session = self.sessions[self.view.list.get_selected()]
|
selected_session = self.sessions[self.view.list.get_selected()]
|
||||||
shutil.rmtree(path=os.path.join(paths.config_path(), selected_session[0]), ignore_errors=True)
|
shutil.rmtree(path=os.path.join(paths.config_path(), selected_session[0]), ignore_errors=True)
|
||||||
self.sessions.remove(selected_session)
|
self.sessions.remove(selected_session)
|
||||||
self.view.list.remove_item(self.view.list.get_selected())
|
self.view.list.remove_item(self.view.list.get_selected())
|
||||||
self.modified = True
|
self.modified = True
|
||||||
|
@ -12,93 +12,93 @@ url_re = re.compile("(?:\w+://|www\.)[^ ,.?!#%=+][^ ]*")
|
|||||||
bad_chars = '\'\\.,[](){}:;"'
|
bad_chars = '\'\\.,[](){}:;"'
|
||||||
|
|
||||||
def seconds_to_string(seconds, precision=0):
|
def seconds_to_string(seconds, precision=0):
|
||||||
""" convert a number of seconds in a string representation."""
|
""" convert a number of seconds in a string representation."""
|
||||||
# ToDo: Improve it to handle properly Russian plurals.
|
# ToDo: Improve it to handle properly Russian plurals.
|
||||||
day = seconds // 86400
|
day = seconds // 86400
|
||||||
hour = seconds // 3600
|
hour = seconds // 3600
|
||||||
min = (seconds // 60) % 60
|
min = (seconds // 60) % 60
|
||||||
sec = seconds - (hour * 3600) - (min * 60)
|
sec = seconds - (hour * 3600) - (min * 60)
|
||||||
sec_spec = "." + str(precision) + "f"
|
sec_spec = "." + str(precision) + "f"
|
||||||
sec_string = sec.__format__(sec_spec)
|
sec_string = sec.__format__(sec_spec)
|
||||||
string = ""
|
string = ""
|
||||||
if day == 1:
|
if day == 1:
|
||||||
string += _("%d day, ") % day
|
string += _("%d day, ") % day
|
||||||
elif day >= 2:
|
elif day >= 2:
|
||||||
string += _("%d days, ") % day
|
string += _("%d days, ") % day
|
||||||
if (hour == 1):
|
if (hour == 1):
|
||||||
string += _("%d hour, ") % hour
|
string += _("%d hour, ") % hour
|
||||||
elif (hour >= 2):
|
elif (hour >= 2):
|
||||||
string += _("%d hours, ") % hour
|
string += _("%d hours, ") % hour
|
||||||
if (min == 1):
|
if (min == 1):
|
||||||
string += _("%d minute, ") % min
|
string += _("%d minute, ") % min
|
||||||
elif (min >= 2):
|
elif (min >= 2):
|
||||||
string += _("%d minutes, ") % min
|
string += _("%d minutes, ") % min
|
||||||
if sec >= 0 and sec <= 2:
|
if sec >= 0 and sec <= 2:
|
||||||
string += _("%s second") % sec_string
|
string += _("%s second") % sec_string
|
||||||
else:
|
else:
|
||||||
string += _("%s seconds") % sec_string
|
string += _("%s seconds") % sec_string
|
||||||
return string
|
return string
|
||||||
|
|
||||||
def find_urls_in_text(text):
|
def find_urls_in_text(text):
|
||||||
return [s.strip(bad_chars) for s in url_re.findall(text)]
|
return [s.strip(bad_chars) for s in url_re.findall(text)]
|
||||||
|
|
||||||
def download_file(url, local_filename):
|
def download_file(url, local_filename):
|
||||||
r = requests.get(url, stream=True)
|
r = requests.get(url, stream=True)
|
||||||
pub.sendMessage("change_status", status=_("Downloading {0}").format(local_filename,))
|
pub.sendMessage("change_status", status=_("Downloading {0}").format(local_filename,))
|
||||||
total_length = r.headers.get("content-length")
|
total_length = r.headers.get("content-length")
|
||||||
dl = 0
|
dl = 0
|
||||||
total_length = int(total_length)
|
total_length = int(total_length)
|
||||||
with open(local_filename, 'wb') as f:
|
with open(local_filename, 'wb') as f:
|
||||||
for chunk in r.iter_content(chunk_size=512*1024):
|
for chunk in r.iter_content(chunk_size=512*1024):
|
||||||
if chunk: # filter out keep-alive new chunks
|
if chunk: # filter out keep-alive new chunks
|
||||||
dl += len(chunk)
|
dl += len(chunk)
|
||||||
f.write(chunk)
|
f.write(chunk)
|
||||||
done = int(100 * dl/total_length)
|
done = int(100 * dl/total_length)
|
||||||
msg = _("Downloading {0} ({1}%)").format(os.path.basename(local_filename), done)
|
msg = _("Downloading {0} ({1}%)").format(os.path.basename(local_filename), done)
|
||||||
# print(msg)
|
# print(msg)
|
||||||
pub.sendMessage("change_status", status=msg)
|
pub.sendMessage("change_status", status=msg)
|
||||||
pub.sendMessage("change_status", status=_("Ready"))
|
pub.sendMessage("change_status", status=_("Ready"))
|
||||||
return local_filename
|
return local_filename
|
||||||
|
|
||||||
def download_files(downloads):
|
def download_files(downloads):
|
||||||
for download in downloads:
|
for download in downloads:
|
||||||
download_file(download[0], download[1])
|
download_file(download[0], download[1])
|
||||||
|
|
||||||
def detect_users(text):
|
def detect_users(text):
|
||||||
""" Detect all users and communities mentionned in any text posted in VK."""
|
""" Detect all users and communities mentionned in any text posted in VK."""
|
||||||
# This regexp gets group and users mentionned in topic comments.
|
# This regexp gets group and users mentionned in topic comments.
|
||||||
for matched_data in re.finditer("(\[)(id|club)(\d+:bp-\d+_\d+\|)(\D+)(\])", text):
|
for matched_data in re.finditer("(\[)(id|club)(\d+:bp-\d+_\d+\|)(\D+)(\])", text):
|
||||||
text = re.sub("\[(id|club)\d+:bp-\d+_\d+\|\D+\]", matched_data.groups()[3]+", ", text, count=1)
|
text = re.sub("\[(id|club)\d+:bp-\d+_\d+\|\D+\]", matched_data.groups()[3]+", ", text, count=1)
|
||||||
# This is for users and communities just mentionned in wall comments or posts.
|
# This is for users and communities just mentionned in wall comments or posts.
|
||||||
for matched_data in re.finditer("(\[)(id|club)(\d+\|)(\D+)(\])", text):
|
for matched_data in re.finditer("(\[)(id|club)(\d+\|)(\D+)(\])", text):
|
||||||
text = re.sub("\[(id|club)\d+\|\D+\]", matched_data.groups()[3]+", ", text, count=1)
|
text = re.sub("\[(id|club)\d+\|\D+\]", matched_data.groups()[3]+", ", text, count=1)
|
||||||
return text
|
return text
|
||||||
|
|
||||||
def clean_text(text):
|
def clean_text(text):
|
||||||
""" Clean text, removing all unneeded HTMl and converting HTML represented characters in their unicode counterparts."""
|
""" Clean text, removing all unneeded HTMl and converting HTML represented characters in their unicode counterparts."""
|
||||||
text = detect_users(text)
|
text = detect_users(text)
|
||||||
text = html.unescape(text)
|
text = html.unescape(text)
|
||||||
return text
|
return text
|
||||||
|
|
||||||
def transform_audio_url(url):
|
def transform_audio_url(url):
|
||||||
""" Transforms the URL offered by VK to the unencrypted stream so we can still play it.
|
""" Transforms the URL offered by VK to the unencrypted stream so we can still play it.
|
||||||
This function will be updated every time VK decides to change something in their Audio API'S.
|
This function will be updated every time VK decides to change something in their Audio API'S.
|
||||||
Changelog:
|
Changelog:
|
||||||
30/04/2019: Re-enabled old methods as VK changed everything as how it was working on 16.04.2019.
|
30/04/2019: Re-enabled old methods as VK changed everything as how it was working on 16.04.2019.
|
||||||
17.04.2019: Updated function. Now it is not required to strip anything, just replacing /index.m3u8 with .mp3 should be enough.
|
17.04.2019: Updated function. Now it is not required to strip anything, just replacing /index.m3u8 with .mp3 should be enough.
|
||||||
16.04.2019: Implemented this function. For now it replaces /index.m3u8 by .mp3, also removes the path component before "/audios" if the URL contains the word /audios, or the last path component before the filename if doesn't.
|
16.04.2019: Implemented this function. For now it replaces /index.m3u8 by .mp3, also removes the path component before "/audios" if the URL contains the word /audios, or the last path component before the filename if doesn't.
|
||||||
"""
|
"""
|
||||||
if "vkuseraudio.net" not in url and "index.m3u8" not in url:
|
if "vkuseraudio.net" not in url and "index.m3u8" not in url:
|
||||||
return url
|
return url
|
||||||
url = url.replace("/index.m3u8", ".mp3")
|
url = url.replace("/index.m3u8", ".mp3")
|
||||||
parts = url.split("/")
|
parts = url.split("/")
|
||||||
if "/audios" not in url:
|
if "/audios" not in url:
|
||||||
url = url.replace("/"+parts[-2], "")
|
url = url.replace("/"+parts[-2], "")
|
||||||
else:
|
else:
|
||||||
url = url.replace("/"+parts[-3], "")
|
url = url.replace("/"+parts[-3], "")
|
||||||
url = url.split(".mp3?")[0]+".mp3"
|
url = url.split(".mp3?")[0]+".mp3"
|
||||||
return url
|
return url
|
||||||
|
|
||||||
def safe_filename(filename):
|
def safe_filename(filename):
|
||||||
allowed_symbols = ["_", ".", ",", "-", "(", ")"]
|
allowed_symbols = ["_", ".", ",", "-", "(", ")"]
|
||||||
return "".join([c for c in filename if c.isalpha() or c.isdigit() or c==' ' or c in allowed_symbols]).rstrip()
|
return "".join([c for c in filename if c.isalpha() or c.isdigit() or c==' ' or c in allowed_symbols]).rstrip()
|
||||||
|
@ -9,28 +9,28 @@ log = logging.getLogger("vkSessionHandler")
|
|||||||
|
|
||||||
class vkObject(object):
|
class vkObject(object):
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.api_key = keys.keyring.get_api_key()
|
self.api_key = keys.keyring.get_api_key()
|
||||||
|
|
||||||
def login(self, user, password, token, alt_token, filename):
|
def login(self, user, password, token, alt_token, filename):
|
||||||
if alt_token == False:
|
if alt_token == False:
|
||||||
log.info("Using kate's token...")
|
log.info("Using kate's token...")
|
||||||
# Let's import the patched vk_api module for using a different user agent
|
# Let's import the patched vk_api module for using a different user agent
|
||||||
from . import vk_api_patched as vk_api
|
from . import vk_api_patched as vk_api
|
||||||
if token == "" or token == None:
|
if token == "" or token == None:
|
||||||
log.info("Token is not valid. Generating one...")
|
log.info("Token is not valid. Generating one...")
|
||||||
original_token = official.login(user, password)
|
original_token = official.login(user, password)
|
||||||
token = original_token
|
token = original_token
|
||||||
log.info("Token validated...")
|
log.info("Token validated...")
|
||||||
self.session_object = vk_api.VkApi(app_id=self.api_key, login=user, password=password, token=token, scope="all", config_filename=filename)
|
self.session_object = vk_api.VkApi(app_id=self.api_key, login=user, password=password, token=token, scope="all", config_filename=filename)
|
||||||
else:
|
else:
|
||||||
import vk_api
|
import vk_api
|
||||||
self.session_object = vk_api.VkApi(app_id=self.api_key, login=user, password=password, scope="offline, wall, notify, friends, photos, audio, video, docs, notes, pages, status, groups, messages, notifications, stats", config_filename=filename, auth_handler=two_factor_auth)
|
self.session_object = vk_api.VkApi(app_id=self.api_key, login=user, password=password, scope="offline, wall, notify, friends, photos, audio, video, docs, notes, pages, status, groups, messages, notifications, stats", config_filename=filename, auth_handler=two_factor_auth)
|
||||||
self.session_object.auth()
|
self.session_object.auth()
|
||||||
self.client = self.session_object.get_api()
|
self.client = self.session_object.get_api()
|
||||||
# print self.client.audio.get()
|
# print self.client.audio.get()
|
||||||
log.debug("Getting tokens for 24 hours...")
|
log.debug("Getting tokens for 24 hours...")
|
||||||
# info = self.client.account.getProfileInfo()
|
# info = self.client.account.getProfileInfo()
|
||||||
# Add session data to the application statistics.
|
# Add session data to the application statistics.
|
||||||
self.client.stats.trackVisitor()
|
self.client.stats.trackVisitor()
|
||||||
self.client_audio = VkAudio(self.session_object)
|
self.client_audio = VkAudio(self.session_object)
|
||||||
|
@ -4,71 +4,71 @@ import wx
|
|||||||
import widgetUtils
|
import widgetUtils
|
||||||
|
|
||||||
def new_account_dialog():
|
def new_account_dialog():
|
||||||
return wx.MessageDialog(None, _("In order to continue, you need to configure your VK account before. Would you like to autorhise a new account now?"), _("Authorisation"), wx.YES_NO).ShowModal()
|
return wx.MessageDialog(None, _("In order to continue, you need to configure your VK account before. Would you like to autorhise a new account now?"), _("Authorisation"), wx.YES_NO).ShowModal()
|
||||||
|
|
||||||
class newSessionDialog(widgetUtils.BaseDialog):
|
class newSessionDialog(widgetUtils.BaseDialog):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super(newSessionDialog, self).__init__(parent=None, id=wx.NewId(), title=_("Authorise VK"))
|
super(newSessionDialog, self).__init__(parent=None, id=wx.NewId(), title=_("Authorise VK"))
|
||||||
panel = wx.Panel(self)
|
panel = wx.Panel(self)
|
||||||
lbl1 = wx.StaticText(panel, -1, _("&Email or phone number"))
|
lbl1 = wx.StaticText(panel, -1, _("&Email or phone number"))
|
||||||
self.email = wx.TextCtrl(panel, -1)
|
self.email = wx.TextCtrl(panel, -1)
|
||||||
lbl2 = wx.StaticText(panel, -1, _("&Password"))
|
lbl2 = wx.StaticText(panel, -1, _("&Password"))
|
||||||
self.passw = wx.TextCtrl(panel, -1, style=wx.TE_PASSWORD)
|
self.passw = wx.TextCtrl(panel, -1, style=wx.TE_PASSWORD)
|
||||||
sizer = wx.BoxSizer()
|
sizer = wx.BoxSizer()
|
||||||
b1 = wx.BoxSizer(wx.HORIZONTAL)
|
b1 = wx.BoxSizer(wx.HORIZONTAL)
|
||||||
b1.Add(lbl1, 0, wx.ALL, 5)
|
b1.Add(lbl1, 0, wx.ALL, 5)
|
||||||
b1.Add(self.email, 0, wx.ALL, 5)
|
b1.Add(self.email, 0, wx.ALL, 5)
|
||||||
b2 = wx.BoxSizer(wx.HORIZONTAL)
|
b2 = wx.BoxSizer(wx.HORIZONTAL)
|
||||||
b2.Add(lbl2, 0, wx.ALL, 5)
|
b2.Add(lbl2, 0, wx.ALL, 5)
|
||||||
b2.Add(self.passw, 0, wx.ALL, 5)
|
b2.Add(self.passw, 0, wx.ALL, 5)
|
||||||
sizer.Add(b1, 0, wx.ALL, 5)
|
sizer.Add(b1, 0, wx.ALL, 5)
|
||||||
sizer.Add(b2, 0, wx.ALL, 5)
|
sizer.Add(b2, 0, wx.ALL, 5)
|
||||||
ok = wx.Button(panel, wx.ID_OK)
|
ok = wx.Button(panel, wx.ID_OK)
|
||||||
ok.SetDefault()
|
ok.SetDefault()
|
||||||
cancel = wx.Button(panel, wx.ID_CANCEL)
|
cancel = wx.Button(panel, wx.ID_CANCEL)
|
||||||
btnb = wx.BoxSizer(wx.HORIZONTAL)
|
btnb = wx.BoxSizer(wx.HORIZONTAL)
|
||||||
btnb.Add(ok, 0, wx.ALL, 5)
|
btnb.Add(ok, 0, wx.ALL, 5)
|
||||||
btnb.Add(cancel, 0, wx.ALL, 5)
|
btnb.Add(cancel, 0, wx.ALL, 5)
|
||||||
sizer.Add(btnb, 0, wx.ALL, 5)
|
sizer.Add(btnb, 0, wx.ALL, 5)
|
||||||
panel.SetSizer(sizer)
|
panel.SetSizer(sizer)
|
||||||
|
|
||||||
def get_email(self):
|
def get_email(self):
|
||||||
return self.email.GetValue()
|
return self.email.GetValue()
|
||||||
|
|
||||||
def get_password(self):
|
def get_password(self):
|
||||||
return self.passw.GetValue()
|
return self.passw.GetValue()
|
||||||
|
|
||||||
class sessionManagerWindow(widgetUtils.BaseDialog):
|
class sessionManagerWindow(widgetUtils.BaseDialog):
|
||||||
def __init__(self, title, starting=True):
|
def __init__(self, title, starting=True):
|
||||||
super(sessionManagerWindow, self).__init__(parent=None, title=title, size=wx.DefaultSize)
|
super(sessionManagerWindow, self).__init__(parent=None, title=title, size=wx.DefaultSize)
|
||||||
panel = wx.Panel(self)
|
panel = wx.Panel(self)
|
||||||
sizer = wx.BoxSizer(wx.VERTICAL)
|
sizer = wx.BoxSizer(wx.VERTICAL)
|
||||||
label = wx.StaticText(panel, -1, _(u"Accounts list"), size=wx.DefaultSize)
|
label = wx.StaticText(panel, -1, _(u"Accounts list"), size=wx.DefaultSize)
|
||||||
listSizer = wx.BoxSizer(wx.HORIZONTAL)
|
listSizer = wx.BoxSizer(wx.HORIZONTAL)
|
||||||
self.list = widgetUtils.list(panel, _("Account"), style=wx.LC_SINGLE_SEL|wx.LC_REPORT)
|
self.list = widgetUtils.list(panel, _("Account"), style=wx.LC_SINGLE_SEL|wx.LC_REPORT)
|
||||||
listSizer.Add(label, 0, wx.ALL, 5)
|
listSizer.Add(label, 0, wx.ALL, 5)
|
||||||
listSizer.Add(self.list.list, 0, wx.ALL, 5)
|
listSizer.Add(self.list.list, 0, wx.ALL, 5)
|
||||||
sizer.Add(listSizer, 0, wx.ALL, 5)
|
sizer.Add(listSizer, 0, wx.ALL, 5)
|
||||||
self.new = wx.Button(panel, -1, _("New account"), size=wx.DefaultSize)
|
self.new = wx.Button(panel, -1, _("New account"), size=wx.DefaultSize)
|
||||||
self.remove = wx.Button(panel, -1, _(u"Remove account"))
|
self.remove = wx.Button(panel, -1, _(u"Remove account"))
|
||||||
if starting:
|
if starting:
|
||||||
id_ok = wx.ID_OK
|
id_ok = wx.ID_OK
|
||||||
else:
|
else:
|
||||||
id_ok = wx.ID_CANCEL
|
id_ok = wx.ID_CANCEL
|
||||||
ok = wx.Button(panel, id_ok, size=wx.DefaultSize)
|
ok = wx.Button(panel, id_ok, size=wx.DefaultSize)
|
||||||
ok.SetDefault()
|
ok.SetDefault()
|
||||||
if starting:
|
if starting:
|
||||||
cancel = wx.Button(panel, wx.ID_CANCEL, size=wx.DefaultSize)
|
cancel = wx.Button(panel, wx.ID_CANCEL, size=wx.DefaultSize)
|
||||||
self.SetAffirmativeId(id_ok)
|
self.SetAffirmativeId(id_ok)
|
||||||
buttons = wx.BoxSizer(wx.HORIZONTAL)
|
buttons = wx.BoxSizer(wx.HORIZONTAL)
|
||||||
buttons.Add(self.new, 0, wx.ALL, 5)
|
buttons.Add(self.new, 0, wx.ALL, 5)
|
||||||
buttons.Add(ok, 0, wx.ALL, 5)
|
buttons.Add(ok, 0, wx.ALL, 5)
|
||||||
if starting:
|
if starting:
|
||||||
buttons.Add(cancel, 0, wx.ALL, 5)
|
buttons.Add(cancel, 0, wx.ALL, 5)
|
||||||
sizer.Add(buttons, 0, wx.ALL, 5)
|
sizer.Add(buttons, 0, wx.ALL, 5)
|
||||||
panel.SetSizer(sizer)
|
panel.SetSizer(sizer)
|
||||||
min = sizer.CalcMin()
|
min = sizer.CalcMin()
|
||||||
self.SetClientSize(min)
|
self.SetClientSize(min)
|
||||||
|
|
||||||
def remove_account_dialog(self):
|
def remove_account_dialog(self):
|
||||||
return wx.MessageDialog(self, _("Do you really want to delete this account?"), _("Remove account"), wx.YES_NO).ShowModal()
|
return wx.MessageDialog(self, _("Do you really want to delete this account?"), _("Remove account"), wx.YES_NO).ShowModal()
|
||||||
|
48
src/setup.py
48
src/setup.py
@ -10,38 +10,38 @@ from babel.messages import frontend as babel
|
|||||||
languageHandler.setLanguage("en")
|
languageHandler.setLanguage("en")
|
||||||
|
|
||||||
def find_sound_lib_datafiles():
|
def find_sound_lib_datafiles():
|
||||||
import os
|
import os
|
||||||
import platform
|
import platform
|
||||||
import sound_lib
|
import sound_lib
|
||||||
path = os.path.join(sound_lib.__path__[0], 'lib')
|
path = os.path.join(sound_lib.__path__[0], 'lib')
|
||||||
if platform.architecture()[0] == '32bit' or platform.system() == 'Darwin':
|
if platform.architecture()[0] == '32bit' or platform.system() == 'Darwin':
|
||||||
arch = 'x86'
|
arch = 'x86'
|
||||||
else:
|
else:
|
||||||
arch = 'x64'
|
arch = 'x64'
|
||||||
dest_dir = os.path.join('sound_lib', 'lib', arch)
|
dest_dir = os.path.join('sound_lib', 'lib', arch)
|
||||||
source = os.path.join(path, arch)
|
source = os.path.join(path, arch)
|
||||||
return (source, dest_dir)
|
return (source, dest_dir)
|
||||||
|
|
||||||
def find_accessible_output2_datafiles():
|
def find_accessible_output2_datafiles():
|
||||||
import os
|
import os
|
||||||
import accessible_output2
|
import accessible_output2
|
||||||
path = os.path.join(accessible_output2.__path__[0], 'lib')
|
path = os.path.join(accessible_output2.__path__[0], 'lib')
|
||||||
dest_dir = os.path.join('accessible_output2', 'lib')
|
dest_dir = os.path.join('accessible_output2', 'lib')
|
||||||
return (path, dest_dir)
|
return (path, dest_dir)
|
||||||
|
|
||||||
base = None
|
base = None
|
||||||
if sys.platform == 'win32':
|
if sys.platform == 'win32':
|
||||||
base = 'Win32GUI'
|
base = 'Win32GUI'
|
||||||
|
|
||||||
build_exe_options = dict(
|
build_exe_options = dict(
|
||||||
build_exe="dist",
|
build_exe="dist",
|
||||||
optimize=1,
|
optimize=1,
|
||||||
include_msvcr=True,
|
include_msvcr=True,
|
||||||
zip_include_packages=["accessible_output2", "sound_lib", "arrow"],
|
zip_include_packages=["accessible_output2", "sound_lib", "arrow"],
|
||||||
replace_paths = [("*", "")],
|
replace_paths = [("*", "")],
|
||||||
include_files=["session.defaults", "cacert.pem", "app-configuration.defaults", "locales", "sounds", "documentation", "../windows-dependencies/x86/oggenc2.exe", "../windows-dependencies/x86/bootstrap.exe", find_sound_lib_datafiles(), find_accessible_output2_datafiles(), ("../windows-dependencies/msvc32", "."), ("../windows-dependencies/dictionaries", "lib/enchant/data/mingw32/share/enchant/hunspell")],
|
include_files=["session.defaults", "cacert.pem", "app-configuration.defaults", "locales", "sounds", "documentation", "../windows-dependencies/x86/oggenc2.exe", "../windows-dependencies/x86/bootstrap.exe", find_sound_lib_datafiles(), find_accessible_output2_datafiles(), ("../windows-dependencies/msvc32", "."), ("../windows-dependencies/dictionaries", "lib/enchant/data/mingw32/share/enchant/hunspell")],
|
||||||
packages=["interactors", "presenters", "views", "wxUI"],
|
packages=["interactors", "presenters", "views", "wxUI"],
|
||||||
)
|
)
|
||||||
|
|
||||||
executables = [
|
executables = [
|
||||||
Executable('main.py', base=base, targetName="socializer")
|
Executable('main.py', base=base, targetName="socializer")
|
||||||
|
112
src/sound.py
112
src/sound.py
@ -18,72 +18,72 @@ from sound_lib import output, input
|
|||||||
log = logging.getLogger("sound")
|
log = logging.getLogger("sound")
|
||||||
|
|
||||||
def recode_audio(filename, quality=10):
|
def recode_audio(filename, quality=10):
|
||||||
subprocess.call(r'"%s" --downmix -q %r "%s"' % (os.path.join(paths.app_path(), 'oggenc2.exe'), quality, filename))
|
subprocess.call(r'"%s" --downmix -q %r "%s"' % (os.path.join(paths.app_path(), 'oggenc2.exe'), quality, filename))
|
||||||
|
|
||||||
def get_recording(filename):
|
def get_recording(filename):
|
||||||
# try:
|
# try:
|
||||||
val = recording.WaveRecording(filename=filename)
|
val = recording.WaveRecording(filename=filename)
|
||||||
# except sound_lib.main.BassError:
|
# except sound_lib.main.BassError:
|
||||||
# sound_lib.input.Input()
|
# sound_lib.input.Input()
|
||||||
# val = sound_lib.recording.WaveRecording(filename=filename)
|
# val = sound_lib.recording.WaveRecording(filename=filename)
|
||||||
return val
|
return val
|
||||||
|
|
||||||
class soundSystem(object):
|
class soundSystem(object):
|
||||||
|
|
||||||
def check_soundpack(self):
|
def check_soundpack(self):
|
||||||
""" Checks if the folder where live the current soundpack exists."""
|
""" Checks if the folder where live the current soundpack exists."""
|
||||||
self.soundpack_OK = False
|
self.soundpack_OK = False
|
||||||
if os.path.exists(os.path.join(paths.sound_path(), self.config["current_soundpack"])):
|
if os.path.exists(os.path.join(paths.sound_path(), self.config["current_soundpack"])):
|
||||||
self.path = os.path.join(paths.sound_path(), self.config["current_soundpack"])
|
self.path = os.path.join(paths.sound_path(), self.config["current_soundpack"])
|
||||||
self.soundpack_OK = True
|
self.soundpack_OK = True
|
||||||
elif os.path.exists(os.path.join(paths.sound_path(), "default")):
|
elif os.path.exists(os.path.join(paths.sound_path(), "default")):
|
||||||
log.error("The soundpack does not exist, using default...")
|
log.error("The soundpack does not exist, using default...")
|
||||||
self.path = os.path.join(paths.sound_path(), "default")
|
self.path = os.path.join(paths.sound_path(), "default")
|
||||||
self.soundpack_OK = True
|
self.soundpack_OK = True
|
||||||
else:
|
else:
|
||||||
log.error("The current soundpack could not be found and the default soundpack has been deleted, Socializer will not play sounds.")
|
log.error("The current soundpack could not be found and the default soundpack has been deleted, Socializer will not play sounds.")
|
||||||
self.soundpack_OK = False
|
self.soundpack_OK = False
|
||||||
|
|
||||||
def __init__(self, soundConfig):
|
def __init__(self, soundConfig):
|
||||||
""" Sound Player."""
|
""" Sound Player."""
|
||||||
self.config = soundConfig
|
self.config = soundConfig
|
||||||
# Set the output and input default devices.
|
# Set the output and input default devices.
|
||||||
try:
|
try:
|
||||||
self.output = output.Output()
|
self.output = output.Output()
|
||||||
self.input = input.Input()
|
self.input = input.Input()
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
# Try to use the selected device from the configuration. It can fail if the machine does not has a mic.
|
# Try to use the selected device from the configuration. It can fail if the machine does not has a mic.
|
||||||
try:
|
try:
|
||||||
log.debug("Setting input and output devices...")
|
log.debug("Setting input and output devices...")
|
||||||
self.output.set_device(self.output.find_device_by_name(self.config["output_device"]))
|
self.output.set_device(self.output.find_device_by_name(self.config["output_device"]))
|
||||||
self.input.set_device(self.input.find_device_by_name(self.config["input_device"]))
|
self.input.set_device(self.input.find_device_by_name(self.config["input_device"]))
|
||||||
except:
|
except:
|
||||||
log.error("Error in input or output devices, using defaults...")
|
log.error("Error in input or output devices, using defaults...")
|
||||||
self.config["output_device"] = "Default"
|
self.config["output_device"] = "Default"
|
||||||
self.config["input_device"] = "Default"
|
self.config["input_device"] = "Default"
|
||||||
# Set proxy for audio.
|
# Set proxy for audio.
|
||||||
if config.app["app-settings"]["use_proxy"]:
|
if config.app["app-settings"]["use_proxy"]:
|
||||||
self.output.set_proxy(b"socializer:socializer@socializer.su:3128")
|
self.output.set_proxy(b"socializer:socializer@socializer.su:3128")
|
||||||
self.files = []
|
self.files = []
|
||||||
self.cleaner = RepeatingTimer(60, self.clear_list)
|
self.cleaner = RepeatingTimer(60, self.clear_list)
|
||||||
self.cleaner.start()
|
self.cleaner.start()
|
||||||
self.check_soundpack()
|
self.check_soundpack()
|
||||||
|
|
||||||
def clear_list(self):
|
def clear_list(self):
|
||||||
if len(self.files) == 0: return
|
if len(self.files) == 0: return
|
||||||
try:
|
try:
|
||||||
for i in range(0, len(self.files)):
|
for i in range(0, len(self.files)):
|
||||||
if self.files[i].is_playing == False:
|
if self.files[i].is_playing == False:
|
||||||
self.files[i].free()
|
self.files[i].free()
|
||||||
self.files.pop(i)
|
self.files.pop(i)
|
||||||
except IndexError:
|
except IndexError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def play(self, sound, argument=False):
|
def play(self, sound, argument=False):
|
||||||
if self.soundpack_OK == False: return
|
if self.soundpack_OK == False: return
|
||||||
if self.config["session_mute"] == True: return
|
if self.config["session_mute"] == True: return
|
||||||
sound_object = sound_lib.stream.FileStream(file="%s/%s" % (self.path, sound))
|
sound_object = sound_lib.stream.FileStream(file="%s/%s" % (self.path, sound))
|
||||||
# sound_object.volume = self.config["volume"]/100
|
# sound_object.volume = self.config["volume"]/100
|
||||||
self.files.append(sound_object)
|
self.files.append(sound_object)
|
||||||
sound_object.play()
|
sound_object.play()
|
||||||
|
@ -7,64 +7,64 @@ from interactors import audioRecorder as interactor
|
|||||||
|
|
||||||
class audioRecorderTestCase(unittest.TestCase):
|
class audioRecorderTestCase(unittest.TestCase):
|
||||||
|
|
||||||
""" Test both the presenter and interactor of the audio recorder feature. View stuff will be mocked."""
|
""" Test both the presenter and interactor of the audio recorder feature. View stuff will be mocked."""
|
||||||
|
|
||||||
@mock.patch("presenters.audioRecorder.sound_lib", esp_set=True)
|
@mock.patch("presenters.audioRecorder.sound_lib", esp_set=True)
|
||||||
@mock.patch("presenters.base.pub", esp_set=True)
|
@mock.patch("presenters.base.pub", esp_set=True)
|
||||||
@mock.patch("presenters.audioRecorder.tempfile", esp_set=True)
|
@mock.patch("presenters.audioRecorder.tempfile", esp_set=True)
|
||||||
@mock.patch("presenters.audioRecorder.sound", esp_set=True)
|
@mock.patch("presenters.audioRecorder.sound", esp_set=True)
|
||||||
@mock.patch("presenters.audioRecorder.output", esp_set=True)
|
@mock.patch("presenters.audioRecorder.output", esp_set=True)
|
||||||
@mock.patch("presenters.audioRecorder.os", esp_set=True)
|
@mock.patch("presenters.audioRecorder.os", esp_set=True)
|
||||||
def test_audiorecorder_presenter(self, os_mock, output_mock, sound_mock, tempfile_mock, pub_mock, soundlib_mock):
|
def test_audiorecorder_presenter(self, os_mock, output_mock, sound_mock, tempfile_mock, pub_mock, soundlib_mock):
|
||||||
""" Test methods for audio recorder presenter. """
|
""" Test methods for audio recorder presenter. """
|
||||||
tempfile_mock.mktemp.return_value = "somefile.wav"
|
tempfile_mock.mktemp.return_value = "somefile.wav"
|
||||||
sound_mock.get_recording.return_value = mock.MagicMock()
|
sound_mock.get_recording.return_value = mock.MagicMock()
|
||||||
soundlib_mock.stream.fileStream.return_value = mock.MagicMock()
|
soundlib_mock.stream.fileStream.return_value = mock.MagicMock()
|
||||||
view=mock.MagicMock(name="view")
|
view=mock.MagicMock(name="view")
|
||||||
interactor_ = mock.MagicMock(name="interactor", esp_set=interactor.audioRecorderInteractor)
|
interactor_ = mock.MagicMock(name="interactor", esp_set=interactor.audioRecorderInteractor)
|
||||||
presenter_ = presenter.audioRecorderPresenter(view=view, interactor=interactor_)
|
presenter_ = presenter.audioRecorderPresenter(view=view, interactor=interactor_)
|
||||||
# Start sending events to the presenter and see its reactions.
|
# Start sending events to the presenter and see its reactions.
|
||||||
presenter_.start_recording()
|
presenter_.start_recording()
|
||||||
tempfile_mock.mktemp.assert_any_call(suffix=".wav")
|
tempfile_mock.mktemp.assert_any_call(suffix=".wav")
|
||||||
sound_mock.get_recording.assert_any_call(presenter_.file)
|
sound_mock.get_recording.assert_any_call(presenter_.file)
|
||||||
presenter_.recording.play.assert_any_call()
|
presenter_.recording.play.assert_any_call()
|
||||||
pub_mock.sendMessage.assert_any_call("audiorecorder_set_label", control="record", label=_("&Stop"))
|
pub_mock.sendMessage.assert_any_call("audiorecorder_set_label", control="record", label=_("&Stop"))
|
||||||
pub_mock.sendMessage.assert_any_call("audiorecorder_disable_control", control="ok")
|
pub_mock.sendMessage.assert_any_call("audiorecorder_disable_control", control="ok")
|
||||||
presenter_.stop_recording()
|
presenter_.stop_recording()
|
||||||
presenter_.recording.stop.assert_any_call()
|
presenter_.recording.stop.assert_any_call()
|
||||||
presenter_.recording.free.assert_any_call()
|
presenter_.recording.free.assert_any_call()
|
||||||
pub_mock.sendMessage.assert_any_call("audiorecorder_set_label", control="record", label=_("&Record"))
|
pub_mock.sendMessage.assert_any_call("audiorecorder_set_label", control="record", label=_("&Record"))
|
||||||
pub_mock.sendMessage.assert_any_call("audiorecorder_disable_control", control="record")
|
pub_mock.sendMessage.assert_any_call("audiorecorder_disable_control", control="record")
|
||||||
pub_mock.sendMessage.assert_any_call("audiorecorder_enable_control", control="play")
|
pub_mock.sendMessage.assert_any_call("audiorecorder_enable_control", control="play")
|
||||||
pub_mock.sendMessage.assert_any_call("audiorecorder_enable_control", control="discard")
|
pub_mock.sendMessage.assert_any_call("audiorecorder_enable_control", control="discard")
|
||||||
pub_mock.sendMessage.assert_any_call("audiorecorder_enable_control", control="ok")
|
pub_mock.sendMessage.assert_any_call("audiorecorder_enable_control", control="ok")
|
||||||
pub_mock.sendMessage.assert_any_call("audiorecorder_focus_control", control="play")
|
pub_mock.sendMessage.assert_any_call("audiorecorder_focus_control", control="play")
|
||||||
presenter_.discard_recording()
|
presenter_.discard_recording()
|
||||||
self.assertTrue(presenter_.playing==None)
|
self.assertTrue(presenter_.playing==None)
|
||||||
|
|
||||||
@mock.patch("interactors.audioRecorder.widgetUtils", esp_set=True)
|
@mock.patch("interactors.audioRecorder.widgetUtils", esp_set=True)
|
||||||
def test_audiorecorder_interactor(self, widgetUtils_mock):
|
def test_audiorecorder_interactor(self, widgetUtils_mock):
|
||||||
view=mock.MagicMock(name="view")
|
view=mock.MagicMock(name="view")
|
||||||
interactor_ = interactor.audioRecorderInteractor()
|
interactor_ = interactor.audioRecorderInteractor()
|
||||||
presenter_ = mock.MagicMock(name="Presenter", esp_set=presenter.audioRecorderPresenter)
|
presenter_ = mock.MagicMock(name="Presenter", esp_set=presenter.audioRecorderPresenter)
|
||||||
interactor_.install(view=view, presenter=presenter_)
|
interactor_.install(view=view, presenter=presenter_)
|
||||||
# Test if events have been connected to WX
|
# Test if events have been connected to WX
|
||||||
widgetUtils_mock.connect_event.assert_any_call(view.play, widgetUtils_mock.BUTTON_PRESSED, interactor_.on_play)
|
widgetUtils_mock.connect_event.assert_any_call(view.play, widgetUtils_mock.BUTTON_PRESSED, interactor_.on_play)
|
||||||
widgetUtils_mock.connect_event.assert_any_call(view.record, widgetUtils_mock.BUTTON_PRESSED, interactor_.on_record)
|
widgetUtils_mock.connect_event.assert_any_call(view.record, widgetUtils_mock.BUTTON_PRESSED, interactor_.on_record)
|
||||||
widgetUtils_mock.connect_event.assert_any_call(view.discard, widgetUtils_mock.BUTTON_PRESSED, interactor_.on_discard)
|
widgetUtils_mock.connect_event.assert_any_call(view.discard, widgetUtils_mock.BUTTON_PRESSED, interactor_.on_discard)
|
||||||
# Let's call some methods simulating user interaction.
|
# Let's call some methods simulating user interaction.
|
||||||
interactor_.on_record()
|
interactor_.on_record()
|
||||||
presenter_.toggle_recording.assert_called_with()
|
presenter_.toggle_recording.assert_called_with()
|
||||||
interactor_.on_play()
|
interactor_.on_play()
|
||||||
presenter_.play.assert_called_with()
|
presenter_.play.assert_called_with()
|
||||||
# Let's simulate user response here
|
# Let's simulate user response here
|
||||||
view.get_response.return_value = widgetUtils_mock.OK
|
view.get_response.return_value = widgetUtils_mock.OK
|
||||||
interactor_.start()
|
interactor_.start()
|
||||||
# this should call on_postprocess after receiving the OK signal.
|
# this should call on_postprocess after receiving the OK signal.
|
||||||
presenter_.postprocess.assert_called_with()
|
presenter_.postprocess.assert_called_with()
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
languageHandler.setLanguage("en")
|
languageHandler.setLanguage("en")
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
@ -4,34 +4,34 @@ import mock
|
|||||||
from interactors import base
|
from interactors import base
|
||||||
|
|
||||||
class baseInteractorTestCase(unittest.TestCase):
|
class baseInteractorTestCase(unittest.TestCase):
|
||||||
""" some tests for the base interactor implementation."""
|
""" some tests for the base interactor implementation."""
|
||||||
|
|
||||||
@mock.patch("interactors.base.pub", esp_set=True)
|
@mock.patch("interactors.base.pub", esp_set=True)
|
||||||
def test_base_interactor(self, pub_mock):
|
def test_base_interactor(self, pub_mock):
|
||||||
""" Test the base interactor class. """
|
""" Test the base interactor class. """
|
||||||
view=mock.MagicMock(name="view")
|
view=mock.MagicMock(name="view")
|
||||||
interactor_ = base.baseInteractor()
|
interactor_ = base.baseInteractor()
|
||||||
presenter_ = mock.MagicMock(name="Presenter")
|
presenter_ = mock.MagicMock(name="Presenter")
|
||||||
interactor_.install(view=view, presenter=presenter_, modulename="base")
|
interactor_.install(view=view, presenter=presenter_, modulename="base")
|
||||||
# Check if the interactor has called pubsub correctly.
|
# Check if the interactor has called pubsub correctly.
|
||||||
pub_mock.subscribe.assert_any_call(interactor_.disable_control, "base_disable_control"),
|
pub_mock.subscribe.assert_any_call(interactor_.disable_control, "base_disable_control"),
|
||||||
pub_mock.subscribe.assert_any_call(interactor_.enable_control, "base_enable_control"),
|
pub_mock.subscribe.assert_any_call(interactor_.enable_control, "base_enable_control"),
|
||||||
pub_mock.subscribe.assert_any_call(interactor_.set_label, "base_set_label"),
|
pub_mock.subscribe.assert_any_call(interactor_.set_label, "base_set_label"),
|
||||||
pub_mock.subscribe.assert_any_call(interactor_.focus_control, "base_focus_control")
|
pub_mock.subscribe.assert_any_call(interactor_.focus_control, "base_focus_control")
|
||||||
# Now, simulate some event calls.
|
# Now, simulate some event calls.
|
||||||
interactor_.disable_control(control="some_control")
|
interactor_.disable_control(control="some_control")
|
||||||
view.disable.assert_called_with("some_control")
|
view.disable.assert_called_with("some_control")
|
||||||
interactor_.enable_control(control="some_control")
|
interactor_.enable_control(control="some_control")
|
||||||
view.enable.assert_called_with("some_control")
|
view.enable.assert_called_with("some_control")
|
||||||
interactor_.set_label(control="some_control", label="label")
|
interactor_.set_label(control="some_control", label="label")
|
||||||
view.set.assert_called_with("some_control", "label")
|
view.set.assert_called_with("some_control", "label")
|
||||||
interactor_.focus_control(control="some_control")
|
interactor_.focus_control(control="some_control")
|
||||||
view.some_control.SetFocus.assert_called_with()
|
view.some_control.SetFocus.assert_called_with()
|
||||||
interactor_.uninstall()
|
interactor_.uninstall()
|
||||||
pub_mock.unsubscribe.assert_any_call(interactor_.disable_control, "base_disable_control"),
|
pub_mock.unsubscribe.assert_any_call(interactor_.disable_control, "base_disable_control"),
|
||||||
pub_mock.unsubscribe.assert_any_call(interactor_.enable_control, "base_enable_control"),
|
pub_mock.unsubscribe.assert_any_call(interactor_.enable_control, "base_enable_control"),
|
||||||
pub_mock.unsubscribe.assert_any_call(interactor_.set_label, "base_set_label"),
|
pub_mock.unsubscribe.assert_any_call(interactor_.set_label, "base_set_label"),
|
||||||
pub_mock.unsubscribe.assert_any_call(interactor_.focus_control, "base_focus_control")
|
pub_mock.unsubscribe.assert_any_call(interactor_.focus_control, "base_focus_control")
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
@ -7,22 +7,22 @@ from sessionmanager import renderers
|
|||||||
|
|
||||||
class renderersTestCase(unittest.TestCase):
|
class renderersTestCase(unittest.TestCase):
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
languageHandler.setLanguage("en")
|
languageHandler.setLanguage("en")
|
||||||
vk = testconfig.get_vk()
|
vk = testconfig.get_vk()
|
||||||
self.vk = vk.get_api()
|
self.vk = vk.get_api()
|
||||||
|
|
||||||
def test_render_person(self):
|
def test_render_person(self):
|
||||||
""" Test the person renderer function."""
|
""" Test the person renderer function."""
|
||||||
user = self.vk.users.get(user_ids=1, fields="first_name, last_name, last_seen")
|
user = self.vk.users.get(user_ids=1, fields="first_name, last_name, last_seen")
|
||||||
self.assertIsInstance(user, list)
|
self.assertIsInstance(user, list)
|
||||||
self.assertEquals(len(user), 1)
|
self.assertEquals(len(user), 1)
|
||||||
user = user[0]
|
user = user[0]
|
||||||
rendered_object = renderers.render_person(user, user["last_seen"])
|
rendered_object = renderers.render_person(user, user["last_seen"])
|
||||||
self.assertIsInstance(rendered_object, list)
|
self.assertIsInstance(rendered_object, list)
|
||||||
self.assertEquals(len(rendered_object), 2)
|
self.assertEquals(len(rendered_object), 2)
|
||||||
self.assertIsInstance(rendered_object[0], str)
|
self.assertIsInstance(rendered_object[0], str)
|
||||||
self.assertIsInstance(rendered_object[1], str)
|
self.assertIsInstance(rendered_object[1], str)
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
@ -4,14 +4,14 @@ import application
|
|||||||
|
|
||||||
class py2exeTestCase(unittest.TestCase):
|
class py2exeTestCase(unittest.TestCase):
|
||||||
|
|
||||||
@unittest.skipUnless(sys.version[0] == "2", "this only fails under Python 2")
|
@unittest.skipUnless(sys.version[0] == "2", "this only fails under Python 2")
|
||||||
def test_application_not_unicode(self):
|
def test_application_not_unicode(self):
|
||||||
""" Testing if some strings present in application have not changed to unicode. """
|
""" Testing if some strings present in application have not changed to unicode. """
|
||||||
self.assertIsInstance(application.name, str)
|
self.assertIsInstance(application.name, str)
|
||||||
self.assertIsInstance(application.author, str)
|
self.assertIsInstance(application.author, str)
|
||||||
self.assertIsInstance(application.authorEmail, str)
|
self.assertIsInstance(application.authorEmail, str)
|
||||||
self.assertIsInstance(application.version, str)
|
self.assertIsInstance(application.version, str)
|
||||||
self.assertIsInstance(application.url, str)
|
self.assertIsInstance(application.url, str)
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
@ -3,8 +3,8 @@ import os
|
|||||||
from vk_api import VkApi
|
from vk_api import VkApi
|
||||||
|
|
||||||
def get_vk():
|
def get_vk():
|
||||||
login = os.environ['LOGIN']
|
login = os.environ['LOGIN']
|
||||||
password = os.environ['PASSWORD']
|
password = os.environ['PASSWORD']
|
||||||
vk = VkApi(login, password)
|
vk = VkApi(login, password)
|
||||||
vk.auth(token_only=True)
|
vk.auth(token_only=True)
|
||||||
return vk
|
return vk
|
||||||
|
@ -3,10 +3,10 @@ import os.path
|
|||||||
import platform
|
import platform
|
||||||
|
|
||||||
def find_datafiles():
|
def find_datafiles():
|
||||||
system = platform.system()
|
system = platform.system()
|
||||||
if system == 'Windows':
|
if system == 'Windows':
|
||||||
file_ext = '*.exe'
|
file_ext = '*.exe'
|
||||||
else:
|
else:
|
||||||
file_ext = '*.sh'
|
file_ext = '*.sh'
|
||||||
path = os.path.abspath(os.path.join(__path__[0], 'bootstrappers', file_ext))
|
path = os.path.abspath(os.path.join(__path__[0], 'bootstrappers', file_ext))
|
||||||
return [('', glob.glob(path))]
|
return [('', glob.glob(path))]
|
||||||
|
@ -11,123 +11,123 @@ import tempfile
|
|||||||
import widgetUtils
|
import widgetUtils
|
||||||
import webbrowser
|
import webbrowser
|
||||||
try:
|
try:
|
||||||
import czipfile as zipfile
|
import czipfile as zipfile
|
||||||
except ImportError:
|
except ImportError:
|
||||||
import zipfile
|
import zipfile
|
||||||
|
|
||||||
from platform_utils import paths
|
from platform_utils import paths
|
||||||
|
|
||||||
def perform_update(endpoint, current_version, update_type="stable", app_name='', password=None, update_available_callback=None, progress_callback=None, update_complete_callback=None):
|
def perform_update(endpoint, current_version, update_type="stable", app_name='', password=None, update_available_callback=None, progress_callback=None, update_complete_callback=None):
|
||||||
requests_session = create_requests_session(app_name=app_name, version=current_version)
|
requests_session = create_requests_session(app_name=app_name, version=current_version)
|
||||||
available_update = find_update(endpoint, requests_session=requests_session)
|
available_update = find_update(endpoint, requests_session=requests_session)
|
||||||
if not available_update:
|
if not available_update:
|
||||||
logger.debug("No update available")
|
logger.debug("No update available")
|
||||||
return False
|
return False
|
||||||
available_version, available_description, update_url = find_version_data(update_type, current_version, available_update)
|
available_version, available_description, update_url = find_version_data(update_type, current_version, available_update)
|
||||||
if available_version == False:
|
if available_version == False:
|
||||||
return False
|
return False
|
||||||
logger.info("A new update is available. Version %s" % available_version)
|
logger.info("A new update is available. Version %s" % available_version)
|
||||||
if callable(update_available_callback) and not update_available_callback(version=available_version, description=available_description): #update_available_callback should return a falsy value to stop the process
|
if callable(update_available_callback) and not update_available_callback(version=available_version, description=available_description): #update_available_callback should return a falsy value to stop the process
|
||||||
logger.info("User canceled update.")
|
logger.info("User canceled update.")
|
||||||
return
|
return
|
||||||
base_path = tempfile.mkdtemp()
|
base_path = tempfile.mkdtemp()
|
||||||
download_path = os.path.join(base_path, 'update.zip')
|
download_path = os.path.join(base_path, 'update.zip')
|
||||||
update_path = os.path.join(base_path, 'update')
|
update_path = os.path.join(base_path, 'update')
|
||||||
downloaded = download_update(update_url, download_path, requests_session=requests_session, progress_callback=progress_callback)
|
downloaded = download_update(update_url, download_path, requests_session=requests_session, progress_callback=progress_callback)
|
||||||
extracted = extract_update(downloaded, update_path, password=password)
|
extracted = extract_update(downloaded, update_path, password=password)
|
||||||
bootstrap_path = move_bootstrap(extracted)
|
bootstrap_path = move_bootstrap(extracted)
|
||||||
execute_bootstrap(bootstrap_path, extracted)
|
execute_bootstrap(bootstrap_path, extracted)
|
||||||
logger.info("Update prepared for installation.")
|
logger.info("Update prepared for installation.")
|
||||||
if callable(update_complete_callback):
|
if callable(update_complete_callback):
|
||||||
update_complete_callback()
|
update_complete_callback()
|
||||||
|
|
||||||
def create_requests_session(app_name=None, version=None):
|
def create_requests_session(app_name=None, version=None):
|
||||||
user_agent = ''
|
user_agent = ''
|
||||||
session = requests.session()
|
session = requests.session()
|
||||||
if app_name:
|
if app_name:
|
||||||
user_agent = ' %s/%r' % (app_name, version)
|
user_agent = ' %s/%r' % (app_name, version)
|
||||||
session.headers['User-Agent'] = session.headers['User-Agent'] + user_agent
|
session.headers['User-Agent'] = session.headers['User-Agent'] + user_agent
|
||||||
return session
|
return session
|
||||||
|
|
||||||
def find_update(endpoint, requests_session):
|
def find_update(endpoint, requests_session):
|
||||||
response = requests_session.get(endpoint)
|
response = requests_session.get(endpoint)
|
||||||
response.raise_for_status()
|
response.raise_for_status()
|
||||||
content = response.json()
|
content = response.json()
|
||||||
return content
|
return content
|
||||||
|
|
||||||
def find_version_data(update_type, current_version, available_update):
|
def find_version_data(update_type, current_version, available_update):
|
||||||
if update_type == "stable":
|
if update_type == "stable":
|
||||||
available_version = float(available_update['current_version'])
|
available_version = float(available_update['current_version'])
|
||||||
if not float(available_version) > float(current_version) or platform.system()+platform.architecture()[0][:2] not in available_update['downloads']:
|
if not float(available_version) > float(current_version) or platform.system()+platform.architecture()[0][:2] not in available_update['downloads']:
|
||||||
logger.debug("No update for this architecture")
|
logger.debug("No update for this architecture")
|
||||||
return (False, False, False)
|
return (False, False, False)
|
||||||
available_description = available_update.get('description', None)
|
available_description = available_update.get('description', None)
|
||||||
update_url = available_update ['downloads'][platform.system()+platform.architecture()[0][:2]]
|
update_url = available_update ['downloads'][platform.system()+platform.architecture()[0][:2]]
|
||||||
return (available_version, available_description, update_url)
|
return (available_version, available_description, update_url)
|
||||||
else: # Unstable versions, based in commits instead of version numbers.
|
else: # Unstable versions, based in commits instead of version numbers.
|
||||||
available_version = available_update["current_version"]
|
available_version = available_update["current_version"]
|
||||||
if available_version == current_version:
|
if available_version == current_version:
|
||||||
return (False, False, False)
|
return (False, False, False)
|
||||||
available_description = available_update["description"]
|
available_description = available_update["description"]
|
||||||
update_url = available_update ['downloads'][platform.system()+platform.architecture()[0][:2]]
|
update_url = available_update ['downloads'][platform.system()+platform.architecture()[0][:2]]
|
||||||
return (available_version, available_description, update_url)
|
return (available_version, available_description, update_url)
|
||||||
|
|
||||||
def download_update(update_url, update_destination, requests_session, progress_callback=None, chunk_size=io.DEFAULT_BUFFER_SIZE):
|
def download_update(update_url, update_destination, requests_session, progress_callback=None, chunk_size=io.DEFAULT_BUFFER_SIZE):
|
||||||
total_downloaded = total_size = 0
|
total_downloaded = total_size = 0
|
||||||
with io.open(update_destination, 'w+b') as outfile:
|
with io.open(update_destination, 'w+b') as outfile:
|
||||||
download = requests_session.get(update_url, stream=True)
|
download = requests_session.get(update_url, stream=True)
|
||||||
total_size = int(download.headers.get('content-length', 0))
|
total_size = int(download.headers.get('content-length', 0))
|
||||||
logger.debug("Total update size: %d" % total_size)
|
logger.debug("Total update size: %d" % total_size)
|
||||||
download.raise_for_status()
|
download.raise_for_status()
|
||||||
for chunk in download.iter_content(chunk_size):
|
for chunk in download.iter_content(chunk_size):
|
||||||
outfile.write(chunk)
|
outfile.write(chunk)
|
||||||
total_downloaded += len(chunk)
|
total_downloaded += len(chunk)
|
||||||
if callable(progress_callback):
|
if callable(progress_callback):
|
||||||
call_callback(progress_callback, total_downloaded, total_size)
|
call_callback(progress_callback, total_downloaded, total_size)
|
||||||
logger.debug("Update downloaded")
|
logger.debug("Update downloaded")
|
||||||
return update_destination
|
return update_destination
|
||||||
|
|
||||||
def extract_update(update_archive, destination, password=None):
|
def extract_update(update_archive, destination, password=None):
|
||||||
"""Given an update archive, extracts it. Returns the directory to which it has been extracted"""
|
"""Given an update archive, extracts it. Returns the directory to which it has been extracted"""
|
||||||
with contextlib.closing(zipfile.ZipFile(update_archive)) as archive:
|
with contextlib.closing(zipfile.ZipFile(update_archive)) as archive:
|
||||||
if password:
|
if password:
|
||||||
archive.setpassword(password)
|
archive.setpassword(password)
|
||||||
archive.extractall(path=destination)
|
archive.extractall(path=destination)
|
||||||
logger.debug("Update extracted")
|
logger.debug("Update extracted")
|
||||||
return destination
|
return destination
|
||||||
|
|
||||||
def move_bootstrap(extracted_path):
|
def move_bootstrap(extracted_path):
|
||||||
working_path = os.path.abspath(os.path.join(extracted_path, '..'))
|
working_path = os.path.abspath(os.path.join(extracted_path, '..'))
|
||||||
if platform.system() == 'Darwin':
|
if platform.system() == 'Darwin':
|
||||||
extracted_path = os.path.join(extracted_path, 'Contents', 'Resources')
|
extracted_path = os.path.join(extracted_path, 'Contents', 'Resources')
|
||||||
downloaded_bootstrap = os.path.join(extracted_path, bootstrap_name())
|
downloaded_bootstrap = os.path.join(extracted_path, bootstrap_name())
|
||||||
new_bootstrap_path = os.path.join(working_path, bootstrap_name())
|
new_bootstrap_path = os.path.join(working_path, bootstrap_name())
|
||||||
os.rename(downloaded_bootstrap, new_bootstrap_path)
|
os.rename(downloaded_bootstrap, new_bootstrap_path)
|
||||||
return new_bootstrap_path
|
return new_bootstrap_path
|
||||||
|
|
||||||
def execute_bootstrap(bootstrap_path, source_path):
|
def execute_bootstrap(bootstrap_path, source_path):
|
||||||
arguments = r'"%s" "%s" "%s" "%s"' % (os.getpid(), source_path, paths.app_path(), paths.get_executable())
|
arguments = r'"%s" "%s" "%s" "%s"' % (os.getpid(), source_path, paths.app_path(), paths.get_executable())
|
||||||
if platform.system() == 'Windows':
|
if platform.system() == 'Windows':
|
||||||
import win32api
|
import win32api
|
||||||
win32api.ShellExecute(0, 'open', bootstrap_path, arguments, '', 5)
|
win32api.ShellExecute(0, 'open', bootstrap_path, arguments, '', 5)
|
||||||
else:
|
else:
|
||||||
import subprocess
|
import subprocess
|
||||||
make_executable(bootstrap_path)
|
make_executable(bootstrap_path)
|
||||||
subprocess.Popen(['%s %s' % (bootstrap_path, arguments)], shell=True)
|
subprocess.Popen(['%s %s' % (bootstrap_path, arguments)], shell=True)
|
||||||
logger.info("Bootstrap executed")
|
logger.info("Bootstrap executed")
|
||||||
|
|
||||||
def bootstrap_name():
|
def bootstrap_name():
|
||||||
if platform.system() == 'Windows': return 'bootstrap.exe'
|
if platform.system() == 'Windows': return 'bootstrap.exe'
|
||||||
if platform.system() == 'Darwin': return 'bootstrap-mac.sh'
|
if platform.system() == 'Darwin': return 'bootstrap-mac.sh'
|
||||||
return 'bootstrap-lin.sh'
|
return 'bootstrap-lin.sh'
|
||||||
|
|
||||||
def make_executable(path):
|
def make_executable(path):
|
||||||
import stat
|
import stat
|
||||||
st = os.stat(path)
|
st = os.stat(path)
|
||||||
os.chmod(path, st.st_mode | stat.S_IEXEC)
|
os.chmod(path, st.st_mode | stat.S_IEXEC)
|
||||||
|
|
||||||
def call_callback(callback, *args, **kwargs):
|
def call_callback(callback, *args, **kwargs):
|
||||||
# try:
|
# try:
|
||||||
callback(*args, **kwargs)
|
callback(*args, **kwargs)
|
||||||
# except:
|
# except:
|
||||||
# logger.exception("Failed calling callback %r with args %r and kwargs %r" % (callback, args, kwargs))
|
# logger.exception("Failed calling callback %r with args %r and kwargs %r" % (callback, args, kwargs))
|
||||||
|
@ -10,17 +10,17 @@ from .wxUpdater import *
|
|||||||
logger = logging.getLogger("updater")
|
logger = logging.getLogger("updater")
|
||||||
|
|
||||||
def do_update(update_type="stable"):
|
def do_update(update_type="stable"):
|
||||||
# Updates cannot be performed in the source code version of Socializer.
|
# Updates cannot be performed in the source code version of Socializer.
|
||||||
if hasattr(sys, "frozen") == False:
|
if hasattr(sys, "frozen") == False:
|
||||||
return
|
return
|
||||||
if update_type == "stable":
|
if update_type == "stable":
|
||||||
endpoint = application.update_stable_url
|
endpoint = application.update_stable_url
|
||||||
version = application.version
|
version = application.version
|
||||||
else:
|
else:
|
||||||
endpoint = application.update_next_url
|
endpoint = application.update_next_url
|
||||||
version = application.update_next_version
|
version = application.update_next_version
|
||||||
try:
|
try:
|
||||||
return update.perform_update(endpoint=endpoint, current_version=version, app_name=application.name, update_type=update_type, update_available_callback=available_update_dialog, progress_callback=progress_callback, update_complete_callback=update_finished)
|
return update.perform_update(endpoint=endpoint, current_version=version, app_name=application.name, update_type=update_type, update_available_callback=available_update_dialog, progress_callback=progress_callback, update_complete_callback=update_finished)
|
||||||
except ConnectionError:
|
except ConnectionError:
|
||||||
logger.exception("Update failed.")
|
logger.exception("Update failed.")
|
||||||
output.speak("An exception occurred while attempting to update " + application.name + ". If this message persists, contact the " + application.name + " developers. More information about the exception has been written to the error log.",True)
|
output.speak("An exception occurred while attempting to update " + application.name + ". If this message persists, contact the " + application.name + " developers. More information about the exception has been written to the error log.",True)
|
||||||
|
@ -2,42 +2,42 @@
|
|||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
def convert_bytes(n):
|
def convert_bytes(n):
|
||||||
K, M, G, T, P = 1 << 10, 1 << 20, 1 << 30, 1 << 40, 1 << 50
|
K, M, G, T, P = 1 << 10, 1 << 20, 1 << 30, 1 << 40, 1 << 50
|
||||||
if n >= P:
|
if n >= P:
|
||||||
return '%.2fPb' % (float(n) / T)
|
return '%.2fPb' % (float(n) / T)
|
||||||
elif n >= T:
|
elif n >= T:
|
||||||
return '%.2fTb' % (float(n) / T)
|
return '%.2fTb' % (float(n) / T)
|
||||||
elif n >= G:
|
elif n >= G:
|
||||||
return '%.2fGb' % (float(n) / G)
|
return '%.2fGb' % (float(n) / G)
|
||||||
elif n >= M:
|
elif n >= M:
|
||||||
return '%.2fMb' % (float(n) / M)
|
return '%.2fMb' % (float(n) / M)
|
||||||
elif n >= K:
|
elif n >= K:
|
||||||
return '%.2fKb' % (float(n) / K)
|
return '%.2fKb' % (float(n) / K)
|
||||||
else:
|
else:
|
||||||
return '%d' % n
|
return '%d' % n
|
||||||
|
|
||||||
def seconds_to_string(seconds, precision=0):
|
def seconds_to_string(seconds, precision=0):
|
||||||
day = seconds // 86400
|
day = seconds // 86400
|
||||||
hour = seconds // 3600
|
hour = seconds // 3600
|
||||||
min = (seconds // 60) % 60
|
min = (seconds // 60) % 60
|
||||||
sec = seconds - (hour * 3600) - (min * 60)
|
sec = seconds - (hour * 3600) - (min * 60)
|
||||||
sec_spec = "." + str(precision) + "f"
|
sec_spec = "." + str(precision) + "f"
|
||||||
sec_string = sec.__format__(sec_spec)
|
sec_string = sec.__format__(sec_spec)
|
||||||
string = ""
|
string = ""
|
||||||
if day == 1:
|
if day == 1:
|
||||||
string += _("%d day, ") % day
|
string += _("%d day, ") % day
|
||||||
elif day >= 2:
|
elif day >= 2:
|
||||||
string += _("%d days, ") % day
|
string += _("%d days, ") % day
|
||||||
if (hour == 1):
|
if (hour == 1):
|
||||||
string += _("%d hour, ") % hour
|
string += _("%d hour, ") % hour
|
||||||
elif (hour >= 2):
|
elif (hour >= 2):
|
||||||
string += _("%d hours, ") % hour
|
string += _("%d hours, ") % hour
|
||||||
if (min == 1):
|
if (min == 1):
|
||||||
string += _("%d minute, ") % min
|
string += _("%d minute, ") % min
|
||||||
elif (min >= 2):
|
elif (min >= 2):
|
||||||
string += _("%d minutes, ") % min
|
string += _("%d minutes, ") % min
|
||||||
if sec >= 0 and sec <= 2:
|
if sec >= 0 and sec <= 2:
|
||||||
string += _("%s second") % sec_string
|
string += _("%s second") % sec_string
|
||||||
else:
|
else:
|
||||||
string += _("%s seconds") % sec_string
|
string += _("%s seconds") % sec_string
|
||||||
return string
|
return string
|
||||||
|
@ -8,27 +8,27 @@ from . import utils
|
|||||||
progress_dialog = None
|
progress_dialog = None
|
||||||
|
|
||||||
def available_update_dialog(version, description):
|
def available_update_dialog(version, description):
|
||||||
dialog = wx.MessageDialog(None, _("There's a new {app_name} version available. Would you like to download it now?\n\n {app_name} version: {app_version}\n\nChanges:\n{changes}").format(app_name=application.name, app_version=version, changes=description), _("New version for %s") % application.name, style=wx.YES|wx.NO|wx.ICON_WARNING)
|
dialog = wx.MessageDialog(None, _("There's a new {app_name} version available. Would you like to download it now?\n\n {app_name} version: {app_version}\n\nChanges:\n{changes}").format(app_name=application.name, app_version=version, changes=description), _("New version for %s") % application.name, style=wx.YES|wx.NO|wx.ICON_WARNING)
|
||||||
if dialog.ShowModal() == wx.ID_YES:
|
if dialog.ShowModal() == wx.ID_YES:
|
||||||
return True
|
return True
|
||||||
else:
|
else:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def create_progress_dialog():
|
def create_progress_dialog():
|
||||||
return wx.ProgressDialog(_("Download in Progress"), _("Downloading the new version..."), parent=None, maximum=100)
|
return wx.ProgressDialog(_("Download in Progress"), _("Downloading the new version..."), parent=None, maximum=100)
|
||||||
|
|
||||||
def progress_callback(total_downloaded, total_size):
|
def progress_callback(total_downloaded, total_size):
|
||||||
wx.CallAfter(_progress_callback, total_downloaded, total_size)
|
wx.CallAfter(_progress_callback, total_downloaded, total_size)
|
||||||
|
|
||||||
def _progress_callback(total_downloaded, total_size):
|
def _progress_callback(total_downloaded, total_size):
|
||||||
global progress_dialog
|
global progress_dialog
|
||||||
if progress_dialog == None:
|
if progress_dialog == None:
|
||||||
progress_dialog = create_progress_dialog()
|
progress_dialog = create_progress_dialog()
|
||||||
progress_dialog.Show()
|
progress_dialog.Show()
|
||||||
if total_downloaded == total_size:
|
if total_downloaded == total_size:
|
||||||
progress_dialog.Destroy()
|
progress_dialog.Destroy()
|
||||||
else:
|
else:
|
||||||
progress_dialog.Update((total_downloaded*100)/total_size, _("Updating... {total_transferred} of {total_size}").format(total_transferred=utils.convert_bytes(total_downloaded), total_size=utils.convert_bytes(total_size)))
|
progress_dialog.Update((total_downloaded*100)/total_size, _("Updating... {total_transferred} of {total_size}").format(total_transferred=utils.convert_bytes(total_downloaded), total_size=utils.convert_bytes(total_size)))
|
||||||
|
|
||||||
def update_finished():
|
def update_finished():
|
||||||
return wx.MessageDialog(None, _("The update has been downloaded and installed successfully. Press OK to continue."), _("Done!")).ShowModal()
|
return wx.MessageDialog(None, _("The update has been downloaded and installed successfully. Press OK to continue."), _("Done!")).ShowModal()
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
""" Views package for socializer. A view is the Graphical user interface in the application. This package includes everything needed to render a window.
|
""" Views package for socializer. A view is the Graphical user interface in the application. This package includes everything needed to render a window.
|
||||||
No other functionality is assumed in this package.
|
No other functionality is assumed in this package.
|
||||||
All modules from here should be used via an interactor (read description of the interactors package).
|
All modules from here should be used via an interactor (read description of the interactors package).
|
||||||
Interactors will be routing user events (like buttons pressed, menus activated and so on) to presenter functions.
|
Interactors will be routing user events (like buttons pressed, menus activated and so on) to presenter functions.
|
||||||
"""
|
"""
|
||||||
from .dialogs.attach import *
|
from .dialogs.attach import *
|
||||||
from .dialogs.audioRecorder import *
|
from .dialogs.audioRecorder import *
|
||||||
|
@ -4,65 +4,65 @@ import wx
|
|||||||
import widgetUtils
|
import widgetUtils
|
||||||
|
|
||||||
class attachDialog(widgetUtils.BaseDialog):
|
class attachDialog(widgetUtils.BaseDialog):
|
||||||
def __init__(self, voice_messages=False):
|
def __init__(self, voice_messages=False):
|
||||||
super(attachDialog, self).__init__(None, title=_("Add an attachment"))
|
super(attachDialog, self).__init__(None, title=_("Add an attachment"))
|
||||||
panel = wx.Panel(self)
|
panel = wx.Panel(self)
|
||||||
sizer = wx.BoxSizer(wx.VERTICAL)
|
sizer = wx.BoxSizer(wx.VERTICAL)
|
||||||
lbl1 = wx.StaticText(panel, wx.NewId(), _("Attachments"))
|
lbl1 = wx.StaticText(panel, wx.NewId(), _("Attachments"))
|
||||||
self.attachments = widgetUtils.list(panel, _("Type"), _("Title"), style=wx.LC_REPORT)
|
self.attachments = widgetUtils.list(panel, _("Type"), _("Title"), style=wx.LC_REPORT)
|
||||||
box = wx.BoxSizer(wx.HORIZONTAL)
|
box = wx.BoxSizer(wx.HORIZONTAL)
|
||||||
box.Add(lbl1, 0, wx.ALL, 5)
|
box.Add(lbl1, 0, wx.ALL, 5)
|
||||||
box.Add(self.attachments.list, 0, wx.ALL, 5)
|
box.Add(self.attachments.list, 0, wx.ALL, 5)
|
||||||
sizer.Add(box, 0, wx.ALL, 5)
|
sizer.Add(box, 0, wx.ALL, 5)
|
||||||
static = wx.StaticBoxSizer(parent=panel, orient=wx.HORIZONTAL, label=_("Add attachments"))
|
static = wx.StaticBoxSizer(parent=panel, orient=wx.HORIZONTAL, label=_("Add attachments"))
|
||||||
self.photo = wx.Button(static.GetStaticBox(), wx.NewId(), _("&Photo"))
|
self.photo = wx.Button(static.GetStaticBox(), wx.NewId(), _("&Photo"))
|
||||||
self.audio = wx.Button(static.GetStaticBox(), wx.NewId(), _("Audio file"))
|
self.audio = wx.Button(static.GetStaticBox(), wx.NewId(), _("Audio file"))
|
||||||
self.document = wx.Button(static.GetStaticBox(), wx.NewId(), _("Document"))
|
self.document = wx.Button(static.GetStaticBox(), wx.NewId(), _("Document"))
|
||||||
if voice_messages:
|
if voice_messages:
|
||||||
self.voice_message = wx.Button(static.GetStaticBox(), wx.NewId(), _("Voice message"))
|
self.voice_message = wx.Button(static.GetStaticBox(), wx.NewId(), _("Voice message"))
|
||||||
self.remove = wx.Button(static.GetStaticBox(), wx.NewId(), _("Remove attachment"))
|
self.remove = wx.Button(static.GetStaticBox(), wx.NewId(), _("Remove attachment"))
|
||||||
self.remove.Enable(False)
|
self.remove.Enable(False)
|
||||||
static.Add(self.photo, 0, wx.ALL, 5)
|
static.Add(self.photo, 0, wx.ALL, 5)
|
||||||
static.Add(self.audio, 0, wx.ALL, 5)
|
static.Add(self.audio, 0, wx.ALL, 5)
|
||||||
static.Add(self.document, 0, wx.ALL, 5)
|
static.Add(self.document, 0, wx.ALL, 5)
|
||||||
if voice_messages:
|
if voice_messages:
|
||||||
static.Add(self.voice_message, 0, wx.ALL, 5)
|
static.Add(self.voice_message, 0, wx.ALL, 5)
|
||||||
sizer.Add(static, 0, wx.ALL, 5)
|
sizer.Add(static, 0, wx.ALL, 5)
|
||||||
ok = wx.Button(panel, wx.ID_OK)
|
ok = wx.Button(panel, wx.ID_OK)
|
||||||
ok.SetDefault()
|
ok.SetDefault()
|
||||||
cancelBtn = wx.Button(panel, wx.ID_CANCEL)
|
cancelBtn = wx.Button(panel, wx.ID_CANCEL)
|
||||||
btnSizer = wx.BoxSizer()
|
btnSizer = wx.BoxSizer()
|
||||||
btnSizer.Add(ok, 0, wx.ALL, 5)
|
btnSizer.Add(ok, 0, wx.ALL, 5)
|
||||||
btnSizer.Add(cancelBtn, 0, wx.ALL, 5)
|
btnSizer.Add(cancelBtn, 0, wx.ALL, 5)
|
||||||
sizer.Add(btnSizer, 0, wx.ALL, 5)
|
sizer.Add(btnSizer, 0, wx.ALL, 5)
|
||||||
panel.SetSizer(sizer)
|
panel.SetSizer(sizer)
|
||||||
self.SetClientSize(sizer.CalcMin())
|
self.SetClientSize(sizer.CalcMin())
|
||||||
|
|
||||||
def get_image(self):
|
def get_image(self):
|
||||||
openFileDialog = wx.FileDialog(self, _("Select the picture to be uploaded"), "", "", _("Image files (*.png, *.jpg, *.gif)|*.png; *.jpg; *.gif"), wx.FD_OPEN | wx.FD_FILE_MUST_EXIST)
|
openFileDialog = wx.FileDialog(self, _("Select the picture to be uploaded"), "", "", _("Image files (*.png, *.jpg, *.gif)|*.png; *.jpg; *.gif"), wx.FD_OPEN | wx.FD_FILE_MUST_EXIST)
|
||||||
if openFileDialog.ShowModal() == wx.ID_CANCEL:
|
if openFileDialog.ShowModal() == wx.ID_CANCEL:
|
||||||
return (None, None)
|
return (None, None)
|
||||||
dsc = self.ask_description()
|
dsc = self.ask_description()
|
||||||
return (openFileDialog.GetPath(), dsc)
|
return (openFileDialog.GetPath(), dsc)
|
||||||
|
|
||||||
def ask_description(self):
|
def ask_description(self):
|
||||||
dlg = wx.TextEntryDialog(self, _("please provide a description"), _("Description"))
|
dlg = wx.TextEntryDialog(self, _("please provide a description"), _("Description"))
|
||||||
dlg.ShowModal()
|
dlg.ShowModal()
|
||||||
result = dlg.GetValue()
|
result = dlg.GetValue()
|
||||||
dlg.Destroy()
|
dlg.Destroy()
|
||||||
return result
|
return result
|
||||||
|
|
||||||
def get_audio(self):
|
def get_audio(self):
|
||||||
openFileDialog = wx.FileDialog(self, _("Select the audio file to be uploaded"), "", "", _("Audio files (*.mp3)|*.mp3"), wx.FD_OPEN | wx.FD_FILE_MUST_EXIST)
|
openFileDialog = wx.FileDialog(self, _("Select the audio file to be uploaded"), "", "", _("Audio files (*.mp3)|*.mp3"), wx.FD_OPEN | wx.FD_FILE_MUST_EXIST)
|
||||||
if openFileDialog.ShowModal() == wx.ID_CANCEL:
|
if openFileDialog.ShowModal() == wx.ID_CANCEL:
|
||||||
return None
|
return None
|
||||||
return openFileDialog.GetPath()
|
return openFileDialog.GetPath()
|
||||||
|
|
||||||
def get_document(self):
|
def get_document(self):
|
||||||
openFileDialog = wx.FileDialog(self, _("Select the file to be uploaded. All extensions are allowed except .mp3 and .exe."), "", "", _("All files (*.*)|*.*"), wx.FD_OPEN | wx.FD_FILE_MUST_EXIST)
|
openFileDialog = wx.FileDialog(self, _("Select the file to be uploaded. All extensions are allowed except .mp3 and .exe."), "", "", _("All files (*.*)|*.*"), wx.FD_OPEN | wx.FD_FILE_MUST_EXIST)
|
||||||
if openFileDialog.ShowModal() == wx.ID_CANCEL:
|
if openFileDialog.ShowModal() == wx.ID_CANCEL:
|
||||||
return None
|
return None
|
||||||
return openFileDialog.GetPath()
|
return openFileDialog.GetPath()
|
||||||
|
|
||||||
def invalid_attachment(self):
|
def invalid_attachment(self):
|
||||||
return wx.MessageDialog(None, _("The file you are trying to upload contains an extension that is not allowed by VK."), _("Error"), style=wx.ICON_ERROR).ShowModal()
|
return wx.MessageDialog(None, _("The file you are trying to upload contains an extension that is not allowed by VK."), _("Error"), style=wx.ICON_ERROR).ShowModal()
|
||||||
|
@ -4,33 +4,33 @@ import wx
|
|||||||
import widgetUtils
|
import widgetUtils
|
||||||
|
|
||||||
class audioRecorderDialog(widgetUtils.BaseDialog):
|
class audioRecorderDialog(widgetUtils.BaseDialog):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super(audioRecorderDialog, self).__init__(None, title=_("Record voice message"))
|
super(audioRecorderDialog, self).__init__(None, title=_("Record voice message"))
|
||||||
panel = wx.Panel(self)
|
panel = wx.Panel(self)
|
||||||
sizer = wx.BoxSizer(wx.VERTICAL)
|
sizer = wx.BoxSizer(wx.VERTICAL)
|
||||||
self.play = wx.Button(panel, -1, _("&Play"))
|
self.play = wx.Button(panel, -1, _("&Play"))
|
||||||
self.play.Disable()
|
self.play.Disable()
|
||||||
self.record = wx.Button(panel, -1, _("&Record"))
|
self.record = wx.Button(panel, -1, _("&Record"))
|
||||||
self.record.SetFocus()
|
self.record.SetFocus()
|
||||||
self.discard = wx.Button(panel, -1, _("&Discard"))
|
self.discard = wx.Button(panel, -1, _("&Discard"))
|
||||||
self.discard.Disable()
|
self.discard.Disable()
|
||||||
self.ok = wx.Button(panel, wx.ID_OK, _("&Add"))
|
self.ok = wx.Button(panel, wx.ID_OK, _("&Add"))
|
||||||
cancel = wx.Button(panel, wx.ID_CANCEL, _("&Cancel"))
|
cancel = wx.Button(panel, wx.ID_CANCEL, _("&Cancel"))
|
||||||
btnSizer = wx.BoxSizer(wx.HORIZONTAL)
|
btnSizer = wx.BoxSizer(wx.HORIZONTAL)
|
||||||
btnSizer2 = wx.BoxSizer(wx.HORIZONTAL)
|
btnSizer2 = wx.BoxSizer(wx.HORIZONTAL)
|
||||||
btnSizer.Add(self.play, 0, wx.ALL, 5)
|
btnSizer.Add(self.play, 0, wx.ALL, 5)
|
||||||
btnSizer.Add(self.record, 0, wx.ALL, 5)
|
btnSizer.Add(self.record, 0, wx.ALL, 5)
|
||||||
btnSizer2.Add(self.ok, 0, wx.ALL, 5)
|
btnSizer2.Add(self.ok, 0, wx.ALL, 5)
|
||||||
btnSizer2.Add(cancel, 0, wx.ALL, 5)
|
btnSizer2.Add(cancel, 0, wx.ALL, 5)
|
||||||
sizer.Add(btnSizer, 0, wx.ALL, 5)
|
sizer.Add(btnSizer, 0, wx.ALL, 5)
|
||||||
sizer.Add(btnSizer2, 0, wx.ALL, 5)
|
sizer.Add(btnSizer2, 0, wx.ALL, 5)
|
||||||
panel.SetSizer(sizer)
|
panel.SetSizer(sizer)
|
||||||
self.SetClientSize(sizer.CalcMin())
|
self.SetClientSize(sizer.CalcMin())
|
||||||
|
|
||||||
def enable_control(self, control):
|
def enable_control(self, control):
|
||||||
if hasattr(self, control):
|
if hasattr(self, control):
|
||||||
getattr(self, control).Enable()
|
getattr(self, control).Enable()
|
||||||
|
|
||||||
def disable_control(self, control):
|
def disable_control(self, control):
|
||||||
if hasattr(self, control):
|
if hasattr(self, control):
|
||||||
getattr(self, control).Disable()
|
getattr(self, control).Disable()
|
||||||
|
@ -3,17 +3,17 @@ import wx
|
|||||||
import widgetUtils
|
import widgetUtils
|
||||||
|
|
||||||
class blacklistDialog(widgetUtils.BaseDialog):
|
class blacklistDialog(widgetUtils.BaseDialog):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super(blacklistDialog, self).__init__(parent=None, title=_("blacklist"))
|
super(blacklistDialog, self).__init__(parent=None, title=_("blacklist"))
|
||||||
panel = wx.Panel(self)
|
panel = wx.Panel(self)
|
||||||
sizer = wx.BoxSizer(wx.VERTICAL)
|
sizer = wx.BoxSizer(wx.VERTICAL)
|
||||||
box1 = wx.StaticBoxSizer(parent=panel, orient=wx.HORIZONTAL, label=_("blocked users"))
|
box1 = wx.StaticBoxSizer(parent=panel, orient=wx.HORIZONTAL, label=_("blocked users"))
|
||||||
self.persons = widgetUtils.list(panel, _("User"), style=wx.LC_REPORT)
|
self.persons = widgetUtils.list(panel, _("User"), style=wx.LC_REPORT)
|
||||||
box1.Add(self.persons.list, 0, wx.ALL, 5)
|
box1.Add(self.persons.list, 0, wx.ALL, 5)
|
||||||
sizer.Add(box1, 0, wx.ALL, 5)
|
sizer.Add(box1, 0, wx.ALL, 5)
|
||||||
self.unblock = wx.Button(panel, wx.NewId(), _("Unblock"))
|
self.unblock = wx.Button(panel, wx.NewId(), _("Unblock"))
|
||||||
sizer.Add(self.unblock, 0, wx.ALL, 5)
|
sizer.Add(self.unblock, 0, wx.ALL, 5)
|
||||||
close = wx.Button(panel, wx.ID_CANCEL, _("Close"))
|
close = wx.Button(panel, wx.ID_CANCEL, _("Close"))
|
||||||
sizer.Add(close, 0, wx.ALL, 5)
|
sizer.Add(close, 0, wx.ALL, 5)
|
||||||
panel.SetSizer(sizer)
|
panel.SetSizer(sizer)
|
||||||
self.SetClientSize(sizer.CalcMin())
|
self.SetClientSize(sizer.CalcMin())
|
||||||
|
@ -4,179 +4,179 @@ import wx
|
|||||||
import widgetUtils
|
import widgetUtils
|
||||||
|
|
||||||
class general(wx.Panel, widgetUtils.BaseDialog):
|
class general(wx.Panel, widgetUtils.BaseDialog):
|
||||||
def __init__(self, panel, languages):
|
def __init__(self, panel, languages):
|
||||||
super(general, self).__init__(panel)
|
super(general, self).__init__(panel)
|
||||||
sizer = wx.BoxSizer(wx.VERTICAL)
|
sizer = wx.BoxSizer(wx.VERTICAL)
|
||||||
langBox = wx.StaticBoxSizer(parent=self, orient=wx.HORIZONTAL, label=_("Language"))
|
langBox = wx.StaticBoxSizer(parent=self, orient=wx.HORIZONTAL, label=_("Language"))
|
||||||
self.language = wx.ListBox(langBox.GetStaticBox(), wx.NewId(), choices=languages)
|
self.language = wx.ListBox(langBox.GetStaticBox(), wx.NewId(), choices=languages)
|
||||||
self.language.SetSize(self.language.GetBestSize())
|
self.language.SetSize(self.language.GetBestSize())
|
||||||
langBox.Add(self.language, 0, wx.ALL, 5)
|
langBox.Add(self.language, 0, wx.ALL, 5)
|
||||||
sizer.Add(langBox, 0, wx.ALL, 5)
|
sizer.Add(langBox, 0, wx.ALL, 5)
|
||||||
self.load_images = wx.CheckBox(self, wx.NewId(), _("Load images in posts"))
|
self.load_images = wx.CheckBox(self, wx.NewId(), _("Load images in posts"))
|
||||||
sizer.Add(self.load_images, 0, wx.ALL, 5)
|
sizer.Add(self.load_images, 0, wx.ALL, 5)
|
||||||
self.use_proxy = wx.CheckBox(self, wx.NewId(), _("Use proxy"))
|
self.use_proxy = wx.CheckBox(self, wx.NewId(), _("Use proxy"))
|
||||||
sizer.Add(self.use_proxy, 0, wx.ALL, 5)
|
sizer.Add(self.use_proxy, 0, wx.ALL, 5)
|
||||||
self.debug_logging = wx.CheckBox(self, wx.NewId(), _("Enable debug logging (useful for reporting errors)"))
|
self.debug_logging = wx.CheckBox(self, wx.NewId(), _("Enable debug logging (useful for reporting errors)"))
|
||||||
sizer.Add(self.debug_logging, 0, wx.ALL, 5)
|
sizer.Add(self.debug_logging, 0, wx.ALL, 5)
|
||||||
lbl4 = wx.StaticText(self, wx.NewId(), _("Update channel"))
|
lbl4 = wx.StaticText(self, wx.NewId(), _("Update channel"))
|
||||||
self.update_channel = wx.ComboBox(self, wx.NewId(), choices=[_("Stable"), _("Alpha")], value=_("Native"), style=wx.CB_READONLY)
|
self.update_channel = wx.ComboBox(self, wx.NewId(), choices=[_("Stable"), _("Alpha")], value=_("Native"), style=wx.CB_READONLY)
|
||||||
box4 = wx.BoxSizer(wx.HORIZONTAL)
|
box4 = wx.BoxSizer(wx.HORIZONTAL)
|
||||||
box4.Add(lbl4, 0, wx.ALL, 5)
|
box4.Add(lbl4, 0, wx.ALL, 5)
|
||||||
box4.Add(self.update_channel, 0, wx.ALL, 5)
|
box4.Add(self.update_channel, 0, wx.ALL, 5)
|
||||||
sizer.Add(box4, 0, wx.ALL, 5)
|
sizer.Add(box4, 0, wx.ALL, 5)
|
||||||
self.SetSizer(sizer)
|
self.SetSizer(sizer)
|
||||||
|
|
||||||
class buffers(wx.Panel, widgetUtils.BaseDialog):
|
class buffers(wx.Panel, widgetUtils.BaseDialog):
|
||||||
|
|
||||||
def __init__(self, panel):
|
def __init__(self, panel):
|
||||||
super(buffers, self).__init__(panel)
|
super(buffers, self).__init__(panel)
|
||||||
sizer = wx.BoxSizer(wx.VERTICAL)
|
sizer = wx.BoxSizer(wx.VERTICAL)
|
||||||
lbl1 = wx.StaticText(self, wx.NewId(), _("Number of items to load for newsfeed and wall buffers (maximun 100)"))
|
lbl1 = wx.StaticText(self, wx.NewId(), _("Number of items to load for newsfeed and wall buffers (maximun 100)"))
|
||||||
self.wall_buffer_count = wx.SpinCtrl(self, wx.NewId())
|
self.wall_buffer_count = wx.SpinCtrl(self, wx.NewId())
|
||||||
self.wall_buffer_count.SetRange(1, 100)
|
self.wall_buffer_count.SetRange(1, 100)
|
||||||
box1 = wx.BoxSizer(wx.HORIZONTAL)
|
box1 = wx.BoxSizer(wx.HORIZONTAL)
|
||||||
box1.Add(lbl1, 0, wx.ALL, 5)
|
box1.Add(lbl1, 0, wx.ALL, 5)
|
||||||
box1.Add(self.wall_buffer_count, 0, wx.ALL, 5)
|
box1.Add(self.wall_buffer_count, 0, wx.ALL, 5)
|
||||||
sizer.Add(box1, 0, wx.ALL, 5)
|
sizer.Add(box1, 0, wx.ALL, 5)
|
||||||
lbl3 = wx.StaticText(self, wx.NewId(), _("Number of items to load in video buffers (maximun 200)"))
|
lbl3 = wx.StaticText(self, wx.NewId(), _("Number of items to load in video buffers (maximun 200)"))
|
||||||
self.video_buffers_count = wx.SpinCtrl(self, wx.NewId())
|
self.video_buffers_count = wx.SpinCtrl(self, wx.NewId())
|
||||||
self.video_buffers_count.SetRange(1, 200)
|
self.video_buffers_count.SetRange(1, 200)
|
||||||
box3 = wx.BoxSizer(wx.HORIZONTAL)
|
box3 = wx.BoxSizer(wx.HORIZONTAL)
|
||||||
box3.Add(lbl3, 0, wx.ALL, 5)
|
box3.Add(lbl3, 0, wx.ALL, 5)
|
||||||
box3.Add(self.video_buffers_count, 0, wx.ALL, 5)
|
box3.Add(self.video_buffers_count, 0, wx.ALL, 5)
|
||||||
sizer.Add(box3, 0, wx.ALL, 5)
|
sizer.Add(box3, 0, wx.ALL, 5)
|
||||||
lbl4 = wx.StaticText(self, wx.NewId(), _("Number of items to load in conversation buffers (maximun 200)"))
|
lbl4 = wx.StaticText(self, wx.NewId(), _("Number of items to load in conversation buffers (maximun 200)"))
|
||||||
self.chat_buffers_count = wx.SpinCtrl(self, wx.NewId())
|
self.chat_buffers_count = wx.SpinCtrl(self, wx.NewId())
|
||||||
self.chat_buffers_count.SetRange(1, 200)
|
self.chat_buffers_count.SetRange(1, 200)
|
||||||
box4 = wx.BoxSizer(wx.HORIZONTAL)
|
box4 = wx.BoxSizer(wx.HORIZONTAL)
|
||||||
box4.Add(lbl4, 0, wx.ALL, 5)
|
box4.Add(lbl4, 0, wx.ALL, 5)
|
||||||
box4.Add(self.chat_buffers_count, 0, wx.ALL, 5)
|
box4.Add(self.chat_buffers_count, 0, wx.ALL, 5)
|
||||||
sizer.Add(box4, 0, wx.ALL, 5)
|
sizer.Add(box4, 0, wx.ALL, 5)
|
||||||
self.SetSizer(sizer)
|
self.SetSizer(sizer)
|
||||||
|
|
||||||
class chat(wx.Panel, widgetUtils.BaseDialog):
|
class chat(wx.Panel, widgetUtils.BaseDialog):
|
||||||
def __init__(self, panel):
|
def __init__(self, panel):
|
||||||
super(chat, self).__init__(panel)
|
super(chat, self).__init__(panel)
|
||||||
sizer = wx.BoxSizer(wx.VERTICAL)
|
sizer = wx.BoxSizer(wx.VERTICAL)
|
||||||
self.notify_online = wx.CheckBox(self, wx.NewId(), _("Show notifications when users are online"))
|
self.notify_online = wx.CheckBox(self, wx.NewId(), _("Show notifications when users are online"))
|
||||||
sizer.Add(self.notify_online, 0, wx.ALL, 5)
|
sizer.Add(self.notify_online, 0, wx.ALL, 5)
|
||||||
self.notify_offline = wx.CheckBox(self, wx.NewId(), _("Show notifications when users are offline"))
|
self.notify_offline = wx.CheckBox(self, wx.NewId(), _("Show notifications when users are offline"))
|
||||||
sizer.Add(self.notify_offline, 0, wx.ALL, 5)
|
sizer.Add(self.notify_offline, 0, wx.ALL, 5)
|
||||||
lbl = wx.StaticText(self, wx.NewId(), _("Notification type"))
|
lbl = wx.StaticText(self, wx.NewId(), _("Notification type"))
|
||||||
self.notifications = wx.ComboBox(self, wx.NewId(), choices=[_("Native"), _("Custom"),], value=_("Native"), style=wx.CB_READONLY)
|
self.notifications = wx.ComboBox(self, wx.NewId(), choices=[_("Native"), _("Custom"),], value=_("Native"), style=wx.CB_READONLY)
|
||||||
nbox = wx.BoxSizer(wx.HORIZONTAL)
|
nbox = wx.BoxSizer(wx.HORIZONTAL)
|
||||||
nbox.Add(lbl, 0, wx.ALL, 5)
|
nbox.Add(lbl, 0, wx.ALL, 5)
|
||||||
nbox.Add(self.notifications, 0, wx.ALL, 5)
|
nbox.Add(self.notifications, 0, wx.ALL, 5)
|
||||||
sizer.Add(nbox, 0, wx.ALL, 5)
|
sizer.Add(nbox, 0, wx.ALL, 5)
|
||||||
self.SetSizer(sizer)
|
self.SetSizer(sizer)
|
||||||
|
|
||||||
class loadAtStartup(wx.Panel, widgetUtils.BaseDialog):
|
class loadAtStartup(wx.Panel, widgetUtils.BaseDialog):
|
||||||
def __init__(self, panel):
|
def __init__(self, panel):
|
||||||
super(loadAtStartup, self).__init__(panel)
|
super(loadAtStartup, self).__init__(panel)
|
||||||
sizer = wx.BoxSizer(wx.VERTICAL)
|
sizer = wx.BoxSizer(wx.VERTICAL)
|
||||||
self.audio_albums = wx.CheckBox(self, wx.NewId(), _("Create buffers for audio albums at startup"))
|
self.audio_albums = wx.CheckBox(self, wx.NewId(), _("Create buffers for audio albums at startup"))
|
||||||
sizer.Add(self.audio_albums, 0, wx.ALL, 5)
|
sizer.Add(self.audio_albums, 0, wx.ALL, 5)
|
||||||
self.video_albums = wx.CheckBox(self, wx.NewId(), _("Create buffers for video albums at startup"))
|
self.video_albums = wx.CheckBox(self, wx.NewId(), _("Create buffers for video albums at startup"))
|
||||||
sizer.Add(self.video_albums, 0, wx.ALL, 5)
|
sizer.Add(self.video_albums, 0, wx.ALL, 5)
|
||||||
self.communities = wx.CheckBox(self, wx.NewId(), _("Create buffers for communities and public pages at startup"))
|
self.communities = wx.CheckBox(self, wx.NewId(), _("Create buffers for communities and public pages at startup"))
|
||||||
sizer.Add(self.communities, 0, wx.ALL, 5)
|
sizer.Add(self.communities, 0, wx.ALL, 5)
|
||||||
self.SetSizer(sizer)
|
self.SetSizer(sizer)
|
||||||
|
|
||||||
class sound(wx.Panel, widgetUtils.BaseDialog):
|
class sound(wx.Panel, widgetUtils.BaseDialog):
|
||||||
def __init__(self, panel, input_devices, output_devices, soundpacks):
|
def __init__(self, panel, input_devices, output_devices, soundpacks):
|
||||||
super(sound, self).__init__(panel)
|
super(sound, self).__init__(panel)
|
||||||
sizer = wx.BoxSizer(wx.VERTICAL)
|
sizer = wx.BoxSizer(wx.VERTICAL)
|
||||||
output_label = wx.StaticText(self, wx.NewId(), _("Output device"))
|
output_label = wx.StaticText(self, wx.NewId(), _("Output device"))
|
||||||
self.output = wx.ComboBox(self, wx.NewId(), choices=output_devices, style=wx.CB_READONLY)
|
self.output = wx.ComboBox(self, wx.NewId(), choices=output_devices, style=wx.CB_READONLY)
|
||||||
self.output.SetSize(self.output.GetBestSize())
|
self.output.SetSize(self.output.GetBestSize())
|
||||||
outputBox = wx.BoxSizer(wx.HORIZONTAL)
|
outputBox = wx.BoxSizer(wx.HORIZONTAL)
|
||||||
outputBox.Add(output_label, 0, wx.ALL, 5)
|
outputBox.Add(output_label, 0, wx.ALL, 5)
|
||||||
outputBox.Add(self.output, 0, wx.ALL, 5)
|
outputBox.Add(self.output, 0, wx.ALL, 5)
|
||||||
sizer.Add(outputBox, 0, wx.ALL, 5)
|
sizer.Add(outputBox, 0, wx.ALL, 5)
|
||||||
input_label = wx.StaticText(self, wx.NewId(), _("Input device"))
|
input_label = wx.StaticText(self, wx.NewId(), _("Input device"))
|
||||||
self.input = wx.ComboBox(self, wx.NewId(), choices=input_devices, style=wx.CB_READONLY)
|
self.input = wx.ComboBox(self, wx.NewId(), choices=input_devices, style=wx.CB_READONLY)
|
||||||
self.input.SetSize(self.input.GetBestSize())
|
self.input.SetSize(self.input.GetBestSize())
|
||||||
inputBox = wx.BoxSizer(wx.HORIZONTAL)
|
inputBox = wx.BoxSizer(wx.HORIZONTAL)
|
||||||
inputBox.Add(input_label, 0, wx.ALL, 5)
|
inputBox.Add(input_label, 0, wx.ALL, 5)
|
||||||
inputBox.Add(self.input, 0, wx.ALL, 5)
|
inputBox.Add(self.input, 0, wx.ALL, 5)
|
||||||
sizer.Add(inputBox, 0, wx.ALL, 5)
|
sizer.Add(inputBox, 0, wx.ALL, 5)
|
||||||
# soundBox = wx.BoxSizer(wx.VERTICAL)
|
# soundBox = wx.BoxSizer(wx.VERTICAL)
|
||||||
# soundpack_label = wx.StaticText(self, wx.NewId(), _(u"Sound pack"))
|
# soundpack_label = wx.StaticText(self, wx.NewId(), _(u"Sound pack"))
|
||||||
# self.soundpack = wx.ComboBox(self, -1, choices=soundpacks, style=wx.CB_READONLY)
|
# self.soundpack = wx.ComboBox(self, -1, choices=soundpacks, style=wx.CB_READONLY)
|
||||||
# self.soundpack.SetSize(self.soundpack.GetBestSize())
|
# self.soundpack.SetSize(self.soundpack.GetBestSize())
|
||||||
# soundBox.Add(soundpack_label, 0, wx.ALL, 5)
|
# soundBox.Add(soundpack_label, 0, wx.ALL, 5)
|
||||||
# soundBox.Add(self.soundpack, 0, wx.ALL, 5)
|
# soundBox.Add(self.soundpack, 0, wx.ALL, 5)
|
||||||
# sizer.Add(soundBox, 0, wx.ALL, 5)
|
# sizer.Add(soundBox, 0, wx.ALL, 5)
|
||||||
self.SetSizer(sizer)
|
self.SetSizer(sizer)
|
||||||
|
|
||||||
def on_keypress(self, event, *args, **kwargs):
|
def on_keypress(self, event, *args, **kwargs):
|
||||||
""" Invert movement of up and down arrow keys when dealing with a wX Slider.
|
""" Invert movement of up and down arrow keys when dealing with a wX Slider.
|
||||||
See https://github.com/manuelcortez/TWBlue/issues/261
|
See https://github.com/manuelcortez/TWBlue/issues/261
|
||||||
and http://trac.wxwidgets.org/ticket/2068
|
and http://trac.wxwidgets.org/ticket/2068
|
||||||
"""
|
"""
|
||||||
keycode = event.GetKeyCode()
|
keycode = event.GetKeyCode()
|
||||||
if keycode == wx.WXK_UP:
|
if keycode == wx.WXK_UP:
|
||||||
return self.volumeCtrl.SetValue(self.volumeCtrl.GetValue()+1)
|
return self.volumeCtrl.SetValue(self.volumeCtrl.GetValue()+1)
|
||||||
elif keycode == wx.WXK_DOWN:
|
elif keycode == wx.WXK_DOWN:
|
||||||
return self.volumeCtrl.SetValue(self.volumeCtrl.GetValue()-1)
|
return self.volumeCtrl.SetValue(self.volumeCtrl.GetValue()-1)
|
||||||
event.Skip()
|
event.Skip()
|
||||||
|
|
||||||
def get(self, control):
|
def get(self, control):
|
||||||
return getattr(self, control).GetStringSelection()
|
return getattr(self, control).GetStringSelection()
|
||||||
|
|
||||||
class configurationDialog(widgetUtils.BaseDialog):
|
class configurationDialog(widgetUtils.BaseDialog):
|
||||||
|
|
||||||
def __init__(self, title):
|
def __init__(self, title):
|
||||||
super(configurationDialog, self).__init__(None, -1, title=title)
|
super(configurationDialog, self).__init__(None, -1, title=title)
|
||||||
self.panel = wx.Panel(self)
|
self.panel = wx.Panel(self)
|
||||||
self.sizer = wx.BoxSizer(wx.VERTICAL)
|
self.sizer = wx.BoxSizer(wx.VERTICAL)
|
||||||
self.notebook = wx.Notebook(self.panel)
|
self.notebook = wx.Notebook(self.panel)
|
||||||
|
|
||||||
def create_general(self, languages):
|
def create_general(self, languages):
|
||||||
self.general = general(self.notebook, languages)
|
self.general = general(self.notebook, languages)
|
||||||
self.notebook.AddPage(self.general, _("General"))
|
self.notebook.AddPage(self.general, _("General"))
|
||||||
self.general.SetFocus()
|
self.general.SetFocus()
|
||||||
|
|
||||||
def create_buffers(self):
|
def create_buffers(self):
|
||||||
self.buffers = buffers(self.notebook)
|
self.buffers = buffers(self.notebook)
|
||||||
self.notebook.AddPage(self.buffers, _("Buffer settings"))
|
self.notebook.AddPage(self.buffers, _("Buffer settings"))
|
||||||
|
|
||||||
def create_chat(self):
|
def create_chat(self):
|
||||||
self.chat = chat(self.notebook)
|
self.chat = chat(self.notebook)
|
||||||
self.notebook.AddPage(self.chat, _("Chat settings"))
|
self.notebook.AddPage(self.chat, _("Chat settings"))
|
||||||
|
|
||||||
def create_startup_options(self):
|
def create_startup_options(self):
|
||||||
self.startup = loadAtStartup(self.notebook)
|
self.startup = loadAtStartup(self.notebook)
|
||||||
self.notebook.AddPage(self.startup, _("Optional buffers"))
|
self.notebook.AddPage(self.startup, _("Optional buffers"))
|
||||||
|
|
||||||
def create_sound(self, input_devices, output_devices, soundpacks):
|
def create_sound(self, input_devices, output_devices, soundpacks):
|
||||||
self.sound = sound(self.notebook, input_devices, output_devices, soundpacks)
|
self.sound = sound(self.notebook, input_devices, output_devices, soundpacks)
|
||||||
self.notebook.AddPage(self.sound, _("Sound settings"))
|
self.notebook.AddPage(self.sound, _("Sound settings"))
|
||||||
|
|
||||||
def realize(self):
|
def realize(self):
|
||||||
self.sizer.Add(self.notebook, 0, wx.ALL, 5)
|
self.sizer.Add(self.notebook, 0, wx.ALL, 5)
|
||||||
ok_cancel_box = wx.BoxSizer(wx.HORIZONTAL)
|
ok_cancel_box = wx.BoxSizer(wx.HORIZONTAL)
|
||||||
ok = wx.Button(self.panel, wx.ID_OK, _("Save"))
|
ok = wx.Button(self.panel, wx.ID_OK, _("Save"))
|
||||||
ok.SetDefault()
|
ok.SetDefault()
|
||||||
cancel = wx.Button(self.panel, wx.ID_CANCEL, _("Close"))
|
cancel = wx.Button(self.panel, wx.ID_CANCEL, _("Close"))
|
||||||
self.SetEscapeId(cancel.GetId())
|
self.SetEscapeId(cancel.GetId())
|
||||||
ok_cancel_box.Add(ok, 0, wx.ALL, 5)
|
ok_cancel_box.Add(ok, 0, wx.ALL, 5)
|
||||||
ok_cancel_box.Add(cancel, 0, wx.ALL, 5)
|
ok_cancel_box.Add(cancel, 0, wx.ALL, 5)
|
||||||
self.sizer.Add(ok_cancel_box, 0, wx.ALL, 5)
|
self.sizer.Add(ok_cancel_box, 0, wx.ALL, 5)
|
||||||
self.panel.SetSizer(self.sizer)
|
self.panel.SetSizer(self.sizer)
|
||||||
self.SetClientSize(self.sizer.CalcMin())
|
self.SetClientSize(self.sizer.CalcMin())
|
||||||
|
|
||||||
def get_value(self, panel, key):
|
def get_value(self, panel, key):
|
||||||
p = getattr(self, panel)
|
p = getattr(self, panel)
|
||||||
return getattr(p, key).GetValue()
|
return getattr(p, key).GetValue()
|
||||||
|
|
||||||
def set_value(self, panel, key, value):
|
def set_value(self, panel, key, value):
|
||||||
p = getattr(self, panel)
|
p = getattr(self, panel)
|
||||||
control = getattr(p, key)
|
control = getattr(p, key)
|
||||||
getattr(control, "SetValue")(value)
|
getattr(control, "SetValue")(value)
|
||||||
|
|
||||||
def alpha_channel(self):
|
def alpha_channel(self):
|
||||||
return wx.MessageDialog(self, _("The alpha channel contains bleeding edge changes introduced to Socializer. A new alpha update is generated every time there are new changes in the project. Take into account that updates are generated automatically and may fail at any time due to errors in the build process. Use alpha channels when you are sure you want to try the latest changes and contribute with reports to fix bugs. Never use alpha channel updates for everyday use. Do you want to continue?"), _("Attention"), style=wx.ICON_QUESTION|wx.YES_NO).ShowModal()
|
return wx.MessageDialog(self, _("The alpha channel contains bleeding edge changes introduced to Socializer. A new alpha update is generated every time there are new changes in the project. Take into account that updates are generated automatically and may fail at any time due to errors in the build process. Use alpha channels when you are sure you want to try the latest changes and contribute with reports to fix bugs. Never use alpha channel updates for everyday use. Do you want to continue?"), _("Attention"), style=wx.ICON_QUESTION|wx.YES_NO).ShowModal()
|
||||||
|
|
||||||
def weekly_channel(self):
|
def weekly_channel(self):
|
||||||
return wx.MessageDialog(self, _("The weekly channel generates an update automatically every week by building the source code present in the project. This version is used to test features added to the next stable version. Do you want to continue?"), _("Attention"), style=wx.ICON_QUESTION|wx.YES_NO).ShowModal()
|
return wx.MessageDialog(self, _("The weekly channel generates an update automatically every week by building the source code present in the project. This version is used to test features added to the next stable version. Do you want to continue?"), _("Attention"), style=wx.ICON_QUESTION|wx.YES_NO).ShowModal()
|
||||||
|
@ -4,168 +4,167 @@ import wx
|
|||||||
import widgetUtils
|
import widgetUtils
|
||||||
|
|
||||||
class createTextMessage(widgetUtils.BaseDialog):
|
class createTextMessage(widgetUtils.BaseDialog):
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
super(createTextMessage, self).__init__(parent=None, *args, **kwargs)
|
super(createTextMessage, self).__init__(parent=None, *args, **kwargs)
|
||||||
|
|
||||||
def createTextArea(self, message="", text=""):
|
def createTextArea(self, message="", text=""):
|
||||||
self.panel = wx.Panel(self)
|
self.panel = wx.Panel(self)
|
||||||
self.label = wx.StaticText(self.panel, -1, message)
|
self.label = wx.StaticText(self.panel, -1, message)
|
||||||
self.text = wx.TextCtrl(self.panel, -1, text, size=(439, -1), style=wx.TE_MULTILINE)
|
self.text = wx.TextCtrl(self.panel, -1, text, size=(439, -1), style=wx.TE_MULTILINE)
|
||||||
self.text.SetFocus()
|
self.text.SetFocus()
|
||||||
self.textBox = wx.BoxSizer(wx.HORIZONTAL)
|
self.textBox = wx.BoxSizer(wx.HORIZONTAL)
|
||||||
self.textBox.Add(self.label, 0, wx.ALL, 5)
|
self.textBox.Add(self.label, 0, wx.ALL, 5)
|
||||||
self.textBox.Add(self.text, 0, wx.ALL, 5)
|
self.textBox.Add(self.text, 0, wx.ALL, 5)
|
||||||
|
|
||||||
def create_privacy_box(self):
|
def create_privacy_box(self):
|
||||||
lbl = wx.StaticText(self.panel, wx.NewId(), _("&Privacy"))
|
lbl = wx.StaticText(self.panel, wx.NewId(), _("&Privacy"))
|
||||||
self.privacy = wx.ComboBox(self.panel, wx.NewId(), choices=[_("All users"), _("Friends of friends"),], value=_("All users"), style=wx.CB_READONLY)
|
self.privacy = wx.ComboBox(self.panel, wx.NewId(), choices=[_("All users"), _("Friends of friends"),], value=_("All users"), style=wx.CB_READONLY)
|
||||||
self.privacyBox = wx.BoxSizer(wx.HORIZONTAL)
|
self.privacyBox = wx.BoxSizer(wx.HORIZONTAL)
|
||||||
self.privacyBox.Add(lbl, 0, wx.ALL, 5)
|
self.privacyBox.Add(lbl, 0, wx.ALL, 5)
|
||||||
self.privacyBox.Add(self.privacy, 0, wx.ALL, 5)
|
self.privacyBox.Add(self.privacy, 0, wx.ALL, 5)
|
||||||
|
|
||||||
def text_focus(self):
|
def text_focus(self):
|
||||||
self.text.SetFocus()
|
self.text.SetFocus()
|
||||||
|
|
||||||
def get_text(self):
|
def get_text(self):
|
||||||
return self.text.GetValue()
|
return self.text.GetValue()
|
||||||
|
|
||||||
def set_text(self, text):
|
def set_text(self, text):
|
||||||
return self.text.ChangeValue(text)
|
return self.text.ChangeValue(text)
|
||||||
|
|
||||||
def enable_button(self, buttonName):
|
def enable_button(self, buttonName):
|
||||||
if getattr(self, buttonName):
|
if getattr(self, buttonName):
|
||||||
return getattr(self, buttonName).Enable()
|
return getattr(self, buttonName).Enable()
|
||||||
|
|
||||||
def disable_button(self, buttonName):
|
def disable_button(self, buttonName):
|
||||||
if getattr(self, buttonName):
|
if getattr(self, buttonName):
|
||||||
return getattr(self, buttonName).Disable()
|
return getattr(self, buttonName).Disable()
|
||||||
|
|
||||||
def onSelect(self, ev):
|
def onSelect(self, ev):
|
||||||
self.text.SelectAll()
|
self.text.SelectAll()
|
||||||
|
|
||||||
def set_cursor_at_end(self):
|
def set_cursor_at_end(self):
|
||||||
self.text.SetInsertionPoint(len(self.text.GetValue()))
|
self.text.SetInsertionPoint(len(self.text.GetValue()))
|
||||||
|
|
||||||
def set_cursor_at_position(self, position):
|
def set_cursor_at_position(self, position):
|
||||||
self.text.SetInsertionPoint(position)
|
self.text.SetInsertionPoint(position)
|
||||||
|
|
||||||
def get_position(self):
|
def get_position(self):
|
||||||
return self.text.GetInsertionPoint()
|
return self.text.GetInsertionPoint()
|
||||||
|
|
||||||
class createPostDialog(createTextMessage):
|
class createPostDialog(createTextMessage):
|
||||||
def createControls(self, title, message, text, mode):
|
def createControls(self, title, message, text, mode):
|
||||||
self.mainBox = wx.BoxSizer(wx.VERTICAL)
|
self.mainBox = wx.BoxSizer(wx.VERTICAL)
|
||||||
self.createTextArea(message, text)
|
self.createTextArea(message, text)
|
||||||
self.mainBox.Add(self.textBox, 0, wx.ALL, 5)
|
self.mainBox.Add(self.textBox, 0, wx.ALL, 5)
|
||||||
if mode == "post":
|
if mode == "post":
|
||||||
self.create_privacy_box()
|
self.create_privacy_box()
|
||||||
self.mainBox.Add(self.privacyBox, 0, wx.ALL, 5)
|
self.mainBox.Add(self.privacyBox, 0, wx.ALL, 5)
|
||||||
self.attach = wx.Button(self.panel, -1, _("Attach"), size=wx.DefaultSize)
|
self.attach = wx.Button(self.panel, -1, _("Attach"), size=wx.DefaultSize)
|
||||||
self.mention = wx.Button(self.panel, wx.NewId(), _("Tag a friend"))
|
self.mention = wx.Button(self.panel, wx.NewId(), _("Tag a friend"))
|
||||||
self.spellcheck = wx.Button(self.panel, -1, _("Spelling &correction"), size=wx.DefaultSize)
|
self.spellcheck = wx.Button(self.panel, -1, _("Spelling &correction"), size=wx.DefaultSize)
|
||||||
self.translateButton = wx.Button(self.panel, -1, _("&Translate message"), size=wx.DefaultSize)
|
self.translateButton = wx.Button(self.panel, -1, _("&Translate message"), size=wx.DefaultSize)
|
||||||
self.okButton = wx.Button(self.panel, wx.ID_OK, _("Send"), size=wx.DefaultSize)
|
self.okButton = wx.Button(self.panel, wx.ID_OK, _("Send"), size=wx.DefaultSize)
|
||||||
self.okButton.SetDefault()
|
self.okButton.SetDefault()
|
||||||
cancelButton = wx.Button(self.panel, wx.ID_CANCEL, _("Close"), size=wx.DefaultSize)
|
cancelButton = wx.Button(self.panel, wx.ID_CANCEL, _("Close"), size=wx.DefaultSize)
|
||||||
self.buttonsBox1 = wx.BoxSizer(wx.HORIZONTAL)
|
self.buttonsBox1 = wx.BoxSizer(wx.HORIZONTAL)
|
||||||
self.buttonsBox1.Add(self.attach, 0, wx.ALL, 10)
|
self.buttonsBox1.Add(self.attach, 0, wx.ALL, 10)
|
||||||
self.buttonsBox1.Add(self.mention, 0, wx.ALL, 10)
|
self.buttonsBox1.Add(self.mention, 0, wx.ALL, 10)
|
||||||
self.buttonsBox1.Add(self.spellcheck, 0, wx.ALL, 10)
|
self.buttonsBox1.Add(self.spellcheck, 0, wx.ALL, 10)
|
||||||
self.buttonsBox1.Add(self.translateButton, 0, wx.ALL, 10)
|
self.buttonsBox1.Add(self.translateButton, 0, wx.ALL, 10)
|
||||||
self.mainBox.Add(self.buttonsBox1, 0, wx.ALL, 10)
|
self.mainBox.Add(self.buttonsBox1, 0, wx.ALL, 10)
|
||||||
self.ok_cancelSizer = wx.BoxSizer(wx.HORIZONTAL)
|
self.ok_cancelSizer = wx.BoxSizer(wx.HORIZONTAL)
|
||||||
self.ok_cancelSizer.Add(self.okButton, 0, wx.ALL, 10)
|
self.ok_cancelSizer.Add(self.okButton, 0, wx.ALL, 10)
|
||||||
self.ok_cancelSizer.Add(cancelButton, 0, wx.ALL, 10)
|
self.ok_cancelSizer.Add(cancelButton, 0, wx.ALL, 10)
|
||||||
self.mainBox.Add(self.ok_cancelSizer)
|
self.mainBox.Add(self.ok_cancelSizer)
|
||||||
selectId = wx.NewId()
|
selectId = wx.NewId()
|
||||||
self.Bind(wx.EVT_MENU, self.onSelect, id=selectId)
|
self.Bind(wx.EVT_MENU, self.onSelect, id=selectId)
|
||||||
self.accel_tbl = wx.AcceleratorTable([
|
self.accel_tbl = wx.AcceleratorTable([
|
||||||
(wx.ACCEL_CTRL, ord('A'), selectId),])
|
(wx.ACCEL_CTRL, ord('A'), selectId),])
|
||||||
self.SetAcceleratorTable(self.accel_tbl)
|
self.SetAcceleratorTable(self.accel_tbl)
|
||||||
self.panel.SetSizer(self.mainBox)
|
self.panel.SetSizer(self.mainBox)
|
||||||
self.SetTitle(title)
|
self.SetTitle(title)
|
||||||
|
|
||||||
def __init__(self, title, message, text, mode="post"):
|
def __init__(self, title, message, text, mode="post"):
|
||||||
super(createPostDialog, self).__init__()
|
super(createPostDialog, self).__init__()
|
||||||
self.createControls(title, message, text, mode)
|
self.createControls(title, message, text, mode)
|
||||||
self.SetClientSize(self.mainBox.CalcMin())
|
self.SetClientSize(self.mainBox.CalcMin())
|
||||||
|
|
||||||
class createCommentDialog(createTextMessage):
|
class createCommentDialog(createTextMessage):
|
||||||
def createControls(self, title, message, text, **kwargs):
|
def createControls(self, title, message, text, **kwargs):
|
||||||
self.mainBox = wx.BoxSizer(wx.VERTICAL)
|
self.mainBox = wx.BoxSizer(wx.VERTICAL)
|
||||||
self.createTextArea(message, text)
|
self.createTextArea(message, text)
|
||||||
self.mainBox.Add(self.textBox, 0, wx.ALL, 5)
|
self.mainBox.Add(self.textBox, 0, wx.ALL, 5)
|
||||||
self.spellcheck = wx.Button(self.panel, -1, _("Spelling correction"), size=wx.DefaultSize)
|
self.spellcheck = wx.Button(self.panel, -1, _("Spelling correction"), size=wx.DefaultSize)
|
||||||
self.mention = wx.Button(self.panel, wx.NewId(), _("Tag a friend"))
|
self.mention = wx.Button(self.panel, wx.NewId(), _("Tag a friend"))
|
||||||
self.translateButton = wx.Button(self.panel, -1, _("Translate message"), size=wx.DefaultSize)
|
self.translateButton = wx.Button(self.panel, -1, _("Translate message"), size=wx.DefaultSize)
|
||||||
self.okButton = wx.Button(self.panel, wx.ID_OK, _("Send"), size=wx.DefaultSize)
|
self.okButton = wx.Button(self.panel, wx.ID_OK, _("Send"), size=wx.DefaultSize)
|
||||||
self.okButton.SetDefault()
|
self.okButton.SetDefault()
|
||||||
cancelButton = wx.Button(self.panel, wx.ID_CANCEL, _("Close"), size=wx.DefaultSize)
|
cancelButton = wx.Button(self.panel, wx.ID_CANCEL, _("Close"), size=wx.DefaultSize)
|
||||||
self.buttonsBox1 = wx.BoxSizer(wx.HORIZONTAL)
|
self.buttonsBox1 = wx.BoxSizer(wx.HORIZONTAL)
|
||||||
self.buttonsBox1.Add(self.spellcheck, 0, wx.ALL, 10)
|
self.buttonsBox1.Add(self.spellcheck, 0, wx.ALL, 10)
|
||||||
self.buttonsBox1.Add(self.mention, 0, wx.ALL, 10)
|
self.buttonsBox1.Add(self.mention, 0, wx.ALL, 10)
|
||||||
self.buttonsBox1.Add(self.translateButton, 0, wx.ALL, 10)
|
self.buttonsBox1.Add(self.translateButton, 0, wx.ALL, 10)
|
||||||
self.mainBox.Add(self.buttonsBox1, 0, wx.ALL, 10)
|
self.mainBox.Add(self.buttonsBox1, 0, wx.ALL, 10)
|
||||||
self.ok_cancelSizer = wx.BoxSizer(wx.HORIZONTAL)
|
self.ok_cancelSizer = wx.BoxSizer(wx.HORIZONTAL)
|
||||||
self.ok_cancelSizer.Add(self.okButton, 0, wx.ALL, 10)
|
self.ok_cancelSizer.Add(self.okButton, 0, wx.ALL, 10)
|
||||||
self.ok_cancelSizer.Add(cancelButton, 0, wx.ALL, 10)
|
self.ok_cancelSizer.Add(cancelButton, 0, wx.ALL, 10)
|
||||||
self.mainBox.Add(self.ok_cancelSizer)
|
self.mainBox.Add(self.ok_cancelSizer)
|
||||||
selectId = wx.NewId()
|
selectId = wx.NewId()
|
||||||
self.Bind(wx.EVT_MENU, self.onSelect, id=selectId)
|
self.Bind(wx.EVT_MENU, self.onSelect, id=selectId)
|
||||||
self.accel_tbl = wx.AcceleratorTable([(wx.ACCEL_CTRL, ord('A'), selectId),])
|
self.accel_tbl = wx.AcceleratorTable([(wx.ACCEL_CTRL, ord('A'), selectId),])
|
||||||
self.SetAcceleratorTable(self.accel_tbl)
|
self.SetAcceleratorTable(self.accel_tbl)
|
||||||
self.panel.SetSizer(self.mainBox)
|
self.panel.SetSizer(self.mainBox)
|
||||||
self.SetTitle(title)
|
self.SetTitle(title)
|
||||||
|
|
||||||
def __init__(self, title, message, text, *args, **kwargs):
|
def __init__(self, title, message, text, *args, **kwargs):
|
||||||
super(createCommentDialog, self).__init__()
|
super(createCommentDialog, self).__init__()
|
||||||
self.createControls(message, title, text, **kwargs)
|
self.createControls(message, title, text, **kwargs)
|
||||||
self.SetClientSize(self.mainBox.CalcMin())
|
self.SetClientSize(self.mainBox.CalcMin())
|
||||||
self.SetTitle(title)
|
self.SetTitle(title)
|
||||||
|
|
||||||
class createTopicDialog(createCommentDialog):
|
class createTopicDialog(createCommentDialog):
|
||||||
def createTextArea(self, message="", text="", topic_title=""):
|
def createTextArea(self, message="", text="", topic_title=""):
|
||||||
self.panel = wx.Panel(self)
|
self.panel = wx.Panel(self)
|
||||||
label = wx.StaticText(self.panel, -1, _("Title"))
|
label = wx.StaticText(self.panel, -1, _("Title"))
|
||||||
self.title = wx.TextCtrl(self.panel, wx.NewId(), topic_title)
|
self.title = wx.TextCtrl(self.panel, wx.NewId(), topic_title)
|
||||||
label2 = wx.StaticText(self.panel, -1, _("Message"))
|
label2 = wx.StaticText(self.panel, -1, _("Message"))
|
||||||
self.text = wx.TextCtrl(self.panel, -1, text, size=(439, -1), style=wx.TE_MULTILINE)
|
self.text = wx.TextCtrl(self.panel, -1, text, size=(439, -1), style=wx.TE_MULTILINE)
|
||||||
self.title.SetFocus()
|
self.title.SetFocus()
|
||||||
self.textBox = wx.BoxSizer(wx.VERTICAL)
|
self.textBox = wx.BoxSizer(wx.VERTICAL)
|
||||||
titleb = wx.BoxSizer(wx.HORIZONTAL)
|
titleb = wx.BoxSizer(wx.HORIZONTAL)
|
||||||
titleb.Add(label, 0, wx.ALL, 5)
|
titleb.Add(label, 0, wx.ALL, 5)
|
||||||
titleb.Add(self.title, 0, wx.ALL, 5)
|
titleb.Add(self.title, 0, wx.ALL, 5)
|
||||||
self.textBox.Add(titleb, 0, wx.ALL, 5)
|
self.textBox.Add(titleb, 0, wx.ALL, 5)
|
||||||
textb = wx.BoxSizer(wx.HORIZONTAL)
|
textb = wx.BoxSizer(wx.HORIZONTAL)
|
||||||
textb.Add(label2, 0, wx.ALL, 5)
|
textb.Add(label2, 0, wx.ALL, 5)
|
||||||
textb.Add(self.text, 0, wx.ALL, 5)
|
textb.Add(self.text, 0, wx.ALL, 5)
|
||||||
self.textBox.Add(textb, 0, wx.ALL, 5)
|
self.textBox.Add(textb, 0, wx.ALL, 5)
|
||||||
|
|
||||||
def createControls(self, title, message, text, topic_title):
|
|
||||||
self.mainBox = wx.BoxSizer(wx.VERTICAL)
|
|
||||||
self.createTextArea(message, text, topic_title)
|
|
||||||
self.mainBox.Add(self.textBox, 0, wx.ALL, 5)
|
|
||||||
self.attach = wx.Button(self.panel, -1, _("Attach"), size=wx.DefaultSize)
|
|
||||||
self.mention = wx.Button(self.panel, wx.NewId(), _("Tag a friend"))
|
|
||||||
self.spellcheck = wx.Button(self.panel, -1, _("Spelling &correction"), size=wx.DefaultSize)
|
|
||||||
self.translateButton = wx.Button(self.panel, -1, _("&Translate message"), size=wx.DefaultSize)
|
|
||||||
self.okButton = wx.Button(self.panel, wx.ID_OK, _("Send"), size=wx.DefaultSize)
|
|
||||||
self.okButton.SetDefault()
|
|
||||||
cancelButton = wx.Button(self.panel, wx.ID_CANCEL, _("Close"), size=wx.DefaultSize)
|
|
||||||
self.buttonsBox1 = wx.BoxSizer(wx.HORIZONTAL)
|
|
||||||
self.buttonsBox1.Add(self.attach, 0, wx.ALL, 10)
|
|
||||||
self.buttonsBox1.Add(self.mention, 0, wx.ALL, 10)
|
|
||||||
self.buttonsBox1.Add(self.spellcheck, 0, wx.ALL, 10)
|
|
||||||
self.buttonsBox1.Add(self.translateButton, 0, wx.ALL, 10)
|
|
||||||
self.mainBox.Add(self.buttonsBox1, 0, wx.ALL, 10)
|
|
||||||
self.ok_cancelSizer = wx.BoxSizer(wx.HORIZONTAL)
|
|
||||||
self.ok_cancelSizer.Add(self.okButton, 0, wx.ALL, 10)
|
|
||||||
self.ok_cancelSizer.Add(cancelButton, 0, wx.ALL, 10)
|
|
||||||
self.mainBox.Add(self.ok_cancelSizer)
|
|
||||||
selectId = wx.NewId()
|
|
||||||
self.Bind(wx.EVT_MENU, self.onSelect, id=selectId)
|
|
||||||
self.accel_tbl = wx.AcceleratorTable([
|
|
||||||
(wx.ACCEL_CTRL, ord('A'), selectId),])
|
|
||||||
self.SetAcceleratorTable(self.accel_tbl)
|
|
||||||
self.panel.SetSizer(self.mainBox)
|
|
||||||
|
|
||||||
|
def createControls(self, title, message, text, topic_title):
|
||||||
|
self.mainBox = wx.BoxSizer(wx.VERTICAL)
|
||||||
|
self.createTextArea(message, text, topic_title)
|
||||||
|
self.mainBox.Add(self.textBox, 0, wx.ALL, 5)
|
||||||
|
self.attach = wx.Button(self.panel, -1, _("Attach"), size=wx.DefaultSize)
|
||||||
|
self.mention = wx.Button(self.panel, wx.NewId(), _("Tag a friend"))
|
||||||
|
self.spellcheck = wx.Button(self.panel, -1, _("Spelling &correction"), size=wx.DefaultSize)
|
||||||
|
self.translateButton = wx.Button(self.panel, -1, _("&Translate message"), size=wx.DefaultSize)
|
||||||
|
self.okButton = wx.Button(self.panel, wx.ID_OK, _("Send"), size=wx.DefaultSize)
|
||||||
|
self.okButton.SetDefault()
|
||||||
|
cancelButton = wx.Button(self.panel, wx.ID_CANCEL, _("Close"), size=wx.DefaultSize)
|
||||||
|
self.buttonsBox1 = wx.BoxSizer(wx.HORIZONTAL)
|
||||||
|
self.buttonsBox1.Add(self.attach, 0, wx.ALL, 10)
|
||||||
|
self.buttonsBox1.Add(self.mention, 0, wx.ALL, 10)
|
||||||
|
self.buttonsBox1.Add(self.spellcheck, 0, wx.ALL, 10)
|
||||||
|
self.buttonsBox1.Add(self.translateButton, 0, wx.ALL, 10)
|
||||||
|
self.mainBox.Add(self.buttonsBox1, 0, wx.ALL, 10)
|
||||||
|
self.ok_cancelSizer = wx.BoxSizer(wx.HORIZONTAL)
|
||||||
|
self.ok_cancelSizer.Add(self.okButton, 0, wx.ALL, 10)
|
||||||
|
self.ok_cancelSizer.Add(cancelButton, 0, wx.ALL, 10)
|
||||||
|
self.mainBox.Add(self.ok_cancelSizer)
|
||||||
|
selectId = wx.NewId()
|
||||||
|
self.Bind(wx.EVT_MENU, self.onSelect, id=selectId)
|
||||||
|
self.accel_tbl = wx.AcceleratorTable([
|
||||||
|
(wx.ACCEL_CTRL, ord('A'), selectId),])
|
||||||
|
self.SetAcceleratorTable(self.accel_tbl)
|
||||||
|
self.panel.SetSizer(self.mainBox)
|
||||||
|
@ -3,420 +3,419 @@ import wx
|
|||||||
import widgetUtils
|
import widgetUtils
|
||||||
|
|
||||||
class displayBasicPost(widgetUtils.BaseDialog):
|
class displayBasicPost(widgetUtils.BaseDialog):
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
super(displayBasicPost, self).__init__(parent=None, *args, **kwargs)
|
super(displayBasicPost, self).__init__(parent=None, *args, **kwargs)
|
||||||
self.panel = wx.Panel(self, -1)
|
self.panel = wx.Panel(self, -1)
|
||||||
self.sizer = wx.BoxSizer(wx.VERTICAL)
|
self.sizer = wx.BoxSizer(wx.VERTICAL)
|
||||||
|
|
||||||
def done(self):
|
def done(self):
|
||||||
self.panel.SetSizer(self.sizer)
|
self.panel.SetSizer(self.sizer)
|
||||||
self.SetClientSize(self.sizer.CalcMin())
|
self.SetClientSize(self.sizer.CalcMin())
|
||||||
|
|
||||||
def create_post_view(self, label=_("Message")):
|
def create_post_view(self, label=_("Message")):
|
||||||
lbl = wx.StaticText(self.panel, -1, label)
|
lbl = wx.StaticText(self.panel, -1, label)
|
||||||
self.post_view = wx.TextCtrl(self.panel, -1, size=(730, -1), style=wx.TE_READONLY|wx.TE_MULTILINE)
|
self.post_view = wx.TextCtrl(self.panel, -1, size=(730, -1), style=wx.TE_READONLY|wx.TE_MULTILINE)
|
||||||
selectId = wx.NewId()
|
selectId = wx.NewId()
|
||||||
self.Bind(wx.EVT_MENU, self.onSelect, id=selectId)
|
self.Bind(wx.EVT_MENU, self.onSelect, id=selectId)
|
||||||
self.accel_tbl = wx.AcceleratorTable([
|
self.accel_tbl = wx.AcceleratorTable([
|
||||||
(wx.ACCEL_CTRL, ord('A'), selectId),])
|
(wx.ACCEL_CTRL, ord('A'), selectId),])
|
||||||
self.SetAcceleratorTable(self.accel_tbl)
|
self.SetAcceleratorTable(self.accel_tbl)
|
||||||
box = wx.BoxSizer(wx.HORIZONTAL)
|
box = wx.BoxSizer(wx.HORIZONTAL)
|
||||||
box.Add(lbl, 0, wx.ALL, 5)
|
box.Add(lbl, 0, wx.ALL, 5)
|
||||||
box.Add(self.post_view, 0, wx.ALL, 5)
|
box.Add(self.post_view, 0, wx.ALL, 5)
|
||||||
return box
|
return box
|
||||||
|
|
||||||
def onSelect(self, event):
|
def onSelect(self, event):
|
||||||
self.post_view.SelectAll()
|
self.post_view.SelectAll()
|
||||||
|
|
||||||
def create_views_control(self):
|
def create_views_control(self):
|
||||||
lbl = wx.StaticText(self.panel, -1, _("Views"))
|
lbl = wx.StaticText(self.panel, -1, _("Views"))
|
||||||
self.views = wx.TextCtrl(self.panel, -1, style=wx.TE_READONLY|wx.TE_MULTILINE)
|
self.views = wx.TextCtrl(self.panel, -1, style=wx.TE_READONLY|wx.TE_MULTILINE)
|
||||||
box = wx.BoxSizer(wx.HORIZONTAL)
|
box = wx.BoxSizer(wx.HORIZONTAL)
|
||||||
box.Add(lbl, 0, wx.ALL, 5)
|
box.Add(lbl, 0, wx.ALL, 5)
|
||||||
box.Add(self.views, 0, wx.ALL, 5)
|
box.Add(self.views, 0, wx.ALL, 5)
|
||||||
return box
|
return box
|
||||||
|
|
||||||
|
|
||||||
def create_comments_list(self):
|
def create_comments_list(self):
|
||||||
lbl = wx.StaticText(self.panel, -1, _("Comments"))
|
lbl = wx.StaticText(self.panel, -1, _("Comments"))
|
||||||
self.comments = widgetUtils.list(self.panel, _("User"), _("Comment"), _("Date"), _("Likes"), style=wx.LC_REPORT)
|
self.comments = widgetUtils.list(self.panel, _("User"), _("Comment"), _("Date"), _("Likes"), style=wx.LC_REPORT)
|
||||||
self.reply = wx.Button(self.panel, -1, _("Reply to comment"))
|
self.reply = wx.Button(self.panel, -1, _("Reply to comment"))
|
||||||
self.reply.Enable(False)
|
self.reply.Enable(False)
|
||||||
box = wx.BoxSizer(wx.HORIZONTAL)
|
box = wx.BoxSizer(wx.HORIZONTAL)
|
||||||
box.Add(lbl, 0, wx.ALL, 5)
|
box.Add(lbl, 0, wx.ALL, 5)
|
||||||
box.Add(self.comments.list, 0, wx.ALL, 5)
|
box.Add(self.comments.list, 0, wx.ALL, 5)
|
||||||
box.Add(self.reply, 0, wx.ALL, 5)
|
box.Add(self.reply, 0, wx.ALL, 5)
|
||||||
return box
|
return box
|
||||||
|
|
||||||
def create_attachments(self):
|
def create_attachments(self):
|
||||||
lbl = wx.StaticText(self.panel, -1, _("Attachments"))
|
lbl = wx.StaticText(self.panel, -1, _("Attachments"))
|
||||||
self.attachments = widgetUtils.list(self.panel, _("Type"), _("Title"), style=wx.LC_REPORT)
|
self.attachments = widgetUtils.list(self.panel, _("Type"), _("Title"), style=wx.LC_REPORT)
|
||||||
box = wx.BoxSizer(wx.HORIZONTAL)
|
box = wx.BoxSizer(wx.HORIZONTAL)
|
||||||
box.Add(lbl, 0, wx.ALL, 5)
|
box.Add(lbl, 0, wx.ALL, 5)
|
||||||
box.Add(self.attachments.list, 0, wx.ALL, 5)
|
box.Add(self.attachments.list, 0, wx.ALL, 5)
|
||||||
return box
|
return box
|
||||||
|
|
||||||
def create_photo_viewer(self):
|
def create_photo_viewer(self):
|
||||||
self.image = wx.StaticBitmap(self.panel, bitmap=wx.Bitmap(1280, 860), size=(604, 604))
|
self.image = wx.StaticBitmap(self.panel, bitmap=wx.Bitmap(1280, 860), size=(604, 604))
|
||||||
self.sizer.Add(self.image, 1, wx.ALL, 10)
|
self.sizer.Add(self.image, 1, wx.ALL, 10)
|
||||||
self.previous_photo = wx.Button(self.panel, wx.NewId(), _("Previous photo"))
|
self.previous_photo = wx.Button(self.panel, wx.NewId(), _("Previous photo"))
|
||||||
self.view_photo = wx.Button(self.panel, wx.NewId(), _("View in full screen"))
|
self.view_photo = wx.Button(self.panel, wx.NewId(), _("View in full screen"))
|
||||||
self.next_photo = wx.Button(self.panel, wx.NewId(), _("Next photo"))
|
self.next_photo = wx.Button(self.panel, wx.NewId(), _("Next photo"))
|
||||||
actionsS = wx.BoxSizer(wx.HORIZONTAL)
|
actionsS = wx.BoxSizer(wx.HORIZONTAL)
|
||||||
actionsS.Add(self.previous_photo, 0, wx.ALL, 5)
|
actionsS.Add(self.previous_photo, 0, wx.ALL, 5)
|
||||||
actionsS.Add(self.view_photo, 0, wx.ALL, 5)
|
actionsS.Add(self.view_photo, 0, wx.ALL, 5)
|
||||||
actionsS.Add(self.next_photo, wx.ALL, 5)
|
actionsS.Add(self.next_photo, wx.ALL, 5)
|
||||||
self.previous_photo.Enable(False)
|
self.previous_photo.Enable(False)
|
||||||
self.view_photo.Enable(False)
|
self.view_photo.Enable(False)
|
||||||
self.next_photo.Enable(False)
|
self.next_photo.Enable(False)
|
||||||
self.sizer.Add(actionsS, 0, wx.ALL, 5)
|
self.sizer.Add(actionsS, 0, wx.ALL, 5)
|
||||||
|
|
||||||
def enable_photo_controls(self, navigation=True):
|
def enable_photo_controls(self, navigation=True):
|
||||||
self.view_photo.Enable(True)
|
self.view_photo.Enable(True)
|
||||||
if navigation:
|
if navigation:
|
||||||
self.previous_photo.Enable(True)
|
self.previous_photo.Enable(True)
|
||||||
self.next_photo.Enable(True)
|
self.next_photo.Enable(True)
|
||||||
|
|
||||||
def create_likes_box(self):
|
def create_likes_box(self):
|
||||||
self.likes = wx.Button(self.panel, -1, _("Loading data..."))
|
self.likes = wx.Button(self.panel, -1, _("Loading data..."))
|
||||||
return self.likes
|
return self.likes
|
||||||
|
|
||||||
def create_shares_box(self):
|
def create_shares_box(self):
|
||||||
self.shares = wx.Button(self.panel, -1, _("Loading data..."))
|
self.shares = wx.Button(self.panel, -1, _("Loading data..."))
|
||||||
return self.shares
|
return self.shares
|
||||||
|
|
||||||
def create_action_buttons(self, comment=True):
|
def create_action_buttons(self, comment=True):
|
||||||
self.like = wx.Button(self.panel, -1, _("&Like"))
|
self.like = wx.Button(self.panel, -1, _("&Like"))
|
||||||
self.repost = wx.Button(self.panel, -1, _("Repost"))
|
self.repost = wx.Button(self.panel, -1, _("Repost"))
|
||||||
if comment: self.comment = wx.Button(self.panel, -1, _("Add comment"))
|
if comment: self.comment = wx.Button(self.panel, -1, _("Add comment"))
|
||||||
box = wx.BoxSizer(wx.HORIZONTAL)
|
box = wx.BoxSizer(wx.HORIZONTAL)
|
||||||
box.Add(self.like, 0, wx.ALL, 5)
|
box.Add(self.like, 0, wx.ALL, 5)
|
||||||
box.Add(self.repost, 0, wx.ALL, 5)
|
box.Add(self.repost, 0, wx.ALL, 5)
|
||||||
if comment: box.Add(self.comment, 0, wx.ALL, 5)
|
if comment: box.Add(self.comment, 0, wx.ALL, 5)
|
||||||
return box
|
return box
|
||||||
|
|
||||||
def create_tools_button(self):
|
def create_tools_button(self):
|
||||||
self.tools = wx.Button(self.panel, -1, _("Actions"))
|
self.tools = wx.Button(self.panel, -1, _("Actions"))
|
||||||
|
|
||||||
def create_dialog_buttons(self):
|
def create_dialog_buttons(self):
|
||||||
self.close = wx.Button(self.panel, wx.ID_CANCEL, _("Close"))
|
self.close = wx.Button(self.panel, wx.ID_CANCEL, _("Close"))
|
||||||
return self.close
|
return self.close
|
||||||
|
|
||||||
def set_post(self, text):
|
def set_post(self, text):
|
||||||
if hasattr(self, "post_view"):
|
if hasattr(self, "post_view"):
|
||||||
self.post_view.ChangeValue(text)
|
self.post_view.ChangeValue(text)
|
||||||
else:
|
else:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def insert_comments(self, comments):
|
def insert_comments(self, comments):
|
||||||
for i in comments:
|
for i in comments:
|
||||||
self.comments.insert_item(False, *i)
|
self.comments.insert_item(False, *i)
|
||||||
|
|
||||||
def insert_attachments(self, attachments):
|
def insert_attachments(self, attachments):
|
||||||
for i in attachments:
|
for i in attachments:
|
||||||
self.attachments.insert_item(False, *i)
|
self.attachments.insert_item(False, *i)
|
||||||
|
|
||||||
def set_likes(self, likes):
|
def set_likes(self, likes):
|
||||||
if hasattr(self, "likes"):
|
if hasattr(self, "likes"):
|
||||||
self.likes.SetLabel(_("{0} people like this").format(likes,))
|
self.likes.SetLabel(_("{0} people like this").format(likes,))
|
||||||
else:
|
else:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def set_shares(self, shares):
|
def set_shares(self, shares):
|
||||||
if hasattr(self, "shares"):
|
if hasattr(self, "shares"):
|
||||||
self.shares.SetLabel(_("Shared {0} times").format(shares,))
|
self.shares.SetLabel(_("Shared {0} times").format(shares,))
|
||||||
else:
|
else:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
class displayPost(displayBasicPost):
|
class displayPost(displayBasicPost):
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
super(displayPost, self).__init__(*args, **kwargs)
|
super(displayPost, self).__init__(*args, **kwargs)
|
||||||
post_view_box = self.create_post_view()
|
post_view_box = self.create_post_view()
|
||||||
self.sizer.Add(post_view_box, 0, wx.ALL, 5)
|
self.sizer.Add(post_view_box, 0, wx.ALL, 5)
|
||||||
views_box = self.create_views_control()
|
views_box = self.create_views_control()
|
||||||
self.sizer.Add(views_box, 0, wx.ALL, 5)
|
self.sizer.Add(views_box, 0, wx.ALL, 5)
|
||||||
attachments_box = self.create_attachments()
|
attachments_box = self.create_attachments()
|
||||||
self.sizer.Add(attachments_box, 0, wx.ALL, 5)
|
self.sizer.Add(attachments_box, 0, wx.ALL, 5)
|
||||||
self.attachments.list.Enable(False)
|
self.attachments.list.Enable(False)
|
||||||
self.create_photo_viewer()
|
self.create_photo_viewer()
|
||||||
self.image.Enable(False)
|
self.image.Enable(False)
|
||||||
self.create_tools_button()
|
self.create_tools_button()
|
||||||
self.sizer.Add(self.tools, 0, wx.ALL, 5)
|
self.sizer.Add(self.tools, 0, wx.ALL, 5)
|
||||||
likes_box = self.create_likes_box()
|
likes_box = self.create_likes_box()
|
||||||
self.sizer.Add(likes_box, 0, wx.ALL, 5)
|
self.sizer.Add(likes_box, 0, wx.ALL, 5)
|
||||||
shares_box = self.create_shares_box()
|
shares_box = self.create_shares_box()
|
||||||
self.sizer.Add(shares_box, 0, wx.ALL, 5)
|
self.sizer.Add(shares_box, 0, wx.ALL, 5)
|
||||||
actions_box = self.create_action_buttons()
|
actions_box = self.create_action_buttons()
|
||||||
self.sizer.Add(actions_box, 0, wx.ALL, 5)
|
self.sizer.Add(actions_box, 0, wx.ALL, 5)
|
||||||
comments_box = self.create_comments_list()
|
comments_box = self.create_comments_list()
|
||||||
self.sizer.Add(comments_box, 0, wx.ALL, 5)
|
self.sizer.Add(comments_box, 0, wx.ALL, 5)
|
||||||
self.sizer.Add(self.create_dialog_buttons())
|
self.sizer.Add(self.create_dialog_buttons())
|
||||||
self.done()
|
self.done()
|
||||||
|
|
||||||
class displayComment(displayBasicPost):
|
class displayComment(displayBasicPost):
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
super(displayComment, self).__init__(*args, **kwargs)
|
super(displayComment, self).__init__(*args, **kwargs)
|
||||||
post_view_box = self.create_post_view()
|
post_view_box = self.create_post_view()
|
||||||
self.sizer.Add(post_view_box, 0, wx.ALL, 5)
|
self.sizer.Add(post_view_box, 0, wx.ALL, 5)
|
||||||
attachments_box = self.create_attachments()
|
attachments_box = self.create_attachments()
|
||||||
self.sizer.Add(attachments_box, 0, wx.ALL, 5)
|
self.sizer.Add(attachments_box, 0, wx.ALL, 5)
|
||||||
self.attachments.list.Enable(False)
|
self.attachments.list.Enable(False)
|
||||||
self.create_photo_viewer()
|
self.create_photo_viewer()
|
||||||
self.image.Enable(False)
|
self.image.Enable(False)
|
||||||
self.create_tools_button()
|
self.create_tools_button()
|
||||||
self.sizer.Add(self.tools, 0, wx.ALL, 5)
|
self.sizer.Add(self.tools, 0, wx.ALL, 5)
|
||||||
likes_box = self.create_likes_box()
|
likes_box = self.create_likes_box()
|
||||||
self.sizer.Add(likes_box, 0, wx.ALL, 5)
|
self.sizer.Add(likes_box, 0, wx.ALL, 5)
|
||||||
actions_box = self.create_action_buttons()
|
actions_box = self.create_action_buttons()
|
||||||
self.sizer.Add(actions_box, 0, wx.ALL, 5)
|
self.sizer.Add(actions_box, 0, wx.ALL, 5)
|
||||||
self.sizer.Add(self.create_dialog_buttons())
|
self.sizer.Add(self.create_dialog_buttons())
|
||||||
self.done()
|
self.done()
|
||||||
|
|
||||||
def create_action_buttons(self, comment=True):
|
def create_action_buttons(self, comment=True):
|
||||||
self.like = wx.Button(self.panel, -1, _("&Like"))
|
self.like = wx.Button(self.panel, -1, _("&Like"))
|
||||||
self.reply = wx.Button(self.panel, -1, _("Reply"))
|
self.reply = wx.Button(self.panel, -1, _("Reply"))
|
||||||
if comment: self.comment = wx.Button(self.panel, -1, _("Add comment"))
|
if comment: self.comment = wx.Button(self.panel, -1, _("Add comment"))
|
||||||
box = wx.BoxSizer(wx.HORIZONTAL)
|
box = wx.BoxSizer(wx.HORIZONTAL)
|
||||||
box.Add(self.like, 0, wx.ALL, 5)
|
box.Add(self.like, 0, wx.ALL, 5)
|
||||||
box.Add(self.reply, 0, wx.ALL, 5)
|
box.Add(self.reply, 0, wx.ALL, 5)
|
||||||
if comment: box.Add(self.comment, 0, wx.ALL, 5)
|
if comment: box.Add(self.comment, 0, wx.ALL, 5)
|
||||||
return box
|
return box
|
||||||
|
|
||||||
class displayTopic(displayBasicPost):
|
class displayTopic(displayBasicPost):
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
super(displayTopic, self).__init__(*args, **kwargs)
|
super(displayTopic, self).__init__(*args, **kwargs)
|
||||||
comments_box = self.create_comments_list()
|
comments_box = self.create_comments_list()
|
||||||
self.sizer.Add(comments_box, 0, wx.ALL, 5)
|
self.sizer.Add(comments_box, 0, wx.ALL, 5)
|
||||||
attachments_box = self.create_attachments()
|
attachments_box = self.create_attachments()
|
||||||
self.sizer.Add(attachments_box, 0, wx.ALL, 5)
|
self.sizer.Add(attachments_box, 0, wx.ALL, 5)
|
||||||
self.attachments.list.Enable(False)
|
self.attachments.list.Enable(False)
|
||||||
self.create_photo_viewer()
|
self.create_photo_viewer()
|
||||||
self.image.Enable(False)
|
self.image.Enable(False)
|
||||||
self.create_tools_button()
|
self.create_tools_button()
|
||||||
self.sizer.Add(self.tools, 0, wx.ALL, 5)
|
self.sizer.Add(self.tools, 0, wx.ALL, 5)
|
||||||
actions_box = self.create_action_buttons()
|
actions_box = self.create_action_buttons()
|
||||||
self.sizer.Add(actions_box, 0, wx.ALL, 5)
|
self.sizer.Add(actions_box, 0, wx.ALL, 5)
|
||||||
self.sizer.Add(self.create_dialog_buttons())
|
self.sizer.Add(self.create_dialog_buttons())
|
||||||
self.done()
|
self.done()
|
||||||
|
|
||||||
def create_action_buttons(self, comment=True):
|
def create_action_buttons(self, comment=True):
|
||||||
self.like = wx.Button(self.panel, -1, _("&Like"))
|
self.like = wx.Button(self.panel, -1, _("&Like"))
|
||||||
if comment: self.comment = wx.Button(self.panel, -1, _("Add comment"))
|
if comment: self.comment = wx.Button(self.panel, -1, _("Add comment"))
|
||||||
box = wx.BoxSizer(wx.HORIZONTAL)
|
box = wx.BoxSizer(wx.HORIZONTAL)
|
||||||
box.Add(self.like, 0, wx.ALL, 5)
|
box.Add(self.like, 0, wx.ALL, 5)
|
||||||
if comment: box.Add(self.comment, 0, wx.ALL, 5)
|
if comment: box.Add(self.comment, 0, wx.ALL, 5)
|
||||||
return box
|
return box
|
||||||
|
|
||||||
def create_comments_list(self):
|
def create_comments_list(self):
|
||||||
lbl = wx.StaticText(self.panel, -1, _("Posts"))
|
lbl = wx.StaticText(self.panel, -1, _("Posts"))
|
||||||
self.comments = widgetUtils.list(self.panel, _("User"), _("Comment"), _("Date"), _("Likes"), style=wx.LC_REPORT)
|
self.comments = widgetUtils.list(self.panel, _("User"), _("Comment"), _("Date"), _("Likes"), style=wx.LC_REPORT)
|
||||||
self.load_more_comments = wx.Button(self.panel, wx.NewId(), _("Load previous comments"))
|
self.load_more_comments = wx.Button(self.panel, wx.NewId(), _("Load previous comments"))
|
||||||
self.reply = wx.Button(self.panel, -1, _("Reply"))
|
self.reply = wx.Button(self.panel, -1, _("Reply"))
|
||||||
box = wx.BoxSizer(wx.HORIZONTAL)
|
box = wx.BoxSizer(wx.HORIZONTAL)
|
||||||
box.Add(lbl, 0, wx.ALL, 5)
|
box.Add(lbl, 0, wx.ALL, 5)
|
||||||
box.Add(self.comments.list, 0, wx.ALL, 5)
|
box.Add(self.comments.list, 0, wx.ALL, 5)
|
||||||
box.Add(self.reply, 0, wx.ALL, 5)
|
box.Add(self.reply, 0, wx.ALL, 5)
|
||||||
return box
|
return box
|
||||||
|
|
||||||
class displayAudio(widgetUtils.BaseDialog):
|
class displayAudio(widgetUtils.BaseDialog):
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
super(displayAudio, self).__init__(parent=None, *args, **kwargs)
|
super(displayAudio, self).__init__(parent=None, *args, **kwargs)
|
||||||
panel = wx.Panel(self)
|
panel = wx.Panel(self)
|
||||||
sizer = wx.BoxSizer(wx.VERTICAL)
|
sizer = wx.BoxSizer(wx.VERTICAL)
|
||||||
lbl_list = wx.StaticText(panel, wx.NewId(), _("Audio &files"))
|
lbl_list = wx.StaticText(panel, wx.NewId(), _("Audio &files"))
|
||||||
self.list = wx.ListBox(panel, wx.NewId())
|
self.list = wx.ListBox(panel, wx.NewId())
|
||||||
listS = wx.BoxSizer(wx.HORIZONTAL)
|
listS = wx.BoxSizer(wx.HORIZONTAL)
|
||||||
listS.Add(lbl_list, 0, wx.ALL, 5)
|
listS.Add(lbl_list, 0, wx.ALL, 5)
|
||||||
listS.Add(self.list, 0, wx.ALL, 5)
|
listS.Add(self.list, 0, wx.ALL, 5)
|
||||||
sizer.Add(listS, 0, wx.ALL, 5)
|
sizer.Add(listS, 0, wx.ALL, 5)
|
||||||
lbl_title = wx.StaticText(panel, wx.NewId(), _("&Title"))
|
lbl_title = wx.StaticText(panel, wx.NewId(), _("&Title"))
|
||||||
self.title = wx.TextCtrl(panel, wx.NewId(), size=(413, -1), style=wx.TE_READONLY|wx.TE_MULTILINE)
|
self.title = wx.TextCtrl(panel, wx.NewId(), size=(413, -1), style=wx.TE_READONLY|wx.TE_MULTILINE)
|
||||||
titleBox = wx.BoxSizer(wx.HORIZONTAL)
|
titleBox = wx.BoxSizer(wx.HORIZONTAL)
|
||||||
titleBox.Add(lbl_title, 0, wx.ALL, 5)
|
titleBox.Add(lbl_title, 0, wx.ALL, 5)
|
||||||
titleBox.Add(self.title, 0, wx.ALL, 5)
|
titleBox.Add(self.title, 0, wx.ALL, 5)
|
||||||
sizer.Add(titleBox, 0, wx.ALL, 5)
|
sizer.Add(titleBox, 0, wx.ALL, 5)
|
||||||
lbl_artist = wx.StaticText(panel, wx.NewId(), _("&Artist"))
|
lbl_artist = wx.StaticText(panel, wx.NewId(), _("&Artist"))
|
||||||
self.artist = wx.TextCtrl(panel, wx.NewId(), size=(413, -1), style=wx.TE_READONLY|wx.TE_MULTILINE)
|
self.artist = wx.TextCtrl(panel, wx.NewId(), size=(413, -1), style=wx.TE_READONLY|wx.TE_MULTILINE)
|
||||||
artistBox = wx.BoxSizer(wx.HORIZONTAL)
|
artistBox = wx.BoxSizer(wx.HORIZONTAL)
|
||||||
artistBox.Add(lbl_artist, 0, wx.ALL, 5)
|
artistBox.Add(lbl_artist, 0, wx.ALL, 5)
|
||||||
artistBox.Add(self.artist, 0, wx.ALL, 5)
|
artistBox.Add(self.artist, 0, wx.ALL, 5)
|
||||||
sizer.Add(artistBox, 0, wx.ALL, 5)
|
sizer.Add(artistBox, 0, wx.ALL, 5)
|
||||||
lbl_duration = wx.StaticText(panel, wx.NewId(), _("&Duration"))
|
lbl_duration = wx.StaticText(panel, wx.NewId(), _("&Duration"))
|
||||||
self.duration = wx.TextCtrl(panel, wx.NewId(), size=(413, -1), style=wx.TE_READONLY|wx.TE_MULTILINE)
|
self.duration = wx.TextCtrl(panel, wx.NewId(), size=(413, -1), style=wx.TE_READONLY|wx.TE_MULTILINE)
|
||||||
durationBox = wx.BoxSizer(wx.HORIZONTAL)
|
durationBox = wx.BoxSizer(wx.HORIZONTAL)
|
||||||
durationBox.Add(lbl_duration, 0, wx.ALL, 5)
|
durationBox.Add(lbl_duration, 0, wx.ALL, 5)
|
||||||
durationBox.Add(self.duration, 0, wx.ALL, 5)
|
durationBox.Add(self.duration, 0, wx.ALL, 5)
|
||||||
sizer.Add(durationBox, 0, wx.ALL, 5)
|
sizer.Add(durationBox, 0, wx.ALL, 5)
|
||||||
lbl_lyrics = wx.StaticText(panel, wx.NewId(), _("&Lyric"))
|
lbl_lyrics = wx.StaticText(panel, wx.NewId(), _("&Lyric"))
|
||||||
self.lyric = wx.TextCtrl(panel, wx.NewId(), size=(500, 500), style=wx.TE_READONLY|wx.TE_MULTILINE)
|
self.lyric = wx.TextCtrl(panel, wx.NewId(), size=(500, 500), style=wx.TE_READONLY|wx.TE_MULTILINE)
|
||||||
lbox = wx.BoxSizer(wx.HORIZONTAL)
|
lbox = wx.BoxSizer(wx.HORIZONTAL)
|
||||||
lbox.Add(lbl_lyrics, 0, wx.ALL, 5)
|
lbox.Add(lbl_lyrics, 0, wx.ALL, 5)
|
||||||
lbox.Add(self.lyric, 0, wx.ALL, 5)
|
lbox.Add(self.lyric, 0, wx.ALL, 5)
|
||||||
sizer.Add(lbox, 0, wx.ALL, 5)
|
sizer.Add(lbox, 0, wx.ALL, 5)
|
||||||
self.play = wx.Button(panel, wx.NewId(), _("&Play"))
|
self.play = wx.Button(panel, wx.NewId(), _("&Play"))
|
||||||
self.download = wx.Button(panel, wx.NewId(), _("&Download"))
|
self.download = wx.Button(panel, wx.NewId(), _("&Download"))
|
||||||
self.add = wx.Button(panel, wx.NewId(), _("&Add to your library"))
|
self.add = wx.Button(panel, wx.NewId(), _("&Add to your library"))
|
||||||
self.remove = wx.Button(panel, wx.NewId(), _("&Remove from your library"))
|
self.remove = wx.Button(panel, wx.NewId(), _("&Remove from your library"))
|
||||||
self.add.Enable(False)
|
self.add.Enable(False)
|
||||||
self.remove.Enable(False)
|
self.remove.Enable(False)
|
||||||
close = wx.Button(panel, wx.ID_CANCEL)
|
close = wx.Button(panel, wx.ID_CANCEL)
|
||||||
bbox = wx.BoxSizer(wx.HORIZONTAL)
|
bbox = wx.BoxSizer(wx.HORIZONTAL)
|
||||||
bbox.Add(self.play, 0, wx.ALL, 5)
|
bbox.Add(self.play, 0, wx.ALL, 5)
|
||||||
bbox.Add(self.download, 0, wx.ALL, 5)
|
bbox.Add(self.download, 0, wx.ALL, 5)
|
||||||
bbox.Add(self.add, 0, wx.ALL, 5)
|
bbox.Add(self.add, 0, wx.ALL, 5)
|
||||||
bbox.Add(self.remove, 0, wx.ALL, 5)
|
bbox.Add(self.remove, 0, wx.ALL, 5)
|
||||||
bbox.Add(close, 0, wx.ALL, 5)
|
bbox.Add(close, 0, wx.ALL, 5)
|
||||||
|
|
||||||
def change_state(self, button_name, state):
|
def change_state(self, button_name, state):
|
||||||
getattr(self, button_name).Enable(state)
|
getattr(self, button_name).Enable(state)
|
||||||
|
|
||||||
def get_destination_path(self, filename):
|
def get_destination_path(self, filename):
|
||||||
saveFileDialog = wx.FileDialog(self, _("Save this file"), "", filename, _("Audio Files(*.mp3)|*.mp3"), wx.FD_SAVE | wx.FD_OVERWRITE_PROMPT)
|
saveFileDialog = wx.FileDialog(self, _("Save this file"), "", filename, _("Audio Files(*.mp3)|*.mp3"), wx.FD_SAVE | wx.FD_OVERWRITE_PROMPT)
|
||||||
if saveFileDialog.ShowModal() == wx.ID_OK:
|
if saveFileDialog.ShowModal() == wx.ID_OK:
|
||||||
return saveFileDialog.GetPath()
|
return saveFileDialog.GetPath()
|
||||||
saveFileDialog.Destroy()
|
saveFileDialog.Destroy()
|
||||||
|
|
||||||
def insert_audio(self, audio_):
|
def insert_audio(self, audio_):
|
||||||
self.list.Append(audio_)
|
self.list.Append(audio_)
|
||||||
|
|
||||||
def get_audio(self):
|
def get_audio(self):
|
||||||
return self.list.GetSelection()
|
return self.list.GetSelection()
|
||||||
|
|
||||||
class displayArticle(widgetUtils.BaseDialog):
|
class displayArticle(widgetUtils.BaseDialog):
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
super(displayArticle, self).__init__(parent=None, *args, **kwargs)
|
super(displayArticle, self).__init__(parent=None, *args, **kwargs)
|
||||||
self.panel = wx.Panel(self, -1)
|
self.panel = wx.Panel(self, -1)
|
||||||
self.sizer = wx.BoxSizer(wx.VERTICAL)
|
self.sizer = wx.BoxSizer(wx.VERTICAL)
|
||||||
article_view_box = self.create_article_view()
|
article_view_box = self.create_article_view()
|
||||||
self.sizer.Add(article_view_box, 0, wx.ALL, 5)
|
self.sizer.Add(article_view_box, 0, wx.ALL, 5)
|
||||||
views_box = self.create_views_control()
|
views_box = self.create_views_control()
|
||||||
self.sizer.Add(views_box, 0, wx.ALL, 5)
|
self.sizer.Add(views_box, 0, wx.ALL, 5)
|
||||||
attachments_box = self.create_attachments()
|
attachments_box = self.create_attachments()
|
||||||
self.sizer.Add(attachments_box, 0, wx.ALL, 5)
|
self.sizer.Add(attachments_box, 0, wx.ALL, 5)
|
||||||
self.attachments.list.Enable(False)
|
self.attachments.list.Enable(False)
|
||||||
self.create_tools_button()
|
self.create_tools_button()
|
||||||
self.sizer.Add(self.tools, 0, wx.ALL, 5)
|
self.sizer.Add(self.tools, 0, wx.ALL, 5)
|
||||||
self.sizer.Add(self.create_dialog_buttons())
|
self.sizer.Add(self.create_dialog_buttons())
|
||||||
self.done()
|
self.done()
|
||||||
|
|
||||||
def done(self):
|
def done(self):
|
||||||
self.panel.SetSizer(self.sizer)
|
self.panel.SetSizer(self.sizer)
|
||||||
self.SetClientSize(self.sizer.CalcMin())
|
self.SetClientSize(self.sizer.CalcMin())
|
||||||
|
|
||||||
def create_article_view(self, label=_("Article")):
|
def create_article_view(self, label=_("Article")):
|
||||||
lbl = wx.StaticText(self.panel, -1, label)
|
lbl = wx.StaticText(self.panel, -1, label)
|
||||||
self.article_view = wx.TextCtrl(self.panel, -1, size=(730, -1), style=wx.TE_READONLY|wx.TE_MULTILINE|wx.BORDER_SIMPLE)
|
self.article_view = wx.TextCtrl(self.panel, -1, size=(730, -1), style=wx.TE_READONLY|wx.TE_MULTILINE|wx.BORDER_SIMPLE)
|
||||||
selectId = wx.NewId()
|
selectId = wx.NewId()
|
||||||
self.Bind(wx.EVT_MENU, self.onSelect, id=selectId)
|
self.Bind(wx.EVT_MENU, self.onSelect, id=selectId)
|
||||||
self.accel_tbl = wx.AcceleratorTable([
|
self.accel_tbl = wx.AcceleratorTable([
|
||||||
(wx.ACCEL_CTRL, ord('A'), selectId),])
|
(wx.ACCEL_CTRL, ord('A'), selectId),])
|
||||||
self.SetAcceleratorTable(self.accel_tbl)
|
self.SetAcceleratorTable(self.accel_tbl)
|
||||||
box = wx.BoxSizer(wx.HORIZONTAL)
|
box = wx.BoxSizer(wx.HORIZONTAL)
|
||||||
box.Add(lbl, 0, wx.ALL, 5)
|
box.Add(lbl, 0, wx.ALL, 5)
|
||||||
box.Add(self.article_view, 0, wx.ALL, 5)
|
box.Add(self.article_view, 0, wx.ALL, 5)
|
||||||
return box
|
return box
|
||||||
|
|
||||||
def onSelect(self, event):
|
def onSelect(self, event):
|
||||||
self.article_view.SelectAll()
|
self.article_view.SelectAll()
|
||||||
|
|
||||||
def create_views_control(self):
|
def create_views_control(self):
|
||||||
lbl = wx.StaticText(self.panel, -1, _("Views"))
|
lbl = wx.StaticText(self.panel, -1, _("Views"))
|
||||||
self.views = wx.TextCtrl(self.panel, -1, style=wx.TE_READONLY|wx.TE_MULTILINE)
|
self.views = wx.TextCtrl(self.panel, -1, style=wx.TE_READONLY|wx.TE_MULTILINE)
|
||||||
box = wx.BoxSizer(wx.HORIZONTAL)
|
box = wx.BoxSizer(wx.HORIZONTAL)
|
||||||
box.Add(lbl, 0, wx.ALL, 5)
|
box.Add(lbl, 0, wx.ALL, 5)
|
||||||
box.Add(self.views, 0, wx.ALL, 5)
|
box.Add(self.views, 0, wx.ALL, 5)
|
||||||
return box
|
return box
|
||||||
|
|
||||||
def create_tools_button(self):
|
def create_tools_button(self):
|
||||||
self.tools = wx.Button(self.panel, -1, _("Actions"))
|
self.tools = wx.Button(self.panel, -1, _("Actions"))
|
||||||
|
|
||||||
def create_dialog_buttons(self):
|
def create_dialog_buttons(self):
|
||||||
self.close = wx.Button(self.panel, wx.ID_CANCEL, _("Close"))
|
self.close = wx.Button(self.panel, wx.ID_CANCEL, _("Close"))
|
||||||
return self.close
|
return self.close
|
||||||
|
|
||||||
def create_attachments(self):
|
def create_attachments(self):
|
||||||
lbl = wx.StaticText(self.panel, -1, _("Attachments"))
|
lbl = wx.StaticText(self.panel, -1, _("Attachments"))
|
||||||
self.attachments = widgetUtils.list(self.panel, _("Type"), _("Title"), style=wx.LC_REPORT)
|
self.attachments = widgetUtils.list(self.panel, _("Type"), _("Title"), style=wx.LC_REPORT)
|
||||||
box = wx.BoxSizer(wx.HORIZONTAL)
|
box = wx.BoxSizer(wx.HORIZONTAL)
|
||||||
box.Add(lbl, 0, wx.ALL, 5)
|
box.Add(lbl, 0, wx.ALL, 5)
|
||||||
box.Add(self.attachments.list, 0, wx.ALL, 5)
|
box.Add(self.attachments.list, 0, wx.ALL, 5)
|
||||||
return box
|
return box
|
||||||
|
|
||||||
def set_article(self, text):
|
def set_article(self, text):
|
||||||
if hasattr(self, "article_view"):
|
if hasattr(self, "article_view"):
|
||||||
self.article_view.ChangeValue(text)
|
self.article_view.ChangeValue(text)
|
||||||
else:
|
else:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def insert_attachments(self, attachments):
|
def insert_attachments(self, attachments):
|
||||||
for i in attachments:
|
for i in attachments:
|
||||||
self.attachments.insert_item(False, *i)
|
self.attachments.insert_item(False, *i)
|
||||||
|
|
||||||
class displayFriendship(widgetUtils.BaseDialog):
|
class displayFriendship(widgetUtils.BaseDialog):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super(displayFriendship, self).__init__(parent=None)
|
super(displayFriendship, self).__init__(parent=None)
|
||||||
panel = wx.Panel(self)
|
panel = wx.Panel(self)
|
||||||
sizer = wx.BoxSizer(wx.VERTICAL)
|
sizer = wx.BoxSizer(wx.VERTICAL)
|
||||||
self.friends = widgetUtils.list(panel, [_("Friend")], style=wx.LC_REPORT)
|
self.friends = widgetUtils.list(panel, [_("Friend")], style=wx.LC_REPORT)
|
||||||
sizer.Add(self.friends.list, 0, wx.ALL, 5)
|
sizer.Add(self.friends.list, 0, wx.ALL, 5)
|
||||||
close = wx.Button(panel, wx.ID_CANCEL)
|
close = wx.Button(panel, wx.ID_CANCEL)
|
||||||
btnbox = wx.BoxSizer(wx.HORIZONTAL)
|
btnbox = wx.BoxSizer(wx.HORIZONTAL)
|
||||||
btnbox.Add(close, 0, wx.ALL, 5)
|
btnbox.Add(close, 0, wx.ALL, 5)
|
||||||
sizer.Add(btnbox, 0, wx.ALL, 5)
|
sizer.Add(btnbox, 0, wx.ALL, 5)
|
||||||
panel.SetSizer(sizer)
|
panel.SetSizer(sizer)
|
||||||
self.SetClientSize(sizer.CalcMin())
|
self.SetClientSize(sizer.CalcMin())
|
||||||
|
|
||||||
class displayPoll(widgetUtils.BaseDialog):
|
class displayPoll(widgetUtils.BaseDialog):
|
||||||
|
|
||||||
def __init__(self, question="", *args, **kwargs):
|
def __init__(self, question="", *args, **kwargs):
|
||||||
super(displayPoll, self).__init__(parent=None, *args, **kwargs)
|
super(displayPoll, self).__init__(parent=None, *args, **kwargs)
|
||||||
self.panel = wx.Panel(self, -1)
|
self.panel = wx.Panel(self, -1)
|
||||||
self.sizer = wx.BoxSizer(wx.VERTICAL)
|
self.sizer = wx.BoxSizer(wx.VERTICAL)
|
||||||
label = wx.StaticText(self.panel, wx.NewId(), _("Question"))
|
label = wx.StaticText(self.panel, wx.NewId(), _("Question"))
|
||||||
self.question = wx.TextCtrl(self.panel, wx.NewId(), question, style=wx.TE_MULTILINE|wx.TE_READONLY, size=(730, -1))
|
self.question = wx.TextCtrl(self.panel, wx.NewId(), question, style=wx.TE_MULTILINE|wx.TE_READONLY, size=(730, -1))
|
||||||
self.sizer.Add(label, 0, wx.ALL, 5)
|
self.sizer.Add(label, 0, wx.ALL, 5)
|
||||||
self.sizer.Add(self.question, 0, wx.ALL, 5)
|
self.sizer.Add(self.question, 0, wx.ALL, 5)
|
||||||
|
|
||||||
def add_options(self, options, multiple=False):
|
def add_options(self, options, multiple=False):
|
||||||
if not isinstance(options[0], str):
|
if not isinstance(options[0], str):
|
||||||
return self.add_results(options)
|
return self.add_results(options)
|
||||||
self.options = []
|
self.options = []
|
||||||
sizer = wx.StaticBoxSizer(parent=self.panel, orient=wx.VERTICAL, label=_("Options"))
|
sizer = wx.StaticBoxSizer(parent=self.panel, orient=wx.VERTICAL, label=_("Options"))
|
||||||
for i in options:
|
for i in options:
|
||||||
if multiple == False:
|
if multiple == False:
|
||||||
if len(self.options) == 0:
|
if len(self.options) == 0:
|
||||||
control = wx.RadioButton(sizer.GetStaticBox(), wx.NewId(), i, style=wx.RB_GROUP)
|
control = wx.RadioButton(sizer.GetStaticBox(), wx.NewId(), i, style=wx.RB_GROUP)
|
||||||
else:
|
else:
|
||||||
control = wx.RadioButton(sizer.GetStaticBox(), wx.NewId(), i)
|
control = wx.RadioButton(sizer.GetStaticBox(), wx.NewId(), i)
|
||||||
else:
|
else:
|
||||||
control = wx.CheckBox(sizer.GetStaticBox(), wx.NewId(), i)
|
control = wx.CheckBox(sizer.GetStaticBox(), wx.NewId(), i)
|
||||||
self.options.append(control)
|
self.options.append(control)
|
||||||
sizer.Add(control, 0, wx.ALL, 5)
|
sizer.Add(control, 0, wx.ALL, 5)
|
||||||
self.sizer.Add(sizer, 0, wx.ALL, 5)
|
self.sizer.Add(sizer, 0, wx.ALL, 5)
|
||||||
|
|
||||||
def get_answers(self):
|
def get_answers(self):
|
||||||
answers = []
|
answers = []
|
||||||
for i in self.options:
|
for i in self.options:
|
||||||
answers.append(i.GetValue())
|
answers.append(i.GetValue())
|
||||||
return answers
|
return answers
|
||||||
|
|
||||||
def add_results(self, options):
|
def add_results(self, options):
|
||||||
sizer = wx.StaticBoxSizer(parent=self.panel, orient=wx.VERTICAL, label=_("Poll results"))
|
sizer = wx.StaticBoxSizer(parent=self.panel, orient=wx.VERTICAL, label=_("Poll results"))
|
||||||
for i in options:
|
for i in options:
|
||||||
sizer2 = wx.StaticBoxSizer(parent=sizer.GetStaticBox(), orient=wx.HORIZONTAL, label=i[0])
|
sizer2 = wx.StaticBoxSizer(parent=sizer.GetStaticBox(), orient=wx.HORIZONTAL, label=i[0])
|
||||||
staticcontrol = wx.StaticText(sizer2.GetStaticBox(), wx.NewId(), i[0])
|
staticcontrol = wx.StaticText(sizer2.GetStaticBox(), wx.NewId(), i[0])
|
||||||
control = wx.TextCtrl(sizer2.GetStaticBox(), wx.NewId(), _("{votes} ({rate}%)").format(votes=i[1], rate=i[2]), style=wx.TE_READONLY|wx.TE_MULTILINE)
|
control = wx.TextCtrl(sizer2.GetStaticBox(), wx.NewId(), _("{votes} ({rate}%)").format(votes=i[1], rate=i[2]), style=wx.TE_READONLY|wx.TE_MULTILINE)
|
||||||
sizer2.Add(staticcontrol, 0, wx.ALL, 5)
|
sizer2.Add(staticcontrol, 0, wx.ALL, 5)
|
||||||
sizer2.Add(control, 0, wx.ALL, 5)
|
sizer2.Add(control, 0, wx.ALL, 5)
|
||||||
sizer.Add(sizer2, 0, wx.ALL, 5)
|
sizer.Add(sizer2, 0, wx.ALL, 5)
|
||||||
self.sizer.Add(sizer, 0, wx.ALL, 5)
|
self.sizer.Add(sizer, 0, wx.ALL, 5)
|
||||||
|
|
||||||
def done(self):
|
|
||||||
self.ok = wx.Button(self.panel, wx.ID_OK, _("Vote"))
|
|
||||||
cancel = wx.Button(self.panel, wx.ID_CANCEL)
|
|
||||||
sizer = wx.BoxSizer(wx.HORIZONTAL)
|
|
||||||
sizer.Add(self.ok, 0, wx.ALL, 5)
|
|
||||||
sizer.Add(cancel, 0, wx.ALL, 5)
|
|
||||||
self.panel.SetSizer(self.sizer)
|
|
||||||
self.SetClientSize(self.sizer.CalcMin())
|
|
||||||
|
|
||||||
|
def done(self):
|
||||||
|
self.ok = wx.Button(self.panel, wx.ID_OK, _("Vote"))
|
||||||
|
cancel = wx.Button(self.panel, wx.ID_CANCEL)
|
||||||
|
sizer = wx.BoxSizer(wx.HORIZONTAL)
|
||||||
|
sizer.Add(self.ok, 0, wx.ALL, 5)
|
||||||
|
sizer.Add(cancel, 0, wx.ALL, 5)
|
||||||
|
self.panel.SetSizer(self.sizer)
|
||||||
|
self.SetClientSize(self.sizer.CalcMin())
|
||||||
|
@ -5,173 +5,173 @@ import wx
|
|||||||
import widgetUtils
|
import widgetUtils
|
||||||
|
|
||||||
def text_size(wxObject, chars):
|
def text_size(wxObject, chars):
|
||||||
""" Takes a wx object and the amount of characters supposed to hold and gives the best size for the control.
|
""" Takes a wx object and the amount of characters supposed to hold and gives the best size for the control.
|
||||||
wxObject wx.TextCtrl: Text control to be taken as a reference.
|
wxObject wx.TextCtrl: Text control to be taken as a reference.
|
||||||
chars int: Number of characters the control would hold.
|
chars int: Number of characters the control would hold.
|
||||||
returns (x, y)"""
|
returns (x, y)"""
|
||||||
dc = wx.WindowDC(wxObject)
|
dc = wx.WindowDC(wxObject)
|
||||||
dc.SetFont(wxObject.GetFont())
|
dc.SetFont(wxObject.GetFont())
|
||||||
(x, y) = dc.GetMultiLineTextExtent("0"*chars)
|
(x, y) = dc.GetMultiLineTextExtent("0"*chars)
|
||||||
return (x, -1)
|
return (x, -1)
|
||||||
|
|
||||||
class baseTab(wx.Panel):
|
class baseTab(wx.Panel):
|
||||||
""" Panel to store main user information in a profile viewer."""
|
""" Panel to store main user information in a profile viewer."""
|
||||||
|
|
||||||
def get(self, control):
|
def get(self, control):
|
||||||
if hasattr(self, control):
|
if hasattr(self, control):
|
||||||
control = getattr(self, control)
|
control = getattr(self, control)
|
||||||
if hasattr(control, "GetValue"): return getattr(control, "GetValue")()
|
if hasattr(control, "GetValue"): return getattr(control, "GetValue")()
|
||||||
elif hasattr(control, "GetLabel"): return getattr(control, "GetLabel")()
|
elif hasattr(control, "GetLabel"): return getattr(control, "GetLabel")()
|
||||||
else: return -1
|
else: return -1
|
||||||
else: return 0
|
else: return 0
|
||||||
|
|
||||||
def set(self, control, text):
|
def set(self, control, text):
|
||||||
if hasattr(self, control):
|
if hasattr(self, control):
|
||||||
control = getattr(self, control)
|
control = getattr(self, control)
|
||||||
if hasattr(control, "SetValue"): return getattr(control, "SetValue")(text)
|
if hasattr(control, "SetValue"): return getattr(control, "SetValue")(text)
|
||||||
elif hasattr(control, "SetLabel"): return getattr(control, "SetLabel")(text)
|
elif hasattr(control, "SetLabel"): return getattr(control, "SetLabel")(text)
|
||||||
elif hasattr(control, "ChangeValue"): return getattr(control, "ChangeValue")(text)
|
elif hasattr(control, "ChangeValue"): return getattr(control, "ChangeValue")(text)
|
||||||
else: return -1
|
else: return -1
|
||||||
else: return 0
|
else: return 0
|
||||||
|
|
||||||
def enable(self, control):
|
def enable(self, control):
|
||||||
getattr(self, control).Enable(True)
|
getattr(self, control).Enable(True)
|
||||||
|
|
||||||
def disable(self, control):
|
def disable(self, control):
|
||||||
getattr(self, control).Enable(False)
|
getattr(self, control).Enable(False)
|
||||||
|
|
||||||
class mainInfo(baseTab):
|
class mainInfo(baseTab):
|
||||||
|
|
||||||
def __init__(self, panel):
|
def __init__(self, panel):
|
||||||
super(mainInfo, self).__init__(panel)
|
super(mainInfo, self).__init__(panel)
|
||||||
sizer = wx.BoxSizer(wx.VERTICAL)
|
sizer = wx.BoxSizer(wx.VERTICAL)
|
||||||
lblName = wx.StaticText(self, wx.NewId(), _("Name"))
|
lblName = wx.StaticText(self, wx.NewId(), _("Name"))
|
||||||
self.name = wx.TextCtrl(self, wx.NewId(), style=wx.TE_READONLY|wx.TE_MULTILINE)
|
self.name = wx.TextCtrl(self, wx.NewId(), style=wx.TE_READONLY|wx.TE_MULTILINE)
|
||||||
self.name.SetMinSize(text_size(self.name, 60))
|
self.name.SetMinSize(text_size(self.name, 60))
|
||||||
sizerName = wx.BoxSizer(wx.HORIZONTAL)
|
sizerName = wx.BoxSizer(wx.HORIZONTAL)
|
||||||
sizerName.Add(lblName, 0, wx.ALL, 5)
|
sizerName.Add(lblName, 0, wx.ALL, 5)
|
||||||
sizerName.Add(self.name, 0, wx.ALL, 5)
|
sizerName.Add(self.name, 0, wx.ALL, 5)
|
||||||
sizer.Add(sizerName, 0, wx.ALL, 5)
|
sizer.Add(sizerName, 0, wx.ALL, 5)
|
||||||
|
|
||||||
lblStatus = wx.StaticText(self, wx.NewId(), _("Status"))
|
lblStatus = wx.StaticText(self, wx.NewId(), _("Status"))
|
||||||
self.status = wx.TextCtrl(self, wx.NewId(), style=wx.TE_READONLY|wx.TE_MULTILINE)
|
self.status = wx.TextCtrl(self, wx.NewId(), style=wx.TE_READONLY|wx.TE_MULTILINE)
|
||||||
self.status.Enable(False)
|
self.status.Enable(False)
|
||||||
self.status.SetMinSize(text_size(self.status, 300))
|
self.status.SetMinSize(text_size(self.status, 300))
|
||||||
sizerStatus = wx.BoxSizer(wx.HORIZONTAL)
|
sizerStatus = wx.BoxSizer(wx.HORIZONTAL)
|
||||||
sizerStatus.Add(lblStatus, 0, wx.ALL, 5)
|
sizerStatus.Add(lblStatus, 0, wx.ALL, 5)
|
||||||
sizerStatus.Add(self.status, 0, wx.ALL, 5)
|
sizerStatus.Add(self.status, 0, wx.ALL, 5)
|
||||||
sizer.Add(sizerStatus, 0, wx.ALL, 5)
|
sizer.Add(sizerStatus, 0, wx.ALL, 5)
|
||||||
|
|
||||||
lblLastSeen = wx.StaticText(self, wx.NewId(), _("Last seen"))
|
lblLastSeen = wx.StaticText(self, wx.NewId(), _("Last seen"))
|
||||||
self.last_seen = wx.TextCtrl(self, wx.NewId(), style=wx.TE_READONLY|wx.TE_MULTILINE)
|
self.last_seen = wx.TextCtrl(self, wx.NewId(), style=wx.TE_READONLY|wx.TE_MULTILINE)
|
||||||
self.last_seen.Enable(False)
|
self.last_seen.Enable(False)
|
||||||
sizerLastSeen = wx.BoxSizer(wx.HORIZONTAL)
|
sizerLastSeen = wx.BoxSizer(wx.HORIZONTAL)
|
||||||
sizerLastSeen.Add(lblLastSeen, 0, wx.ALL, 5)
|
sizerLastSeen.Add(lblLastSeen, 0, wx.ALL, 5)
|
||||||
sizerLastSeen.Add(self.last_seen, 0, wx.ALL, 5)
|
sizerLastSeen.Add(self.last_seen, 0, wx.ALL, 5)
|
||||||
sizer.Add(sizerLastSeen, 0, wx.ALL, 5)
|
sizer.Add(sizerLastSeen, 0, wx.ALL, 5)
|
||||||
|
|
||||||
lblMobilePhone = wx.StaticText(self, wx.NewId(), _("Mobile phone"))
|
lblMobilePhone = wx.StaticText(self, wx.NewId(), _("Mobile phone"))
|
||||||
self.mobile_phone = wx.TextCtrl(self, wx.NewId(), style=wx.TE_READONLY|wx.TE_MULTILINE)
|
self.mobile_phone = wx.TextCtrl(self, wx.NewId(), style=wx.TE_READONLY|wx.TE_MULTILINE)
|
||||||
self.mobile_phone.Enable(False)
|
self.mobile_phone.Enable(False)
|
||||||
sizerMobilePhone = wx.BoxSizer(wx.HORIZONTAL)
|
sizerMobilePhone = wx.BoxSizer(wx.HORIZONTAL)
|
||||||
sizerMobilePhone.Add(lblMobilePhone, 0, wx.ALL, 5)
|
sizerMobilePhone.Add(lblMobilePhone, 0, wx.ALL, 5)
|
||||||
sizerMobilePhone.Add(self.mobile_phone, 0, wx.ALL, 5)
|
sizerMobilePhone.Add(self.mobile_phone, 0, wx.ALL, 5)
|
||||||
sizer.Add(sizerMobilePhone, 0, wx.ALL, 5)
|
sizer.Add(sizerMobilePhone, 0, wx.ALL, 5)
|
||||||
|
|
||||||
lblHomePhone = wx.StaticText(self, wx.NewId(), _("Home phone"))
|
lblHomePhone = wx.StaticText(self, wx.NewId(), _("Home phone"))
|
||||||
self.home_phone = wx.TextCtrl(self, wx.NewId(), style=wx.TE_READONLY|wx.TE_MULTILINE)
|
self.home_phone = wx.TextCtrl(self, wx.NewId(), style=wx.TE_READONLY|wx.TE_MULTILINE)
|
||||||
self.home_phone.Enable(False)
|
self.home_phone.Enable(False)
|
||||||
sizerHomePhone = wx.BoxSizer(wx.HORIZONTAL)
|
sizerHomePhone = wx.BoxSizer(wx.HORIZONTAL)
|
||||||
sizerHomePhone.Add(lblHomePhone, 0, wx.ALL, 5)
|
sizerHomePhone.Add(lblHomePhone, 0, wx.ALL, 5)
|
||||||
sizerHomePhone.Add(self.home_phone, 0, wx.ALL, 5)
|
sizerHomePhone.Add(self.home_phone, 0, wx.ALL, 5)
|
||||||
sizer.Add(sizerHomePhone, 0, wx.ALL, 5)
|
sizer.Add(sizerHomePhone, 0, wx.ALL, 5)
|
||||||
|
|
||||||
lblBDate = wx.StaticText(self, wx.NewId(), _("Birthdate"))
|
lblBDate = wx.StaticText(self, wx.NewId(), _("Birthdate"))
|
||||||
self.bdate = wx.TextCtrl(self, wx.NewId(), style=wx.TE_READONLY|wx.TE_MULTILINE)
|
self.bdate = wx.TextCtrl(self, wx.NewId(), style=wx.TE_READONLY|wx.TE_MULTILINE)
|
||||||
self.bdate.Enable(False)
|
self.bdate.Enable(False)
|
||||||
sizerBDate = wx.BoxSizer(wx.HORIZONTAL)
|
sizerBDate = wx.BoxSizer(wx.HORIZONTAL)
|
||||||
sizerBDate.Add(lblBDate, 0, wx.ALL, 5)
|
sizerBDate.Add(lblBDate, 0, wx.ALL, 5)
|
||||||
sizerBDate.Add(self.bdate, 0, wx.ALL, 5)
|
sizerBDate.Add(self.bdate, 0, wx.ALL, 5)
|
||||||
sizer.Add(sizerBDate, 0, wx.ALL, 5)
|
sizer.Add(sizerBDate, 0, wx.ALL, 5)
|
||||||
|
|
||||||
self.relation = wx.Button(self, -1, "")
|
self.relation = wx.Button(self, -1, "")
|
||||||
self.relation.Enable(False)
|
self.relation.Enable(False)
|
||||||
sizer.Add(self.relation, 0, wx.ALL, 5)
|
sizer.Add(self.relation, 0, wx.ALL, 5)
|
||||||
|
|
||||||
lblCity = wx.StaticText(self, wx.NewId(), _("Current city"))
|
lblCity = wx.StaticText(self, wx.NewId(), _("Current city"))
|
||||||
self.city = wx.TextCtrl(self, wx.NewId(), style=wx.TE_READONLY|wx.TE_MULTILINE)
|
self.city = wx.TextCtrl(self, wx.NewId(), style=wx.TE_READONLY|wx.TE_MULTILINE)
|
||||||
self.city.SetMinSize(text_size(self.city, 40))
|
self.city.SetMinSize(text_size(self.city, 40))
|
||||||
self.city.Enable(False)
|
self.city.Enable(False)
|
||||||
sizerCity = wx.BoxSizer(wx.HORIZONTAL)
|
sizerCity = wx.BoxSizer(wx.HORIZONTAL)
|
||||||
sizerCity.Add(lblCity, 0, wx.ALL, 5)
|
sizerCity.Add(lblCity, 0, wx.ALL, 5)
|
||||||
sizerCity.Add(self.city, 0, wx.ALL, 5)
|
sizerCity.Add(self.city, 0, wx.ALL, 5)
|
||||||
sizer.Add(sizerCity, 0, wx.ALL, 5)
|
sizer.Add(sizerCity, 0, wx.ALL, 5)
|
||||||
|
|
||||||
lblHometown = wx.StaticText(self, wx.NewId(), _("Home Town"))
|
lblHometown = wx.StaticText(self, wx.NewId(), _("Home Town"))
|
||||||
self.home_town = wx.TextCtrl(self, wx.NewId(), style=wx.TE_READONLY|wx.TE_MULTILINE)
|
self.home_town = wx.TextCtrl(self, wx.NewId(), style=wx.TE_READONLY|wx.TE_MULTILINE)
|
||||||
self.home_town.SetMinSize(text_size(self.home_town, 40))
|
self.home_town.SetMinSize(text_size(self.home_town, 40))
|
||||||
self.home_town.Enable(False)
|
self.home_town.Enable(False)
|
||||||
sizerHometown = wx.BoxSizer(wx.HORIZONTAL)
|
sizerHometown = wx.BoxSizer(wx.HORIZONTAL)
|
||||||
sizerHometown.Add(lblHometown, 0, wx.ALL, 5)
|
sizerHometown.Add(lblHometown, 0, wx.ALL, 5)
|
||||||
sizerHometown.Add(self.home_town, 0, wx.ALL, 5)
|
sizerHometown.Add(self.home_town, 0, wx.ALL, 5)
|
||||||
sizer.Add(sizerHometown, 0, wx.ALL, 5)
|
sizer.Add(sizerHometown, 0, wx.ALL, 5)
|
||||||
|
|
||||||
lblWebsite = wx.StaticText(self, wx.NewId(), _("Website"))
|
lblWebsite = wx.StaticText(self, wx.NewId(), _("Website"))
|
||||||
self.website = wx.TextCtrl(self, wx.NewId(), style=wx.TE_READONLY|wx.TE_MULTILINE)#size=(500, -1))
|
self.website = wx.TextCtrl(self, wx.NewId(), style=wx.TE_READONLY|wx.TE_MULTILINE)#size=(500, -1))
|
||||||
self.website.SetMinSize(text_size(self.website, 90))
|
self.website.SetMinSize(text_size(self.website, 90))
|
||||||
self.website.Enable(False)
|
self.website.Enable(False)
|
||||||
self.go_site = wx.Button(self, -1, _("Visit website"))
|
self.go_site = wx.Button(self, -1, _("Visit website"))
|
||||||
self.go_site.Enable(False)
|
self.go_site.Enable(False)
|
||||||
sizerWebsite = wx.BoxSizer(wx.HORIZONTAL)
|
sizerWebsite = wx.BoxSizer(wx.HORIZONTAL)
|
||||||
sizerWebsite.Add(lblWebsite, 0, wx.ALL, 5)
|
sizerWebsite.Add(lblWebsite, 0, wx.ALL, 5)
|
||||||
sizerWebsite.Add(self.website, 1, wx.ALL, 5)
|
sizerWebsite.Add(self.website, 1, wx.ALL, 5)
|
||||||
sizerWebsite.Add(self.go_site, 1, wx.ALL, 5)
|
sizerWebsite.Add(self.go_site, 1, wx.ALL, 5)
|
||||||
sizer.Add(sizerWebsite, 1, wx.ALL, 5)
|
sizer.Add(sizerWebsite, 1, wx.ALL, 5)
|
||||||
|
|
||||||
lblOccupation = wx.StaticText(self, wx.NewId(), _("Occupation"))
|
lblOccupation = wx.StaticText(self, wx.NewId(), _("Occupation"))
|
||||||
self.occupation = wx.TextCtrl(self, wx.NewId(), style=wx.TE_READONLY|wx.TE_MULTILINE)
|
self.occupation = wx.TextCtrl(self, wx.NewId(), style=wx.TE_READONLY|wx.TE_MULTILINE)
|
||||||
self.occupation.SetMinSize(text_size(self.occupation, 90))
|
self.occupation.SetMinSize(text_size(self.occupation, 90))
|
||||||
self.occupation.Enable(False)
|
self.occupation.Enable(False)
|
||||||
sizerOccupation = wx.BoxSizer(wx.HORIZONTAL)
|
sizerOccupation = wx.BoxSizer(wx.HORIZONTAL)
|
||||||
sizerOccupation.Add(lblOccupation, 0, wx.ALL, 5)
|
sizerOccupation.Add(lblOccupation, 0, wx.ALL, 5)
|
||||||
sizerOccupation.Add(self.occupation, 0, wx.ALL, 5)
|
sizerOccupation.Add(self.occupation, 0, wx.ALL, 5)
|
||||||
sizer.Add(sizerOccupation, 0, wx.ALL, 5)
|
sizer.Add(sizerOccupation, 0, wx.ALL, 5)
|
||||||
self.SetSizer(sizer)
|
self.SetSizer(sizer)
|
||||||
|
|
||||||
class userProfileDialog(widgetUtils.BaseDialog):
|
class userProfileDialog(widgetUtils.BaseDialog):
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
super(userProfileDialog, self).__init__(parent=None, *args, **kwargs)
|
super(userProfileDialog, self).__init__(parent=None, *args, **kwargs)
|
||||||
self.panel = wx.Panel(self)
|
self.panel = wx.Panel(self)
|
||||||
self.sizer = wx.BoxSizer(wx.VERTICAL)
|
self.sizer = wx.BoxSizer(wx.VERTICAL)
|
||||||
self.notebook = wx.Notebook(self.panel)
|
self.notebook = wx.Notebook(self.panel)
|
||||||
|
|
||||||
def create_controls(self, section):
|
def create_controls(self, section):
|
||||||
if section == "main_info":
|
if section == "main_info":
|
||||||
self.main_info = mainInfo(self.notebook)
|
self.main_info = mainInfo(self.notebook)
|
||||||
self.notebook.AddPage(self.main_info, _("Basic information"))
|
self.notebook.AddPage(self.main_info, _("Basic information"))
|
||||||
self.main_info.SetFocus()
|
self.main_info.SetFocus()
|
||||||
|
|
||||||
def realice(self):
|
def realice(self):
|
||||||
self.image = wx.StaticBitmap(self.panel, bitmap=wx.Bitmap(200, 200), size=(200, 200))
|
self.image = wx.StaticBitmap(self.panel, bitmap=wx.Bitmap(200, 200), size=(200, 200))
|
||||||
self.sizer.Add(self.image, 1, wx.ALL, 10)
|
self.sizer.Add(self.image, 1, wx.ALL, 10)
|
||||||
self.sizer.Add(self.notebook, 1, wx.ALL, 5)
|
self.sizer.Add(self.notebook, 1, wx.ALL, 5)
|
||||||
cancel = wx.Button(self.panel, wx.ID_CANCEL)
|
cancel = wx.Button(self.panel, wx.ID_CANCEL)
|
||||||
btnSizer = wx.BoxSizer(wx.HORIZONTAL)
|
btnSizer = wx.BoxSizer(wx.HORIZONTAL)
|
||||||
btnSizer.Add(cancel, 0, wx.ALL, 5)
|
btnSizer.Add(cancel, 0, wx.ALL, 5)
|
||||||
self.sizer.Add(btnSizer, 0, wx.ALL, 5)
|
self.sizer.Add(btnSizer, 0, wx.ALL, 5)
|
||||||
self.panel.SetSizer(self.sizer)
|
self.panel.SetSizer(self.sizer)
|
||||||
self.SetClientSize(self.sizer.CalcMin())
|
self.SetClientSize(self.sizer.CalcMin())
|
||||||
|
|
||||||
def get_value(self, panel, key):
|
def get_value(self, panel, key):
|
||||||
p = getattr(self, panel)
|
p = getattr(self, panel)
|
||||||
return getattr(p, key).GetValue()
|
return getattr(p, key).GetValue()
|
||||||
|
|
||||||
def set_value(self, panel, key, value):
|
def set_value(self, panel, key, value):
|
||||||
p = getattr(self, panel)
|
p = getattr(self, panel)
|
||||||
control = getattr(p, key)
|
control = getattr(p, key)
|
||||||
getattr(control, "SetValue")(value)
|
getattr(control, "SetValue")(value)
|
||||||
|
|
||||||
def enable(self, panel, key, value=False):
|
def enable(self, panel, key, value=False):
|
||||||
p = getattr(self, panel)
|
p = getattr(self, panel)
|
||||||
control = getattr(p, key)
|
control = getattr(p, key)
|
||||||
getattr(control, "Enable")(value)
|
getattr(control, "Enable")(value)
|
||||||
|
@ -3,34 +3,34 @@ from __future__ import unicode_literals
|
|||||||
import wx
|
import wx
|
||||||
|
|
||||||
class urlList(wx.Dialog):
|
class urlList(wx.Dialog):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super(urlList, self).__init__(parent=None, title=_("Select URL"))
|
super(urlList, self).__init__(parent=None, title=_("Select URL"))
|
||||||
panel = wx.Panel(self)
|
panel = wx.Panel(self)
|
||||||
self.lista = wx.ListBox(panel, -1)
|
self.lista = wx.ListBox(panel, -1)
|
||||||
self.lista.SetFocus()
|
self.lista.SetFocus()
|
||||||
self.lista.SetSize(self.lista.GetBestSize())
|
self.lista.SetSize(self.lista.GetBestSize())
|
||||||
sizer = wx.BoxSizer(wx.VERTICAL)
|
sizer = wx.BoxSizer(wx.VERTICAL)
|
||||||
sizer.Add(self.lista, 0, wx.ALL, 5)
|
sizer.Add(self.lista, 0, wx.ALL, 5)
|
||||||
goBtn = wx.Button(panel, wx.ID_OK)
|
goBtn = wx.Button(panel, wx.ID_OK)
|
||||||
goBtn.SetDefault()
|
goBtn.SetDefault()
|
||||||
cancelBtn = wx.Button(panel, wx.ID_CANCEL)
|
cancelBtn = wx.Button(panel, wx.ID_CANCEL)
|
||||||
btnSizer = wx.BoxSizer()
|
btnSizer = wx.BoxSizer()
|
||||||
btnSizer.Add(goBtn, 0, wx.ALL, 5)
|
btnSizer.Add(goBtn, 0, wx.ALL, 5)
|
||||||
btnSizer.Add(cancelBtn, 0, wx.ALL, 5)
|
btnSizer.Add(cancelBtn, 0, wx.ALL, 5)
|
||||||
sizer.Add(btnSizer, 0, wx.ALL, 5)
|
sizer.Add(btnSizer, 0, wx.ALL, 5)
|
||||||
panel.SetSizer(sizer)
|
panel.SetSizer(sizer)
|
||||||
self.SetClientSize(sizer.CalcMin())
|
self.SetClientSize(sizer.CalcMin())
|
||||||
|
|
||||||
def populate_list(self, urls):
|
def populate_list(self, urls):
|
||||||
for i in urls:
|
for i in urls:
|
||||||
self.lista.Append(i)
|
self.lista.Append(i)
|
||||||
self.lista.SetSelection(0)
|
self.lista.SetSelection(0)
|
||||||
|
|
||||||
def get_string(self):
|
def get_string(self):
|
||||||
return self.lista.GetStringSelection()
|
return self.lista.GetStringSelection()
|
||||||
|
|
||||||
def get_item(self):
|
def get_item(self):
|
||||||
return self.lista.GetSelection()
|
return self.lista.GetSelection()
|
||||||
|
|
||||||
def get_response(self):
|
def get_response(self):
|
||||||
return self.ShowModal()
|
return self.ShowModal()
|
||||||
|
@ -63,172 +63,172 @@ LISTBOX_CHANGED = wx.EVT_LISTBOX
|
|||||||
LISTBOX_ITEM_ACTIVATED = wx.EVT_LIST_ITEM_ACTIVATED
|
LISTBOX_ITEM_ACTIVATED = wx.EVT_LIST_ITEM_ACTIVATED
|
||||||
|
|
||||||
def exit_application():
|
def exit_application():
|
||||||
""" Closes the current window cleanly. """
|
""" Closes the current window cleanly. """
|
||||||
wx.GetApp().ExitMainLoop()
|
wx.GetApp().ExitMainLoop()
|
||||||
|
|
||||||
def connect_event(parent, event, func, menuitem=None, *args, **kwargs):
|
def connect_event(parent, event, func, menuitem=None, *args, **kwargs):
|
||||||
""" Connects an event to a function.
|
""" Connects an event to a function.
|
||||||
parent wx.window: The widget that will listen for the event.
|
parent wx.window: The widget that will listen for the event.
|
||||||
event widgetUtils.event: The event that will be listened for the parent. The event should be one of the widgetUtils events.
|
event widgetUtils.event: The event that will be listened for the parent. The event should be one of the widgetUtils events.
|
||||||
function func: The function that will be connected to the event."""
|
function func: The function that will be connected to the event."""
|
||||||
if menuitem == None:
|
if menuitem == None:
|
||||||
return getattr(parent, "Bind")(event, func, *args, **kwargs)
|
return getattr(parent, "Bind")(event, func, *args, **kwargs)
|
||||||
else:
|
else:
|
||||||
return getattr(parent, "Bind")(event, func, menuitem, *args, **kwargs)
|
return getattr(parent, "Bind")(event, func, menuitem, *args, **kwargs)
|
||||||
|
|
||||||
def connectExitFunction(exitFunction):
|
def connectExitFunction(exitFunction):
|
||||||
""" This connect the events in WX when an user is turning off the machine."""
|
""" This connect the events in WX when an user is turning off the machine."""
|
||||||
wx.GetApp().Bind(wx.EVT_QUERY_END_SESSION, exitFunction)
|
wx.GetApp().Bind(wx.EVT_QUERY_END_SESSION, exitFunction)
|
||||||
wx.GetApp().Bind(wx.EVT_END_SESSION, exitFunction)
|
wx.GetApp().Bind(wx.EVT_END_SESSION, exitFunction)
|
||||||
|
|
||||||
class BaseDialog(wx.Dialog):
|
class BaseDialog(wx.Dialog):
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
super(BaseDialog, self).__init__(*args, **kwargs)
|
super(BaseDialog, self).__init__(*args, **kwargs)
|
||||||
|
|
||||||
def get_response(self):
|
def get_response(self):
|
||||||
return self.ShowModal()
|
return self.ShowModal()
|
||||||
|
|
||||||
def get(self, control):
|
def get(self, control):
|
||||||
if hasattr(self, control):
|
if hasattr(self, control):
|
||||||
control = getattr(self, control)
|
control = getattr(self, control)
|
||||||
if hasattr(control, "GetValue"): return getattr(control, "GetValue")()
|
if hasattr(control, "GetValue"): return getattr(control, "GetValue")()
|
||||||
elif hasattr(control, "GetLabel"): return getattr(control, "GetLabel")()
|
elif hasattr(control, "GetLabel"): return getattr(control, "GetLabel")()
|
||||||
else: return -1
|
else: return -1
|
||||||
else: return 0
|
else: return 0
|
||||||
|
|
||||||
def set(self, control, text):
|
def set(self, control, text):
|
||||||
if hasattr(self, control):
|
if hasattr(self, control):
|
||||||
control = getattr(self, control)
|
control = getattr(self, control)
|
||||||
if hasattr(control, "SetValue"): return getattr(control, "SetValue")(text)
|
if hasattr(control, "SetValue"): return getattr(control, "SetValue")(text)
|
||||||
elif hasattr(control, "SetLabel"): return getattr(control, "SetLabel")(text)
|
elif hasattr(control, "SetLabel"): return getattr(control, "SetLabel")(text)
|
||||||
elif hasattr(control, "ChangeValue"): return getattr(control, "ChangeValue")(text)
|
elif hasattr(control, "ChangeValue"): return getattr(control, "ChangeValue")(text)
|
||||||
else: return -1
|
else: return -1
|
||||||
else: return 0
|
else: return 0
|
||||||
|
|
||||||
def destroy(self):
|
def destroy(self):
|
||||||
self.Destroy()
|
self.Destroy()
|
||||||
|
|
||||||
def set_title(self, title):
|
def set_title(self, title):
|
||||||
self.SetTitle(title)
|
self.SetTitle(title)
|
||||||
|
|
||||||
def get_title(self):
|
def get_title(self):
|
||||||
return self.GetTitle()
|
return self.GetTitle()
|
||||||
|
|
||||||
def enable(self, control):
|
def enable(self, control):
|
||||||
getattr(self, control).Enable(True)
|
getattr(self, control).Enable(True)
|
||||||
|
|
||||||
def disable(self, control):
|
def disable(self, control):
|
||||||
getattr(self, control).Enable(False)
|
getattr(self, control).Enable(False)
|
||||||
|
|
||||||
class mainLoopObject(wx.App):
|
class mainLoopObject(wx.App):
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.app = wx.App()
|
self.app = wx.App()
|
||||||
self.lc = wx.Locale()
|
self.lc = wx.Locale()
|
||||||
lang=languageHandler.getLanguage()
|
lang=languageHandler.getLanguage()
|
||||||
wxLang=self.lc.FindLanguageInfo(lang)
|
wxLang=self.lc.FindLanguageInfo(lang)
|
||||||
if not wxLang and '_' in lang:
|
if not wxLang and '_' in lang:
|
||||||
wxLang=self.lc.FindLanguageInfo(lang.split('_')[0])
|
wxLang=self.lc.FindLanguageInfo(lang.split('_')[0])
|
||||||
self.lc.AddCatalogLookupPathPrefix(paths.locale_path())
|
self.lc.AddCatalogLookupPathPrefix(paths.locale_path())
|
||||||
if wxLang:
|
if wxLang:
|
||||||
self.lc.Init(wxLang.Language)
|
self.lc.Init(wxLang.Language)
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
self.app.MainLoop()
|
self.app.MainLoop()
|
||||||
|
|
||||||
class multiselectionBaseList(wx.ListCtrl, listmix.CheckListCtrlMixin):
|
class multiselectionBaseList(wx.ListCtrl, listmix.CheckListCtrlMixin):
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
super(multiselectionBaseList, self).__init__(*args, **kwargs)
|
super(multiselectionBaseList, self).__init__(*args, **kwargs)
|
||||||
# wx.ListCtrl.__init__(self, *args, **kwargs)
|
# wx.ListCtrl.__init__(self, *args, **kwargs)
|
||||||
# listmix.CheckListCtrlMixin.__init__(self)
|
# listmix.CheckListCtrlMixin.__init__(self)
|
||||||
self.Bind(wx.EVT_CHAR_HOOK, self.on_keydown)
|
self.Bind(wx.EVT_CHAR_HOOK, self.on_keydown)
|
||||||
self.Bind(wx.EVT_LIST_ITEM_FOCUSED, self.on_focus)
|
self.Bind(wx.EVT_LIST_ITEM_FOCUSED, self.on_focus)
|
||||||
|
|
||||||
def on_focus(self, event):
|
def on_focus(self, event):
|
||||||
currentItem = self.GetFocusedItem()
|
currentItem = self.GetFocusedItem()
|
||||||
if self.IsChecked(currentItem):
|
if self.IsChecked(currentItem):
|
||||||
pub.sendMessage("play-sound", sound="selected.ogg")
|
pub.sendMessage("play-sound", sound="selected.ogg")
|
||||||
event.Skip()
|
event.Skip()
|
||||||
|
|
||||||
def OnCheckItem(self, index, flag):
|
def OnCheckItem(self, index, flag):
|
||||||
if flag == True:
|
if flag == True:
|
||||||
pub.sendMessage("play-sound", sound="checked.ogg")
|
pub.sendMessage("play-sound", sound="checked.ogg")
|
||||||
else:
|
else:
|
||||||
pub.sendMessage("play-sound", sound="unchecked.ogg")
|
pub.sendMessage("play-sound", sound="unchecked.ogg")
|
||||||
|
|
||||||
def on_keydown(self, event):
|
def on_keydown(self, event):
|
||||||
if event.GetKeyCode() == wx.WXK_SPACE:
|
if event.GetKeyCode() == wx.WXK_SPACE:
|
||||||
# In the example of wx multiselection list they call ToggleItem.
|
# In the example of wx multiselection list they call ToggleItem.
|
||||||
# however this didn't worked quite well. So let's implement it manually.
|
# however this didn't worked quite well. So let's implement it manually.
|
||||||
if self.IsChecked(self.GetFocusedItem()):
|
if self.IsChecked(self.GetFocusedItem()):
|
||||||
self.SetItemImage(self.GetFocusedItem(), 0)
|
self.SetItemImage(self.GetFocusedItem(), 0)
|
||||||
self.OnCheckItem(self.GetFocusedItem(), False)
|
self.OnCheckItem(self.GetFocusedItem(), False)
|
||||||
else:
|
else:
|
||||||
self.SetItemImage(self.GetFocusedItem(), 1)
|
self.SetItemImage(self.GetFocusedItem(), 1)
|
||||||
self.OnCheckItem(self.GetFocusedItem(), True)
|
self.OnCheckItem(self.GetFocusedItem(), True)
|
||||||
event.Skip()
|
event.Skip()
|
||||||
|
|
||||||
class list(object):
|
class list(object):
|
||||||
def __init__(self, parent, *columns, **listArguments):
|
def __init__(self, parent, *columns, **listArguments):
|
||||||
self.columns = columns
|
self.columns = columns
|
||||||
self.listArguments = listArguments
|
self.listArguments = listArguments
|
||||||
self.create_list(parent)
|
self.create_list(parent)
|
||||||
|
|
||||||
def set_windows_size(self, column, characters_max):
|
def set_windows_size(self, column, characters_max):
|
||||||
self.list.SetColumnWidth(column, characters_max*2)
|
self.list.SetColumnWidth(column, characters_max*2)
|
||||||
|
|
||||||
def set_size(self):
|
def set_size(self):
|
||||||
self.list.SetSize((self.list.GetBestSize()[0], 1000))
|
self.list.SetSize((self.list.GetBestSize()[0], 1000))
|
||||||
|
|
||||||
def create_list(self, parent):
|
def create_list(self, parent):
|
||||||
self.list = wx.ListCtrl(parent, -1, **self.listArguments)
|
self.list = wx.ListCtrl(parent, -1, **self.listArguments)
|
||||||
for i in range(0, len(self.columns)):
|
for i in range(0, len(self.columns)):
|
||||||
self.list.InsertColumn(i, "%s" % (self.columns[i]))
|
self.list.InsertColumn(i, "%s" % (self.columns[i]))
|
||||||
|
|
||||||
def insert_item(self, reversed, *item):
|
def insert_item(self, reversed, *item):
|
||||||
""" Inserts an item on the list."""
|
""" Inserts an item on the list."""
|
||||||
if reversed == False: items = self.list.GetItemCount()
|
if reversed == False: items = self.list.GetItemCount()
|
||||||
else: items = 0
|
else: items = 0
|
||||||
self.list.InsertItem(items, item[0])
|
self.list.InsertItem(items, item[0])
|
||||||
for i in range(1, len(self.columns)):
|
for i in range(1, len(self.columns)):
|
||||||
self.list.SetItem(items, i, item[i])
|
self.list.SetItem(items, i, item[i])
|
||||||
|
|
||||||
def remove_item(self, pos):
|
def remove_item(self, pos):
|
||||||
""" Deletes an item from the list."""
|
""" Deletes an item from the list."""
|
||||||
if pos > 0: self.list.Focus(pos-1)
|
if pos > 0: self.list.Focus(pos-1)
|
||||||
self.list.DeleteItem(pos)
|
self.list.DeleteItem(pos)
|
||||||
|
|
||||||
def clear(self):
|
def clear(self):
|
||||||
self.list.DeleteAllItems()
|
self.list.DeleteAllItems()
|
||||||
|
|
||||||
def get_selected(self):
|
def get_selected(self):
|
||||||
return self.list.GetFocusedItem()
|
return self.list.GetFocusedItem()
|
||||||
|
|
||||||
def select_item(self, pos):
|
def select_item(self, pos):
|
||||||
self.list.Focus(pos)
|
self.list.Focus(pos)
|
||||||
|
|
||||||
def get_count(self):
|
def get_count(self):
|
||||||
selected = self.list.GetItemCount()
|
selected = self.list.GetItemCount()
|
||||||
if selected == -1:
|
if selected == -1:
|
||||||
return 0
|
return 0
|
||||||
else:
|
else:
|
||||||
return selected
|
return selected
|
||||||
|
|
||||||
def Enable(self, value):
|
def Enable(self, value):
|
||||||
return self.list.Enable(value)
|
return self.list.Enable(value)
|
||||||
|
|
||||||
class multiselectionList(list):
|
class multiselectionList(list):
|
||||||
|
|
||||||
def create_list(self, parent):
|
def create_list(self, parent):
|
||||||
self.list = multiselectionBaseList(parent, -1, **self.listArguments)
|
self.list = multiselectionBaseList(parent, -1, **self.listArguments)
|
||||||
for i in range(0, len(self.columns)):
|
for i in range(0, len(self.columns)):
|
||||||
self.list.InsertColumn(i, "%s" % (self.columns[i]))
|
self.list.InsertColumn(i, "%s" % (self.columns[i]))
|
||||||
|
|
||||||
def get_multiple_selection(self):
|
def get_multiple_selection(self):
|
||||||
selected = []
|
selected = []
|
||||||
for item in range(0, self.list.GetItemCount()):
|
for item in range(0, self.list.GetItemCount()):
|
||||||
if self.list.IsChecked(item):
|
if self.list.IsChecked(item):
|
||||||
selected.append(item)
|
selected.append(item)
|
||||||
if len(selected) == 0 and self.list.GetFocusedItem() != -1:
|
if len(selected) == 0 and self.list.GetFocusedItem() != -1:
|
||||||
selected.append(self.list.GetFocusedItem())
|
selected.append(self.list.GetFocusedItem())
|
||||||
return selected
|
return selected
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user