changed indentation from tabs to spaces
This commit is contained in:
parent
5c02a67ac7
commit
4bdba42eab
@ -19,4 +19,4 @@ update_stable_url = "https://files.manuelcortez.net/socializer/update/stable.jso
|
||||
# Every commit will trigger an update, so users wanting to have the bleeding edge code will get it as soon as it is committed here and build by a runner.
|
||||
update_next_url = "https://files.manuelcortez.net/socializer/update/alpha.json"
|
||||
# Short_id of the last commit, this is set to none here because it will be set manually by the building tools.
|
||||
update_next_version = "03286a44"
|
||||
update_next_version = "03286a44"
|
||||
|
@ -8,24 +8,24 @@ log = logging.getLogger("authenticator.official")
|
||||
class AuthenticationError(Exception): pass
|
||||
|
||||
def login(user, password):
|
||||
""" Generates authentication workflow at VK servers. """
|
||||
log.info("Authenticating user account.")
|
||||
access_token = None
|
||||
try:
|
||||
params = CommonParams(supported_clients.VK_OFFICIAL.user_agent)
|
||||
receiver = TokenReceiverOfficial(user, password, params, "GET_CODE")
|
||||
access_token = receiver.get_token()["access_token"]
|
||||
log.debug("got a valid access token for {}".format(user))
|
||||
except TokenException as err:
|
||||
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...")
|
||||
try:
|
||||
TwoFAHelper(params).validate_phone(err.extra['validation_sid'])
|
||||
except TokenException as err:
|
||||
if err.code == TokenException.TWOFA_ERR:
|
||||
wxUI.two_auth_limit()
|
||||
raise AuthenticationError("Error authentication two factor auth.")
|
||||
code, remember = wxUI.two_factor_auth()
|
||||
receiver = TokenReceiverOfficial(user, password, params, code)
|
||||
access_token = receiver.get_token()["access_token"]
|
||||
return access_token
|
||||
""" Generates authentication workflow at VK servers. """
|
||||
log.info("Authenticating user account.")
|
||||
access_token = None
|
||||
try:
|
||||
params = CommonParams(supported_clients.VK_OFFICIAL.user_agent)
|
||||
receiver = TokenReceiverOfficial(user, password, params, "GET_CODE")
|
||||
access_token = receiver.get_token()["access_token"]
|
||||
log.debug("got a valid access token for {}".format(user))
|
||||
except TokenException as err:
|
||||
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...")
|
||||
try:
|
||||
TwoFAHelper(params).validate_phone(err.extra['validation_sid'])
|
||||
except TokenException as err:
|
||||
if err.code == TokenException.TWOFA_ERR:
|
||||
wxUI.two_auth_limit()
|
||||
raise AuthenticationError("Error authentication two factor auth.")
|
||||
code, remember = wxUI.two_factor_auth()
|
||||
receiver = TokenReceiverOfficial(user, password, params, code)
|
||||
access_token = receiver.get_token()["access_token"]
|
||||
return access_token
|
||||
|
@ -5,16 +5,16 @@ import wx
|
||||
import widgetUtils
|
||||
|
||||
def two_factor_auth():
|
||||
code = None
|
||||
dlg = wx.TextEntryDialog(None, _("Please provide the authentication code you have received from VK."), _("Two factor authentication code"))
|
||||
response = dlg.ShowModal()
|
||||
if response == widgetUtils.OK:
|
||||
code = dlg.GetValue()
|
||||
dlg.Destroy()
|
||||
return (code, True)
|
||||
code = None
|
||||
dlg = wx.TextEntryDialog(None, _("Please provide the authentication code you have received from VK."), _("Two factor authentication code"))
|
||||
response = dlg.ShowModal()
|
||||
if response == widgetUtils.OK:
|
||||
code = dlg.GetValue()
|
||||
dlg.Destroy()
|
||||
return (code, True)
|
||||
|
||||
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():
|
||||
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
|
||||
def setup ():
|
||||
global app
|
||||
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))
|
||||
|
||||
global app
|
||||
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))
|
||||
|
@ -6,68 +6,68 @@ import string
|
||||
class ConfigLoadError(Exception): pass
|
||||
|
||||
def load_config(config_path, configspec_path=None, *args, **kwargs):
|
||||
if os.path.exists(config_path):
|
||||
clean_config(config_path)
|
||||
spec = ConfigObj(configspec_path, encoding='UTF8', list_values=False, _inspec=True)
|
||||
try:
|
||||
config = ConfigObj(infile=config_path, configspec=spec, create_empty=True, encoding='UTF8', *args, **kwargs)
|
||||
except ParseError:
|
||||
raise ConfigLoadError("Unable to load %r" % config_path)
|
||||
validator = Validator()
|
||||
validated = config.validate(validator, copy=True)
|
||||
if validated == True:
|
||||
config.write()
|
||||
return config
|
||||
if os.path.exists(config_path):
|
||||
clean_config(config_path)
|
||||
spec = ConfigObj(configspec_path, encoding='UTF8', list_values=False, _inspec=True)
|
||||
try:
|
||||
config = ConfigObj(infile=config_path, configspec=spec, create_empty=True, encoding='UTF8', *args, **kwargs)
|
||||
except ParseError:
|
||||
raise ConfigLoadError("Unable to load %r" % config_path)
|
||||
validator = Validator()
|
||||
validated = config.validate(validator, copy=True)
|
||||
if validated == True:
|
||||
config.write()
|
||||
return config
|
||||
|
||||
def is_blank(arg):
|
||||
"Check if a line is blank."
|
||||
for c in arg:
|
||||
if c not in string.whitespace:
|
||||
return False
|
||||
return True
|
||||
"Check if a line is blank."
|
||||
for c in arg:
|
||||
if c not in string.whitespace:
|
||||
return False
|
||||
return True
|
||||
def get_keys(path):
|
||||
"Gets the keys of a configobj config file."
|
||||
res=[]
|
||||
fin=open(path)
|
||||
for line in fin:
|
||||
if not is_blank(line):
|
||||
res.append(line[0:line.find('=')].strip())
|
||||
fin.close()
|
||||
return res
|
||||
"Gets the keys of a configobj config file."
|
||||
res=[]
|
||||
fin=open(path)
|
||||
for line in fin:
|
||||
if not is_blank(line):
|
||||
res.append(line[0:line.find('=')].strip())
|
||||
fin.close()
|
||||
return res
|
||||
|
||||
def hist(keys):
|
||||
"Generates a histogram of an iterable."
|
||||
res={}
|
||||
for k in keys:
|
||||
res[k]=res.setdefault(k,0)+1
|
||||
return res
|
||||
"Generates a histogram of an iterable."
|
||||
res={}
|
||||
for k in keys:
|
||||
res[k]=res.setdefault(k,0)+1
|
||||
return res
|
||||
|
||||
def find_problems(hist):
|
||||
"Takes a histogram and returns a list of items occurring more than once."
|
||||
res=[]
|
||||
for k,v in list(hist.items()):
|
||||
if v>1:
|
||||
res.append(k)
|
||||
return res
|
||||
"Takes a histogram and returns a list of items occurring more than once."
|
||||
res=[]
|
||||
for k,v in list(hist.items()):
|
||||
if v>1:
|
||||
res.append(k)
|
||||
return res
|
||||
|
||||
def clean_config(path):
|
||||
"Cleans a config file. If duplicate values are found, delete all of them and just use the default."
|
||||
orig=[]
|
||||
cleaned=[]
|
||||
fin=open(path)
|
||||
for line in fin:
|
||||
orig.append(line)
|
||||
fin.close()
|
||||
for p in find_problems(hist(get_keys(path))):
|
||||
for o in orig:
|
||||
o.strip()
|
||||
if p not in o:
|
||||
cleaned.append(o)
|
||||
if len(cleaned) != 0:
|
||||
cam=open(path,'w')
|
||||
for c in cleaned:
|
||||
cam.write(c)
|
||||
cam.close()
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
"Cleans a config file. If duplicate values are found, delete all of them and just use the default."
|
||||
orig=[]
|
||||
cleaned=[]
|
||||
fin=open(path)
|
||||
for line in fin:
|
||||
orig.append(line)
|
||||
fin.close()
|
||||
for p in find_problems(hist(get_keys(path))):
|
||||
for o in orig:
|
||||
o.strip()
|
||||
if p not in o:
|
||||
cleaned.append(o)
|
||||
if len(cleaned) != 0:
|
||||
cam=open(path,'w')
|
||||
for c in cleaned:
|
||||
cam.write(c)
|
||||
cam.close()
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
@ -21,289 +21,289 @@ from .wall import wallBuffer
|
||||
log = logging.getLogger("controller.buffers.audio")
|
||||
|
||||
class audioBuffer(wallBuffer):
|
||||
def create_tab(self, parent):
|
||||
self.tab = audio.audioTab(parent)
|
||||
self.tab.name = self.name
|
||||
self.connect_events()
|
||||
if self.name == "me_audio":
|
||||
self.tab.post.Enable(True)
|
||||
def create_tab(self, parent):
|
||||
self.tab = audio.audioTab(parent)
|
||||
self.tab.name = self.name
|
||||
self.connect_events()
|
||||
if self.name == "me_audio":
|
||||
self.tab.post.Enable(True)
|
||||
|
||||
def get_event(self, ev):
|
||||
if ev.GetKeyCode() == wx.WXK_RETURN:
|
||||
if len(self.tab.list.get_multiple_selection()) < 2:
|
||||
event = "play_all"
|
||||
else:
|
||||
event = "play_audio"
|
||||
else:
|
||||
event = None
|
||||
ev.Skip()
|
||||
if event != None:
|
||||
try:
|
||||
getattr(self, event)(skip_pause=True)
|
||||
except AttributeError:
|
||||
pass
|
||||
def get_event(self, ev):
|
||||
if ev.GetKeyCode() == wx.WXK_RETURN:
|
||||
if len(self.tab.list.get_multiple_selection()) < 2:
|
||||
event = "play_all"
|
||||
else:
|
||||
event = "play_audio"
|
||||
else:
|
||||
event = None
|
||||
ev.Skip()
|
||||
if event != None:
|
||||
try:
|
||||
getattr(self, event)(skip_pause=True)
|
||||
except AttributeError:
|
||||
pass
|
||||
|
||||
def connect_events(self):
|
||||
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)
|
||||
pub.subscribe(self.change_label, "playback-changed")
|
||||
super(audioBuffer, self).connect_events()
|
||||
def connect_events(self):
|
||||
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)
|
||||
pub.subscribe(self.change_label, "playback-changed")
|
||||
super(audioBuffer, self).connect_events()
|
||||
|
||||
def play_audio(self, *args, **kwargs):
|
||||
if player.player.check_is_playing() and not "skip_pause" in kwargs:
|
||||
return pub.sendMessage("pause")
|
||||
selected = self.tab.list.get_multiple_selection()
|
||||
if len(selected) == 0:
|
||||
return
|
||||
elif len(selected) == 1:
|
||||
pub.sendMessage("play", object=self.session.db[self.name]["items"][selected[0]])
|
||||
else:
|
||||
selected_audios = [self.session.db[self.name]["items"][item] for item in selected]
|
||||
pub.sendMessage("play-all", list_of_songs=selected_audios)
|
||||
return True
|
||||
def play_audio(self, *args, **kwargs):
|
||||
if player.player.check_is_playing() and not "skip_pause" in kwargs:
|
||||
return pub.sendMessage("pause")
|
||||
selected = self.tab.list.get_multiple_selection()
|
||||
if len(selected) == 0:
|
||||
return
|
||||
elif len(selected) == 1:
|
||||
pub.sendMessage("play", object=self.session.db[self.name]["items"][selected[0]])
|
||||
else:
|
||||
selected_audios = [self.session.db[self.name]["items"][item] for item in selected]
|
||||
pub.sendMessage("play-all", list_of_songs=selected_audios)
|
||||
return True
|
||||
|
||||
def play_next(self, *args, **kwargs):
|
||||
selected = self.tab.list.get_selected()
|
||||
if selected < 0:
|
||||
selected = 0
|
||||
if self.tab.list.get_count() <= selected+1:
|
||||
newpos = 0
|
||||
else:
|
||||
newpos = selected+1
|
||||
self.tab.list.select_item(newpos)
|
||||
self.play_audio()
|
||||
def play_next(self, *args, **kwargs):
|
||||
selected = self.tab.list.get_selected()
|
||||
if selected < 0:
|
||||
selected = 0
|
||||
if self.tab.list.get_count() <= selected+1:
|
||||
newpos = 0
|
||||
else:
|
||||
newpos = selected+1
|
||||
self.tab.list.select_item(newpos)
|
||||
self.play_audio()
|
||||
|
||||
def play_previous(self, *args, **kwargs):
|
||||
selected = self.tab.list.get_selected()
|
||||
if selected <= 0:
|
||||
selected = self.tab.list.get_count()
|
||||
newpos = selected-1
|
||||
self.tab.list.select_item(newpos)
|
||||
self.play_audio()
|
||||
def play_previous(self, *args, **kwargs):
|
||||
selected = self.tab.list.get_selected()
|
||||
if selected <= 0:
|
||||
selected = self.tab.list.get_count()
|
||||
newpos = selected-1
|
||||
self.tab.list.select_item(newpos)
|
||||
self.play_audio()
|
||||
|
||||
def open_post(self, *args, **kwargs):
|
||||
selected = self.tab.list.get_multiple_selection()
|
||||
if len(selected) < 1:
|
||||
return
|
||||
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())
|
||||
def open_post(self, *args, **kwargs):
|
||||
selected = self.tab.list.get_multiple_selection()
|
||||
if len(selected) < 1:
|
||||
return
|
||||
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())
|
||||
|
||||
def play_all(self, *args, **kwargs):
|
||||
selected = self.tab.list.get_selected()
|
||||
if selected == -1:
|
||||
selected = 0
|
||||
if self.name not in self.session.db:
|
||||
return
|
||||
audios = [i for i in self.session.db[self.name]["items"][selected:]]
|
||||
pub.sendMessage("play-all", list_of_songs=audios)
|
||||
return True
|
||||
def play_all(self, *args, **kwargs):
|
||||
selected = self.tab.list.get_selected()
|
||||
if selected == -1:
|
||||
selected = 0
|
||||
if self.name not in self.session.db:
|
||||
return
|
||||
audios = [i for i in self.session.db[self.name]["items"][selected:]]
|
||||
pub.sendMessage("play-all", list_of_songs=audios)
|
||||
return True
|
||||
|
||||
def remove_buffer(self, mandatory=False):
|
||||
if "me_audio" == self.name or "popular_audio" == self.name or "recommended_audio" == self.name:
|
||||
output.speak(_("This buffer can't be deleted"))
|
||||
return False
|
||||
else:
|
||||
if mandatory == False:
|
||||
dlg = commonMessages.remove_buffer()
|
||||
else:
|
||||
dlg = widgetUtils.YES
|
||||
if dlg == widgetUtils.YES:
|
||||
self.session.db.pop(self.name)
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
def remove_buffer(self, mandatory=False):
|
||||
if "me_audio" == self.name or "popular_audio" == self.name or "recommended_audio" == self.name:
|
||||
output.speak(_("This buffer can't be deleted"))
|
||||
return False
|
||||
else:
|
||||
if mandatory == False:
|
||||
dlg = commonMessages.remove_buffer()
|
||||
else:
|
||||
dlg = widgetUtils.YES
|
||||
if dlg == widgetUtils.YES:
|
||||
self.session.db.pop(self.name)
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
def get_more_items(self, *args, **kwargs):
|
||||
# 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."))
|
||||
def get_more_items(self, *args, **kwargs):
|
||||
# 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."))
|
||||
|
||||
def onFocus(self, event, *args, **kwargs):
|
||||
event.Skip()
|
||||
def onFocus(self, event, *args, **kwargs):
|
||||
event.Skip()
|
||||
|
||||
def add_to_library(self, *args, **kwargs):
|
||||
call_threaded(self._add_to_library, *args, **kwargs)
|
||||
def add_to_library(self, *args, **kwargs):
|
||||
call_threaded(self._add_to_library, *args, **kwargs)
|
||||
|
||||
def _add_to_library(self, *args, **kwargs):
|
||||
selected = self.tab.list.get_multiple_selection()
|
||||
if len(selected) < 1:
|
||||
return
|
||||
audios = [self.session.db[self.name]["items"][audio] for audio in selected]
|
||||
errors_detected = 0
|
||||
for i in audios:
|
||||
args = {}
|
||||
args["audio_id"] = i["id"]
|
||||
if "album_id" in i:
|
||||
args["album_id"] = i["album_id"]
|
||||
args["owner_id"] = i["owner_id"]
|
||||
try:
|
||||
audio = self.session.vk.client.audio.add(**args)
|
||||
except VkApiError:
|
||||
errors_detected = errors_detected + 1
|
||||
continue
|
||||
if audio != None and int(audio) < 21:
|
||||
errors_detected = errors_detected + 1
|
||||
if errors_detected == 0:
|
||||
if len(selected) == 1:
|
||||
msg = _("Audio added to your library")
|
||||
elif len(selected) > 1 and len(selected) < 5:
|
||||
msg = _("{0} audios were added to your library.").format(len(selected),)
|
||||
else:
|
||||
msg = _("{audios} audios were added to your library.").format(audios=len(selected),)
|
||||
output.speak(msg)
|
||||
else:
|
||||
output.speak(_("{0} errors occurred while attempting to add {1} audios to your library.").format(errors_detected, len(selected)))
|
||||
def _add_to_library(self, *args, **kwargs):
|
||||
selected = self.tab.list.get_multiple_selection()
|
||||
if len(selected) < 1:
|
||||
return
|
||||
audios = [self.session.db[self.name]["items"][audio] for audio in selected]
|
||||
errors_detected = 0
|
||||
for i in audios:
|
||||
args = {}
|
||||
args["audio_id"] = i["id"]
|
||||
if "album_id" in i:
|
||||
args["album_id"] = i["album_id"]
|
||||
args["owner_id"] = i["owner_id"]
|
||||
try:
|
||||
audio = self.session.vk.client.audio.add(**args)
|
||||
except VkApiError:
|
||||
errors_detected = errors_detected + 1
|
||||
continue
|
||||
if audio != None and int(audio) < 21:
|
||||
errors_detected = errors_detected + 1
|
||||
if errors_detected == 0:
|
||||
if len(selected) == 1:
|
||||
msg = _("Audio added to your library")
|
||||
elif len(selected) > 1 and len(selected) < 5:
|
||||
msg = _("{0} audios were added to your library.").format(len(selected),)
|
||||
else:
|
||||
msg = _("{audios} audios were added to your library.").format(audios=len(selected),)
|
||||
output.speak(msg)
|
||||
else:
|
||||
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):
|
||||
call_threaded(self._remove_from_library, *args, **kwargs)
|
||||
def remove_from_library(self, *args, **kwargs):
|
||||
call_threaded(self._remove_from_library, *args, **kwargs)
|
||||
|
||||
def _remove_from_library(self, *args, **kwargs):
|
||||
selected = self.tab.list.get_multiple_selection()
|
||||
if len(selected) < 1:
|
||||
return
|
||||
audios = [self.session.db[self.name]["items"][audio] for audio in selected]
|
||||
errors_detected = 0
|
||||
audios_removed = 0
|
||||
for i in range(0, len(selected)):
|
||||
args = {}
|
||||
args["audio_id"] = audios[i]["id"]
|
||||
args["owner_id"] = self.session.user_id
|
||||
result = self.session.vk.client.audio.delete(**args)
|
||||
if int(result) != 1:
|
||||
errors_dtected = errors_detected + 1
|
||||
else:
|
||||
self.session.db[self.name]["items"].pop(selected[i]-audios_removed)
|
||||
self.tab.list.remove_item(selected[i]-audios_removed)
|
||||
audios_removed = audios_removed + 1
|
||||
if errors_detected == 0:
|
||||
if len(selected) == 1:
|
||||
msg = _("Audio removed.")
|
||||
elif len(selected) > 1 and len(selected) < 5:
|
||||
msg = _("{0} audios were removed.").format(len(selected),)
|
||||
else:
|
||||
msg = _("{audios} audios were removed.").format(audios=len(selected),)
|
||||
output.speak(msg)
|
||||
else:
|
||||
output.speak(_("{0} errors occurred while attempting to remove {1} audios.").format(errors_detected, len(selected)))
|
||||
def _remove_from_library(self, *args, **kwargs):
|
||||
selected = self.tab.list.get_multiple_selection()
|
||||
if len(selected) < 1:
|
||||
return
|
||||
audios = [self.session.db[self.name]["items"][audio] for audio in selected]
|
||||
errors_detected = 0
|
||||
audios_removed = 0
|
||||
for i in range(0, len(selected)):
|
||||
args = {}
|
||||
args["audio_id"] = audios[i]["id"]
|
||||
args["owner_id"] = self.session.user_id
|
||||
result = self.session.vk.client.audio.delete(**args)
|
||||
if int(result) != 1:
|
||||
errors_dtected = errors_detected + 1
|
||||
else:
|
||||
self.session.db[self.name]["items"].pop(selected[i]-audios_removed)
|
||||
self.tab.list.remove_item(selected[i]-audios_removed)
|
||||
audios_removed = audios_removed + 1
|
||||
if errors_detected == 0:
|
||||
if len(selected) == 1:
|
||||
msg = _("Audio removed.")
|
||||
elif len(selected) > 1 and len(selected) < 5:
|
||||
msg = _("{0} audios were removed.").format(len(selected),)
|
||||
else:
|
||||
msg = _("{audios} audios were removed.").format(audios=len(selected),)
|
||||
output.speak(msg)
|
||||
else:
|
||||
output.speak(_("{0} errors occurred while attempting to remove {1} audios.").format(errors_detected, len(selected)))
|
||||
|
||||
def move_to_album(self, *args, **kwargs):
|
||||
if len(self.session.audio_albums) == 0:
|
||||
return commonMessages.no_audio_albums()
|
||||
album = selector.album(_("Select the album where you want to move this song"), self.session)
|
||||
if album.item == None:
|
||||
return
|
||||
call_threaded(self._move_to_album, album.item, *args, **kwargs)
|
||||
def move_to_album(self, *args, **kwargs):
|
||||
if len(self.session.audio_albums) == 0:
|
||||
return commonMessages.no_audio_albums()
|
||||
album = selector.album(_("Select the album where you want to move this song"), self.session)
|
||||
if album.item == None:
|
||||
return
|
||||
call_threaded(self._move_to_album, album.item, *args, **kwargs)
|
||||
|
||||
def _move_to_album(self, album, *args, **kwargs):
|
||||
selected = self.tab.list.get_multiple_selection()
|
||||
if len(selected) < 1:
|
||||
return
|
||||
audios = [self.session.db[self.name]["items"][audio] for audio in selected]
|
||||
errors_detected = 0
|
||||
for i in audios:
|
||||
id = i["id"]
|
||||
try:
|
||||
response = self.session.vk.client.audio.add(playlist_id=album, audio_id=id, owner_id=i["owner_id"])
|
||||
except VkApiError:
|
||||
errors_detected = errors_detected + 1
|
||||
if errors_detected == 0:
|
||||
if len(selected) == 1:
|
||||
msg = _("Audio added to playlist.")
|
||||
elif len(selected) > 1 and len(selected) < 5:
|
||||
msg = _("{0} audios were added to playlist.").format(len(selected),)
|
||||
else:
|
||||
msg = _("{audios} audios were added to playlist.").format(audios=len(selected),)
|
||||
output.speak(msg)
|
||||
else:
|
||||
output.speak(_("{0} errors occurred while attempting to add {1} audios to your playlist.").format(errors_detected, len(selected)))
|
||||
def _move_to_album(self, album, *args, **kwargs):
|
||||
selected = self.tab.list.get_multiple_selection()
|
||||
if len(selected) < 1:
|
||||
return
|
||||
audios = [self.session.db[self.name]["items"][audio] for audio in selected]
|
||||
errors_detected = 0
|
||||
for i in audios:
|
||||
id = i["id"]
|
||||
try:
|
||||
response = self.session.vk.client.audio.add(playlist_id=album, audio_id=id, owner_id=i["owner_id"])
|
||||
except VkApiError:
|
||||
errors_detected = errors_detected + 1
|
||||
if errors_detected == 0:
|
||||
if len(selected) == 1:
|
||||
msg = _("Audio added to playlist.")
|
||||
elif len(selected) > 1 and len(selected) < 5:
|
||||
msg = _("{0} audios were added to playlist.").format(len(selected),)
|
||||
else:
|
||||
msg = _("{audios} audios were added to playlist.").format(audios=len(selected),)
|
||||
output.speak(msg)
|
||||
else:
|
||||
output.speak(_("{0} errors occurred while attempting to add {1} audios to your playlist.").format(errors_detected, len(selected)))
|
||||
|
||||
def get_menu(self):
|
||||
p = self.get_post()
|
||||
if p == None:
|
||||
return
|
||||
m = menus.audioMenu()
|
||||
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.move_to_album, menuitem=m.move)
|
||||
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.deselect_all, menuitem=m.deselect)
|
||||
# if owner_id is the current user, the audio is added to the user's audios.
|
||||
if p["owner_id"] == self.session.user_id:
|
||||
m.library.SetItemLabel(_("&Remove"))
|
||||
widgetUtils.connect_event(m, widgetUtils.MENU, self.remove_from_library, menuitem=m.library)
|
||||
else:
|
||||
widgetUtils.connect_event(m, widgetUtils.MENU, self.add_to_library, menuitem=m.library)
|
||||
return m
|
||||
def get_menu(self):
|
||||
p = self.get_post()
|
||||
if p == None:
|
||||
return
|
||||
m = menus.audioMenu()
|
||||
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.move_to_album, menuitem=m.move)
|
||||
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.deselect_all, menuitem=m.deselect)
|
||||
# if owner_id is the current user, the audio is added to the user's audios.
|
||||
if p["owner_id"] == self.session.user_id:
|
||||
m.library.SetItemLabel(_("&Remove"))
|
||||
widgetUtils.connect_event(m, widgetUtils.MENU, self.remove_from_library, menuitem=m.library)
|
||||
else:
|
||||
widgetUtils.connect_event(m, widgetUtils.MENU, self.add_to_library, menuitem=m.library)
|
||||
return m
|
||||
|
||||
def post(self, *args, **kwargs):
|
||||
""" Uploads an audio to the current user's library from the computer. """
|
||||
file = self.tab.get_file_to_upload()
|
||||
if file == None:
|
||||
return
|
||||
audio_tags = ID3(file)
|
||||
if "TIT2" in audio_tags:
|
||||
title = audio_tags["TIT2"].text[0]
|
||||
else:
|
||||
title = _("Untitled")
|
||||
if "TPE1" in audio_tags:
|
||||
artist = audio_tags["TPE1"].text[0]
|
||||
else:
|
||||
artist = _("Unknown artist")
|
||||
uploader = upload.VkUpload(self.session.vk.session_object)
|
||||
call_threaded(uploader.audio, file, title=title, artist=artist)
|
||||
def post(self, *args, **kwargs):
|
||||
""" Uploads an audio to the current user's library from the computer. """
|
||||
file = self.tab.get_file_to_upload()
|
||||
if file == None:
|
||||
return
|
||||
audio_tags = ID3(file)
|
||||
if "TIT2" in audio_tags:
|
||||
title = audio_tags["TIT2"].text[0]
|
||||
else:
|
||||
title = _("Untitled")
|
||||
if "TPE1" in audio_tags:
|
||||
artist = audio_tags["TPE1"].text[0]
|
||||
else:
|
||||
artist = _("Unknown artist")
|
||||
uploader = upload.VkUpload(self.session.vk.session_object)
|
||||
call_threaded(uploader.audio, file, title=title, artist=artist)
|
||||
|
||||
def open_in_browser(self, *args, **kwargs):
|
||||
post = self.get_post()
|
||||
if post == None:
|
||||
return
|
||||
url = "https://vk.com/audio{user_id}_{post_id}".format(user_id=post["owner_id"], post_id=post["id"])
|
||||
webbrowser.open_new_tab(url)
|
||||
def open_in_browser(self, *args, **kwargs):
|
||||
post = self.get_post()
|
||||
if post == None:
|
||||
return
|
||||
url = "https://vk.com/audio{user_id}_{post_id}".format(user_id=post["owner_id"], post_id=post["id"])
|
||||
webbrowser.open_new_tab(url)
|
||||
|
||||
def change_label(self, stopped):
|
||||
if hasattr(self.tab, "play"):
|
||||
if stopped == False:
|
||||
self.tab.play.SetLabel(_("P&ause"))
|
||||
else:
|
||||
self.tab.play.SetLabel(_("P&lay"))
|
||||
def change_label(self, stopped):
|
||||
if hasattr(self.tab, "play"):
|
||||
if stopped == False:
|
||||
self.tab.play.SetLabel(_("P&ause"))
|
||||
else:
|
||||
self.tab.play.SetLabel(_("P&lay"))
|
||||
|
||||
def __del__(self):
|
||||
pub.unsubscribe(self.change_label, "playback-changed")
|
||||
def __del__(self):
|
||||
pub.unsubscribe(self.change_label, "playback-changed")
|
||||
|
||||
def download(self, *args, **kwargs):
|
||||
selected = self.tab.list.get_multiple_selection()
|
||||
if len(selected) < 1:
|
||||
return
|
||||
audios = [self.session.db[self.name]["items"][audio] for audio in selected]
|
||||
if len(audios) == 0:
|
||||
return
|
||||
elif len(audios) == 1:
|
||||
multiple = False
|
||||
filename = utils.safe_filename("{0} - {1}.mp3".format(audios[0]["title"], audios[0]["artist"]))
|
||||
else:
|
||||
multiple = True
|
||||
filename = "" # No default filename for multiple files.
|
||||
path = self.tab.get_download_path(filename=filename, multiple=multiple)
|
||||
self.download_threaded(path, multiple, audios)
|
||||
def download(self, *args, **kwargs):
|
||||
selected = self.tab.list.get_multiple_selection()
|
||||
if len(selected) < 1:
|
||||
return
|
||||
audios = [self.session.db[self.name]["items"][audio] for audio in selected]
|
||||
if len(audios) == 0:
|
||||
return
|
||||
elif len(audios) == 1:
|
||||
multiple = False
|
||||
filename = utils.safe_filename("{0} - {1}.mp3".format(audios[0]["title"], audios[0]["artist"]))
|
||||
else:
|
||||
multiple = True
|
||||
filename = "" # No default filename for multiple files.
|
||||
path = self.tab.get_download_path(filename=filename, multiple=multiple)
|
||||
self.download_threaded(path, multiple, audios)
|
||||
|
||||
def download_threaded(self, path, multiple, audios):
|
||||
if multiple == False:
|
||||
url = audios[0]["url"]
|
||||
pub.sendMessage("download-file", url=url, filename=path)
|
||||
return
|
||||
else:
|
||||
downloads = []
|
||||
for i in audios:
|
||||
filename = utils.safe_filename("{0} - {1}.mp3".format(i["title"], i["artist"]))
|
||||
filepath = os.path.join(path, filename)
|
||||
downloads.append((utils.transform_audio_url(i["url"]), filepath))
|
||||
pub.sendMessage("download-files", downloads=downloads)
|
||||
def download_threaded(self, path, multiple, audios):
|
||||
if multiple == False:
|
||||
url = audios[0]["url"]
|
||||
pub.sendMessage("download-file", url=url, filename=path)
|
||||
return
|
||||
else:
|
||||
downloads = []
|
||||
for i in audios:
|
||||
filename = utils.safe_filename("{0} - {1}.mp3".format(i["title"], i["artist"]))
|
||||
filepath = os.path.join(path, filename)
|
||||
downloads.append((utils.transform_audio_url(i["url"]), filepath))
|
||||
pub.sendMessage("download-files", downloads=downloads)
|
||||
|
||||
def select_all(self, *args, **kwargs):
|
||||
items = self.tab.list.list.GetItemCount()
|
||||
for i in range(0, items):
|
||||
self.tab.list.list.SetItemImage(i, 1)
|
||||
def select_all(self, *args, **kwargs):
|
||||
items = self.tab.list.list.GetItemCount()
|
||||
for i in range(0, items):
|
||||
self.tab.list.list.SetItemImage(i, 1)
|
||||
|
||||
def deselect_all(self, *args, **kwargs):
|
||||
items = self.tab.list.list.GetItemCount()
|
||||
for i in range(0, items):
|
||||
self.tab.list.list.SetItemImage(i, 0)
|
||||
def deselect_all(self, *args, **kwargs):
|
||||
items = self.tab.list.list.GetItemCount()
|
||||
for i in range(0, items):
|
||||
self.tab.list.list.SetItemImage(i, 0)
|
||||
|
@ -9,26 +9,26 @@ from .audio import audioBuffer
|
||||
log = logging.getLogger("controller.buffers.audioPlaylist")
|
||||
|
||||
class audioAlbumBuffer(audioBuffer):
|
||||
""" this buffer was supposed to be used with audio albums
|
||||
but is deprecated as VK removed its audio support for third party apps."""
|
||||
""" this buffer was supposed to be used with audio albums
|
||||
but is deprecated as VK removed its audio support for third party apps."""
|
||||
|
||||
def create_tab(self, parent):
|
||||
self.tab = audioAlbum.audioAlbumTab(parent)
|
||||
self.tab.play.Enable(False)
|
||||
self.tab.play_all.Enable(False)
|
||||
self.connect_events()
|
||||
self.tab.name = self.name
|
||||
if hasattr(self, "can_post") and self.can_post == False and hasattr(self.tab, "post"):
|
||||
self.tab.post.Enable(False)
|
||||
def create_tab(self, parent):
|
||||
self.tab = audioAlbum.audioAlbumTab(parent)
|
||||
self.tab.play.Enable(False)
|
||||
self.tab.play_all.Enable(False)
|
||||
self.connect_events()
|
||||
self.tab.name = self.name
|
||||
if hasattr(self, "can_post") and self.can_post == False and hasattr(self.tab, "post"):
|
||||
self.tab.post.Enable(False)
|
||||
|
||||
def connect_events(self):
|
||||
super(audioAlbumBuffer, self).connect_events()
|
||||
widgetUtils.connect_event(self.tab.load, widgetUtils.BUTTON_PRESSED, self.load_album)
|
||||
def connect_events(self):
|
||||
super(audioAlbumBuffer, self).connect_events()
|
||||
widgetUtils.connect_event(self.tab.load, widgetUtils.BUTTON_PRESSED, self.load_album)
|
||||
|
||||
def load_album(self, *args, **kwargs):
|
||||
output.speak(_("Loading album..."))
|
||||
self.can_get_items = True
|
||||
self.tab.load.Enable(False)
|
||||
wx.CallAfter(self.get_items)
|
||||
self.tab.play.Enable(True)
|
||||
self.tab.play_all.Enable(True)
|
||||
def load_album(self, *args, **kwargs):
|
||||
output.speak(_("Loading album..."))
|
||||
self.can_get_items = True
|
||||
self.tab.load.Enable(False)
|
||||
wx.CallAfter(self.get_items)
|
||||
self.tab.play.Enable(True)
|
||||
self.tab.play_all.Enable(True)
|
||||
|
@ -22,286 +22,286 @@ log = logging.getLogger("controller.buffers.chat")
|
||||
|
||||
class chatBuffer(homeBuffer):
|
||||
|
||||
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."""
|
||||
# as this tab is based in a text control, we have to overwrite the defaults.
|
||||
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.
|
||||
# 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)
|
||||
self.chats[values] = item["id"]
|
||||
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."""
|
||||
# as this tab is based in a text control, we have to overwrite the defaults.
|
||||
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.
|
||||
# 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)
|
||||
self.chats[values] = item["id"]
|
||||
|
||||
def get_focused_post(self):
|
||||
""" 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.
|
||||
# Instead of the traditional method to do the trick.
|
||||
# Get text position here.
|
||||
position = self.tab.history.PositionToXY(self.tab.history.GetInsertionPoint())
|
||||
id_ = None
|
||||
# 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())):
|
||||
# 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).
|
||||
# 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]:
|
||||
id_ = self.chats[i]
|
||||
# If we find our chat message, let's skip the rest of the loop.
|
||||
break
|
||||
# Retrieve here the object based in id_
|
||||
if id_ != None:
|
||||
for i in self.session.db[self.name]["items"]:
|
||||
if i["id"] == id_:
|
||||
return i
|
||||
return False
|
||||
def get_focused_post(self):
|
||||
""" 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.
|
||||
# Instead of the traditional method to do the trick.
|
||||
# Get text position here.
|
||||
position = self.tab.history.PositionToXY(self.tab.history.GetInsertionPoint())
|
||||
id_ = None
|
||||
# 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())):
|
||||
# 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).
|
||||
# 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]:
|
||||
id_ = self.chats[i]
|
||||
# If we find our chat message, let's skip the rest of the loop.
|
||||
break
|
||||
# Retrieve here the object based in id_
|
||||
if id_ != None:
|
||||
for i in self.session.db[self.name]["items"]:
|
||||
if i["id"] == id_:
|
||||
return i
|
||||
return False
|
||||
|
||||
get_post = get_focused_post
|
||||
get_post = get_focused_post
|
||||
|
||||
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:
|
||||
msg = self.get_focused_post()
|
||||
if msg == False: # Handle the case where the last line of the control cannot be matched to anything.
|
||||
return
|
||||
# Mark unread conversations as read.
|
||||
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")
|
||||
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"]]
|
||||
if "attachments" in msg and len(msg["attachments"]) > 0:
|
||||
self.tab.attachments.list.Enable(True)
|
||||
self.attachments = list()
|
||||
self.tab.attachments.clear()
|
||||
self.parse_attachments(msg)
|
||||
else:
|
||||
self.tab.attachments.list.Enable(False)
|
||||
self.tab.attachments.clear()
|
||||
event.Skip()
|
||||
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:
|
||||
msg = self.get_focused_post()
|
||||
if msg == False: # Handle the case where the last line of the control cannot be matched to anything.
|
||||
return
|
||||
# Mark unread conversations as read.
|
||||
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")
|
||||
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"]]
|
||||
if "attachments" in msg and len(msg["attachments"]) > 0:
|
||||
self.tab.attachments.list.Enable(True)
|
||||
self.attachments = list()
|
||||
self.tab.attachments.clear()
|
||||
self.parse_attachments(msg)
|
||||
else:
|
||||
self.tab.attachments.list.Enable(False)
|
||||
self.tab.attachments.clear()
|
||||
event.Skip()
|
||||
|
||||
def create_tab(self, parent):
|
||||
self.tab = chat.chatTab(parent)
|
||||
self.attachments = list()
|
||||
self.connect_events()
|
||||
self.tab.name = self.name
|
||||
if hasattr(self, "can_post") and self.can_post == False and hasattr(self.tab, "post"):
|
||||
self.tab.post.Enable(False)
|
||||
def create_tab(self, parent):
|
||||
self.tab = chat.chatTab(parent)
|
||||
self.attachments = list()
|
||||
self.connect_events()
|
||||
self.tab.name = self.name
|
||||
if hasattr(self, "can_post") and self.can_post == False and hasattr(self.tab, "post"):
|
||||
self.tab.post.Enable(False)
|
||||
|
||||
def connect_events(self):
|
||||
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.text, widgetUtils.KEYPRESS, self.catch_enter)
|
||||
widgetUtils.connect_event(self.tab.actions, widgetUtils.BUTTON_PRESSED, self.actions)
|
||||
self.tab.set_focus_function(self.onFocus)
|
||||
def connect_events(self):
|
||||
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.text, widgetUtils.KEYPRESS, self.catch_enter)
|
||||
widgetUtils.connect_event(self.tab.actions, widgetUtils.BUTTON_PRESSED, self.actions)
|
||||
self.tab.set_focus_function(self.onFocus)
|
||||
|
||||
def catch_enter(self, event, *args, **kwargs):
|
||||
shift=event.ShiftDown()
|
||||
if event.GetKeyCode() == wx.WXK_RETURN and shift == False:
|
||||
return self.send_chat_to_user()
|
||||
t = time.time()
|
||||
if event.GetUnicodeKey() != wx.WXK_NONE and t-self.last_keypress > 5:
|
||||
self.last_keypress = t
|
||||
call_threaded(self.session.vk.client.messages.setActivity, peer_id=self.kwargs["peer_id"], type="typing")
|
||||
event.Skip()
|
||||
def catch_enter(self, event, *args, **kwargs):
|
||||
shift=event.ShiftDown()
|
||||
if event.GetKeyCode() == wx.WXK_RETURN and shift == False:
|
||||
return self.send_chat_to_user()
|
||||
t = time.time()
|
||||
if event.GetUnicodeKey() != wx.WXK_NONE and t-self.last_keypress > 5:
|
||||
self.last_keypress = t
|
||||
call_threaded(self.session.vk.client.messages.setActivity, peer_id=self.kwargs["peer_id"], type="typing")
|
||||
event.Skip()
|
||||
|
||||
def get_items(self, show_nextpage=False):
|
||||
""" Update buffer with newest items or get older items in the buffer."""
|
||||
if self.can_get_items == False: return
|
||||
retrieved = True
|
||||
try:
|
||||
num = getattr(self.session, "get_page")(show_nextpage=show_nextpage, name=self.name, *self.args, **self.kwargs)
|
||||
except VkApiError as err:
|
||||
log.error("Error {0}: {1}".format(err.code, err.error))
|
||||
retrieved = err.code
|
||||
return retrieved
|
||||
except:
|
||||
log.exception("Connection error when updating buffer %s. Will try again in 2 minutes" % (self.name,))
|
||||
return False
|
||||
if not hasattr(self, "tab"):
|
||||
# Create GUI associated to this buffer.
|
||||
self.create_tab(self.parent)
|
||||
# Add name to the new control so we could look for it when needed.
|
||||
self.tab.name = self.name
|
||||
if show_nextpage == False:
|
||||
if self.tab.history.GetValue() != "" and num > 0:
|
||||
v = [i for i in self.session.db[self.name]["items"][:num]]
|
||||
[self.insert(i, False) for i in v]
|
||||
else:
|
||||
[self.insert(i) for i in self.session.db[self.name]["items"][:num]]
|
||||
else:
|
||||
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.
|
||||
# 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.
|
||||
focused_post = self.get_post()
|
||||
self.chats = dict()
|
||||
wx.CallAfter(self.tab.history.SetValue, "")
|
||||
v = [i for i in self.session.db[self.name]["items"]]
|
||||
[self.insert(i) for i in v]
|
||||
# Now it's time to set back the focus in the post.
|
||||
for i in self.chats.keys():
|
||||
if self.chats[i] == focused_post["id"]:
|
||||
line = i[0]
|
||||
wx.CallAfter(self.tab.history.SetInsertionPoint, self.tab.history.XYToPosition(0, line))
|
||||
output.speak(_("Items loaded"))
|
||||
break
|
||||
if self.unread == True and num > 0:
|
||||
self.session.db[self.name]["items"][-1].update(read_state=0)
|
||||
return retrieved
|
||||
def get_items(self, show_nextpage=False):
|
||||
""" Update buffer with newest items or get older items in the buffer."""
|
||||
if self.can_get_items == False: return
|
||||
retrieved = True
|
||||
try:
|
||||
num = getattr(self.session, "get_page")(show_nextpage=show_nextpage, name=self.name, *self.args, **self.kwargs)
|
||||
except VkApiError as err:
|
||||
log.error("Error {0}: {1}".format(err.code, err.error))
|
||||
retrieved = err.code
|
||||
return retrieved
|
||||
except:
|
||||
log.exception("Connection error when updating buffer %s. Will try again in 2 minutes" % (self.name,))
|
||||
return False
|
||||
if not hasattr(self, "tab"):
|
||||
# Create GUI associated to this buffer.
|
||||
self.create_tab(self.parent)
|
||||
# Add name to the new control so we could look for it when needed.
|
||||
self.tab.name = self.name
|
||||
if show_nextpage == False:
|
||||
if self.tab.history.GetValue() != "" and num > 0:
|
||||
v = [i for i in self.session.db[self.name]["items"][:num]]
|
||||
[self.insert(i, False) for i in v]
|
||||
else:
|
||||
[self.insert(i) for i in self.session.db[self.name]["items"][:num]]
|
||||
else:
|
||||
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.
|
||||
# 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.
|
||||
focused_post = self.get_post()
|
||||
self.chats = dict()
|
||||
wx.CallAfter(self.tab.history.SetValue, "")
|
||||
v = [i for i in self.session.db[self.name]["items"]]
|
||||
[self.insert(i) for i in v]
|
||||
# Now it's time to set back the focus in the post.
|
||||
for i in self.chats.keys():
|
||||
if self.chats[i] == focused_post["id"]:
|
||||
line = i[0]
|
||||
wx.CallAfter(self.tab.history.SetInsertionPoint, self.tab.history.XYToPosition(0, line))
|
||||
output.speak(_("Items loaded"))
|
||||
break
|
||||
if self.unread == True and num > 0:
|
||||
self.session.db[self.name]["items"][-1].update(read_state=0)
|
||||
return retrieved
|
||||
|
||||
def get_more_items(self):
|
||||
output.speak(_("Getting more items..."))
|
||||
call_threaded(self.get_items, show_nextpage=True)
|
||||
def get_more_items(self):
|
||||
output.speak(_("Getting more items..."))
|
||||
call_threaded(self.get_items, show_nextpage=True)
|
||||
|
||||
def add_attachment(self, *args, **kwargs):
|
||||
a = presenters.attachPresenter(session=self.session, view=views.attachDialog(voice_messages=True), interactor=interactors.attachInteractor())
|
||||
if len(a.attachments) != 0:
|
||||
self.attachments_to_be_sent = a.attachments
|
||||
def add_attachment(self, *args, **kwargs):
|
||||
a = presenters.attachPresenter(session=self.session, view=views.attachDialog(voice_messages=True), interactor=interactors.attachInteractor())
|
||||
if len(a.attachments) != 0:
|
||||
self.attachments_to_be_sent = a.attachments
|
||||
|
||||
def send_chat_to_user(self, *args, **kwargs):
|
||||
text = self.tab.text.GetValue()
|
||||
if text == "" and not hasattr(self, "attachments_to_be_sent"):
|
||||
wx.Bell()
|
||||
return
|
||||
self.tab.text.SetValue("")
|
||||
post_arguments = dict(random_id = random.randint(0, 100000), peer_id=self.kwargs["peer_id"])
|
||||
if len(text) > 0:
|
||||
post_arguments.update(message=text)
|
||||
if hasattr(self, "attachments_to_be_sent") and len(self.attachments_to_be_sent) > 0:
|
||||
attachments = self.attachments_to_be_sent[::]
|
||||
else:
|
||||
attachments = []
|
||||
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"):
|
||||
del self.attachments_to_be_sent
|
||||
def send_chat_to_user(self, *args, **kwargs):
|
||||
text = self.tab.text.GetValue()
|
||||
if text == "" and not hasattr(self, "attachments_to_be_sent"):
|
||||
wx.Bell()
|
||||
return
|
||||
self.tab.text.SetValue("")
|
||||
post_arguments = dict(random_id = random.randint(0, 100000), peer_id=self.kwargs["peer_id"])
|
||||
if len(text) > 0:
|
||||
post_arguments.update(message=text)
|
||||
if hasattr(self, "attachments_to_be_sent") and len(self.attachments_to_be_sent) > 0:
|
||||
attachments = self.attachments_to_be_sent[::]
|
||||
else:
|
||||
attachments = []
|
||||
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"):
|
||||
del self.attachments_to_be_sent
|
||||
|
||||
def __init__(self, unread=False, *args, **kwargs):
|
||||
super(chatBuffer, self).__init__(*args, **kwargs)
|
||||
self.unread = unread
|
||||
self.chats = dict()
|
||||
self.peer_typing = 0
|
||||
self.last_keypress = time.time()
|
||||
def __init__(self, unread=False, *args, **kwargs):
|
||||
super(chatBuffer, self).__init__(*args, **kwargs)
|
||||
self.unread = unread
|
||||
self.chats = dict()
|
||||
self.peer_typing = 0
|
||||
self.last_keypress = time.time()
|
||||
|
||||
def parse_attachments(self, post):
|
||||
attachments = []
|
||||
def parse_attachments(self, post):
|
||||
attachments = []
|
||||
|
||||
if "attachments" in post:
|
||||
for i in post["attachments"]:
|
||||
# We don't need the photos_list attachment, so skip it.
|
||||
if i["type"] == "photos_list":
|
||||
continue
|
||||
try:
|
||||
rendered_object = renderers.add_attachment(i)
|
||||
except:
|
||||
log.exception("Error parsing the following attachment on chat: %r" % (i,))
|
||||
attachments.append(rendered_object)
|
||||
self.attachments.append(i)
|
||||
self.tab.attachments.list.Bind(wx.EVT_LIST_ITEM_ACTIVATED, self.open_attachment)
|
||||
self.tab.insert_attachments(attachments)
|
||||
if "attachments" in post:
|
||||
for i in post["attachments"]:
|
||||
# We don't need the photos_list attachment, so skip it.
|
||||
if i["type"] == "photos_list":
|
||||
continue
|
||||
try:
|
||||
rendered_object = renderers.add_attachment(i)
|
||||
except:
|
||||
log.exception("Error parsing the following attachment on chat: %r" % (i,))
|
||||
attachments.append(rendered_object)
|
||||
self.attachments.append(i)
|
||||
self.tab.attachments.list.Bind(wx.EVT_LIST_ITEM_ACTIVATED, self.open_attachment)
|
||||
self.tab.insert_attachments(attachments)
|
||||
|
||||
def open_attachment(self, *args, **kwargs):
|
||||
index = self.tab.attachments.get_selected()
|
||||
attachment = self.attachments[index]
|
||||
if attachment["type"] == "audio":
|
||||
a = presenters.displayAudioPresenter(session=self.session, postObject=[attachment["audio"]], interactor=interactors.displayAudioInteractor(), view=views.displayAudio())
|
||||
elif attachment["type"] == "audio_message":
|
||||
link = attachment["audio_message"]["link_mp3"]
|
||||
pub.sendMessage("play-message", message_url=link)
|
||||
elif attachment["type"] == "link":
|
||||
output.speak(_("Opening URL..."), True)
|
||||
webbrowser.open_new_tab(attachment["link"]["url"])
|
||||
elif attachment["type"] == "doc":
|
||||
output.speak(_("Opening document in web browser..."))
|
||||
webbrowser.open(attachment["doc"]["url"])
|
||||
elif attachment["type"] == "video":
|
||||
# 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.
|
||||
# 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.
|
||||
# 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.
|
||||
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 = video_object["items"][0]
|
||||
output.speak(_("Opening video in web browser..."), True)
|
||||
webbrowser.open_new_tab(video_object["player"])
|
||||
elif attachment["type"] == "photo":
|
||||
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_sizes = [1280, 604, 130, 75]
|
||||
url = ""
|
||||
for i in possible_sizes:
|
||||
if "photo_{0}".format(i,) in attachment["photo"]:
|
||||
url = attachment["photo"]["photo_{0}".format(i,)]
|
||||
break
|
||||
if url != "":
|
||||
webbrowser.open_new_tab(url)
|
||||
if attachment["type"] == "wall":
|
||||
pub.sendMessage("open-post", post_object=attachment["wall"], controller_="displayPost")
|
||||
else:
|
||||
log.debug("Unhandled attachment: %r" % (attachment,))
|
||||
def open_attachment(self, *args, **kwargs):
|
||||
index = self.tab.attachments.get_selected()
|
||||
attachment = self.attachments[index]
|
||||
if attachment["type"] == "audio":
|
||||
a = presenters.displayAudioPresenter(session=self.session, postObject=[attachment["audio"]], interactor=interactors.displayAudioInteractor(), view=views.displayAudio())
|
||||
elif attachment["type"] == "audio_message":
|
||||
link = attachment["audio_message"]["link_mp3"]
|
||||
pub.sendMessage("play-message", message_url=link)
|
||||
elif attachment["type"] == "link":
|
||||
output.speak(_("Opening URL..."), True)
|
||||
webbrowser.open_new_tab(attachment["link"]["url"])
|
||||
elif attachment["type"] == "doc":
|
||||
output.speak(_("Opening document in web browser..."))
|
||||
webbrowser.open(attachment["doc"]["url"])
|
||||
elif attachment["type"] == "video":
|
||||
# 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.
|
||||
# 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.
|
||||
# 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.
|
||||
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 = video_object["items"][0]
|
||||
output.speak(_("Opening video in web browser..."), True)
|
||||
webbrowser.open_new_tab(video_object["player"])
|
||||
elif attachment["type"] == "photo":
|
||||
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_sizes = [1280, 604, 130, 75]
|
||||
url = ""
|
||||
for i in possible_sizes:
|
||||
if "photo_{0}".format(i,) in attachment["photo"]:
|
||||
url = attachment["photo"]["photo_{0}".format(i,)]
|
||||
break
|
||||
if url != "":
|
||||
webbrowser.open_new_tab(url)
|
||||
if attachment["type"] == "wall":
|
||||
pub.sendMessage("open-post", post_object=attachment["wall"], controller_="displayPost")
|
||||
else:
|
||||
log.debug("Unhandled attachment: %r" % (attachment,))
|
||||
|
||||
def clear_reads(self):
|
||||
for i in self.session.db[self.name]["items"]:
|
||||
if "read_state" in i and i["read_state"] == 0:
|
||||
i["read_state"] = 1
|
||||
def clear_reads(self):
|
||||
for i in self.session.db[self.name]["items"]:
|
||||
if "read_state" in i and i["read_state"] == 0:
|
||||
i["read_state"] = 1
|
||||
|
||||
def remove_buffer(self, mandatory=False):
|
||||
""" Remove buffer if the current buffer is not the logged user's wall."""
|
||||
if mandatory == False:
|
||||
dlg = commonMessages.remove_buffer()
|
||||
else:
|
||||
dlg = widgetUtils.YES
|
||||
if dlg == widgetUtils.YES:
|
||||
self.session.db.pop(self.name)
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
def remove_buffer(self, mandatory=False):
|
||||
""" Remove buffer if the current buffer is not the logged user's wall."""
|
||||
if mandatory == False:
|
||||
dlg = commonMessages.remove_buffer()
|
||||
else:
|
||||
dlg = widgetUtils.YES
|
||||
if dlg == widgetUtils.YES:
|
||||
self.session.db.pop(self.name)
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
def open_in_browser(self, *args, **kwargs):
|
||||
peer_id = self.kwargs["peer_id"]
|
||||
url = "https://vk.com/im?sel={peer_id}".format(peer_id=peer_id)
|
||||
webbrowser.open_new_tab(url)
|
||||
def open_in_browser(self, *args, **kwargs):
|
||||
peer_id = self.kwargs["peer_id"]
|
||||
url = "https://vk.com/im?sel={peer_id}".format(peer_id=peer_id)
|
||||
webbrowser.open_new_tab(url)
|
||||
|
||||
def actions(self, *args, **kwargs):
|
||||
menu = menus.toolsMenu()
|
||||
widgetUtils.connect_event(menu, widgetUtils.MENU, self.translate_action, menuitem=menu.translate)
|
||||
widgetUtils.connect_event(menu, widgetUtils.MENU, self.spellcheck_action, menuitem=menu.spellcheck)
|
||||
self.tab.PopupMenu(menu, self.tab.actions.GetPosition())
|
||||
def actions(self, *args, **kwargs):
|
||||
menu = menus.toolsMenu()
|
||||
widgetUtils.connect_event(menu, widgetUtils.MENU, self.translate_action, menuitem=menu.translate)
|
||||
widgetUtils.connect_event(menu, widgetUtils.MENU, self.spellcheck_action, menuitem=menu.spellcheck)
|
||||
self.tab.PopupMenu(menu, self.tab.actions.GetPosition())
|
||||
|
||||
def translate(self, text):
|
||||
dlg = translator.gui.translateDialog()
|
||||
if dlg.get_response() == widgetUtils.OK:
|
||||
language_dict = translator.translator.available_languages()
|
||||
for k in language_dict:
|
||||
if language_dict[k] == dlg.dest_lang.GetStringSelection():
|
||||
dst = k
|
||||
msg = translator.translator.translate(text, dst)
|
||||
dlg.Destroy()
|
||||
return msg
|
||||
def translate(self, text):
|
||||
dlg = translator.gui.translateDialog()
|
||||
if dlg.get_response() == widgetUtils.OK:
|
||||
language_dict = translator.translator.available_languages()
|
||||
for k in language_dict:
|
||||
if language_dict[k] == dlg.dest_lang.GetStringSelection():
|
||||
dst = k
|
||||
msg = translator.translator.translate(text, dst)
|
||||
dlg.Destroy()
|
||||
return msg
|
||||
|
||||
def spellcheck(self, text):
|
||||
checker = SpellChecker.spellchecker.spellChecker(text)
|
||||
if hasattr(checker, "fixed_text"):
|
||||
final_text = checker.fixed_text
|
||||
return final_text
|
||||
def spellcheck(self, text):
|
||||
checker = SpellChecker.spellchecker.spellChecker(text)
|
||||
if hasattr(checker, "fixed_text"):
|
||||
final_text = checker.fixed_text
|
||||
return final_text
|
||||
|
||||
def translate_action(self, *args, **kwargs):
|
||||
text = self.tab.text.GetValue()
|
||||
if text == "":
|
||||
wx.Bell()
|
||||
return
|
||||
translated = self.translate(text)
|
||||
if translated != None:
|
||||
self.tab.text.ChangeValue(translated)
|
||||
self.tab.text.SetFocus()
|
||||
def translate_action(self, *args, **kwargs):
|
||||
text = self.tab.text.GetValue()
|
||||
if text == "":
|
||||
wx.Bell()
|
||||
return
|
||||
translated = self.translate(text)
|
||||
if translated != None:
|
||||
self.tab.text.ChangeValue(translated)
|
||||
self.tab.text.SetFocus()
|
||||
|
||||
def spellcheck_action(self, *args, **kwargs):
|
||||
text = self.tab.text.GetValue()
|
||||
fixed = self.spellcheck(text)
|
||||
if fixed != None:
|
||||
self.tab.text.ChangeValue(fixed)
|
||||
self.tab.text.SetFocus()
|
||||
def spellcheck_action(self, *args, **kwargs):
|
||||
text = self.tab.text.GetValue()
|
||||
fixed = self.spellcheck(text)
|
||||
if fixed != None:
|
||||
self.tab.text.ChangeValue(fixed)
|
||||
self.tab.text.SetFocus()
|
||||
|
||||
def translate_message(self, *args, **kwargs):
|
||||
pass
|
||||
def translate_message(self, *args, **kwargs):
|
||||
pass
|
||||
|
||||
def spellcheck_message(self, *args, **kwargs):
|
||||
pass
|
||||
def spellcheck_message(self, *args, **kwargs):
|
||||
pass
|
||||
|
@ -16,53 +16,53 @@ log = logging.getLogger("controller.buffers.communityBoard")
|
||||
|
||||
class communityBoardBuffer(wallBuffer):
|
||||
|
||||
def create_tab(self, parent):
|
||||
self.tab = communityBoard.communityBoardTab(parent)
|
||||
self.connect_events()
|
||||
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):
|
||||
self.tab.post.Enable(False)
|
||||
def create_tab(self, parent):
|
||||
self.tab = communityBoard.communityBoardTab(parent)
|
||||
self.connect_events()
|
||||
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):
|
||||
self.tab.post.Enable(False)
|
||||
|
||||
def onFocus(self, event, *args, **kwargs):
|
||||
event.Skip()
|
||||
def onFocus(self, event, *args, **kwargs):
|
||||
event.Skip()
|
||||
|
||||
def open_post(self, *args, **kwargs):
|
||||
""" Opens the currently focused post."""
|
||||
post = self.get_post()
|
||||
if post == None:
|
||||
return
|
||||
a = presenters.displayTopicPresenter(session=self.session, postObject=post, group_id=self.kwargs["group_id"], interactor=interactors.displayPostInteractor(), view=views.displayTopic())
|
||||
def open_post(self, *args, **kwargs):
|
||||
""" Opens the currently focused post."""
|
||||
post = self.get_post()
|
||||
if post == None:
|
||||
return
|
||||
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):
|
||||
post = self.get_post()
|
||||
if post == None:
|
||||
return
|
||||
# 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
|
||||
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"])
|
||||
webbrowser.open_new_tab(url)
|
||||
def open_in_browser(self, *args, **kwargs):
|
||||
post = self.get_post()
|
||||
if post == None:
|
||||
return
|
||||
# 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
|
||||
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"])
|
||||
webbrowser.open_new_tab(url)
|
||||
|
||||
def post(self, *args, **kwargs):
|
||||
menu = wx.Menu()
|
||||
user1 = self.session.get_user(self.session.user_id)
|
||||
user2 = self.session.get_user(-1*self.kwargs["group_id"])
|
||||
user = menu.Append(wx.NewId(), _("Post as {user1_nom}").format(**user1))
|
||||
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, 0), user)
|
||||
self.tab.post.PopupMenu(menu, self.tab.post.GetPosition())
|
||||
def post(self, *args, **kwargs):
|
||||
menu = wx.Menu()
|
||||
user1 = self.session.get_user(self.session.user_id)
|
||||
user2 = self.session.get_user(-1*self.kwargs["group_id"])
|
||||
user = menu.Append(wx.NewId(), _("Post as {user1_nom}").format(**user1))
|
||||
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, 0), user)
|
||||
self.tab.post.PopupMenu(menu, self.tab.post.GetPosition())
|
||||
|
||||
def _post(self, event, from_group):
|
||||
owner_id = self.kwargs["group_id"]
|
||||
user = self.session.get_user(-1*owner_id, key="user1")
|
||||
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=""))
|
||||
if hasattr(p, "text") or hasattr(p, "privacy"):
|
||||
title = p.view.title.GetValue()
|
||||
msg = p.text
|
||||
post_arguments = dict(title=title, text=msg, group_id=owner_id, from_group=from_group)
|
||||
attachments = []
|
||||
if hasattr(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)
|
||||
def _post(self, event, from_group):
|
||||
owner_id = self.kwargs["group_id"]
|
||||
user = self.session.get_user(-1*owner_id, key="user1")
|
||||
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=""))
|
||||
if hasattr(p, "text") or hasattr(p, "privacy"):
|
||||
title = p.view.title.GetValue()
|
||||
msg = p.text
|
||||
post_arguments = dict(title=title, text=msg, group_id=owner_id, from_group=from_group)
|
||||
attachments = []
|
||||
if hasattr(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)
|
||||
|
@ -6,11 +6,11 @@ from .documents import documentsBuffer
|
||||
log = logging.getLogger("controller.buffers.communityDocuments")
|
||||
|
||||
class communityDocumentsBuffer(documentsBuffer):
|
||||
can_get_items = True
|
||||
can_get_items = True
|
||||
|
||||
def create_tab(self, parent):
|
||||
self.tab = communityDocuments.communityDocumentsTab(parent)
|
||||
self.connect_events()
|
||||
self.tab.name = self.name
|
||||
if hasattr(self, "can_post") and self.can_post == False and hasattr(self.tab, "post"):
|
||||
self.tab.post.Enable(False)
|
||||
def create_tab(self, parent):
|
||||
self.tab = communityDocuments.communityDocumentsTab(parent)
|
||||
self.connect_events()
|
||||
self.tab.name = self.name
|
||||
if hasattr(self, "can_post") and self.can_post == False and hasattr(self.tab, "post"):
|
||||
self.tab.post.Enable(False)
|
||||
|
@ -8,19 +8,19 @@ log = logging.getLogger("controller.buffers.communityPeople")
|
||||
|
||||
class communityPeopleBuffer(peopleBuffer):
|
||||
|
||||
def get_menu(self, *args, **kwargs):
|
||||
user = self.get_post()
|
||||
m = wx.Menu()
|
||||
if user.get("can_post") == True:
|
||||
can_post = m.Append(wx.NewId(), _("&Post on user's wall"))
|
||||
widgetUtils.connect_event(m, widgetUtils.MENU, self.post, menuitem=can_post)
|
||||
if user.get("can_write_private_message") == True:
|
||||
can_write_message = m.Append(wx.Id(), _("Send message"))
|
||||
widgetUtils.connect_event(m, widgetUtils.MENU, self.new_chat, menuitem=can_write_message)
|
||||
profile = m.Append(wx.NewId(), _("View profile"))
|
||||
widgetUtils.connect_event(m, widgetUtils.MENU, self.open_person_profile, menuitem=profile)
|
||||
timeline = m.Append(wx.NewId(), _("Open timeline"))
|
||||
widgetUtils.connect_event(m, widgetUtils.MENU, self.open_timeline, menuitem=timeline)
|
||||
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)
|
||||
return m
|
||||
def get_menu(self, *args, **kwargs):
|
||||
user = self.get_post()
|
||||
m = wx.Menu()
|
||||
if user.get("can_post") == True:
|
||||
can_post = m.Append(wx.NewId(), _("&Post on user's wall"))
|
||||
widgetUtils.connect_event(m, widgetUtils.MENU, self.post, menuitem=can_post)
|
||||
if user.get("can_write_private_message") == True:
|
||||
can_write_message = m.Append(wx.Id(), _("Send message"))
|
||||
widgetUtils.connect_event(m, widgetUtils.MENU, self.new_chat, menuitem=can_write_message)
|
||||
profile = m.Append(wx.NewId(), _("View profile"))
|
||||
widgetUtils.connect_event(m, widgetUtils.MENU, self.open_person_profile, menuitem=profile)
|
||||
timeline = m.Append(wx.NewId(), _("Open timeline"))
|
||||
widgetUtils.connect_event(m, widgetUtils.MENU, self.open_timeline, menuitem=timeline)
|
||||
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)
|
||||
return m
|
||||
|
@ -16,54 +16,54 @@ log = logging.getLogger("controller.buffers.communityWall")
|
||||
|
||||
class communityWallBuffer(wallBuffer):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(communityWallBuffer, self).__init__(*args, **kwargs)
|
||||
self.group_id = self.kwargs["owner_id"]
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(communityWallBuffer, self).__init__(*args, **kwargs)
|
||||
self.group_id = self.kwargs["owner_id"]
|
||||
|
||||
def create_tab(self, parent):
|
||||
self.tab = communityWall.communityWallTab(parent)
|
||||
self.connect_events()
|
||||
self.tab.name = self.name
|
||||
self.tab.post.Enable(False)
|
||||
def create_tab(self, parent):
|
||||
self.tab = communityWall.communityWallTab(parent)
|
||||
self.connect_events()
|
||||
self.tab.name = self.name
|
||||
self.tab.post.Enable(False)
|
||||
|
||||
def connect_events(self):
|
||||
super(communityWallBuffer, self).connect_events()
|
||||
widgetUtils.connect_event(self.tab.load, widgetUtils.BUTTON_PRESSED, self.load_community)
|
||||
def connect_events(self):
|
||||
super(communityWallBuffer, self).connect_events()
|
||||
widgetUtils.connect_event(self.tab.load, widgetUtils.BUTTON_PRESSED, self.load_community)
|
||||
|
||||
def load_community(self, *args, **kwargs):
|
||||
output.speak(_("Loading community..."))
|
||||
self.can_get_items = True
|
||||
self.tab.load.Enable(False)
|
||||
wx.CallAfter(self.get_items)
|
||||
def load_community(self, *args, **kwargs):
|
||||
output.speak(_("Loading community..."))
|
||||
self.can_get_items = True
|
||||
self.tab.load.Enable(False)
|
||||
wx.CallAfter(self.get_items)
|
||||
|
||||
def get_items(self, *args, **kwargs):
|
||||
""" This method retrieves community information, useful to show different parts of the community itself."""
|
||||
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.
|
||||
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)
|
||||
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)
|
||||
super(communityWallBuffer, self).get_items(*args, **kwargs)
|
||||
def get_items(self, *args, **kwargs):
|
||||
""" This method retrieves community information, useful to show different parts of the community itself."""
|
||||
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.
|
||||
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)
|
||||
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)
|
||||
super(communityWallBuffer, self).get_items(*args, **kwargs)
|
||||
|
||||
def post(self, *args, **kwargs):
|
||||
menu = wx.Menu()
|
||||
user1 = self.session.get_user(self.session.user_id)
|
||||
user2 = self.session.get_user(self.kwargs["owner_id"])
|
||||
user = menu.Append(wx.NewId(), _("Post as {user1_nom}").format(**user1))
|
||||
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, 0), user)
|
||||
self.tab.post.PopupMenu(menu, self.tab.post.GetPosition())
|
||||
def post(self, *args, **kwargs):
|
||||
menu = wx.Menu()
|
||||
user1 = self.session.get_user(self.session.user_id)
|
||||
user2 = self.session.get_user(self.kwargs["owner_id"])
|
||||
user = menu.Append(wx.NewId(), _("Post as {user1_nom}").format(**user1))
|
||||
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, 0), user)
|
||||
self.tab.post.PopupMenu(menu, self.tab.post.GetPosition())
|
||||
|
||||
def _post(self, event, from_group):
|
||||
owner_id = self.kwargs["owner_id"]
|
||||
user = self.session.get_user(owner_id, key="user1")
|
||||
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=""))
|
||||
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)
|
||||
attachments = []
|
||||
if hasattr(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)
|
||||
def _post(self, event, from_group):
|
||||
owner_id = self.kwargs["owner_id"]
|
||||
user = self.session.get_user(owner_id, key="user1")
|
||||
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=""))
|
||||
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)
|
||||
attachments = []
|
||||
if hasattr(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)
|
||||
|
@ -17,77 +17,77 @@ from .wall import wallBuffer
|
||||
log = logging.getLogger("controller.buffers.documents")
|
||||
|
||||
class documentsBuffer(wallBuffer):
|
||||
can_get_items = False
|
||||
can_get_items = False
|
||||
|
||||
def create_tab(self, parent):
|
||||
self.tab = documents.documentsTab(parent)
|
||||
self.connect_events()
|
||||
self.tab.name = self.name
|
||||
if hasattr(self, "can_post") and self.can_post == False and hasattr(self.tab, "post"):
|
||||
self.tab.post.Enable(False)
|
||||
def create_tab(self, parent):
|
||||
self.tab = documents.documentsTab(parent)
|
||||
self.connect_events()
|
||||
self.tab.name = self.name
|
||||
if hasattr(self, "can_post") and self.can_post == False and hasattr(self.tab, "post"):
|
||||
self.tab.post.Enable(False)
|
||||
|
||||
def onFocus(self, event, *args,**kwargs):
|
||||
post = self.get_post()
|
||||
if post == None:
|
||||
return
|
||||
original_date = arrow.get(post["date"])
|
||||
created_at = original_date.humanize(locale=languageHandler.curLang[:2])
|
||||
self.tab.list.list.SetItem(self.tab.list.get_selected(), 4, created_at)
|
||||
event.Skip()
|
||||
def onFocus(self, event, *args,**kwargs):
|
||||
post = self.get_post()
|
||||
if post == None:
|
||||
return
|
||||
original_date = arrow.get(post["date"])
|
||||
created_at = original_date.humanize(locale=languageHandler.curLang[:2])
|
||||
self.tab.list.list.SetItem(self.tab.list.get_selected(), 4, created_at)
|
||||
event.Skip()
|
||||
|
||||
def connect_events(self):
|
||||
super(documentsBuffer, self).connect_events()
|
||||
# Check if we have a load button in the tab, because documents community buffers don't include it.
|
||||
if hasattr(self.tab, "load"):
|
||||
widgetUtils.connect_event(self.tab.load, widgetUtils.BUTTON_PRESSED, self.load_documents)
|
||||
def connect_events(self):
|
||||
super(documentsBuffer, self).connect_events()
|
||||
# Check if we have a load button in the tab, because documents community buffers don't include it.
|
||||
if hasattr(self.tab, "load"):
|
||||
widgetUtils.connect_event(self.tab.load, widgetUtils.BUTTON_PRESSED, self.load_documents)
|
||||
|
||||
def load_documents(self, *args, **kwargs):
|
||||
output.speak(_("Loading documents..."))
|
||||
self.can_get_items = True
|
||||
self.tab.load.Enable(False)
|
||||
wx.CallAfter(self.get_items)
|
||||
def load_documents(self, *args, **kwargs):
|
||||
output.speak(_("Loading documents..."))
|
||||
self.can_get_items = True
|
||||
self.tab.load.Enable(False)
|
||||
wx.CallAfter(self.get_items)
|
||||
|
||||
def get_menu(self):
|
||||
p = self.get_post()
|
||||
if p == None:
|
||||
return
|
||||
if p["owner_id"] == self.session.user_id:
|
||||
added = True
|
||||
else:
|
||||
added = False
|
||||
m = menus.documentMenu(added)
|
||||
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.open_in_browser, menuitem=m.open_in_browser)
|
||||
return m
|
||||
def get_menu(self):
|
||||
p = self.get_post()
|
||||
if p == None:
|
||||
return
|
||||
if p["owner_id"] == self.session.user_id:
|
||||
added = True
|
||||
else:
|
||||
added = False
|
||||
m = menus.documentMenu(added)
|
||||
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.open_in_browser, menuitem=m.open_in_browser)
|
||||
return m
|
||||
|
||||
def add_remove_document(self, *args, **kwargs):
|
||||
p = self.get_post()
|
||||
if p == None:
|
||||
return
|
||||
if p["owner_id"] == self.session.user_id:
|
||||
result = self.session.vk.client.docs.delete(owner_id=p["owner_id"], doc_id=p["id"])
|
||||
if result == 1:
|
||||
output.speak(_("The document has been successfully deleted."))
|
||||
self.session.db[self.name]["items"].pop(self.tab.list.get_selected())
|
||||
self.tab.list.remove_item(self.tab.list.get_selected())
|
||||
else:
|
||||
result = self.session.vk.client.docs.add(owner_id=p["owner_id"], doc_id=p["id"])
|
||||
output.speak(_("The document has been successfully added."))
|
||||
def add_remove_document(self, *args, **kwargs):
|
||||
p = self.get_post()
|
||||
if p == None:
|
||||
return
|
||||
if p["owner_id"] == self.session.user_id:
|
||||
result = self.session.vk.client.docs.delete(owner_id=p["owner_id"], doc_id=p["id"])
|
||||
if result == 1:
|
||||
output.speak(_("The document has been successfully deleted."))
|
||||
self.session.db[self.name]["items"].pop(self.tab.list.get_selected())
|
||||
self.tab.list.remove_item(self.tab.list.get_selected())
|
||||
else:
|
||||
result = self.session.vk.client.docs.add(owner_id=p["owner_id"], doc_id=p["id"])
|
||||
output.speak(_("The document has been successfully added."))
|
||||
|
||||
def download(self, *args, **kwargs):
|
||||
post = self.get_post()
|
||||
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 filename.endswith(post["ext"]) == False:
|
||||
filename = filename+ "."+post["ext"]
|
||||
filepath = self.tab.get_download_path(filename)
|
||||
if filepath != None:
|
||||
pub.sendMessage("download-file", url=post["url"], filename=filepath)
|
||||
def download(self, *args, **kwargs):
|
||||
post = self.get_post()
|
||||
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 filename.endswith(post["ext"]) == False:
|
||||
filename = filename+ "."+post["ext"]
|
||||
filepath = self.tab.get_download_path(filename)
|
||||
if filepath != None:
|
||||
pub.sendMessage("download-file", url=post["url"], filename=filepath)
|
||||
|
||||
def open_in_browser(self, *args, **kwargs):
|
||||
post = self.get_post()
|
||||
if post == None:
|
||||
return
|
||||
url = "https://vk.com/doc{user_id}_{post_id}".format(user_id=post["owner_id"], post_id=post["id"])
|
||||
webbrowser.open_new_tab(url)
|
||||
def open_in_browser(self, *args, **kwargs):
|
||||
post = self.get_post()
|
||||
if post == None:
|
||||
return
|
||||
url = "https://vk.com/doc{user_id}_{post_id}".format(user_id=post["owner_id"], post_id=post["id"])
|
||||
webbrowser.open_new_tab(url)
|
||||
|
@ -8,20 +8,20 @@ log = logging.getLogger("controller.buffers.empty")
|
||||
|
||||
class emptyBuffer(object):
|
||||
|
||||
def __init__(self, name=None, parent=None, *args, **kwargs):
|
||||
self.tab = empty.emptyTab(parent=parent, name=name)
|
||||
self.name = name
|
||||
def __init__(self, name=None, parent=None, *args, **kwargs):
|
||||
self.tab = empty.emptyTab(parent=parent, name=name)
|
||||
self.name = name
|
||||
|
||||
def get_items(self, *args, **kwargs):
|
||||
if not hasattr(self, "tab"):
|
||||
# Create GUI associated to this buffer.
|
||||
self.create_tab(self.parent)
|
||||
# Add name to the new control so we could look for it when needed.
|
||||
self.tab.name = self.name
|
||||
pass
|
||||
def get_items(self, *args, **kwargs):
|
||||
if not hasattr(self, "tab"):
|
||||
# Create GUI associated to this buffer.
|
||||
self.create_tab(self.parent)
|
||||
# Add name to the new control so we could look for it when needed.
|
||||
self.tab.name = self.name
|
||||
pass
|
||||
|
||||
def get_more_items(self, *args, **kwargs):
|
||||
output.speak(_("This buffer doesn't support getting more items."))
|
||||
def get_more_items(self, *args, **kwargs):
|
||||
output.speak(_("This buffer doesn't support getting more items."))
|
||||
|
||||
def remove_buffer(self, mandatory=False):
|
||||
return False
|
||||
def remove_buffer(self, mandatory=False):
|
||||
return False
|
||||
|
@ -9,73 +9,73 @@ log = logging.getLogger("controller.buffers.friendRequests")
|
||||
|
||||
class friendRequestsBuffer(peopleBuffer):
|
||||
|
||||
def get_items(self, show_nextpage=False):
|
||||
if self.can_get_items == False: return
|
||||
retrieved = True
|
||||
try:
|
||||
ids = self.session.vk.client.friends.getRequests(*self.args, **self.kwargs)
|
||||
except VkApiError as err:
|
||||
log.error("Error {0}: {1}".format(err.code, err.error))
|
||||
retrieved = err.code
|
||||
return retrieved
|
||||
except:
|
||||
log.exception("Connection error when updating buffer %s. Will try again in 2 minutes" % (self.name,))
|
||||
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")
|
||||
if not hasattr(self, "tab"):
|
||||
# Create GUI associated to this buffer.
|
||||
self.create_tab(self.parent)
|
||||
# Add name to the new control so we could look for it when needed.
|
||||
self.tab.name = self.name
|
||||
if show_nextpage == False:
|
||||
if self.tab.list.get_count() > 0 and num > 0:
|
||||
v = [i for i in self.session.db[self.name]["items"][:num]]
|
||||
v.reverse()
|
||||
[wx.CallAfter(self.insert, i, True) for i in v]
|
||||
else:
|
||||
[wx.CallAfter(self.insert, i) for i in self.session.db[self.name]["items"][:num]]
|
||||
return retrieved
|
||||
def get_items(self, show_nextpage=False):
|
||||
if self.can_get_items == False: return
|
||||
retrieved = True
|
||||
try:
|
||||
ids = self.session.vk.client.friends.getRequests(*self.args, **self.kwargs)
|
||||
except VkApiError as err:
|
||||
log.error("Error {0}: {1}".format(err.code, err.error))
|
||||
retrieved = err.code
|
||||
return retrieved
|
||||
except:
|
||||
log.exception("Connection error when updating buffer %s. Will try again in 2 minutes" % (self.name,))
|
||||
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")
|
||||
if not hasattr(self, "tab"):
|
||||
# Create GUI associated to this buffer.
|
||||
self.create_tab(self.parent)
|
||||
# Add name to the new control so we could look for it when needed.
|
||||
self.tab.name = self.name
|
||||
if show_nextpage == False:
|
||||
if self.tab.list.get_count() > 0 and num > 0:
|
||||
v = [i for i in self.session.db[self.name]["items"][:num]]
|
||||
v.reverse()
|
||||
[wx.CallAfter(self.insert, i, True) for i in v]
|
||||
else:
|
||||
[wx.CallAfter(self.insert, i) for i in self.session.db[self.name]["items"][:num]]
|
||||
return retrieved
|
||||
|
||||
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.
|
||||
https://vk.com/dev/friends.add
|
||||
"""
|
||||
person = self.get_post()
|
||||
if person == None:
|
||||
return
|
||||
result = self.session.vk.client.friends.add(user_id=person["id"])
|
||||
if result == 2:
|
||||
msg = _("{0} {1} now is your friend.").format(person["first_name"], person["last_name"])
|
||||
pub.sendMessage("notify", message=msg)
|
||||
self.session.db[self.name]["items"].pop(self.tab.list.get_selected())
|
||||
self.tab.list.remove_item(self.tab.list.get_selected())
|
||||
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.
|
||||
https://vk.com/dev/friends.add
|
||||
"""
|
||||
person = self.get_post()
|
||||
if person == None:
|
||||
return
|
||||
result = self.session.vk.client.friends.add(user_id=person["id"])
|
||||
if result == 2:
|
||||
msg = _("{0} {1} now is your friend.").format(person["first_name"], person["last_name"])
|
||||
pub.sendMessage("notify", message=msg)
|
||||
self.session.db[self.name]["items"].pop(self.tab.list.get_selected())
|
||||
self.tab.list.remove_item(self.tab.list.get_selected())
|
||||
|
||||
def decline_friendship(self, *args, **kwargs):
|
||||
""" Declines a freind request.
|
||||
https://vk.com/dev/friends.delete
|
||||
"""
|
||||
person = self.get_post()
|
||||
if person == None:
|
||||
return
|
||||
result = self.session.vk.client.friends.delete(user_id=person["id"])
|
||||
if "out_request_deleted" in result:
|
||||
msg = _("You've deleted the friends request to {0} {1}.").format(person["first_name"], person["last_name"])
|
||||
elif "in_request_deleted" in result:
|
||||
msg = _("You've declined the friend request of {0} {1}.").format(person["first_name"], person["last_name"])
|
||||
pub.sendMessage("notify", message=msg)
|
||||
self.session.db[self.name]["items"].pop(self.tab.list.get_selected())
|
||||
self.tab.list.remove_item(self.tab.list.get_selected())
|
||||
def decline_friendship(self, *args, **kwargs):
|
||||
""" Declines a freind request.
|
||||
https://vk.com/dev/friends.delete
|
||||
"""
|
||||
person = self.get_post()
|
||||
if person == None:
|
||||
return
|
||||
result = self.session.vk.client.friends.delete(user_id=person["id"])
|
||||
if "out_request_deleted" in result:
|
||||
msg = _("You've deleted the friends request to {0} {1}.").format(person["first_name"], person["last_name"])
|
||||
elif "in_request_deleted" in result:
|
||||
msg = _("You've declined the friend request of {0} {1}.").format(person["first_name"], person["last_name"])
|
||||
pub.sendMessage("notify", message=msg)
|
||||
self.session.db[self.name]["items"].pop(self.tab.list.get_selected())
|
||||
self.tab.list.remove_item(self.tab.list.get_selected())
|
||||
|
||||
def keep_as_follower(self, *args, **kwargs):
|
||||
""" Adds a person to The followers list of the current user.
|
||||
https://vk.com/dev/friends.add
|
||||
"""
|
||||
person = self.get_post()
|
||||
if person == None:
|
||||
return
|
||||
result = self.session.vk.client.friends.add(user_id=person["id"], follow=1)
|
||||
if result == 2:
|
||||
msg = _("{0} {1} is following you.").format(person["first_name"], person["last_name"])
|
||||
pub.sendMessage("notify", message=msg)
|
||||
self.session.db[self.name]["items"].pop(self.tab.list.get_selected())
|
||||
self.tab.list.remove_item(self.tab.list.get_selected())
|
||||
def keep_as_follower(self, *args, **kwargs):
|
||||
""" Adds a person to The followers list of the current user.
|
||||
https://vk.com/dev/friends.add
|
||||
"""
|
||||
person = self.get_post()
|
||||
if person == None:
|
||||
return
|
||||
result = self.session.vk.client.friends.add(user_id=person["id"], follow=1)
|
||||
if result == 2:
|
||||
msg = _("{0} {1} is following you.").format(person["first_name"], person["last_name"])
|
||||
pub.sendMessage("notify", message=msg)
|
||||
self.session.db[self.name]["items"].pop(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")
|
||||
|
||||
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):
|
||||
""" Return the currently focused post."""
|
||||
# Handle case where there are no items in the buffer.
|
||||
if self.tab.list.get_count() == 0:
|
||||
wx.Bell()
|
||||
return None
|
||||
return self.session.db[self.name]["items"][self.tab.list.get_selected()]
|
||||
def get_post(self):
|
||||
""" Return the currently focused post."""
|
||||
# Handle case where there are no items in the buffer.
|
||||
if self.tab.list.get_count() == 0:
|
||||
wx.Bell()
|
||||
return None
|
||||
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):
|
||||
""" Constructor:
|
||||
@parent wx.Treebook: parent for the buffer panel,
|
||||
@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.
|
||||
@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.
|
||||
"""
|
||||
super(homeBuffer, self).__init__()
|
||||
self.parent = parent
|
||||
self.args = args
|
||||
self.kwargs = kwargs
|
||||
self.session = session
|
||||
self.compose_function = composefunc
|
||||
self.name = name
|
||||
if create_tab:
|
||||
self.create_tab(self.parent)
|
||||
#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.
|
||||
# ToDo: Shall we allow dinamically set for update_function?
|
||||
self.update_function = "get_page"
|
||||
self.name = name
|
||||
# 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.
|
||||
self.user_key = "source_id"
|
||||
self.post_key = "post_id"
|
||||
# When set to False, update_function won't be executed here.
|
||||
self.can_get_items = True
|
||||
def __init__(self, parent=None, name="", session=None, composefunc=None, create_tab=True, *args, **kwargs):
|
||||
""" Constructor:
|
||||
@parent wx.Treebook: parent for the buffer panel,
|
||||
@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.
|
||||
@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.
|
||||
"""
|
||||
super(homeBuffer, self).__init__()
|
||||
self.parent = parent
|
||||
self.args = args
|
||||
self.kwargs = kwargs
|
||||
self.session = session
|
||||
self.compose_function = composefunc
|
||||
self.name = name
|
||||
if create_tab:
|
||||
self.create_tab(self.parent)
|
||||
#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.
|
||||
# ToDo: Shall we allow dinamically set for update_function?
|
||||
self.update_function = "get_page"
|
||||
self.name = name
|
||||
# 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.
|
||||
self.user_key = "source_id"
|
||||
self.post_key = "post_id"
|
||||
# When set to False, update_function won't be executed here.
|
||||
self.can_get_items = True
|
||||
|
||||
def create_tab(self, parent):
|
||||
""" Create the Wx panel."""
|
||||
self.tab = home.homeTab(parent)
|
||||
# Bind local events (they will respond to events happened in the buffer).
|
||||
self.connect_events()
|
||||
self.tab.name = self.name
|
||||
if hasattr(self, "can_post") and self.can_post == False and hasattr(self.tab, "post"):
|
||||
self.tab.post.Enable(False)
|
||||
def create_tab(self, parent):
|
||||
""" Create the Wx panel."""
|
||||
self.tab = home.homeTab(parent)
|
||||
# Bind local events (they will respond to events happened in the buffer).
|
||||
self.connect_events()
|
||||
self.tab.name = self.name
|
||||
if hasattr(self, "can_post") and self.can_post == False and hasattr(self.tab, "post"):
|
||||
self.tab.post.Enable(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."""
|
||||
try:
|
||||
item_ = getattr(renderers, self.compose_function)(item, self.session)
|
||||
wx.CallAfter(self.tab.list.insert_item, reversed, *item_)
|
||||
except:
|
||||
log.exception(item)
|
||||
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."""
|
||||
try:
|
||||
item_ = getattr(renderers, self.compose_function)(item, self.session)
|
||||
wx.CallAfter(self.tab.list.insert_item, reversed, *item_)
|
||||
except:
|
||||
log.exception(item)
|
||||
|
||||
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.
|
||||
@show_nextpage boolean: If it's true, it will try to load previous results.
|
||||
"""
|
||||
if self.can_get_items == False: return
|
||||
retrieved = True # Control variable for handling unauthorised/connection errors.
|
||||
try:
|
||||
num = getattr(self.session, "get_newsfeed")(show_nextpage=show_nextpage, name=self.name, *self.args, **self.kwargs)
|
||||
except VkApiError as err:
|
||||
log.error("Error {0}: {1}".format(err.code, err.error))
|
||||
retrieved = err.code
|
||||
return retrieved
|
||||
except:
|
||||
log.exception("Connection error when updating buffer %s. Will try again in 2 minutes" % (self.name,))
|
||||
return False
|
||||
if not hasattr(self, "tab"):
|
||||
# Create GUI associated to this buffer.
|
||||
self.create_tab(self.parent)
|
||||
# Add name to the new control so we could look for it when needed.
|
||||
if show_nextpage == False:
|
||||
if self.tab.list.get_count() > 0 and num > 0:
|
||||
v = [i for i in self.session.db[self.name]["items"][:num]]
|
||||
v.reverse()
|
||||
[wx.CallAfter(self.insert, i, True) for i in v]
|
||||
else:
|
||||
[wx.CallAfter(self.insert, i) for i in self.session.db[self.name]["items"][:num]]
|
||||
else:
|
||||
if num > 0:
|
||||
[wx.CallAfter(self.insert, i, False) for i in self.session.db[self.name]["items"][-num:]]
|
||||
return retrieved
|
||||
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.
|
||||
@show_nextpage boolean: If it's true, it will try to load previous results.
|
||||
"""
|
||||
if self.can_get_items == False: return
|
||||
retrieved = True # Control variable for handling unauthorised/connection errors.
|
||||
try:
|
||||
num = getattr(self.session, "get_newsfeed")(show_nextpage=show_nextpage, name=self.name, *self.args, **self.kwargs)
|
||||
except VkApiError as err:
|
||||
log.error("Error {0}: {1}".format(err.code, err.error))
|
||||
retrieved = err.code
|
||||
return retrieved
|
||||
except:
|
||||
log.exception("Connection error when updating buffer %s. Will try again in 2 minutes" % (self.name,))
|
||||
return False
|
||||
if not hasattr(self, "tab"):
|
||||
# Create GUI associated to this buffer.
|
||||
self.create_tab(self.parent)
|
||||
# Add name to the new control so we could look for it when needed.
|
||||
if show_nextpage == False:
|
||||
if self.tab.list.get_count() > 0 and num > 0:
|
||||
v = [i for i in self.session.db[self.name]["items"][:num]]
|
||||
v.reverse()
|
||||
[wx.CallAfter(self.insert, i, True) for i in v]
|
||||
else:
|
||||
[wx.CallAfter(self.insert, i) for i in self.session.db[self.name]["items"][:num]]
|
||||
else:
|
||||
if num > 0:
|
||||
[wx.CallAfter(self.insert, i, False) for i in self.session.db[self.name]["items"][-num:]]
|
||||
return retrieved
|
||||
|
||||
def get_more_items(self):
|
||||
""" Returns previous items in the buffer."""
|
||||
self.get_items(show_nextpage=True)
|
||||
def get_more_items(self):
|
||||
""" Returns previous items in the buffer."""
|
||||
self.get_items(show_nextpage=True)
|
||||
|
||||
def post(self, *args, **kwargs):
|
||||
""" 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.
|
||||
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=""))
|
||||
if hasattr(p, "text") or hasattr(p, "privacy"):
|
||||
post_arguments=dict(privacy=p.privacy, message=p.text)
|
||||
attachments = []
|
||||
if hasattr(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)
|
||||
def post(self, *args, **kwargs):
|
||||
""" 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.
|
||||
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=""))
|
||||
if hasattr(p, "text") or hasattr(p, "privacy"):
|
||||
post_arguments=dict(privacy=p.privacy, message=p.text)
|
||||
attachments = []
|
||||
if hasattr(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)
|
||||
|
||||
def connect_events(self):
|
||||
""" Bind all events to this buffer"""
|
||||
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, wx.EVT_CONTEXT_MENU, self.show_menu)
|
||||
self.tab.set_focus_function(self.onFocus)
|
||||
def connect_events(self):
|
||||
""" Bind all events to this buffer"""
|
||||
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, wx.EVT_CONTEXT_MENU, self.show_menu)
|
||||
self.tab.set_focus_function(self.onFocus)
|
||||
|
||||
def show_menu(self, ev, pos=0, *args, **kwargs):
|
||||
""" Show contextual menu when pressing menu key or right mouse click in a list item."""
|
||||
if self.tab.list.get_count() == 0: return
|
||||
menu = self.get_menu()
|
||||
if pos != 0:
|
||||
self.tab.PopupMenu(menu, pos)
|
||||
else:
|
||||
self.tab.PopupMenu(menu, self.tab.list.list.GetPosition())
|
||||
def show_menu(self, ev, pos=0, *args, **kwargs):
|
||||
""" Show contextual menu when pressing menu key or right mouse click in a list item."""
|
||||
if self.tab.list.get_count() == 0: return
|
||||
menu = self.get_menu()
|
||||
if pos != 0:
|
||||
self.tab.PopupMenu(menu, pos)
|
||||
else:
|
||||
self.tab.PopupMenu(menu, self.tab.list.list.GetPosition())
|
||||
|
||||
def show_menu_by_key(self, ev):
|
||||
""" Show contextual menu when menu key is pressed"""
|
||||
if self.tab.list.get_count() == 0:
|
||||
return
|
||||
if ev.GetKeyCode() == wx.WXK_WINDOWS_MENU:
|
||||
self.show_menu(widgetUtils.MENU, pos=self.tab.list.list.GetPosition())
|
||||
def show_menu_by_key(self, ev):
|
||||
""" Show contextual menu when menu key is pressed"""
|
||||
if self.tab.list.get_count() == 0:
|
||||
return
|
||||
if ev.GetKeyCode() == wx.WXK_WINDOWS_MENU:
|
||||
self.show_menu(widgetUtils.MENU, pos=self.tab.list.list.GetPosition())
|
||||
|
||||
def get_menu(self):
|
||||
""" Returns contextual menu options. They will change according to the focused item"""
|
||||
p = self.get_post()
|
||||
if p == None:
|
||||
return
|
||||
# determine if the current user is able to delete the object.
|
||||
if "can_delete" in p:
|
||||
can_delete = True==p["can_delete"]
|
||||
else:
|
||||
can_delete = False
|
||||
m = menus.postMenu(can_delete=can_delete)
|
||||
if ("likes" in p) == False:
|
||||
m.like.Enable(False)
|
||||
elif p["likes"]["user_likes"] == 1:
|
||||
m.like.Enable(False)
|
||||
m.dislike.Enable(True)
|
||||
if ("comments" in p) == False:
|
||||
m.comment.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":
|
||||
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.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_comment, menuitem=m.comment)
|
||||
widgetUtils.connect_event(m, widgetUtils.MENU, self.open_in_browser, menuitem=m.open_in_browser)
|
||||
if hasattr(m, "view_profile"):
|
||||
widgetUtils.connect_event(m, widgetUtils.MENU, self.open_person_profile, menuitem=m.view_profile)
|
||||
if hasattr(m, "delete"):
|
||||
widgetUtils.connect_event(m, widgetUtils.MENU, self.delete, menuitem=m.delete)
|
||||
return m
|
||||
def get_menu(self):
|
||||
""" Returns contextual menu options. They will change according to the focused item"""
|
||||
p = self.get_post()
|
||||
if p == None:
|
||||
return
|
||||
# determine if the current user is able to delete the object.
|
||||
if "can_delete" in p:
|
||||
can_delete = True==p["can_delete"]
|
||||
else:
|
||||
can_delete = False
|
||||
m = menus.postMenu(can_delete=can_delete)
|
||||
if ("likes" in p) == False:
|
||||
m.like.Enable(False)
|
||||
elif p["likes"]["user_likes"] == 1:
|
||||
m.like.Enable(False)
|
||||
m.dislike.Enable(True)
|
||||
if ("comments" in p) == False:
|
||||
m.comment.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":
|
||||
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.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_comment, menuitem=m.comment)
|
||||
widgetUtils.connect_event(m, widgetUtils.MENU, self.open_in_browser, menuitem=m.open_in_browser)
|
||||
if hasattr(m, "view_profile"):
|
||||
widgetUtils.connect_event(m, widgetUtils.MENU, self.open_person_profile, menuitem=m.view_profile)
|
||||
if hasattr(m, "delete"):
|
||||
widgetUtils.connect_event(m, widgetUtils.MENU, self.delete, menuitem=m.delete)
|
||||
return m
|
||||
|
||||
def do_like(self, *args, **kwargs):
|
||||
""" Set like in the currently focused post."""
|
||||
post = self.get_post()
|
||||
if post == None:
|
||||
return
|
||||
user = post[self.user_key]
|
||||
id = post[self.post_key]
|
||||
if "type" in post:
|
||||
type_ = post["type"]
|
||||
else:
|
||||
type_ = "post"
|
||||
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"]["user_likes"] = 1
|
||||
# Translators: This will be used when user presses like.
|
||||
output.speak(_("You liked this"))
|
||||
def do_like(self, *args, **kwargs):
|
||||
""" Set like in the currently focused post."""
|
||||
post = self.get_post()
|
||||
if post == None:
|
||||
return
|
||||
user = post[self.user_key]
|
||||
id = post[self.post_key]
|
||||
if "type" in post:
|
||||
type_ = post["type"]
|
||||
else:
|
||||
type_ = "post"
|
||||
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"]["user_likes"] = 1
|
||||
# Translators: This will be used when user presses like.
|
||||
output.speak(_("You liked this"))
|
||||
|
||||
def do_dislike(self, *args, **kwargs):
|
||||
""" Set dislike (undo like) in the currently focused post."""
|
||||
post = self.get_post()
|
||||
if post == None:
|
||||
return
|
||||
user = post[self.user_key]
|
||||
id = post[self.post_key]
|
||||
if "type" in post:
|
||||
type_ = post["type"]
|
||||
else:
|
||||
type_ = "post"
|
||||
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"]["user_likes"] = 2
|
||||
# Translators: This will be user in 'dislike'
|
||||
output.speak(_("You don't like this"))
|
||||
def do_dislike(self, *args, **kwargs):
|
||||
""" Set dislike (undo like) in the currently focused post."""
|
||||
post = self.get_post()
|
||||
if post == None:
|
||||
return
|
||||
user = post[self.user_key]
|
||||
id = post[self.post_key]
|
||||
if "type" in post:
|
||||
type_ = post["type"]
|
||||
else:
|
||||
type_ = "post"
|
||||
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"]["user_likes"] = 2
|
||||
# Translators: This will be user in 'dislike'
|
||||
output.speak(_("You don't like this"))
|
||||
|
||||
def do_comment(self, *args, **kwargs):
|
||||
""" Make a comment into the currently focused post."""
|
||||
post = self.get_post()
|
||||
if post == None:
|
||||
return
|
||||
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"):
|
||||
msg = comment.text
|
||||
try:
|
||||
user = post[self.user_key]
|
||||
id = post[self.post_key]
|
||||
self.session.vk.client.wall.addComment(owner_id=user, post_id=id, text=msg)
|
||||
output.speak(_("You've posted a comment"))
|
||||
except Exception as msg:
|
||||
log.error(msg)
|
||||
def do_comment(self, *args, **kwargs):
|
||||
""" Make a comment into the currently focused post."""
|
||||
post = self.get_post()
|
||||
if post == None:
|
||||
return
|
||||
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"):
|
||||
msg = comment.text
|
||||
try:
|
||||
user = post[self.user_key]
|
||||
id = post[self.post_key]
|
||||
self.session.vk.client.wall.addComment(owner_id=user, post_id=id, text=msg)
|
||||
output.speak(_("You've posted a comment"))
|
||||
except Exception as msg:
|
||||
log.error(msg)
|
||||
|
||||
def delete(self, *args, **kwargs):
|
||||
post = self.get_post()
|
||||
if ("type" in post and post["type"] == "post") or self.name != "newsfeed":
|
||||
question = commonMessages.remove_post()
|
||||
if question == widgetUtils.NO:
|
||||
return
|
||||
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])
|
||||
else:
|
||||
result = self.session.vk.client.wall.delete(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.tab.list.remove_item(self.tab.list.get_selected())
|
||||
def delete(self, *args, **kwargs):
|
||||
post = self.get_post()
|
||||
if ("type" in post and post["type"] == "post") or self.name != "newsfeed":
|
||||
question = commonMessages.remove_post()
|
||||
if question == widgetUtils.NO:
|
||||
return
|
||||
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])
|
||||
else:
|
||||
result = self.session.vk.client.wall.delete(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.tab.list.remove_item(self.tab.list.get_selected())
|
||||
|
||||
def get_event(self, ev):
|
||||
""" Parses keyboard input in the ListCtrl and executes the event associated with user keypresses."""
|
||||
if ev.GetKeyCode() == wx.WXK_RETURN: event = "open_post"
|
||||
else:
|
||||
event = None
|
||||
ev.Skip()
|
||||
if event != None:
|
||||
try:
|
||||
getattr(self, event)()
|
||||
except AttributeError:
|
||||
pass
|
||||
def get_event(self, ev):
|
||||
""" Parses keyboard input in the ListCtrl and executes the event associated with user keypresses."""
|
||||
if ev.GetKeyCode() == wx.WXK_RETURN: event = "open_post"
|
||||
else:
|
||||
event = None
|
||||
ev.Skip()
|
||||
if event != None:
|
||||
try:
|
||||
getattr(self, event)()
|
||||
except AttributeError:
|
||||
pass
|
||||
|
||||
def volume_down(self):
|
||||
""" Decreases player volume by 2%"""
|
||||
player.player.volume = player.player.volume-2
|
||||
def volume_down(self):
|
||||
""" Decreases player volume by 2%"""
|
||||
player.player.volume = player.player.volume-2
|
||||
|
||||
def volume_up(self):
|
||||
""" Increases player volume by 2%"""
|
||||
player.player.volume = player.player.volume+2
|
||||
def volume_up(self):
|
||||
""" Increases player volume by 2%"""
|
||||
player.player.volume = player.player.volume+2
|
||||
|
||||
def play_audio(self, *args, **kwargs):
|
||||
""" Play audio in currently focused buffer, if possible."""
|
||||
post = self.get_post()
|
||||
if post == None:
|
||||
return
|
||||
if "type" in post and post["type"] == "audio":
|
||||
pub.sendMessage("play", object=post["audio"]["items"][0])
|
||||
return True
|
||||
def play_audio(self, *args, **kwargs):
|
||||
""" Play audio in currently focused buffer, if possible."""
|
||||
post = self.get_post()
|
||||
if post == None:
|
||||
return
|
||||
if "type" in post and post["type"] == "audio":
|
||||
pub.sendMessage("play", object=post["audio"]["items"][0])
|
||||
return True
|
||||
|
||||
def open_person_profile(self, *args, **kwargs):
|
||||
""" Views someone's profile."""
|
||||
selected = self.get_post()
|
||||
if selected == None:
|
||||
return
|
||||
# Check all possible keys for an user object in VK API.
|
||||
keys = ["from_id", "source_id", "id"]
|
||||
for i in keys:
|
||||
if i in selected:
|
||||
pub.sendMessage("user-profile", person=selected[i])
|
||||
break
|
||||
def open_person_profile(self, *args, **kwargs):
|
||||
""" Views someone's profile."""
|
||||
selected = self.get_post()
|
||||
if selected == None:
|
||||
return
|
||||
# Check all possible keys for an user object in VK API.
|
||||
keys = ["from_id", "source_id", "id"]
|
||||
for i in keys:
|
||||
if i in selected:
|
||||
pub.sendMessage("user-profile", person=selected[i])
|
||||
break
|
||||
|
||||
def open_post(self, *args, **kwargs):
|
||||
""" Opens the currently focused post."""
|
||||
post = self.get_post()
|
||||
if post == None:
|
||||
return
|
||||
if "type" in post and post["type"] == "audio":
|
||||
a = presenters.displayAudioPresenter(session=self.session, postObject=post["audio"]["items"], interactor=interactors.displayAudioInteractor(), view=views.displayAudio())
|
||||
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")))
|
||||
else:
|
||||
pub.sendMessage("open-post", post_object=post, controller_="displayPost")
|
||||
def open_post(self, *args, **kwargs):
|
||||
""" Opens the currently focused post."""
|
||||
post = self.get_post()
|
||||
if post == None:
|
||||
return
|
||||
if "type" in post and post["type"] == "audio":
|
||||
a = presenters.displayAudioPresenter(session=self.session, postObject=post["audio"]["items"], interactor=interactors.displayAudioInteractor(), view=views.displayAudio())
|
||||
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")))
|
||||
else:
|
||||
pub.sendMessage("open-post", post_object=post, controller_="displayPost")
|
||||
|
||||
def pause_audio(self, *args, **kwargs):
|
||||
""" pauses audio playback."""
|
||||
pub.sendMessage("pause")
|
||||
def pause_audio(self, *args, **kwargs):
|
||||
""" pauses audio playback."""
|
||||
pub.sendMessage("pause")
|
||||
|
||||
def remove_buffer(self, mandatory):
|
||||
""" Function for removing a buffer. Returns True if removal is successful, False otherwise"""
|
||||
return False
|
||||
def remove_buffer(self, mandatory):
|
||||
""" Function for removing a buffer. Returns True if removal is successful, False otherwise"""
|
||||
return False
|
||||
|
||||
def get_users(self):
|
||||
""" Returns source user in the post."""
|
||||
post = self.get_post()
|
||||
if post == None:
|
||||
return
|
||||
if ("type" in post) == False:
|
||||
return [post["from_id"]]
|
||||
else:
|
||||
return [post["source_id"]]
|
||||
def get_users(self):
|
||||
""" Returns source user in the post."""
|
||||
post = self.get_post()
|
||||
if post == None:
|
||||
return
|
||||
if ("type" in post) == False:
|
||||
return [post["from_id"]]
|
||||
else:
|
||||
return [post["source_id"]]
|
||||
|
||||
def onFocus(self, event, *args,**kwargs):
|
||||
""" Function executed when the item in a list is selected.
|
||||
For this buffer it updates the date of posts in the list."""
|
||||
post = self.get_post()
|
||||
if post == None:
|
||||
return
|
||||
original_date = arrow.get(post["date"])
|
||||
created_at = original_date.humanize(locale=languageHandler.curLang[:2])
|
||||
self.tab.list.list.SetItem(self.tab.list.get_selected(), 2, created_at)
|
||||
event.Skip()
|
||||
def onFocus(self, event, *args,**kwargs):
|
||||
""" Function executed when the item in a list is selected.
|
||||
For this buffer it updates the date of posts in the list."""
|
||||
post = self.get_post()
|
||||
if post == None:
|
||||
return
|
||||
original_date = arrow.get(post["date"])
|
||||
created_at = original_date.humanize(locale=languageHandler.curLang[:2])
|
||||
self.tab.list.list.SetItem(self.tab.list.get_selected(), 2, created_at)
|
||||
event.Skip()
|
||||
|
||||
def open_in_browser(self, *args, **kwargs):
|
||||
post = self.get_post()
|
||||
if post == None:
|
||||
return
|
||||
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)
|
||||
def open_in_browser(self, *args, **kwargs):
|
||||
post = self.get_post()
|
||||
if post == None:
|
||||
return
|
||||
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)
|
||||
|
@ -7,10 +7,10 @@ log = logging.getLogger("controller.buffers")
|
||||
|
||||
class notificationBuffer(wallBuffer):
|
||||
|
||||
def create_tab(self, parent):
|
||||
self.tab = notification.notificationTab(parent)
|
||||
self.connect_events()
|
||||
self.tab.name = self.name
|
||||
def create_tab(self, parent):
|
||||
self.tab = notification.notificationTab(parent)
|
||||
self.connect_events()
|
||||
self.tab.name = self.name
|
||||
|
||||
def onFocus(self, event, *args, **kwargs):
|
||||
event.Skip()
|
||||
def onFocus(self, event, *args, **kwargs):
|
||||
event.Skip()
|
||||
|
@ -21,205 +21,205 @@ log = logging.getLogger("controller.buffers.friends")
|
||||
|
||||
class peopleBuffer(wallBuffer):
|
||||
|
||||
def post(self, *args, **kwargs):
|
||||
user = self.get_post()
|
||||
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]
|
||||
if user.get("can_post") == True:
|
||||
user_str = self.session.get_user(user["id"], key="user1")
|
||||
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=""))
|
||||
if hasattr(p, "text") or hasattr(p, "privacy"):
|
||||
post_arguments=dict(privacy=p.privacy, message=p.text, owner_id=user["id"])
|
||||
attachments = []
|
||||
if hasattr(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)
|
||||
def post(self, *args, **kwargs):
|
||||
user = self.get_post()
|
||||
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]
|
||||
if user.get("can_post") == True:
|
||||
user_str = self.session.get_user(user["id"], key="user1")
|
||||
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=""))
|
||||
if hasattr(p, "text") or hasattr(p, "privacy"):
|
||||
post_arguments=dict(privacy=p.privacy, message=p.text, owner_id=user["id"])
|
||||
attachments = []
|
||||
if hasattr(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)
|
||||
|
||||
def create_tab(self, parent):
|
||||
self.tab = people.peopleTab(parent)
|
||||
self.connect_events()
|
||||
self.tab.name = self.name
|
||||
if hasattr(self, "can_post") and self.can_post == False and hasattr(self.tab, "post"):
|
||||
self.tab.post.Enable(False)
|
||||
def create_tab(self, parent):
|
||||
self.tab = people.peopleTab(parent)
|
||||
self.connect_events()
|
||||
self.tab.name = self.name
|
||||
if hasattr(self, "can_post") and self.can_post == False and hasattr(self.tab, "post"):
|
||||
self.tab.post.Enable(False)
|
||||
|
||||
def connect_events(self):
|
||||
super(peopleBuffer, self).connect_events()
|
||||
widgetUtils.connect_event(self.tab.new_chat, widgetUtils.BUTTON_PRESSED, self.new_chat)
|
||||
def connect_events(self):
|
||||
super(peopleBuffer, self).connect_events()
|
||||
widgetUtils.connect_event(self.tab.new_chat, widgetUtils.BUTTON_PRESSED, self.new_chat)
|
||||
|
||||
def new_chat(self, *args, **kwargs):
|
||||
user = self.get_post()
|
||||
if user == None:
|
||||
return
|
||||
user_id = user["id"]
|
||||
pub.sendMessage("new-chat", user_id=user_id)
|
||||
def new_chat(self, *args, **kwargs):
|
||||
user = self.get_post()
|
||||
if user == None:
|
||||
return
|
||||
user_id = user["id"]
|
||||
pub.sendMessage("new-chat", user_id=user_id)
|
||||
|
||||
def onFocus(self, *args, **kwargs):
|
||||
post = self.get_post()
|
||||
if post == None:
|
||||
return
|
||||
if post.get("can_post") == True:
|
||||
self.tab.post.Enable(True)
|
||||
else:
|
||||
self.tab.post.Enable(False)
|
||||
# Check if we are allowed to contact people. this might be false for communitiy members.
|
||||
if post.get("can_write_private_message") == True:
|
||||
self.tab.new_chat.Enable(True)
|
||||
else:
|
||||
self.tab.new_chat.Enable(False)
|
||||
if ("last_seen" in post) == False: return
|
||||
original_date = arrow.get(post["last_seen"]["time"])
|
||||
now = arrow.now()
|
||||
original_date.to(now.tzinfo)
|
||||
diffdate = now-original_date
|
||||
if diffdate.days == 0 and diffdate.seconds <= 360:
|
||||
online_status = _("Online")
|
||||
else:
|
||||
# Translators: This is the date of last seen
|
||||
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)
|
||||
def onFocus(self, *args, **kwargs):
|
||||
post = self.get_post()
|
||||
if post == None:
|
||||
return
|
||||
if post.get("can_post") == True:
|
||||
self.tab.post.Enable(True)
|
||||
else:
|
||||
self.tab.post.Enable(False)
|
||||
# Check if we are allowed to contact people. this might be false for communitiy members.
|
||||
if post.get("can_write_private_message") == True:
|
||||
self.tab.new_chat.Enable(True)
|
||||
else:
|
||||
self.tab.new_chat.Enable(False)
|
||||
if ("last_seen" in post) == False: return
|
||||
original_date = arrow.get(post["last_seen"]["time"])
|
||||
now = arrow.now()
|
||||
original_date.to(now.tzinfo)
|
||||
diffdate = now-original_date
|
||||
if diffdate.days == 0 and diffdate.seconds <= 360:
|
||||
online_status = _("Online")
|
||||
else:
|
||||
# Translators: This is the date of last seen
|
||||
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)
|
||||
|
||||
def open_timeline(self, *args, **kwargs):
|
||||
user = self.get_post()
|
||||
if user == None:
|
||||
return
|
||||
a = timeline.timelineDialog([self.session.get_user(user["id"])["user1_gen"]], show_selector=False)
|
||||
if a.get_response() == widgetUtils.OK:
|
||||
buffer_type = a.get_buffer_type()
|
||||
user_id = user["id"]
|
||||
pub.sendMessage("create-timeline", user_id=user_id, buffer_type=buffer_type)
|
||||
def open_timeline(self, *args, **kwargs):
|
||||
user = self.get_post()
|
||||
if user == None:
|
||||
return
|
||||
a = timeline.timelineDialog([self.session.get_user(user["id"])["user1_gen"]], show_selector=False)
|
||||
if a.get_response() == widgetUtils.OK:
|
||||
buffer_type = a.get_buffer_type()
|
||||
user_id = user["id"]
|
||||
pub.sendMessage("create-timeline", user_id=user_id, buffer_type=buffer_type)
|
||||
|
||||
def get_menu(self, *args, **kwargs):
|
||||
""" 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.
|
||||
# So let's make sure we call it accordingly.
|
||||
if self.name == "friend_requests":
|
||||
m = menus.peopleMenu(is_request=True)
|
||||
# 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.decline_friendship, menuitem=m.decline)
|
||||
widgetUtils.connect_event(m, widgetUtils.MENU, self.keep_as_follower, menuitem=m.keep_as_follower)
|
||||
elif self.name == "subscribers":
|
||||
m = menus.peopleMenu(is_subscriber=True)
|
||||
widgetUtils.connect_event(m, widgetUtils.MENU, self.accept_friendship, menuitem=m.add)
|
||||
else:
|
||||
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.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.
|
||||
if "friend_requests" in self.name:
|
||||
m.message.Enable(False)
|
||||
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_person_profile, menuitem=m.view_profile)
|
||||
widgetUtils.connect_event(m, widgetUtils.MENU, self.open_in_browser, menuitem=m.open_in_browser)
|
||||
return m
|
||||
def get_menu(self, *args, **kwargs):
|
||||
""" 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.
|
||||
# So let's make sure we call it accordingly.
|
||||
if self.name == "friend_requests":
|
||||
m = menus.peopleMenu(is_request=True)
|
||||
# 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.decline_friendship, menuitem=m.decline)
|
||||
widgetUtils.connect_event(m, widgetUtils.MENU, self.keep_as_follower, menuitem=m.keep_as_follower)
|
||||
elif self.name == "subscribers":
|
||||
m = menus.peopleMenu(is_subscriber=True)
|
||||
widgetUtils.connect_event(m, widgetUtils.MENU, self.accept_friendship, menuitem=m.add)
|
||||
else:
|
||||
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.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.
|
||||
if "friend_requests" in self.name:
|
||||
m.message.Enable(False)
|
||||
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_person_profile, menuitem=m.view_profile)
|
||||
widgetUtils.connect_event(m, widgetUtils.MENU, self.open_in_browser, menuitem=m.open_in_browser)
|
||||
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):
|
||||
pass
|
||||
def accept_friendship(self, *args, **kwargs):
|
||||
pass
|
||||
|
||||
def decline_friendship(self, *args, **kwargs):
|
||||
person = self.get_post()
|
||||
if person == None:
|
||||
return
|
||||
user = self.session.get_user(person["id"])
|
||||
question = commonMessages.remove_friend(user)
|
||||
if question == widgetUtils.NO:
|
||||
return
|
||||
result = self.session.vk.client.friends.delete(user_id=person["id"])
|
||||
if "friend_deleted" in result:
|
||||
msg = _("You've removed {user1_nom} from your friends.").format(**user,)
|
||||
pub.sendMessage("notify", message=msg)
|
||||
self.session.db[self.name]["items"].pop(self.tab.list.get_selected())
|
||||
self.tab.list.remove_item(self.tab.list.get_selected())
|
||||
def decline_friendship(self, *args, **kwargs):
|
||||
person = self.get_post()
|
||||
if person == None:
|
||||
return
|
||||
user = self.session.get_user(person["id"])
|
||||
question = commonMessages.remove_friend(user)
|
||||
if question == widgetUtils.NO:
|
||||
return
|
||||
result = self.session.vk.client.friends.delete(user_id=person["id"])
|
||||
if "friend_deleted" in result:
|
||||
msg = _("You've removed {user1_nom} from your friends.").format(**user,)
|
||||
pub.sendMessage("notify", message=msg)
|
||||
self.session.db[self.name]["items"].pop(self.tab.list.get_selected())
|
||||
self.tab.list.remove_item(self.tab.list.get_selected())
|
||||
|
||||
def block_person(self, *args, **kwargs):
|
||||
person = self.get_post()
|
||||
if person == None:
|
||||
return
|
||||
user = self.session.get_user(person["id"])
|
||||
question = commonMessages.block_person(user)
|
||||
if question == widgetUtils.NO:
|
||||
return
|
||||
result = self.session.vk.client.account.ban(owner_id=person["id"])
|
||||
if result == 1:
|
||||
msg = _("You've blocked {user1_nom} from your friends.").format(**user,)
|
||||
pub.sendMessage("notify", message=msg)
|
||||
self.session.db[self.name]["items"].pop(self.tab.list.get_selected())
|
||||
self.tab.list.remove_item(self.tab.list.get_selected())
|
||||
def block_person(self, *args, **kwargs):
|
||||
person = self.get_post()
|
||||
if person == None:
|
||||
return
|
||||
user = self.session.get_user(person["id"])
|
||||
question = commonMessages.block_person(user)
|
||||
if question == widgetUtils.NO:
|
||||
return
|
||||
result = self.session.vk.client.account.ban(owner_id=person["id"])
|
||||
if result == 1:
|
||||
msg = _("You've blocked {user1_nom} from your friends.").format(**user,)
|
||||
pub.sendMessage("notify", message=msg)
|
||||
self.session.db[self.name]["items"].pop(self.tab.list.get_selected())
|
||||
self.tab.list.remove_item(self.tab.list.get_selected())
|
||||
|
||||
def keep_as_follower(self, *args, **kwargs):
|
||||
pass
|
||||
def keep_as_follower(self, *args, **kwargs):
|
||||
pass
|
||||
|
||||
def add_person(self, person):
|
||||
# This tracks if the user already exists here, in such case we just will update the last_seen variable
|
||||
existing = False
|
||||
for i in self.session.db[self.name]["items"]:
|
||||
if person["id"] == i["id"]:
|
||||
existing = True
|
||||
i["last_seen"]["time"] = person["last_seen"]["time"]
|
||||
break
|
||||
# Add the new user to the buffer just if it does not exists previously.
|
||||
if existing == False:
|
||||
# Ensure the user won't loose the focus after the new item is added.
|
||||
focused_item = self.tab.list.get_selected()+1
|
||||
self.session.db[self.name]["items"].insert(0, person)
|
||||
self.insert(person, True)
|
||||
# Selects back the previously focused item.
|
||||
self.tab.list.select_item(focused_item)
|
||||
def add_person(self, person):
|
||||
# This tracks if the user already exists here, in such case we just will update the last_seen variable
|
||||
existing = False
|
||||
for i in self.session.db[self.name]["items"]:
|
||||
if person["id"] == i["id"]:
|
||||
existing = True
|
||||
i["last_seen"]["time"] = person["last_seen"]["time"]
|
||||
break
|
||||
# Add the new user to the buffer just if it does not exists previously.
|
||||
if existing == False:
|
||||
# Ensure the user won't loose the focus after the new item is added.
|
||||
focused_item = self.tab.list.get_selected()+1
|
||||
self.session.db[self.name]["items"].insert(0, person)
|
||||
self.insert(person, True)
|
||||
# Selects back the previously focused item.
|
||||
self.tab.list.select_item(focused_item)
|
||||
|
||||
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.
|
||||
user = None
|
||||
focused_user = self.get_post()
|
||||
for i in self.session.db[self.name]["items"]:
|
||||
if i["id"] == user_id:
|
||||
user = i
|
||||
break
|
||||
if user != None:
|
||||
person_index = self.session.db[self.name]["items"].index(user)
|
||||
focused_item = self.tab.list.get_selected()
|
||||
self.session.db[self.name]["items"].pop(person_index)
|
||||
self.tab.list.remove_item(person_index)
|
||||
if user != focused_user:
|
||||
# Let's find the position of the previously focused user.
|
||||
focus = None
|
||||
for i in range(0, len(self.session.db[self.name]["items"])):
|
||||
if focused_user["id"] == self.session.db[self.name]["items"][i]["id"]:
|
||||
self.tab.list.select_item(i)
|
||||
return
|
||||
elif user == focused_user and person_index < self.tab.list.get_count():
|
||||
self.tab.list.select_item(person_index)
|
||||
else:
|
||||
self.tab.list.select_item(self.tab.list.get_count()-1)
|
||||
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.
|
||||
user = None
|
||||
focused_user = self.get_post()
|
||||
for i in self.session.db[self.name]["items"]:
|
||||
if i["id"] == user_id:
|
||||
user = i
|
||||
break
|
||||
if user != None:
|
||||
person_index = self.session.db[self.name]["items"].index(user)
|
||||
focused_item = self.tab.list.get_selected()
|
||||
self.session.db[self.name]["items"].pop(person_index)
|
||||
self.tab.list.remove_item(person_index)
|
||||
if user != focused_user:
|
||||
# Let's find the position of the previously focused user.
|
||||
focus = None
|
||||
for i in range(0, len(self.session.db[self.name]["items"])):
|
||||
if focused_user["id"] == self.session.db[self.name]["items"][i]["id"]:
|
||||
self.tab.list.select_item(i)
|
||||
return
|
||||
elif user == focused_user and person_index < self.tab.list.get_count():
|
||||
self.tab.list.select_item(person_index)
|
||||
else:
|
||||
self.tab.list.select_item(self.tab.list.get_count()-1)
|
||||
|
||||
def get_friend(self, user_id):
|
||||
for i in self.session.db["friends_"]["items"]:
|
||||
if i["id"] == user_id:
|
||||
return i
|
||||
log.exception("Getting user manually...")
|
||||
user = self.session.vk.client.users.get(user_ids=event.user_id, fields="last_seen")[0]
|
||||
return user
|
||||
def get_friend(self, user_id):
|
||||
for i in self.session.db["friends_"]["items"]:
|
||||
if i["id"] == user_id:
|
||||
return i
|
||||
log.exception("Getting user manually...")
|
||||
user = self.session.vk.client.users.get(user_ids=event.user_id, fields="last_seen")[0]
|
||||
return user
|
||||
|
||||
def update_online(self):
|
||||
online_users = self.session.vk.client.friends.getOnline()
|
||||
now = time.time()
|
||||
for i in self.session.db[self.name]["items"]:
|
||||
if i["id"] in online_users:
|
||||
i["last_seen"]["time"] = now
|
||||
else:
|
||||
log.exception("Removing an user from online status manually... %r" % (i))
|
||||
self.remove_person(i["id"])
|
||||
def update_online(self):
|
||||
online_users = self.session.vk.client.friends.getOnline()
|
||||
now = time.time()
|
||||
for i in self.session.db[self.name]["items"]:
|
||||
if i["id"] in online_users:
|
||||
i["last_seen"]["time"] = now
|
||||
else:
|
||||
log.exception("Removing an user from online status manually... %r" % (i))
|
||||
self.remove_person(i["id"])
|
||||
|
||||
def open_in_browser(self, *args, **kwargs):
|
||||
post = self.get_post()
|
||||
if post == None:
|
||||
return
|
||||
url = "https://vk.com/id{user_id}".format(user_id=post["id"])
|
||||
webbrowser.open_new_tab(url)
|
||||
def open_in_browser(self, *args, **kwargs):
|
||||
post = self.get_post()
|
||||
if post == None:
|
||||
return
|
||||
url = "https://vk.com/id{user_id}".format(user_id=post["id"])
|
||||
webbrowser.open_new_tab(url)
|
||||
|
@ -12,114 +12,114 @@ from .wall import wallBuffer
|
||||
log = logging.getLogger("controller.buffers.video")
|
||||
|
||||
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):
|
||||
self.tab = video.videoTab(parent)
|
||||
self.connect_events()
|
||||
self.tab.name = self.name
|
||||
if hasattr(self, "can_post") and self.can_post == False and hasattr(self.tab, "post"):
|
||||
self.tab.post.Enable(False)
|
||||
def create_tab(self, parent):
|
||||
self.tab = video.videoTab(parent)
|
||||
self.connect_events()
|
||||
self.tab.name = self.name
|
||||
if hasattr(self, "can_post") and self.can_post == False and hasattr(self.tab, "post"):
|
||||
self.tab.post.Enable(False)
|
||||
|
||||
def connect_events(self):
|
||||
widgetUtils.connect_event(self.tab.play, widgetUtils.BUTTON_PRESSED, self.play_audio)
|
||||
super(videoBuffer, self).connect_events()
|
||||
def connect_events(self):
|
||||
widgetUtils.connect_event(self.tab.play, widgetUtils.BUTTON_PRESSED, self.play_audio)
|
||||
super(videoBuffer, self).connect_events()
|
||||
|
||||
def play_audio(self, *args, **kwargs):
|
||||
""" 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."""
|
||||
selected = self.tab.list.get_selected()
|
||||
if self.tab.list.get_count() == 0:
|
||||
return
|
||||
if selected == -1:
|
||||
selected = 0
|
||||
output.speak(_("Opening video in webbrowser..."))
|
||||
webbrowser.open_new_tab(self.session.db[self.name]["items"][selected]["player"])
|
||||
# print self.session.db[self.name]["items"][selected]
|
||||
return True
|
||||
def play_audio(self, *args, **kwargs):
|
||||
""" 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."""
|
||||
selected = self.tab.list.get_selected()
|
||||
if self.tab.list.get_count() == 0:
|
||||
return
|
||||
if selected == -1:
|
||||
selected = 0
|
||||
output.speak(_("Opening video in webbrowser..."))
|
||||
webbrowser.open_new_tab(self.session.db[self.name]["items"][selected]["player"])
|
||||
# print self.session.db[self.name]["items"][selected]
|
||||
return True
|
||||
|
||||
def open_post(self, *args, **kwargs):
|
||||
pass
|
||||
def open_post(self, *args, **kwargs):
|
||||
pass
|
||||
|
||||
def remove_buffer(self, mandatory=False):
|
||||
if "me_video" == self.name:
|
||||
output.speak(_("This buffer can't be deleted"))
|
||||
return False
|
||||
else:
|
||||
if mandatory == False:
|
||||
dlg = commonMessages.remove_buffer()
|
||||
else:
|
||||
dlg = widgetUtils.YES
|
||||
if dlg == widgetUtils.YES:
|
||||
self.session.db.pop(self.name)
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
def remove_buffer(self, mandatory=False):
|
||||
if "me_video" == self.name:
|
||||
output.speak(_("This buffer can't be deleted"))
|
||||
return False
|
||||
else:
|
||||
if mandatory == False:
|
||||
dlg = commonMessages.remove_buffer()
|
||||
else:
|
||||
dlg = widgetUtils.YES
|
||||
if dlg == widgetUtils.YES:
|
||||
self.session.db.pop(self.name)
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
def get_more_items(self, *args, **kwargs):
|
||||
# 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."))
|
||||
def get_more_items(self, *args, **kwargs):
|
||||
# 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."))
|
||||
|
||||
def onFocus(self, event, *args, **kwargs):
|
||||
event.Skip()
|
||||
def onFocus(self, event, *args, **kwargs):
|
||||
event.Skip()
|
||||
|
||||
def add_to_library(self, *args, **kwargs):
|
||||
post = self.get_post()
|
||||
if post == None:
|
||||
return
|
||||
args = {}
|
||||
args["video_id"] = post["id"]
|
||||
if "album_id" in post:
|
||||
args["album_id"] = post["album_id"]
|
||||
args["owner_id"] = post["owner_id"]
|
||||
video = self.session.vk.client.video.add(**args)
|
||||
if video != None and int(video) > 21:
|
||||
output.speak(_("Video added to your library"))
|
||||
def add_to_library(self, *args, **kwargs):
|
||||
post = self.get_post()
|
||||
if post == None:
|
||||
return
|
||||
args = {}
|
||||
args["video_id"] = post["id"]
|
||||
if "album_id" in post:
|
||||
args["album_id"] = post["album_id"]
|
||||
args["owner_id"] = post["owner_id"]
|
||||
video = self.session.vk.client.video.add(**args)
|
||||
if video != None and int(video) > 21:
|
||||
output.speak(_("Video added to your library"))
|
||||
|
||||
def remove_from_library(self, *args, **kwargs):
|
||||
post = self.get_post()
|
||||
if post == None:
|
||||
return
|
||||
args = {}
|
||||
args["video_id"] = post["id"]
|
||||
args["owner_id"] = self.session.user_id
|
||||
result = self.session.vk.client.video.delete(**args)
|
||||
if int(result) == 1:
|
||||
output.speak(_("Removed video from library"))
|
||||
self.tab.list.remove_item(self.tab.list.get_selected())
|
||||
def remove_from_library(self, *args, **kwargs):
|
||||
post = self.get_post()
|
||||
if post == None:
|
||||
return
|
||||
args = {}
|
||||
args["video_id"] = post["id"]
|
||||
args["owner_id"] = self.session.user_id
|
||||
result = self.session.vk.client.video.delete(**args)
|
||||
if int(result) == 1:
|
||||
output.speak(_("Removed video from library"))
|
||||
self.tab.list.remove_item(self.tab.list.get_selected())
|
||||
|
||||
def move_to_album(self, *args, **kwargs):
|
||||
if len(self.session.video_albums) == 0:
|
||||
return commonMessages.no_video_albums()
|
||||
post= self.get_post()
|
||||
if post == None:
|
||||
return
|
||||
album = selector.album(_("Select the album where you want to move this video"), self.session, "video_albums")
|
||||
if album.item == None: return
|
||||
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"])
|
||||
if response == 1:
|
||||
# Translators: Used when the user has moved an video to an album.
|
||||
output.speak(_("Moved"))
|
||||
def move_to_album(self, *args, **kwargs):
|
||||
if len(self.session.video_albums) == 0:
|
||||
return commonMessages.no_video_albums()
|
||||
post= self.get_post()
|
||||
if post == None:
|
||||
return
|
||||
album = selector.album(_("Select the album where you want to move this video"), self.session, "video_albums")
|
||||
if album.item == None: return
|
||||
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"])
|
||||
if response == 1:
|
||||
# Translators: Used when the user has moved an video to an album.
|
||||
output.speak(_("Moved"))
|
||||
|
||||
def get_menu(self):
|
||||
""" We'll use the same menu that is used for audio items, as the options are exactly the same"""
|
||||
p = self.get_post()
|
||||
if p == None:
|
||||
return
|
||||
m = menus.audioMenu()
|
||||
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 p["owner_id"] == self.session.user_id:
|
||||
m.library.SetItemLabel(_("&Remove"))
|
||||
widgetUtils.connect_event(m, widgetUtils.MENU, self.remove_from_library, menuitem=m.library)
|
||||
else:
|
||||
widgetUtils.connect_event(m, widgetUtils.MENU, self.add_to_library, menuitem=m.library)
|
||||
return m
|
||||
def get_menu(self):
|
||||
""" We'll use the same menu that is used for audio items, as the options are exactly the same"""
|
||||
p = self.get_post()
|
||||
if p == None:
|
||||
return
|
||||
m = menus.audioMenu()
|
||||
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 p["owner_id"] == self.session.user_id:
|
||||
m.library.SetItemLabel(_("&Remove"))
|
||||
widgetUtils.connect_event(m, widgetUtils.MENU, self.remove_from_library, menuitem=m.library)
|
||||
else:
|
||||
widgetUtils.connect_event(m, widgetUtils.MENU, self.add_to_library, menuitem=m.library)
|
||||
return m
|
||||
|
||||
def open_in_browser(self, *args, **kwargs):
|
||||
post = self.get_post()
|
||||
if post == None:
|
||||
return
|
||||
url = "https://vk.com/video{user_id}_{video_id}".format(user_id=post["owner_id"], video_id=post["id"])
|
||||
webbrowser.open_new_tab(url)
|
||||
def open_in_browser(self, *args, **kwargs):
|
||||
post = self.get_post()
|
||||
if post == None:
|
||||
return
|
||||
url = "https://vk.com/video{user_id}_{video_id}".format(user_id=post["owner_id"], video_id=post["id"])
|
||||
webbrowser.open_new_tab(url)
|
||||
|
@ -10,21 +10,21 @@ log = logging.getLogger("controller.buffers")
|
||||
|
||||
class videoAlbumBuffer(videoBuffer):
|
||||
|
||||
def create_tab(self, parent):
|
||||
self.tab = video.videoAlbumTab(parent)
|
||||
self.tab.play.Enable(False)
|
||||
self.connect_events()
|
||||
self.tab.name = self.name
|
||||
if hasattr(self, "can_post") and self.can_post == False and hasattr(self.tab, "post"):
|
||||
self.tab.post.Enable(False)
|
||||
def create_tab(self, parent):
|
||||
self.tab = video.videoAlbumTab(parent)
|
||||
self.tab.play.Enable(False)
|
||||
self.connect_events()
|
||||
self.tab.name = self.name
|
||||
if hasattr(self, "can_post") and self.can_post == False and hasattr(self.tab, "post"):
|
||||
self.tab.post.Enable(False)
|
||||
|
||||
def connect_events(self):
|
||||
super(videoAlbumBuffer, self).connect_events()
|
||||
widgetUtils.connect_event(self.tab.load, widgetUtils.BUTTON_PRESSED, self.load_album)
|
||||
def connect_events(self):
|
||||
super(videoAlbumBuffer, self).connect_events()
|
||||
widgetUtils.connect_event(self.tab.load, widgetUtils.BUTTON_PRESSED, self.load_album)
|
||||
|
||||
def load_album(self, *args, **kwargs):
|
||||
output.speak(_("Loading album..."))
|
||||
self.can_get_items = True
|
||||
self.tab.load.Enable(False)
|
||||
wx.CallAfter(self.get_items)
|
||||
self.tab.play.Enable(True)
|
||||
def load_album(self, *args, **kwargs):
|
||||
output.speak(_("Loading album..."))
|
||||
self.can_get_items = True
|
||||
self.tab.load.Enable(False)
|
||||
wx.CallAfter(self.get_items)
|
||||
self.tab.play.Enable(True)
|
||||
|
@ -17,88 +17,88 @@ from .home import homeBuffer
|
||||
log = logging.getLogger("controller.buffers.wall")
|
||||
|
||||
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):
|
||||
""" Update buffer with newest items or get older items in the buffer."""
|
||||
if self.can_get_items == False: return
|
||||
retrieved = True
|
||||
try:
|
||||
num = getattr(self.session, "get_page")(show_nextpage=show_nextpage, name=self.name, *self.args, **self.kwargs)
|
||||
except VkApiError as err:
|
||||
log.error("Error {0}: {1}".format(err.code, err.error))
|
||||
retrieved = err.code
|
||||
return retrieved
|
||||
except:
|
||||
log.exception("Connection error when updating buffer %s. Will try again in 2 minutes" % (self.name,))
|
||||
return False
|
||||
if not hasattr(self, "tab"):
|
||||
# Create GUI associated to this buffer.
|
||||
self.create_tab(self.parent)
|
||||
# Add name to the new control so we could look for it when needed.
|
||||
self.tab.name = self.name
|
||||
if show_nextpage == False:
|
||||
if self.tab.list.get_count() > 0 and num > 0:
|
||||
v = [i for i in self.session.db[self.name]["items"][:num]]
|
||||
v.reverse()
|
||||
[wx.CallAfter(self.insert, i, True) for i in v]
|
||||
else:
|
||||
[wx.CallAfter(self.insert, i) for i in self.session.db[self.name]["items"][:num]]
|
||||
else:
|
||||
if num > 0:
|
||||
[wx.CallAfter(self.insert, i, False) for i in self.session.db[self.name]["items"][-num:]]
|
||||
return retrieved
|
||||
def get_items(self, show_nextpage=False):
|
||||
""" Update buffer with newest items or get older items in the buffer."""
|
||||
if self.can_get_items == False: return
|
||||
retrieved = True
|
||||
try:
|
||||
num = getattr(self.session, "get_page")(show_nextpage=show_nextpage, name=self.name, *self.args, **self.kwargs)
|
||||
except VkApiError as err:
|
||||
log.error("Error {0}: {1}".format(err.code, err.error))
|
||||
retrieved = err.code
|
||||
return retrieved
|
||||
except:
|
||||
log.exception("Connection error when updating buffer %s. Will try again in 2 minutes" % (self.name,))
|
||||
return False
|
||||
if not hasattr(self, "tab"):
|
||||
# Create GUI associated to this buffer.
|
||||
self.create_tab(self.parent)
|
||||
# Add name to the new control so we could look for it when needed.
|
||||
self.tab.name = self.name
|
||||
if show_nextpage == False:
|
||||
if self.tab.list.get_count() > 0 and num > 0:
|
||||
v = [i for i in self.session.db[self.name]["items"][:num]]
|
||||
v.reverse()
|
||||
[wx.CallAfter(self.insert, i, True) for i in v]
|
||||
else:
|
||||
[wx.CallAfter(self.insert, i) for i in self.session.db[self.name]["items"][:num]]
|
||||
else:
|
||||
if num > 0:
|
||||
[wx.CallAfter(self.insert, i, False) for i in self.session.db[self.name]["items"][-num:]]
|
||||
return retrieved
|
||||
|
||||
def remove_buffer(self, mandatory=False):
|
||||
""" Remove buffer if the current buffer is not the logged user's wall."""
|
||||
if "me_feed" == self.name:
|
||||
output.speak(_("This buffer can't be deleted"))
|
||||
return False
|
||||
else:
|
||||
if mandatory == False:
|
||||
dlg = commonMessages.remove_buffer()
|
||||
else:
|
||||
dlg = widgetUtils.YES
|
||||
if dlg == widgetUtils.YES:
|
||||
self.session.db.pop(self.name)
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
def remove_buffer(self, mandatory=False):
|
||||
""" Remove buffer if the current buffer is not the logged user's wall."""
|
||||
if "me_feed" == self.name:
|
||||
output.speak(_("This buffer can't be deleted"))
|
||||
return False
|
||||
else:
|
||||
if mandatory == False:
|
||||
dlg = commonMessages.remove_buffer()
|
||||
else:
|
||||
dlg = widgetUtils.YES
|
||||
if dlg == widgetUtils.YES:
|
||||
self.session.db.pop(self.name)
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(wallBuffer, self).__init__(*args, **kwargs)
|
||||
self.user_key = "from_id"
|
||||
self.post_key = "id"
|
||||
self.can_post = True
|
||||
self.can_write_private_message = True
|
||||
# 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:
|
||||
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_see_all_posts = permissions[0]["can_see_all_posts"]
|
||||
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))
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(wallBuffer, self).__init__(*args, **kwargs)
|
||||
self.user_key = "from_id"
|
||||
self.post_key = "id"
|
||||
self.can_post = True
|
||||
self.can_write_private_message = True
|
||||
# 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:
|
||||
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_see_all_posts = permissions[0]["can_see_all_posts"]
|
||||
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))
|
||||
|
||||
def post(self, *args, **kwargs):
|
||||
""" 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.
|
||||
During the second part (threaded), the post will be sent to the API."""
|
||||
if "owner_id" not in self.kwargs:
|
||||
return super(wallBuffer, self).post()
|
||||
owner_id = self.kwargs["owner_id"]
|
||||
user = self.session.get_user(owner_id, key="user1")
|
||||
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=""))
|
||||
if hasattr(p, "text") or hasattr(p, "privacy"):
|
||||
post_arguments=dict(privacy=p.privacy, message=p.text, owner_id=owner_id)
|
||||
attachments = []
|
||||
if hasattr(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)
|
||||
def post(self, *args, **kwargs):
|
||||
""" 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.
|
||||
During the second part (threaded), the post will be sent to the API."""
|
||||
if "owner_id" not in self.kwargs:
|
||||
return super(wallBuffer, self).post()
|
||||
owner_id = self.kwargs["owner_id"]
|
||||
user = self.session.get_user(owner_id, key="user1")
|
||||
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=""))
|
||||
if hasattr(p, "text") or hasattr(p, "privacy"):
|
||||
post_arguments=dict(privacy=p.privacy, message=p.text, owner_id=owner_id)
|
||||
attachments = []
|
||||
if hasattr(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)
|
||||
|
||||
def open_in_browser(self, *args, **kwargs):
|
||||
post = self.get_post()
|
||||
if post == None:
|
||||
return
|
||||
url = "https://vk.com/wall{user_id}_{post_id}".format(user_id=post["from_id"], post_id=post["id"])
|
||||
webbrowser.open_new_tab(url)
|
||||
def open_in_browser(self, *args, **kwargs):
|
||||
post = self.get_post()
|
||||
if post == None:
|
||||
return
|
||||
url = "https://vk.com/wall{user_id}_{post_id}".format(user_id=post["from_id"], post_id=post["id"])
|
||||
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):
|
||||
|
||||
def __init__(self, title, session, album_type="audio_albums"):
|
||||
super(album, self).__init__()
|
||||
self.item = None
|
||||
self.session = session
|
||||
if not hasattr(self.session, album_type):
|
||||
return
|
||||
self.albums = getattr(self.session, album_type)
|
||||
self.dialog = gui.selectAlbum(title=title, albums=self.get_albums_as_string())
|
||||
response = self.dialog.get_response()
|
||||
if response == widgetUtils.OK:
|
||||
self.item = self.search_item(self.dialog.get_string())
|
||||
def __init__(self, title, session, album_type="audio_albums"):
|
||||
super(album, self).__init__()
|
||||
self.item = None
|
||||
self.session = session
|
||||
if not hasattr(self.session, album_type):
|
||||
return
|
||||
self.albums = getattr(self.session, album_type)
|
||||
self.dialog = gui.selectAlbum(title=title, albums=self.get_albums_as_string())
|
||||
response = self.dialog.get_response()
|
||||
if response == widgetUtils.OK:
|
||||
self.item = self.search_item(self.dialog.get_string())
|
||||
|
||||
def get_albums_as_string(self):
|
||||
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 get_albums_as_string(self):
|
||||
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
|
||||
|
@ -3,4 +3,4 @@ from __future__ import unicode_literals
|
||||
from . import spellchecker
|
||||
import platform
|
||||
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")
|
||||
|
||||
class spellChecker(object):
|
||||
def __init__(self, text):
|
||||
super(spellChecker, self).__init__()
|
||||
self.active = True
|
||||
try:
|
||||
if config.app["app-settings"]["language"] == "system":
|
||||
log.debug("Using the system language")
|
||||
self.dict = enchant.DictWithPWL(languageHandler.curLang[:2], os.path.join(paths.config_path(), "wordlist.dict"))
|
||||
else:
|
||||
log.debug("Using language: %s" % (languageHandler.getLanguage(),))
|
||||
self.dict = enchant.DictWithPWL(languageHandler.getLanguage()[:2], os.path.join(paths.config_path(), "wordlist.dict"))
|
||||
except DictNotFoundError:
|
||||
log.exception("Dictionary for language %s not found." % (languageHandler.getLanguage(),))
|
||||
wx_ui.dict_not_found_error()
|
||||
self.active = False
|
||||
self.checker = SpellChecker(self.dict, filters=[twitterFilter.TwitterFilter, tokenize.EmailFilter, tokenize.URLFilter])
|
||||
self.checker.set_text(text)
|
||||
if self.active == True:
|
||||
log.debug("Creating dialog...")
|
||||
self.dialog = wx_ui.spellCheckerDialog()
|
||||
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.replace, widgetUtils.BUTTON_PRESSED, self.replace)
|
||||
widgetUtils.connect_event(self.dialog.replaceAll, widgetUtils.BUTTON_PRESSED, self.replaceAll)
|
||||
widgetUtils.connect_event(self.dialog.add, widgetUtils.BUTTON_PRESSED, self.add)
|
||||
self.check()
|
||||
self.dialog.get_response()
|
||||
self.fixed_text = self.checker.get_text()
|
||||
def __init__(self, text):
|
||||
super(spellChecker, self).__init__()
|
||||
self.active = True
|
||||
try:
|
||||
if config.app["app-settings"]["language"] == "system":
|
||||
log.debug("Using the system language")
|
||||
self.dict = enchant.DictWithPWL(languageHandler.curLang[:2], os.path.join(paths.config_path(), "wordlist.dict"))
|
||||
else:
|
||||
log.debug("Using language: %s" % (languageHandler.getLanguage(),))
|
||||
self.dict = enchant.DictWithPWL(languageHandler.getLanguage()[:2], os.path.join(paths.config_path(), "wordlist.dict"))
|
||||
except DictNotFoundError:
|
||||
log.exception("Dictionary for language %s not found." % (languageHandler.getLanguage(),))
|
||||
wx_ui.dict_not_found_error()
|
||||
self.active = False
|
||||
self.checker = SpellChecker(self.dict, filters=[twitterFilter.TwitterFilter, tokenize.EmailFilter, tokenize.URLFilter])
|
||||
self.checker.set_text(text)
|
||||
if self.active == True:
|
||||
log.debug("Creating dialog...")
|
||||
self.dialog = wx_ui.spellCheckerDialog()
|
||||
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.replace, widgetUtils.BUTTON_PRESSED, self.replace)
|
||||
widgetUtils.connect_event(self.dialog.replaceAll, widgetUtils.BUTTON_PRESSED, self.replaceAll)
|
||||
widgetUtils.connect_event(self.dialog.add, widgetUtils.BUTTON_PRESSED, self.add)
|
||||
self.check()
|
||||
self.dialog.get_response()
|
||||
self.fixed_text = self.checker.get_text()
|
||||
|
||||
def check(self):
|
||||
try:
|
||||
next(self.checker)
|
||||
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))
|
||||
self.dialog.set_title(textToSay)
|
||||
output.speak(textToSay)
|
||||
self.dialog.set_word_and_suggestions(word=self.checker.word, context=context, suggestions=self.checker.suggest())
|
||||
except StopIteration:
|
||||
log.debug("Process finished.")
|
||||
wx_ui.finished()
|
||||
self.dialog.Destroy()
|
||||
def check(self):
|
||||
try:
|
||||
next(self.checker)
|
||||
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))
|
||||
self.dialog.set_title(textToSay)
|
||||
output.speak(textToSay)
|
||||
self.dialog.set_word_and_suggestions(word=self.checker.word, context=context, suggestions=self.checker.suggest())
|
||||
except StopIteration:
|
||||
log.debug("Process finished.")
|
||||
wx_ui.finished()
|
||||
self.dialog.Destroy()
|
||||
|
||||
def ignore(self, ev):
|
||||
self.check()
|
||||
def ignore(self, ev):
|
||||
self.check()
|
||||
|
||||
def ignoreAll(self, ev):
|
||||
self.checker.ignore_always(word=self.checker.word)
|
||||
self.check()
|
||||
def ignoreAll(self, ev):
|
||||
self.checker.ignore_always(word=self.checker.word)
|
||||
self.check()
|
||||
|
||||
def replace(self, ev):
|
||||
self.checker.replace(self.dialog.get_selected_suggestion())
|
||||
self.check()
|
||||
def replace(self, ev):
|
||||
self.checker.replace(self.dialog.get_selected_suggestion())
|
||||
self.check()
|
||||
|
||||
def replaceAll(self, ev):
|
||||
self.checker.replace_always(self.dialog.get_selected_suggestion())
|
||||
self.check()
|
||||
def replaceAll(self, ev):
|
||||
self.checker.replace_always(self.dialog.get_selected_suggestion())
|
||||
self.check()
|
||||
|
||||
def add(self, ev):
|
||||
self.checker.add()
|
||||
self.check()
|
||||
def add(self, ev):
|
||||
self.checker.add()
|
||||
self.check()
|
||||
|
@ -1,7 +1,7 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
############################################################
|
||||
# Copyright (c) 2013, 2014 Manuel Eduardo Cortéz Vallejo <manuel@manuelcortez.net>
|
||||
#
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 2 of the License, or
|
||||
@ -21,63 +21,63 @@ import wx
|
||||
import application
|
||||
|
||||
class spellCheckerDialog(wx.Dialog):
|
||||
def __init__(self):
|
||||
super(spellCheckerDialog, self).__init__(None, 1)
|
||||
panel = wx.Panel(self)
|
||||
sizer = wx.BoxSizer(wx.VERTICAL)
|
||||
word = wx.StaticText(panel, -1, _(u"Misspelled word"))
|
||||
self.word = wx.TextCtrl(panel, -1)
|
||||
wordBox = wx.BoxSizer(wx.HORIZONTAL)
|
||||
wordBox.Add(word, 0, wx.ALL, 5)
|
||||
wordBox.Add(self.word, 0, wx.ALL, 5)
|
||||
context = wx.StaticText(panel, -1, _(u"Context"))
|
||||
self.context = wx.TextCtrl(panel, -1)
|
||||
contextBox = wx.BoxSizer(wx.HORIZONTAL)
|
||||
contextBox.Add(context, 0, wx.ALL, 5)
|
||||
contextBox.Add(self.context, 0, wx.ALL, 5)
|
||||
suggest = wx.StaticText(panel, -1, _(u"Suggestions"))
|
||||
self.suggestions = wx.ListBox(panel, -1, choices=[], style=wx.LB_SINGLE)
|
||||
suggestionsBox = wx.BoxSizer(wx.HORIZONTAL)
|
||||
suggestionsBox.Add(suggest, 0, wx.ALL, 5)
|
||||
suggestionsBox.Add(self.suggestions, 0, wx.ALL, 5)
|
||||
self.ignore = wx.Button(panel, -1, _(u"&Ignore"))
|
||||
self.ignoreAll = wx.Button(panel, -1, _(u"I&gnore all"))
|
||||
self.replace = wx.Button(panel, -1, _(u"&Replace"))
|
||||
self.replaceAll = wx.Button(panel, -1, _(u"R&eplace all"))
|
||||
self.add = wx.Button(panel, -1, _(u"&Add to personal dictionary"))
|
||||
close = wx.Button(panel, wx.ID_CANCEL)
|
||||
btnBox = wx.BoxSizer(wx.HORIZONTAL)
|
||||
btnBox.Add(self.ignore, 0, wx.ALL, 5)
|
||||
btnBox.Add(self.ignoreAll, 0, wx.ALL, 5)
|
||||
btnBox.Add(self.replace, 0, wx.ALL, 5)
|
||||
btnBox.Add(self.replaceAll, 0, wx.ALL, 5)
|
||||
btnBox.Add(self.add, 0, wx.ALL, 5)
|
||||
btnBox.Add(close, 0, wx.ALL, 5)
|
||||
sizer.Add(wordBox, 0, wx.ALL, 5)
|
||||
sizer.Add(contextBox, 0, wx.ALL, 5)
|
||||
sizer.Add(suggestionsBox, 0, wx.ALL, 5)
|
||||
sizer.Add(btnBox, 0, wx.ALL, 5)
|
||||
panel.SetSizer(sizer)
|
||||
self.SetClientSize(sizer.CalcMin())
|
||||
def __init__(self):
|
||||
super(spellCheckerDialog, self).__init__(None, 1)
|
||||
panel = wx.Panel(self)
|
||||
sizer = wx.BoxSizer(wx.VERTICAL)
|
||||
word = wx.StaticText(panel, -1, _(u"Misspelled word"))
|
||||
self.word = wx.TextCtrl(panel, -1)
|
||||
wordBox = wx.BoxSizer(wx.HORIZONTAL)
|
||||
wordBox.Add(word, 0, wx.ALL, 5)
|
||||
wordBox.Add(self.word, 0, wx.ALL, 5)
|
||||
context = wx.StaticText(panel, -1, _(u"Context"))
|
||||
self.context = wx.TextCtrl(panel, -1)
|
||||
contextBox = wx.BoxSizer(wx.HORIZONTAL)
|
||||
contextBox.Add(context, 0, wx.ALL, 5)
|
||||
contextBox.Add(self.context, 0, wx.ALL, 5)
|
||||
suggest = wx.StaticText(panel, -1, _(u"Suggestions"))
|
||||
self.suggestions = wx.ListBox(panel, -1, choices=[], style=wx.LB_SINGLE)
|
||||
suggestionsBox = wx.BoxSizer(wx.HORIZONTAL)
|
||||
suggestionsBox.Add(suggest, 0, wx.ALL, 5)
|
||||
suggestionsBox.Add(self.suggestions, 0, wx.ALL, 5)
|
||||
self.ignore = wx.Button(panel, -1, _(u"&Ignore"))
|
||||
self.ignoreAll = wx.Button(panel, -1, _(u"I&gnore all"))
|
||||
self.replace = wx.Button(panel, -1, _(u"&Replace"))
|
||||
self.replaceAll = wx.Button(panel, -1, _(u"R&eplace all"))
|
||||
self.add = wx.Button(panel, -1, _(u"&Add to personal dictionary"))
|
||||
close = wx.Button(panel, wx.ID_CANCEL)
|
||||
btnBox = wx.BoxSizer(wx.HORIZONTAL)
|
||||
btnBox.Add(self.ignore, 0, wx.ALL, 5)
|
||||
btnBox.Add(self.ignoreAll, 0, wx.ALL, 5)
|
||||
btnBox.Add(self.replace, 0, wx.ALL, 5)
|
||||
btnBox.Add(self.replaceAll, 0, wx.ALL, 5)
|
||||
btnBox.Add(self.add, 0, wx.ALL, 5)
|
||||
btnBox.Add(close, 0, wx.ALL, 5)
|
||||
sizer.Add(wordBox, 0, wx.ALL, 5)
|
||||
sizer.Add(contextBox, 0, wx.ALL, 5)
|
||||
sizer.Add(suggestionsBox, 0, wx.ALL, 5)
|
||||
sizer.Add(btnBox, 0, wx.ALL, 5)
|
||||
panel.SetSizer(sizer)
|
||||
self.SetClientSize(sizer.CalcMin())
|
||||
|
||||
|
||||
def get_response(self):
|
||||
return self.ShowModal()
|
||||
def get_response(self):
|
||||
return self.ShowModal()
|
||||
|
||||
def set_title(self, title):
|
||||
return self.SetTitle(title)
|
||||
def set_title(self, title):
|
||||
return self.SetTitle(title)
|
||||
|
||||
def set_word_and_suggestions(self, word, context, suggestions):
|
||||
self.word.SetValue(word)
|
||||
self.context.ChangeValue(context)
|
||||
self.suggestions.Set(suggestions)
|
||||
self.suggestions.SetFocus()
|
||||
def set_word_and_suggestions(self, word, context, suggestions):
|
||||
self.word.SetValue(word)
|
||||
self.context.ChangeValue(context)
|
||||
self.suggestions.Set(suggestions)
|
||||
self.suggestions.SetFocus()
|
||||
|
||||
def get_selected_suggestion(self):
|
||||
return self.suggestions.GetStringSelection()
|
||||
def get_selected_suggestion(self):
|
||||
return self.suggestions.GetStringSelection()
|
||||
|
||||
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():
|
||||
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 -*-
|
||||
import platform
|
||||
if platform.system() == "Windows":
|
||||
from . import wx_ui as gui
|
||||
from . import translator
|
||||
from . import wx_ui as gui
|
||||
from . import translator
|
||||
|
@ -9,12 +9,12 @@ log = logging.getLogger("extras.translator")
|
||||
t = None
|
||||
|
||||
def translate(text="", target="en"):
|
||||
global t
|
||||
log.debug("Received translation request for language %s, text=%s" % (target, text))
|
||||
if t == None:
|
||||
t = Translator()
|
||||
vars = dict(text=text, dest=target)
|
||||
return t.translate(**vars).text
|
||||
global t
|
||||
log.debug("Received translation request for language %s, text=%s" % (target, text))
|
||||
if t == None:
|
||||
t = Translator()
|
||||
vars = dict(text=text, dest=target)
|
||||
return t.translate(**vars).text
|
||||
|
||||
supported_langs = None
|
||||
|
||||
@ -113,4 +113,4 @@ languages = {
|
||||
}
|
||||
|
||||
def available_languages():
|
||||
return dict(sorted(languages.items(), key=lambda x: x[1]))
|
||||
return dict(sorted(languages.items(), key=lambda x: x[1]))
|
||||
|
@ -1,7 +1,7 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
############################################################
|
||||
# Copyright (c) 2013, 2014 Manuel Eduardo Cortéz Vallejo <manuel@manuelcortez.net>
|
||||
#
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 2 of the License, or
|
||||
@ -21,25 +21,25 @@ import wx
|
||||
from widgetUtils import BaseDialog
|
||||
|
||||
class translateDialog(BaseDialog):
|
||||
def __init__(self):
|
||||
languages = []
|
||||
language_dict = translator.available_languages()
|
||||
for k in language_dict:
|
||||
languages.append(language_dict[k])
|
||||
super(translateDialog, self).__init__(None, -1, title=_(u"Translate message"))
|
||||
panel = wx.Panel(self)
|
||||
sizer = wx.BoxSizer(wx.VERTICAL)
|
||||
staticDest = wx.StaticText(panel, -1, _(u"Target language"))
|
||||
self.dest_lang = wx.ComboBox(panel, -1, choices=languages, style = wx.CB_READONLY)
|
||||
self.dest_lang.SetFocus()
|
||||
self.dest_lang.SetSelection(0)
|
||||
listSizer = wx.BoxSizer(wx.HORIZONTAL)
|
||||
listSizer.Add(staticDest)
|
||||
listSizer.Add(self.dest_lang)
|
||||
ok = wx.Button(panel, wx.ID_OK)
|
||||
ok.SetDefault()
|
||||
cancel = wx.Button(panel, wx.ID_CANCEL)
|
||||
self.SetEscapeId(wx.ID_CANCEL)
|
||||
def __init__(self):
|
||||
languages = []
|
||||
language_dict = translator.available_languages()
|
||||
for k in language_dict:
|
||||
languages.append(language_dict[k])
|
||||
super(translateDialog, self).__init__(None, -1, title=_(u"Translate message"))
|
||||
panel = wx.Panel(self)
|
||||
sizer = wx.BoxSizer(wx.VERTICAL)
|
||||
staticDest = wx.StaticText(panel, -1, _(u"Target language"))
|
||||
self.dest_lang = wx.ComboBox(panel, -1, choices=languages, style = wx.CB_READONLY)
|
||||
self.dest_lang.SetFocus()
|
||||
self.dest_lang.SetSelection(0)
|
||||
listSizer = wx.BoxSizer(wx.HORIZONTAL)
|
||||
listSizer.Add(staticDest)
|
||||
listSizer.Add(self.dest_lang)
|
||||
ok = wx.Button(panel, wx.ID_OK)
|
||||
ok.SetDefault()
|
||||
cancel = wx.Button(panel, wx.ID_CANCEL)
|
||||
self.SetEscapeId(wx.ID_CANCEL)
|
||||
|
||||
def get(self, control):
|
||||
return getattr(self, control).GetSelection()
|
||||
def get(self, control):
|
||||
return getattr(self, control).GetSelection()
|
||||
|
@ -8,7 +8,7 @@ from . import fix_win32com
|
||||
from . import fix_libloader
|
||||
|
||||
def setup():
|
||||
fix_requests.fix()
|
||||
# if hasattr(sys, "frozen"):
|
||||
fix_libloader.fix()
|
||||
fix_win32com.fix()
|
||||
fix_requests.fix()
|
||||
# if hasattr(sys, "frozen"):
|
||||
fix_libloader.fix()
|
||||
fix_win32com.fix()
|
||||
|
@ -12,25 +12,25 @@ from libloader import com
|
||||
fixed=False
|
||||
|
||||
def patched_getmodule(modname):
|
||||
mod=__import__(modname)
|
||||
return sys.modules[modname]
|
||||
mod=__import__(modname)
|
||||
return sys.modules[modname]
|
||||
|
||||
def load_com(*names):
|
||||
global fixed
|
||||
if fixed==False:
|
||||
gencache._GetModule=patched_getmodule
|
||||
com.prepare_gencache()
|
||||
fixed=True
|
||||
result = None
|
||||
for name in names:
|
||||
try:
|
||||
result = gencache.EnsureDispatch(name)
|
||||
break
|
||||
except com_error:
|
||||
continue
|
||||
if result is None:
|
||||
raise com_error("Unable to load any of the provided com objects.")
|
||||
return result
|
||||
global fixed
|
||||
if fixed==False:
|
||||
gencache._GetModule=patched_getmodule
|
||||
com.prepare_gencache()
|
||||
fixed=True
|
||||
result = None
|
||||
for name in names:
|
||||
try:
|
||||
result = gencache.EnsureDispatch(name)
|
||||
break
|
||||
except com_error:
|
||||
continue
|
||||
if result is None:
|
||||
raise com_error("Unable to load any of the provided com objects.")
|
||||
return result
|
||||
|
||||
def fix():
|
||||
com.load_com = load_com
|
||||
com.load_com = load_com
|
||||
|
@ -7,6 +7,6 @@ import logging
|
||||
log = logging.getLogger("fixes.fix_requests")
|
||||
|
||||
def fix():
|
||||
log.debug("Applying fix for requests...")
|
||||
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("Applying fix for requests...")
|
||||
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)))
|
||||
|
@ -1,6 +1,6 @@
|
||||
from __future__ import unicode_literals
|
||||
import win32com.client
|
||||
def fix():
|
||||
if win32com.client.gencache.is_readonly == True:
|
||||
win32com.client.gencache.is_readonly = False
|
||||
win32com.client.gencache.Rebuild()
|
||||
if win32com.client.gencache.is_readonly == True:
|
||||
win32com.client.gencache.is_readonly = False
|
||||
win32com.client.gencache.Rebuild()
|
||||
|
@ -5,4 +5,4 @@ from . blacklist import *
|
||||
from .configuration import *
|
||||
from .postCreation import *
|
||||
from .postDisplayer import *
|
||||
from .profiles import *
|
||||
from .profiles import *
|
||||
|
@ -8,86 +8,86 @@ from . import base
|
||||
|
||||
class attachInteractor(base.baseInteractor):
|
||||
|
||||
def insert_attachment(self, attachment):
|
||||
self.view.attachments.insert_item(False, *attachment)
|
||||
def insert_attachment(self, attachment):
|
||||
self.view.attachments.insert_item(False, *attachment)
|
||||
|
||||
def remove_attachment(self, attachment):
|
||||
self.view.attachments.remove_item(attachment)
|
||||
def remove_attachment(self, attachment):
|
||||
self.view.attachments.remove_item(attachment)
|
||||
|
||||
def install(self, *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.audio, widgetUtils.BUTTON_PRESSED, self.on_audio)
|
||||
widgetUtils.connect_event(self.view.document, widgetUtils.BUTTON_PRESSED, self.on_document)
|
||||
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.remove, widgetUtils.BUTTON_PRESSED, self.on_remove_attachment)
|
||||
pub.subscribe(self.insert_attachment, self.modulename+"_insert_attachment")
|
||||
pub.subscribe(self.remove_attachment, self.modulename+"_remove_attachment")
|
||||
def install(self, *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.audio, widgetUtils.BUTTON_PRESSED, self.on_audio)
|
||||
widgetUtils.connect_event(self.view.document, widgetUtils.BUTTON_PRESSED, self.on_document)
|
||||
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.remove, widgetUtils.BUTTON_PRESSED, self.on_remove_attachment)
|
||||
pub.subscribe(self.insert_attachment, self.modulename+"_insert_attachment")
|
||||
pub.subscribe(self.remove_attachment, self.modulename+"_remove_attachment")
|
||||
|
||||
def uninstall(self):
|
||||
super(attachInteractor, self).uninstall()
|
||||
pub.unsubscribe(self.insert_attachment, self.modulename+"_insert_attachment")
|
||||
pub.unsubscribe(self.remove_attachment, self.modulename+"_remove_attachment")
|
||||
def uninstall(self):
|
||||
super(attachInteractor, self).uninstall()
|
||||
pub.unsubscribe(self.insert_attachment, self.modulename+"_insert_attachment")
|
||||
pub.unsubscribe(self.remove_attachment, self.modulename+"_remove_attachment")
|
||||
|
||||
def on_image(self, *args, **kwargs):
|
||||
""" display menu for adding image attachments. """
|
||||
m = attachMenu()
|
||||
# disable add from VK as it is not supported in images, yet.
|
||||
m.add.Enable(False)
|
||||
widgetUtils.connect_event(m, widgetUtils.MENU, self.on_upload_image, menuitem=m.upload)
|
||||
self.view.PopupMenu(m, self.view.photo.GetPosition())
|
||||
def on_image(self, *args, **kwargs):
|
||||
""" display menu for adding image attachments. """
|
||||
m = attachMenu()
|
||||
# disable add from VK as it is not supported in images, yet.
|
||||
m.add.Enable(False)
|
||||
widgetUtils.connect_event(m, widgetUtils.MENU, self.on_upload_image, menuitem=m.upload)
|
||||
self.view.PopupMenu(m, self.view.photo.GetPosition())
|
||||
|
||||
def on_audio(self, *args, **kwargs):
|
||||
""" display menu to add audio attachments."""
|
||||
m = attachMenu()
|
||||
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)
|
||||
self.view.PopupMenu(m, self.view.audio.GetPosition())
|
||||
def on_audio(self, *args, **kwargs):
|
||||
""" display menu to add audio attachments."""
|
||||
m = attachMenu()
|
||||
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)
|
||||
self.view.PopupMenu(m, self.view.audio.GetPosition())
|
||||
|
||||
def on_document(self, *args, **kwargs):
|
||||
""" display menu for adding document attachments. """
|
||||
m = attachMenu()
|
||||
# disable add from VK as it is not supported in documents, yet.
|
||||
m.add.Enable(False)
|
||||
widgetUtils.connect_event(m, widgetUtils.MENU, self.on_upload_document, menuitem=m.upload)
|
||||
self.view.PopupMenu(m, self.view.photo.GetPosition())
|
||||
def on_document(self, *args, **kwargs):
|
||||
""" display menu for adding document attachments. """
|
||||
m = attachMenu()
|
||||
# disable add from VK as it is not supported in documents, yet.
|
||||
m.add.Enable(False)
|
||||
widgetUtils.connect_event(m, widgetUtils.MENU, self.on_upload_document, menuitem=m.upload)
|
||||
self.view.PopupMenu(m, self.view.photo.GetPosition())
|
||||
|
||||
def on_upload_image(self, *args, **kwargs):
|
||||
""" allows uploading an image from the computer.
|
||||
"""
|
||||
image, description = self.view.get_image()
|
||||
if image != None:
|
||||
self.presenter.upload_image(image, description)
|
||||
def on_upload_image(self, *args, **kwargs):
|
||||
""" allows uploading an image from the computer.
|
||||
"""
|
||||
image, description = self.view.get_image()
|
||||
if image != None:
|
||||
self.presenter.upload_image(image, description)
|
||||
|
||||
def on_upload_audio(self, *args, **kwargs):
|
||||
""" Allows uploading an audio file from the computer. Only mp3 files are supported. """
|
||||
audio = self.view.get_audio()
|
||||
if audio != None:
|
||||
self.presenter.upload_audio(audio)
|
||||
def on_upload_audio(self, *args, **kwargs):
|
||||
""" Allows uploading an audio file from the computer. Only mp3 files are supported. """
|
||||
audio = self.view.get_audio()
|
||||
if audio != None:
|
||||
self.presenter.upload_audio(audio)
|
||||
|
||||
def on_upload_document(self, *args, **kwargs):
|
||||
""" allows uploading a document from the computer.
|
||||
"""
|
||||
document = self.view.get_document()
|
||||
if document != None:
|
||||
if document.endswith(".mp3") or document.endswith(".exe"):
|
||||
self.view.invalid_attachment()
|
||||
return
|
||||
self.presenter.upload_document(document)
|
||||
def on_upload_document(self, *args, **kwargs):
|
||||
""" allows uploading a document from the computer.
|
||||
"""
|
||||
document = self.view.get_document()
|
||||
if document != None:
|
||||
if document.endswith(".mp3") or document.endswith(".exe"):
|
||||
self.view.invalid_attachment()
|
||||
return
|
||||
self.presenter.upload_document(document)
|
||||
|
||||
def on_upload_voice_message(self, *args, **kwargs):
|
||||
self.presenter.upload_voice_message()
|
||||
def on_upload_voice_message(self, *args, **kwargs):
|
||||
self.presenter.upload_voice_message()
|
||||
|
||||
def on_add_audio(self, *args, **kwargs):
|
||||
""" Allow adding an audio directly from the user's audio library."""
|
||||
audios = self.presenter.get_available_audios()
|
||||
select = selector.selectAttachment(_("Select the audio files you want to send"), audios)
|
||||
if select.get_response() == widgetUtils.OK and select.attachments.GetCount() > 0:
|
||||
attachments = select.get_all_attachments()
|
||||
self.presenter.take_audios(attachments)
|
||||
def on_add_audio(self, *args, **kwargs):
|
||||
""" Allow adding an audio directly from the user's audio library."""
|
||||
audios = self.presenter.get_available_audios()
|
||||
select = selector.selectAttachment(_("Select the audio files you want to send"), audios)
|
||||
if select.get_response() == widgetUtils.OK and select.attachments.GetCount() > 0:
|
||||
attachments = select.get_all_attachments()
|
||||
self.presenter.take_audios(attachments)
|
||||
|
||||
def on_remove_attachment(self, *args, **kwargs):
|
||||
""" Remove the currently focused item from the attachments list."""
|
||||
current_item = self.view.attachments.get_selected()
|
||||
self.presenter.remove_attachment(current_item)
|
||||
def on_remove_attachment(self, *args, **kwargs):
|
||||
""" Remove the currently focused item from the attachments list."""
|
||||
current_item = self.view.attachments.get_selected()
|
||||
self.presenter.remove_attachment(current_item)
|
||||
|
@ -5,25 +5,25 @@ from pubsub import pub
|
||||
from . import base
|
||||
|
||||
class audioRecorderInteractor(base.baseInteractor):
|
||||
def install(self, presenter, view, modulename="audiorecorder"):
|
||||
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.record, widgetUtils.BUTTON_PRESSED, self.on_record)
|
||||
widgetUtils.connect_event(view.discard, widgetUtils.BUTTON_PRESSED, self.on_discard)
|
||||
def install(self, presenter, view, modulename="audiorecorder"):
|
||||
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.record, widgetUtils.BUTTON_PRESSED, self.on_record)
|
||||
widgetUtils.connect_event(view.discard, widgetUtils.BUTTON_PRESSED, self.on_discard)
|
||||
|
||||
def start(self):
|
||||
result = self.view.get_response()
|
||||
if result == widgetUtils.OK:
|
||||
self.on_postprocess()
|
||||
def start(self):
|
||||
result = self.view.get_response()
|
||||
if result == widgetUtils.OK:
|
||||
self.on_postprocess()
|
||||
|
||||
def on_record(self, *args, **kwargs):
|
||||
self.presenter.toggle_recording()
|
||||
def on_record(self, *args, **kwargs):
|
||||
self.presenter.toggle_recording()
|
||||
|
||||
def on_discard(self, *args, **kwargs):
|
||||
self.presenter.discard_recording()
|
||||
def on_discard(self, *args, **kwargs):
|
||||
self.presenter.discard_recording()
|
||||
|
||||
def on_play(self, *args, **kwargs):
|
||||
self.presenter.play()
|
||||
def on_play(self, *args, **kwargs):
|
||||
self.presenter.play()
|
||||
|
||||
def on_postprocess(self):
|
||||
self.presenter.postprocess()
|
||||
def on_postprocess(self):
|
||||
self.presenter.postprocess()
|
||||
|
@ -3,38 +3,38 @@ from pubsub import pub
|
||||
|
||||
class baseInteractor(object):
|
||||
|
||||
def install(self, view, presenter, modulename):
|
||||
self.modulename = modulename
|
||||
self.view = view
|
||||
self.presenter = presenter
|
||||
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.set_label, "{modulename}_set_label".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))
|
||||
def install(self, view, presenter, modulename):
|
||||
self.modulename = modulename
|
||||
self.view = view
|
||||
self.presenter = presenter
|
||||
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.set_label, "{modulename}_set_label".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))
|
||||
|
||||
def uninstall(self):
|
||||
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.set_label, "{modulename}_set_label".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))
|
||||
self.view.Destroy()
|
||||
def uninstall(self):
|
||||
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.set_label, "{modulename}_set_label".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))
|
||||
self.view.Destroy()
|
||||
|
||||
def start(self):
|
||||
self.result = self.view.get_response()
|
||||
def start(self):
|
||||
self.result = self.view.get_response()
|
||||
|
||||
def disable_control(self, control):
|
||||
self.view.disable(control)
|
||||
def disable_control(self, control):
|
||||
self.view.disable(control)
|
||||
|
||||
def enable_control(self, control):
|
||||
self.view.enable(control)
|
||||
def enable_control(self, control):
|
||||
self.view.enable(control)
|
||||
|
||||
def focus_control(self, control):
|
||||
getattr(self.view, control).SetFocus()
|
||||
def focus_control(self, control):
|
||||
getattr(self.view, control).SetFocus()
|
||||
|
||||
def set_label(self, control, label):
|
||||
self.view.set(control, label)
|
||||
def set_label(self, control, label):
|
||||
self.view.set(control, label)
|
||||
|
||||
def set_title(self, value):
|
||||
self.view.SetTitle(value)
|
||||
def set_title(self, value):
|
||||
self.view.SetTitle(value)
|
||||
|
@ -6,26 +6,26 @@ from . import base
|
||||
|
||||
class blacklistInteractor(base.baseInteractor):
|
||||
|
||||
def add_items(self, control, items):
|
||||
if not hasattr(self.view, control):
|
||||
raise AttributeError("The control is not present in the view.")
|
||||
for i in items:
|
||||
getattr(self.view, control).insert_item(False, *i)
|
||||
def add_items(self, control, items):
|
||||
if not hasattr(self.view, control):
|
||||
raise AttributeError("The control is not present in the view.")
|
||||
for i in items:
|
||||
getattr(self.view, control).insert_item(False, *i)
|
||||
|
||||
def install(self, *args, **kwargs):
|
||||
super(blacklistInteractor, self).install(*args, **kwargs)
|
||||
widgetUtils.connect_event(self.view.unblock, widgetUtils.BUTTON_PRESSED, self.on_unblock)
|
||||
pub.subscribe(self.add_items, self.modulename+"_add_items")
|
||||
def install(self, *args, **kwargs):
|
||||
super(blacklistInteractor, self).install(*args, **kwargs)
|
||||
widgetUtils.connect_event(self.view.unblock, widgetUtils.BUTTON_PRESSED, self.on_unblock)
|
||||
pub.subscribe(self.add_items, self.modulename+"_add_items")
|
||||
|
||||
def uninstall(self):
|
||||
super(blacklistInteractor, self).uninstall()
|
||||
pub.unsubscribe(self.add_items, self.modulename+"_add_items")
|
||||
def uninstall(self):
|
||||
super(blacklistInteractor, self).uninstall()
|
||||
pub.unsubscribe(self.add_items, self.modulename+"_add_items")
|
||||
|
||||
|
||||
def on_unblock(self, *args, **kwargs):
|
||||
question = commonMessages.unblock_person()
|
||||
if question == widgetUtils.NO:
|
||||
return
|
||||
item = self.view.persons.get_selected()
|
||||
if self.presenter.unblock_person(item) == 1:
|
||||
self.view.persons.remove_item(item)
|
||||
def on_unblock(self, *args, **kwargs):
|
||||
question = commonMessages.unblock_person()
|
||||
if question == widgetUtils.NO:
|
||||
return
|
||||
item = self.view.persons.get_selected()
|
||||
if self.presenter.unblock_person(item) == 1:
|
||||
self.view.persons.remove_item(item)
|
||||
|
@ -6,67 +6,67 @@ from . import base
|
||||
|
||||
class configurationInteractor(base.baseInteractor):
|
||||
|
||||
def create_tab(self, tab, arglist=dict()):
|
||||
getattr(self.view, "create_"+tab)(**arglist)
|
||||
def create_tab(self, tab, arglist=dict()):
|
||||
getattr(self.view, "create_"+tab)(**arglist)
|
||||
|
||||
def set_setting(self, tab, setting, value):
|
||||
self.view.set_value(tab, setting, value)
|
||||
def set_setting(self, tab, setting, value):
|
||||
self.view.set_value(tab, setting, value)
|
||||
|
||||
def restart(self):
|
||||
dlg = restart_program_dialog()
|
||||
if dlg == widgetUtils.YES:
|
||||
self.presenter.restart_application()
|
||||
def restart(self):
|
||||
dlg = restart_program_dialog()
|
||||
if dlg == widgetUtils.YES:
|
||||
self.presenter.restart_application()
|
||||
|
||||
def set_language(self, language):
|
||||
self.view.general.language.SetSelection(language)
|
||||
def set_language(self, language):
|
||||
self.view.general.language.SetSelection(language)
|
||||
|
||||
def install(self, *args, **kwargs):
|
||||
super(configurationInteractor, self).install(*args, **kwargs)
|
||||
pub.subscribe(self.create_tab, self.modulename+"_create_tab")
|
||||
pub.subscribe(self.set_setting, self.modulename+"_set")
|
||||
pub.subscribe(self.restart, self.modulename+"_restart_program")
|
||||
pub.subscribe(self.set_language, self.modulename+"_set_language")
|
||||
def install(self, *args, **kwargs):
|
||||
super(configurationInteractor, self).install(*args, **kwargs)
|
||||
pub.subscribe(self.create_tab, self.modulename+"_create_tab")
|
||||
pub.subscribe(self.set_setting, self.modulename+"_set")
|
||||
pub.subscribe(self.restart, self.modulename+"_restart_program")
|
||||
pub.subscribe(self.set_language, self.modulename+"_set_language")
|
||||
|
||||
def uninstall(self):
|
||||
super(configurationInteractor, self).uninstall()
|
||||
pub.unsubscribe(self.create_tab, self.modulename+"_create_tab")
|
||||
pub.unsubscribe(self.set_setting, self.modulename+"_set")
|
||||
pub.unsubscribe(self.restart, self.modulename+"_restart_program")
|
||||
pub.unsubscribe(self.set_language, self.modulename+"_set_language")
|
||||
def uninstall(self):
|
||||
super(configurationInteractor, self).uninstall()
|
||||
pub.unsubscribe(self.create_tab, self.modulename+"_create_tab")
|
||||
pub.unsubscribe(self.set_setting, self.modulename+"_set")
|
||||
pub.unsubscribe(self.restart, self.modulename+"_restart_program")
|
||||
pub.unsubscribe(self.set_language, self.modulename+"_set_language")
|
||||
|
||||
def start(self):
|
||||
self.view.realize()
|
||||
result = self.view.get_response()
|
||||
if result == widgetUtils.OK:
|
||||
self.on_save_settings()
|
||||
def start(self):
|
||||
self.view.realize()
|
||||
result = self.view.get_response()
|
||||
if result == widgetUtils.OK:
|
||||
self.on_save_settings()
|
||||
|
||||
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_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="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"))
|
||||
if update_channel != self.presenter.session.settings["general"]["update_channel"]:
|
||||
if update_channel == "stable":
|
||||
self.presenter.update_setting(section="general", setting="update_channel", value=update_channel)
|
||||
elif update_channel == "weekly":
|
||||
dialog = self.view.weekly_channel()
|
||||
if dialog == widgetUtils.YES:
|
||||
self.presenter.update_setting(section="general", setting="update_channel", value=update_channel)
|
||||
elif update_channel == "alpha":
|
||||
dialog = self.view.alpha_channel()
|
||||
if dialog == widgetUtils.YES:
|
||||
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_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="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="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="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="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.save_app_settings_file()
|
||||
self.presenter.save_settings_file()
|
||||
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_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="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"))
|
||||
if update_channel != self.presenter.session.settings["general"]["update_channel"]:
|
||||
if update_channel == "stable":
|
||||
self.presenter.update_setting(section="general", setting="update_channel", value=update_channel)
|
||||
elif update_channel == "weekly":
|
||||
dialog = self.view.weekly_channel()
|
||||
if dialog == widgetUtils.YES:
|
||||
self.presenter.update_setting(section="general", setting="update_channel", value=update_channel)
|
||||
elif update_channel == "alpha":
|
||||
dialog = self.view.alpha_channel()
|
||||
if dialog == widgetUtils.YES:
|
||||
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_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="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="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="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="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.save_app_settings_file()
|
||||
self.presenter.save_settings_file()
|
||||
|
@ -7,67 +7,67 @@ from .import base
|
||||
|
||||
class createPostInteractor(base.baseInteractor):
|
||||
|
||||
def set(self, control, value):
|
||||
if not hasattr(self.view, control):
|
||||
raise AttributeError("The control is not present in the view.")
|
||||
getattr(self.view, control).SetValue(value)
|
||||
def set(self, control, value):
|
||||
if not hasattr(self.view, control):
|
||||
raise AttributeError("The control is not present in the view.")
|
||||
getattr(self.view, control).SetValue(value)
|
||||
|
||||
def add_tagged_users(self, users):
|
||||
self.view.text.SetValue(self.view.text.GetValue()+", ".join(users))
|
||||
def add_tagged_users(self, users):
|
||||
self.view.text.SetValue(self.view.text.GetValue()+", ".join(users))
|
||||
|
||||
def install(self, *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.translateButton, widgetUtils.BUTTON_PRESSED, self.on_translate)
|
||||
widgetUtils.connect_event(self.view.mention, widgetUtils.BUTTON_PRESSED, self.on_mention)
|
||||
if hasattr(self.view, "attach"):
|
||||
widgetUtils.connect_event(self.view.attach, widgetUtils.BUTTON_PRESSED, self.on_add_attachments)
|
||||
pub.subscribe(self.set, self.modulename+"_set")
|
||||
pub.subscribe(self.add_tagged_users, self.modulename+"_add_tagged_users")
|
||||
def install(self, *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.translateButton, widgetUtils.BUTTON_PRESSED, self.on_translate)
|
||||
widgetUtils.connect_event(self.view.mention, widgetUtils.BUTTON_PRESSED, self.on_mention)
|
||||
if hasattr(self.view, "attach"):
|
||||
widgetUtils.connect_event(self.view.attach, widgetUtils.BUTTON_PRESSED, self.on_add_attachments)
|
||||
pub.subscribe(self.set, self.modulename+"_set")
|
||||
pub.subscribe(self.add_tagged_users, self.modulename+"_add_tagged_users")
|
||||
|
||||
def uninstall(self):
|
||||
super(createPostInteractor, self).uninstall()
|
||||
pub.unsubscribe(self.set, self.modulename+"_set")
|
||||
pub.unsubscribe(self.add_tagged_users, self.modulename+"_add_tagged_users")
|
||||
def uninstall(self):
|
||||
super(createPostInteractor, self).uninstall()
|
||||
pub.unsubscribe(self.set, self.modulename+"_set")
|
||||
pub.unsubscribe(self.add_tagged_users, self.modulename+"_add_tagged_users")
|
||||
|
||||
def start(self):
|
||||
self.result = self.view.get_response()
|
||||
if self.result == widgetUtils.OK:
|
||||
self.presenter.text = self.view.get_text()
|
||||
if hasattr(self.view, "privacy"):
|
||||
self.presenter.privacy = self.get_privacy_options()
|
||||
else:
|
||||
self.presenter.privacy = 0
|
||||
def start(self):
|
||||
self.result = self.view.get_response()
|
||||
if self.result == widgetUtils.OK:
|
||||
self.presenter.text = self.view.get_text()
|
||||
if hasattr(self.view, "privacy"):
|
||||
self.presenter.privacy = self.get_privacy_options()
|
||||
else:
|
||||
self.presenter.privacy = 0
|
||||
|
||||
def get_privacy_options(self):
|
||||
p = self.view.get("privacy")
|
||||
if p == _("Friends of friends"):
|
||||
privacy = 0
|
||||
elif p == _("All users"):
|
||||
privacy = 1
|
||||
return privacy
|
||||
def get_privacy_options(self):
|
||||
p = self.view.get("privacy")
|
||||
if p == _("Friends of friends"):
|
||||
privacy = 0
|
||||
elif p == _("All users"):
|
||||
privacy = 1
|
||||
return privacy
|
||||
|
||||
def on_mention(self, *args, **kwargs):
|
||||
users = self.presenter.get_friends()
|
||||
select = selector.selectPeople(users)
|
||||
if select.get_response() == widgetUtils.OK and select.users.GetCount() > 0:
|
||||
tagged_users = select.get_all_users()
|
||||
self.presenter.add_tagged_users(tagged_users)
|
||||
def on_mention(self, *args, **kwargs):
|
||||
users = self.presenter.get_friends()
|
||||
select = selector.selectPeople(users)
|
||||
if select.get_response() == widgetUtils.OK and select.users.GetCount() > 0:
|
||||
tagged_users = select.get_all_users()
|
||||
self.presenter.add_tagged_users(tagged_users)
|
||||
|
||||
def on_translate(self, *args, **kwargs):
|
||||
dlg = translator.gui.translateDialog()
|
||||
if dlg.get_response() == widgetUtils.OK:
|
||||
text_to_translate = self.view.get_text()
|
||||
language_dict = translator.translator.available_languages()
|
||||
for k in language_dict:
|
||||
if language_dict[k] == dlg.dest_lang.GetStringSelection():
|
||||
dst = k
|
||||
self.presenter.translate(text_to_translate, dst)
|
||||
dlg.Destroy()
|
||||
def on_translate(self, *args, **kwargs):
|
||||
dlg = translator.gui.translateDialog()
|
||||
if dlg.get_response() == widgetUtils.OK:
|
||||
text_to_translate = self.view.get_text()
|
||||
language_dict = translator.translator.available_languages()
|
||||
for k in language_dict:
|
||||
if language_dict[k] == dlg.dest_lang.GetStringSelection():
|
||||
dst = k
|
||||
self.presenter.translate(text_to_translate, dst)
|
||||
dlg.Destroy()
|
||||
|
||||
def on_spellcheck(self, event=None):
|
||||
text = self.view.get_text()
|
||||
self.presenter.spellcheck(text)
|
||||
def on_spellcheck(self, event=None):
|
||||
text = self.view.get_text()
|
||||
self.presenter.spellcheck(text)
|
||||
|
||||
def on_add_attachments(self, *args, **kwargs):
|
||||
self.presenter.add_attachments()
|
||||
def on_add_attachments(self, *args, **kwargs):
|
||||
self.presenter.add_attachments()
|
||||
|
@ -10,295 +10,295 @@ from .import base
|
||||
|
||||
class displayPostInteractor(base.baseInteractor):
|
||||
|
||||
def set(self, control, value):
|
||||
if not hasattr(self.view, control):
|
||||
raise AttributeError("The control is not present in the view.")
|
||||
getattr(self.view, control).SetValue(value)
|
||||
def set(self, control, value):
|
||||
if not hasattr(self.view, control):
|
||||
raise AttributeError("The control is not present in the view.")
|
||||
getattr(self.view, control).SetValue(value)
|
||||
|
||||
def load_image(self, image):
|
||||
image = wx.Image(stream=six.BytesIO(image.content))
|
||||
try:
|
||||
self.view.image.SetBitmap(wx.Bitmap(image))
|
||||
except ValueError:
|
||||
return
|
||||
self.view.panel.Layout()
|
||||
def load_image(self, image):
|
||||
image = wx.Image(stream=six.BytesIO(image.content))
|
||||
try:
|
||||
self.view.image.SetBitmap(wx.Bitmap(image))
|
||||
except ValueError:
|
||||
return
|
||||
self.view.panel.Layout()
|
||||
|
||||
def add_items(self, control, items):
|
||||
if not hasattr(self.view, control):
|
||||
raise AttributeError("The control is not present in the view.")
|
||||
for i in items:
|
||||
getattr(self.view, control).insert_item(False, *i)
|
||||
def add_items(self, control, items):
|
||||
if not hasattr(self.view, control):
|
||||
raise AttributeError("The control is not present in the view.")
|
||||
for i in items:
|
||||
getattr(self.view, control).insert_item(False, *i)
|
||||
|
||||
def add_item(self, control, item, reversed=False):
|
||||
if not hasattr(self.view, control):
|
||||
raise AttributeError("The control is not present in the view.")
|
||||
getattr(self.view, control).insert_item(reversed, *item)
|
||||
def add_item(self, control, item, reversed=False):
|
||||
if not hasattr(self.view, control):
|
||||
raise AttributeError("The control is not present in the view.")
|
||||
getattr(self.view, control).insert_item(reversed, *item)
|
||||
|
||||
def enable_attachments(self):
|
||||
self.view.attachments.list.Enable(True)
|
||||
def enable_attachments(self):
|
||||
self.view.attachments.list.Enable(True)
|
||||
|
||||
def enable_photo_controls(self, navigation):
|
||||
self.view.enable_photo_controls(navigation)
|
||||
def enable_photo_controls(self, navigation):
|
||||
self.view.enable_photo_controls(navigation)
|
||||
|
||||
def clean_list(self, list):
|
||||
if not hasattr(self.view, list):
|
||||
raise AttributeError("The control is not present in the view.")
|
||||
getattr(self.view, list).clear()
|
||||
def clean_list(self, list):
|
||||
if not hasattr(self.view, list):
|
||||
raise AttributeError("The control is not present in the view.")
|
||||
getattr(self.view, list).clear()
|
||||
|
||||
def post_deleted(self):
|
||||
msg = commonMessages.post_deleted()
|
||||
def post_deleted(self):
|
||||
msg = commonMessages.post_deleted()
|
||||
|
||||
def install(self, *args, **kwargs):
|
||||
super(displayPostInteractor, self).install(*args, **kwargs)
|
||||
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_FOCUSED, self.on_comment_changed)
|
||||
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.comment, widgetUtils.BUTTON_PRESSED, self.on_add_comment)
|
||||
widgetUtils.connect_event(self.view.tools, widgetUtils.BUTTON_PRESSED, self.on_show_tools_menu)
|
||||
if hasattr(self.view, "likes"):
|
||||
widgetUtils.connect_event(self.view.likes, widgetUtils.BUTTON_PRESSED, self.on_show_likes_menu)
|
||||
if hasattr(self.view, "shares"):
|
||||
widgetUtils.connect_event(self.view.shares, widgetUtils.BUTTON_PRESSED, self.on_show_shares_menu)
|
||||
if hasattr(self.view, "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)
|
||||
if hasattr(self.view, "reply"):
|
||||
widgetUtils.connect_event(self.view.reply, widgetUtils.BUTTON_PRESSED, self.on_reply)
|
||||
if hasattr(self.view, "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_KEY_DOWN, self.on_show_menu_by_key, self.view.comments.list)
|
||||
pub.subscribe(self.set, self.modulename+"_set")
|
||||
pub.subscribe(self.load_image, self.modulename+"_load_image")
|
||||
pub.subscribe(self.add_items, self.modulename+"_add_items")
|
||||
pub.subscribe(self.add_item, self.modulename+"_add_item")
|
||||
pub.subscribe(self.enable_attachments, self.modulename+"_enable_attachments")
|
||||
pub.subscribe(self.enable_photo_controls, self.modulename+"_enable_photo_controls")
|
||||
pub.subscribe(self.post_deleted, self.modulename+"_post_deleted")
|
||||
pub.subscribe(self.clean_list, self.modulename+"_clean_list")
|
||||
def install(self, *args, **kwargs):
|
||||
super(displayPostInteractor, self).install(*args, **kwargs)
|
||||
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_FOCUSED, self.on_comment_changed)
|
||||
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.comment, widgetUtils.BUTTON_PRESSED, self.on_add_comment)
|
||||
widgetUtils.connect_event(self.view.tools, widgetUtils.BUTTON_PRESSED, self.on_show_tools_menu)
|
||||
if hasattr(self.view, "likes"):
|
||||
widgetUtils.connect_event(self.view.likes, widgetUtils.BUTTON_PRESSED, self.on_show_likes_menu)
|
||||
if hasattr(self.view, "shares"):
|
||||
widgetUtils.connect_event(self.view.shares, widgetUtils.BUTTON_PRESSED, self.on_show_shares_menu)
|
||||
if hasattr(self.view, "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)
|
||||
if hasattr(self.view, "reply"):
|
||||
widgetUtils.connect_event(self.view.reply, widgetUtils.BUTTON_PRESSED, self.on_reply)
|
||||
if hasattr(self.view, "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_KEY_DOWN, self.on_show_menu_by_key, self.view.comments.list)
|
||||
pub.subscribe(self.set, self.modulename+"_set")
|
||||
pub.subscribe(self.load_image, self.modulename+"_load_image")
|
||||
pub.subscribe(self.add_items, self.modulename+"_add_items")
|
||||
pub.subscribe(self.add_item, self.modulename+"_add_item")
|
||||
pub.subscribe(self.enable_attachments, self.modulename+"_enable_attachments")
|
||||
pub.subscribe(self.enable_photo_controls, self.modulename+"_enable_photo_controls")
|
||||
pub.subscribe(self.post_deleted, self.modulename+"_post_deleted")
|
||||
pub.subscribe(self.clean_list, self.modulename+"_clean_list")
|
||||
|
||||
def uninstall(self):
|
||||
super(displayPostInteractor, self).uninstall()
|
||||
pub.unsubscribe(self.set, self.modulename+"_set")
|
||||
pub.unsubscribe(self.load_image, self.modulename+"_load_image")
|
||||
pub.unsubscribe(self.add_items, self.modulename+"_add_items")
|
||||
pub.unsubscribe(self.add_item, self.modulename+"_add_item")
|
||||
pub.unsubscribe(self.enable_attachments, self.modulename+"_enable_attachments")
|
||||
pub.unsubscribe(self.enable_photo_controls, self.modulename+"_enable_photo_controls")
|
||||
pub.unsubscribe(self.post_deleted, self.modulename+"_post_deleted")
|
||||
pub.unsubscribe(self.clean_list, self.modulename+"_clean_list")
|
||||
def uninstall(self):
|
||||
super(displayPostInteractor, self).uninstall()
|
||||
pub.unsubscribe(self.set, self.modulename+"_set")
|
||||
pub.unsubscribe(self.load_image, self.modulename+"_load_image")
|
||||
pub.unsubscribe(self.add_items, self.modulename+"_add_items")
|
||||
pub.unsubscribe(self.add_item, self.modulename+"_add_item")
|
||||
pub.unsubscribe(self.enable_attachments, self.modulename+"_enable_attachments")
|
||||
pub.unsubscribe(self.enable_photo_controls, self.modulename+"_enable_photo_controls")
|
||||
pub.unsubscribe(self.post_deleted, self.modulename+"_post_deleted")
|
||||
pub.unsubscribe(self.clean_list, self.modulename+"_clean_list")
|
||||
|
||||
def on_focus(self, *args, **kwargs):
|
||||
item = self.view.comments.get_selected()
|
||||
if item == -1:
|
||||
self.view.reply.Enable(False)
|
||||
else:
|
||||
self.view.reply.Enable(True)
|
||||
def on_focus(self, *args, **kwargs):
|
||||
item = self.view.comments.get_selected()
|
||||
if item == -1:
|
||||
self.view.reply.Enable(False)
|
||||
else:
|
||||
self.view.reply.Enable(True)
|
||||
|
||||
def on_like(self, *args, **kwargs):
|
||||
self.presenter.post_like()
|
||||
def on_like(self, *args, **kwargs):
|
||||
self.presenter.post_like()
|
||||
|
||||
def on_repost(self, *args, **kwargs):
|
||||
self.presenter.post_repost()
|
||||
def on_repost(self, *args, **kwargs):
|
||||
self.presenter.post_repost()
|
||||
|
||||
def on_reply(self, *args, **kwargs):
|
||||
if hasattr(self.view, "comments") and (hasattr(self.view, "repost") or not hasattr(self, "post_view")):
|
||||
comment = self.view.comments.get_selected()
|
||||
self.presenter.reply(comment)
|
||||
else:
|
||||
self.presenter.reply()
|
||||
def on_reply(self, *args, **kwargs):
|
||||
if hasattr(self.view, "comments") and (hasattr(self.view, "repost") or not hasattr(self, "post_view")):
|
||||
comment = self.view.comments.get_selected()
|
||||
self.presenter.reply(comment)
|
||||
else:
|
||||
self.presenter.reply()
|
||||
|
||||
def on_add_comment(self, *args, **kwargs):
|
||||
self.presenter.add_comment()
|
||||
def on_add_comment(self, *args, **kwargs):
|
||||
self.presenter.add_comment()
|
||||
|
||||
def on_load_more_comments(self, *args, **kwargs):
|
||||
if hasattr(self.presenter, "load_more_comments"):
|
||||
self.presenter.load_more_comments()
|
||||
def on_load_more_comments(self, *args, **kwargs):
|
||||
if hasattr(self.presenter, "load_more_comments"):
|
||||
self.presenter.load_more_comments()
|
||||
|
||||
def on_show_tools_menu(self, *args, **kwargs):
|
||||
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_translate, menuitem=menu.translate)
|
||||
widgetUtils.connect_event(self.view, widgetUtils.MENU, self.on_spellcheck, menuitem=menu.spellcheck)
|
||||
self.view.PopupMenu(menu, self.view.tools.GetPosition())
|
||||
def on_show_tools_menu(self, *args, **kwargs):
|
||||
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_translate, menuitem=menu.translate)
|
||||
widgetUtils.connect_event(self.view, widgetUtils.MENU, self.on_spellcheck, menuitem=menu.spellcheck)
|
||||
self.view.PopupMenu(menu, self.view.tools.GetPosition())
|
||||
|
||||
def on_open_url(self, *args, **kwargs):
|
||||
pass
|
||||
def on_open_url(self, *args, **kwargs):
|
||||
pass
|
||||
|
||||
def on_open_attachment(self, *args, **kwargs):
|
||||
attachment = self.view.attachments.get_selected()
|
||||
self.presenter.open_attachment(attachment)
|
||||
def on_open_attachment(self, *args, **kwargs):
|
||||
attachment = self.view.attachments.get_selected()
|
||||
self.presenter.open_attachment(attachment)
|
||||
|
||||
def on_translate(self, *args, **kwargs):
|
||||
dlg = translator.gui.translateDialog()
|
||||
if dlg.get_response() == widgetUtils.OK:
|
||||
text_to_translate = self.view.get("post_view")
|
||||
language_dict = translator.translator.available_languages()
|
||||
for k in language_dict:
|
||||
if language_dict[k] == dlg.dest_lang.GetStringSelection():
|
||||
dst = k
|
||||
self.presenter.translate(text_to_translate, dst)
|
||||
dlg.Destroy()
|
||||
def on_translate(self, *args, **kwargs):
|
||||
dlg = translator.gui.translateDialog()
|
||||
if dlg.get_response() == widgetUtils.OK:
|
||||
text_to_translate = self.view.get("post_view")
|
||||
language_dict = translator.translator.available_languages()
|
||||
for k in language_dict:
|
||||
if language_dict[k] == dlg.dest_lang.GetStringSelection():
|
||||
dst = k
|
||||
self.presenter.translate(text_to_translate, dst)
|
||||
dlg.Destroy()
|
||||
|
||||
def on_spellcheck(self, event=None):
|
||||
text = self.view.get("post_view")
|
||||
self.presenter.spellcheck(text)
|
||||
def on_spellcheck(self, event=None):
|
||||
text = self.view.get("post_view")
|
||||
self.presenter.spellcheck(text)
|
||||
|
||||
def on_show_comment(self, *args, **kwargs):
|
||||
comment = self.view.comments.get_selected()
|
||||
self.presenter.show_comment(comment)
|
||||
def on_show_comment(self, *args, **kwargs):
|
||||
comment = self.view.comments.get_selected()
|
||||
self.presenter.show_comment(comment)
|
||||
|
||||
def on_comment_changed(self, *args, **kwargs):
|
||||
if hasattr(self.presenter, "change_comment"):
|
||||
comment = self.view.comments.get_selected()
|
||||
self.presenter.change_comment(comment)
|
||||
def on_comment_changed(self, *args, **kwargs):
|
||||
if hasattr(self.presenter, "change_comment"):
|
||||
comment = self.view.comments.get_selected()
|
||||
self.presenter.change_comment(comment)
|
||||
|
||||
def on_show_likes_menu(self, *args, **kwargs):
|
||||
self.presenter.show_likes()
|
||||
def on_show_likes_menu(self, *args, **kwargs):
|
||||
self.presenter.show_likes()
|
||||
|
||||
def on_show_shares_menu(self, *args, **kwargs):
|
||||
self.presenter.show_shares()
|
||||
def on_show_shares_menu(self, *args, **kwargs):
|
||||
self.presenter.show_shares()
|
||||
|
||||
class displayAudioInteractor(base.baseInteractor):
|
||||
|
||||
def set(self, control, value):
|
||||
if not hasattr(self.view, control):
|
||||
raise AttributeError("The control is not present in the view.")
|
||||
getattr(self.view, control).SetValue(value)
|
||||
def set(self, control, value):
|
||||
if not hasattr(self.view, control):
|
||||
raise AttributeError("The control is not present in the view.")
|
||||
getattr(self.view, control).SetValue(value)
|
||||
|
||||
def add_items(self, control, items):
|
||||
if not hasattr(self.view, control):
|
||||
raise AttributeError("The control is not present in the view.")
|
||||
for i in items:
|
||||
getattr(self.view, control).Append(i)
|
||||
getattr(self.view, control).SetSelection(0)
|
||||
def add_items(self, control, items):
|
||||
if not hasattr(self.view, control):
|
||||
raise AttributeError("The control is not present in the view.")
|
||||
for i in items:
|
||||
getattr(self.view, control).Append(i)
|
||||
getattr(self.view, control).SetSelection(0)
|
||||
|
||||
def change_label(self, stopped):
|
||||
def change_label(self, stopped):
|
||||
|
||||
if stopped == False:
|
||||
self.view.play.SetLabel(_("P&ause"))
|
||||
else:
|
||||
self.view.play.SetLabel(_("P&lay"))
|
||||
if stopped == False:
|
||||
self.view.play.SetLabel(_("P&ause"))
|
||||
else:
|
||||
self.view.play.SetLabel(_("P&lay"))
|
||||
|
||||
def install(self, *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.download, widgetUtils.BUTTON_PRESSED, self.on_download)
|
||||
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.remove, widgetUtils.BUTTON_PRESSED, self.on_remove_from_library)
|
||||
pub.subscribe(self.set, self.modulename+"_set")
|
||||
pub.subscribe(self.add_items, self.modulename+"_add_items")
|
||||
pub.subscribe(self.change_label, "playback-changed")
|
||||
def install(self, *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.download, widgetUtils.BUTTON_PRESSED, self.on_download)
|
||||
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.remove, widgetUtils.BUTTON_PRESSED, self.on_remove_from_library)
|
||||
pub.subscribe(self.set, self.modulename+"_set")
|
||||
pub.subscribe(self.add_items, self.modulename+"_add_items")
|
||||
pub.subscribe(self.change_label, "playback-changed")
|
||||
|
||||
def uninstall(self):
|
||||
super(displayAudioInteractor, self).uninstall()
|
||||
pub.unsubscribe(self.set, self.modulename+"_set")
|
||||
pub.unsubscribe(self.add_items, self.modulename+"_add_items")
|
||||
pub.unsubscribe(self.change_label, "playback-changed")
|
||||
def uninstall(self):
|
||||
super(displayAudioInteractor, self).uninstall()
|
||||
pub.unsubscribe(self.set, self.modulename+"_set")
|
||||
pub.unsubscribe(self.add_items, self.modulename+"_add_items")
|
||||
pub.unsubscribe(self.change_label, "playback-changed")
|
||||
|
||||
def on_change(self, *args, **kwargs):
|
||||
post = self.view.get_audio()
|
||||
self.presenter.handle_changes(post)
|
||||
def on_change(self, *args, **kwargs):
|
||||
post = self.view.get_audio()
|
||||
self.presenter.handle_changes(post)
|
||||
|
||||
def on_download(self, *args, **kwargs):
|
||||
post = self.view.get_audio()
|
||||
suggested_filename = self.presenter.get_suggested_filename(post)
|
||||
path = self.view.get_destination_path(suggested_filename)
|
||||
self.presenter.download(post, path)
|
||||
def on_download(self, *args, **kwargs):
|
||||
post = self.view.get_audio()
|
||||
suggested_filename = self.presenter.get_suggested_filename(post)
|
||||
path = self.view.get_destination_path(suggested_filename)
|
||||
self.presenter.download(post, path)
|
||||
|
||||
def on_play(self, *args, **kwargs):
|
||||
post = self.view.get_audio()
|
||||
self.presenter.play(post)
|
||||
def on_play(self, *args, **kwargs):
|
||||
post = self.view.get_audio()
|
||||
self.presenter.play(post)
|
||||
|
||||
def on_add_to_library(self, *args, **kwargs):
|
||||
post = self.view.get_audio()
|
||||
self.presenter.add_to_library(post)
|
||||
def on_add_to_library(self, *args, **kwargs):
|
||||
post = self.view.get_audio()
|
||||
self.presenter.add_to_library(post)
|
||||
|
||||
def on_remove_from_library(self, *args, **kwargs):
|
||||
post = self.view.get_audio()
|
||||
self.presenter.remove_from_library(post)
|
||||
def on_remove_from_library(self, *args, **kwargs):
|
||||
post = self.view.get_audio()
|
||||
self.presenter.remove_from_library(post)
|
||||
|
||||
class displayArticleInteractor(base.baseInteractor):
|
||||
|
||||
def set(self, control, value):
|
||||
if not hasattr(self.view, control):
|
||||
raise AttributeError("The control is not present in the view.")
|
||||
getattr(self.view, control).SetValue(value)
|
||||
def set(self, control, value):
|
||||
if not hasattr(self.view, control):
|
||||
raise AttributeError("The control is not present in the view.")
|
||||
getattr(self.view, control).SetValue(value)
|
||||
|
||||
def install(self, *args, **kwargs):
|
||||
super(displayArticleInteractor, self).install(*args, **kwargs)
|
||||
pub.subscribe(self.set, self.modulename+"_set")
|
||||
def install(self, *args, **kwargs):
|
||||
super(displayArticleInteractor, self).install(*args, **kwargs)
|
||||
pub.subscribe(self.set, self.modulename+"_set")
|
||||
|
||||
def uninstall(self):
|
||||
super(displayArticleInteractor, self).uninstall()
|
||||
pub.unsubscribe(self.set, self.modulename+"_set")
|
||||
def uninstall(self):
|
||||
super(displayArticleInteractor, self).uninstall()
|
||||
pub.unsubscribe(self.set, self.modulename+"_set")
|
||||
|
||||
class displayPollInteractor(base.baseInteractor):
|
||||
|
||||
def set(self, control, value):
|
||||
if not hasattr(self.view, control):
|
||||
raise AttributeError("The control is not present in the view.")
|
||||
getattr(self.view, control).SetValue(value)
|
||||
def set(self, control, value):
|
||||
if not hasattr(self.view, control):
|
||||
raise AttributeError("The control is not present in the view.")
|
||||
getattr(self.view, control).SetValue(value)
|
||||
|
||||
def done(self):
|
||||
self.view.done()
|
||||
def done(self):
|
||||
self.view.done()
|
||||
|
||||
def add_options(self, options, multiple):
|
||||
self.view.add_options(options, multiple)
|
||||
def add_options(self, options, multiple):
|
||||
self.view.add_options(options, multiple)
|
||||
|
||||
def install(self, *args, **kwargs):
|
||||
super(displayPollInteractor, self).install(*args, **kwargs)
|
||||
pub.subscribe(self.set, self.modulename+"_set")
|
||||
pub.subscribe(self.done, self.modulename+"_done")
|
||||
pub.subscribe(self.add_options, self.modulename+"_add_options")
|
||||
def install(self, *args, **kwargs):
|
||||
super(displayPollInteractor, self).install(*args, **kwargs)
|
||||
pub.subscribe(self.set, self.modulename+"_set")
|
||||
pub.subscribe(self.done, self.modulename+"_done")
|
||||
pub.subscribe(self.add_options, self.modulename+"_add_options")
|
||||
|
||||
def uninstall(self):
|
||||
super(displayPollInteractor, self).uninstall()
|
||||
pub.unsubscribe(self.set, self.modulename+"_set")
|
||||
pub.unsubscribe(self.done, self.modulename+"_done")
|
||||
pub.unsubscribe(self.add_options, self.modulename+"_add_options")
|
||||
def uninstall(self):
|
||||
super(displayPollInteractor, self).uninstall()
|
||||
pub.unsubscribe(self.set, self.modulename+"_set")
|
||||
pub.unsubscribe(self.done, self.modulename+"_done")
|
||||
pub.unsubscribe(self.add_options, self.modulename+"_add_options")
|
||||
|
||||
def start(self, *args, **kwargs):
|
||||
super(displayPollInteractor, self).start(*args, **kwargs)
|
||||
if self.result == widgetUtils.OK: # USer votd.
|
||||
answers = self.view.get_answers()
|
||||
self.presenter.vote(answers)
|
||||
def start(self, *args, **kwargs):
|
||||
super(displayPollInteractor, self).start(*args, **kwargs)
|
||||
if self.result == widgetUtils.OK: # USer votd.
|
||||
answers = self.view.get_answers()
|
||||
self.presenter.vote(answers)
|
||||
|
||||
class displayFriendshipInteractor(base.baseInteractor):
|
||||
|
||||
def add_items(self, control, items):
|
||||
if not hasattr(self.view, control):
|
||||
raise AttributeError("The control is not present in the view.")
|
||||
for i in items:
|
||||
getattr(self.view, control).insert_item(False, *[i])
|
||||
def add_items(self, control, items):
|
||||
if not hasattr(self.view, control):
|
||||
raise AttributeError("The control is not present in the view.")
|
||||
for i in items:
|
||||
getattr(self.view, control).insert_item(False, *[i])
|
||||
|
||||
def install(self, *args, **kwargs):
|
||||
super(displayFriendshipInteractor, self).install(*args, **kwargs)
|
||||
pub.subscribe(self.add_items, self.modulename+"_add_items")
|
||||
self.view.friends.list.Bind(wx.EVT_CONTEXT_MENU, self.on_context_menu)
|
||||
def install(self, *args, **kwargs):
|
||||
super(displayFriendshipInteractor, self).install(*args, **kwargs)
|
||||
pub.subscribe(self.add_items, self.modulename+"_add_items")
|
||||
self.view.friends.list.Bind(wx.EVT_CONTEXT_MENU, self.on_context_menu)
|
||||
|
||||
def uninstall(self):
|
||||
super(displayFriendshipInteractor, self).uninstall()
|
||||
pub.unsubscribe(self.add_items, self.modulename+"_add_items")
|
||||
def uninstall(self):
|
||||
super(displayFriendshipInteractor, self).uninstall()
|
||||
pub.unsubscribe(self.add_items, self.modulename+"_add_items")
|
||||
|
||||
def on_context_menu(self, *args, **kwargs):
|
||||
item = self.view.friends.get_selected()
|
||||
if item < 0:
|
||||
return
|
||||
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_open_in_browser, menuitem=menu.open_in_browser)
|
||||
# Generally message sending is blocked.
|
||||
menu.message.Enable(False)
|
||||
self.view.PopupMenu(menu, self.view.friends.list.GetPosition())
|
||||
def on_context_menu(self, *args, **kwargs):
|
||||
item = self.view.friends.get_selected()
|
||||
if item < 0:
|
||||
return
|
||||
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_open_in_browser, menuitem=menu.open_in_browser)
|
||||
# Generally message sending is blocked.
|
||||
menu.message.Enable(False)
|
||||
self.view.PopupMenu(menu, self.view.friends.list.GetPosition())
|
||||
|
||||
def on_view_profile(self, *args, **kwargs):
|
||||
item = self.view.friends.get_selected()
|
||||
self.presenter.view_profile(item)
|
||||
def on_view_profile(self, *args, **kwargs):
|
||||
item = self.view.friends.get_selected()
|
||||
self.presenter.view_profile(item)
|
||||
|
||||
def on_open_in_browser(self, *args, **kwargs):
|
||||
item = self.view.friends.get_selected()
|
||||
self.presenter.open_in_browser(item)
|
||||
def on_open_in_browser(self, *args, **kwargs):
|
||||
item = self.view.friends.get_selected()
|
||||
self.presenter.open_in_browser(item)
|
||||
|
@ -9,62 +9,62 @@ from . import base
|
||||
|
||||
class userProfileInteractor(base.baseInteractor):
|
||||
|
||||
def enable_control(self, tab, control):
|
||||
if not hasattr(self.view, tab):
|
||||
raise AttributeError("The viw does not contain the specified tab.")
|
||||
tab = getattr(self.view, tab)
|
||||
if not hasattr(tab, control):
|
||||
raise AttributeError("The control is not present in the tab.")
|
||||
getattr(tab, control).Enable(True)
|
||||
def enable_control(self, tab, control):
|
||||
if not hasattr(self.view, tab):
|
||||
raise AttributeError("The viw does not contain the specified tab.")
|
||||
tab = getattr(self.view, tab)
|
||||
if not hasattr(tab, control):
|
||||
raise AttributeError("The control is not present in the tab.")
|
||||
getattr(tab, control).Enable(True)
|
||||
|
||||
def set(self, tab, control, value):
|
||||
if not hasattr(self.view, tab):
|
||||
raise AttributeError("The view does not contain the specified tab.")
|
||||
tab = getattr(self.view, tab)
|
||||
if not hasattr(tab, control):
|
||||
raise AttributeError("The control is not present in the tab.")
|
||||
control = getattr(tab, control)
|
||||
control.SetValue(value)
|
||||
def set(self, tab, control, value):
|
||||
if not hasattr(self.view, tab):
|
||||
raise AttributeError("The view does not contain the specified tab.")
|
||||
tab = getattr(self.view, tab)
|
||||
if not hasattr(tab, control):
|
||||
raise AttributeError("The control is not present in the tab.")
|
||||
control = getattr(tab, control)
|
||||
control.SetValue(value)
|
||||
|
||||
def set_label(self, tab, control, value):
|
||||
if not hasattr(self.view, tab):
|
||||
raise AttributeError("The viw does not contain the specified tab.")
|
||||
tab = getattr(self.view, tab)
|
||||
if not hasattr(tab, control):
|
||||
raise AttributeError("The control is not present in the tab.")
|
||||
control = getattr(tab, control)
|
||||
control.SetLabel(value)
|
||||
def set_label(self, tab, control, value):
|
||||
if not hasattr(self.view, tab):
|
||||
raise AttributeError("The viw does not contain the specified tab.")
|
||||
tab = getattr(self.view, tab)
|
||||
if not hasattr(tab, control):
|
||||
raise AttributeError("The control is not present in the tab.")
|
||||
control = getattr(tab, control)
|
||||
control.SetLabel(value)
|
||||
|
||||
def load_image(self, image):
|
||||
image = wx.Image(stream=six.BytesIO(image.content))
|
||||
try:
|
||||
self.view.image.SetBitmap(wx.Bitmap(image))
|
||||
except ValueError:
|
||||
return
|
||||
self.view.panel.Layout()
|
||||
def load_image(self, image):
|
||||
image = wx.Image(stream=six.BytesIO(image.content))
|
||||
try:
|
||||
self.view.image.SetBitmap(wx.Bitmap(image))
|
||||
except ValueError:
|
||||
return
|
||||
self.view.panel.Layout()
|
||||
|
||||
def install(self, *args, **kwargs):
|
||||
super(userProfileInteractor, self).install(*args, **kwargs)
|
||||
pub.subscribe(self.set, self.modulename+"_set")
|
||||
pub.subscribe(self.load_image, self.modulename+"_load_image")
|
||||
self.view.create_controls("main_info")
|
||||
self.view.realice()
|
||||
widgetUtils.connect_event(self.view.main_info.go_site, widgetUtils.BUTTON_PRESSED, self.on_visit_website)
|
||||
def install(self, *args, **kwargs):
|
||||
super(userProfileInteractor, self).install(*args, **kwargs)
|
||||
pub.subscribe(self.set, self.modulename+"_set")
|
||||
pub.subscribe(self.load_image, self.modulename+"_load_image")
|
||||
self.view.create_controls("main_info")
|
||||
self.view.realice()
|
||||
widgetUtils.connect_event(self.view.main_info.go_site, widgetUtils.BUTTON_PRESSED, self.on_visit_website)
|
||||
|
||||
def uninstall(self):
|
||||
super(userProfileInteractor, self).uninstall()
|
||||
pub.unsubscribe(self.set, self.modulename+"_set")
|
||||
pub.unsubscribe(self.load_image, self.modulename+"_load_image")
|
||||
def uninstall(self):
|
||||
super(userProfileInteractor, self).uninstall()
|
||||
pub.unsubscribe(self.set, self.modulename+"_set")
|
||||
pub.unsubscribe(self.load_image, self.modulename+"_load_image")
|
||||
|
||||
|
||||
def on_visit_website(self, *args, **kwargs):
|
||||
urls = self.presenter.get_urls()
|
||||
if len(urls) == 1:
|
||||
self.presenter.visit_url(urls[0])
|
||||
else:
|
||||
dialog = urlList.urlList()
|
||||
dialog.populate_list(urls)
|
||||
if dialog.get_response() != widgetUtils.OK:
|
||||
return
|
||||
selected_url = urls[dialog.get_item()]
|
||||
self.presenter.visit_url(selected_url)
|
||||
def on_visit_website(self, *args, **kwargs):
|
||||
urls = self.presenter.get_urls()
|
||||
if len(urls) == 1:
|
||||
self.presenter.visit_url(urls[0])
|
||||
else:
|
||||
dialog = urlList.urlList()
|
||||
dialog.populate_list(urls)
|
||||
if dialog.get_response() != widgetUtils.OK:
|
||||
return
|
||||
selected_url = urls[dialog.get_item()]
|
||||
self.presenter.visit_url(selected_url)
|
||||
|
@ -1,7 +1,7 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
############################################################
|
||||
# Copyright (c) 2018 Manuel Cortez <manuel@manuelcortez.net>
|
||||
#
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 2 of the License, or
|
||||
@ -28,37 +28,37 @@ from mysc.thread_utils import call_threaded
|
||||
from . import wx_ui
|
||||
|
||||
class reportBug(object):
|
||||
def __init__(self):
|
||||
self.dialog = wx_ui.reportBugDialog()
|
||||
widgetUtils.connect_event(self.dialog.ok, widgetUtils.BUTTON_PRESSED, self.send)
|
||||
self.dialog.get_response()
|
||||
def __init__(self):
|
||||
self.dialog = wx_ui.reportBugDialog()
|
||||
widgetUtils.connect_event(self.dialog.ok, widgetUtils.BUTTON_PRESSED, self.send)
|
||||
self.dialog.get_response()
|
||||
|
||||
def do_report(self, *args, **kwargs):
|
||||
r = requests.post(*args, **kwargs)
|
||||
if r.status_code > 300:
|
||||
wx.CallAfter(self.dialog.error)
|
||||
wx.CallAfter(self.dialog.progress.Destroy)
|
||||
wx.CallAfter(self.dialog.success, r.json()["data"]["issue"]["id"])
|
||||
def do_report(self, *args, **kwargs):
|
||||
r = requests.post(*args, **kwargs)
|
||||
if r.status_code > 300:
|
||||
wx.CallAfter(self.dialog.error)
|
||||
wx.CallAfter(self.dialog.progress.Destroy)
|
||||
wx.CallAfter(self.dialog.success, r.json()["data"]["issue"]["id"])
|
||||
|
||||
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") == "":
|
||||
self.dialog.no_filled()
|
||||
return
|
||||
if self.dialog.get("agree") == False:
|
||||
self.dialog.no_checkbox()
|
||||
return
|
||||
title = self.dialog.get("summary")
|
||||
body = self.dialog.get("description")
|
||||
issue_type = "issue" # for now just have issue
|
||||
app_type = paths.mode
|
||||
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_contact_type = "email" # For now just email is supported in the issue reporter
|
||||
reporter_contact_handle = self.dialog.get("email")
|
||||
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)
|
||||
auth=HTTPBasicAuth(application.bts_name, application.bts_access_token)
|
||||
url = "{bts_url}/issue/new".format(bts_url=application.bts_url)
|
||||
call_threaded(self.do_report, url, json=json, auth=auth)
|
||||
self.dialog.show_progress()
|
||||
self.dialog.EndModal(wx.ID_OK)
|
||||
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") == "":
|
||||
self.dialog.no_filled()
|
||||
return
|
||||
if self.dialog.get("agree") == False:
|
||||
self.dialog.no_checkbox()
|
||||
return
|
||||
title = self.dialog.get("summary")
|
||||
body = self.dialog.get("description")
|
||||
issue_type = "issue" # for now just have issue
|
||||
app_type = paths.mode
|
||||
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_contact_type = "email" # For now just email is supported in the issue reporter
|
||||
reporter_contact_handle = self.dialog.get("email")
|
||||
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)
|
||||
auth=HTTPBasicAuth(application.bts_name, application.bts_access_token)
|
||||
url = "{bts_url}/issue/new".format(bts_url=application.bts_url)
|
||||
call_threaded(self.do_report, url, json=json, auth=auth)
|
||||
self.dialog.show_progress()
|
||||
self.dialog.EndModal(wx.ID_OK)
|
||||
|
@ -1,7 +1,7 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
############################################################
|
||||
# Copyright (c) 2018 Manuel cortez <manuel@manuelcortez.net>
|
||||
#
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 2 of the License, or
|
||||
@ -22,89 +22,89 @@ import widgetUtils
|
||||
import application
|
||||
|
||||
class reportBugDialog(widgetUtils.BaseDialog):
|
||||
def __init__(self):
|
||||
super(reportBugDialog, self).__init__(parent=None, id=wx.NewId())
|
||||
self.SetTitle(_("Report an error"))
|
||||
panel = wx.Panel(self)
|
||||
sizer = wx.BoxSizer(wx.VERTICAL)
|
||||
def __init__(self):
|
||||
super(reportBugDialog, self).__init__(parent=None, id=wx.NewId())
|
||||
self.SetTitle(_("Report an error"))
|
||||
panel = wx.Panel(self)
|
||||
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)
|
||||
self.summary = wx.TextCtrl(panel, -1)
|
||||
dc = wx.WindowDC(self.summary)
|
||||
dc.SetFont(self.summary.GetFont())
|
||||
self.summary.SetSize(dc.GetTextExtent("a"*80))
|
||||
summaryB = wx.BoxSizer(wx.HORIZONTAL)
|
||||
summaryB.Add(summaryLabel, 0, wx.ALL, 5)
|
||||
summaryB.Add(self.summary, 0, wx.ALL, 5)
|
||||
sizer.Add(summaryB, 0, wx.ALL, 5)
|
||||
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)
|
||||
dc = wx.WindowDC(self.summary)
|
||||
dc.SetFont(self.summary.GetFont())
|
||||
self.summary.SetSize(dc.GetTextExtent("a"*80))
|
||||
summaryB = wx.BoxSizer(wx.HORIZONTAL)
|
||||
summaryB.Add(summaryLabel, 0, wx.ALL, 5)
|
||||
summaryB.Add(self.summary, 0, wx.ALL, 5)
|
||||
sizer.Add(summaryB, 0, wx.ALL, 5)
|
||||
|
||||
first_nameLabel = wx.StaticText(panel, -1, _("First Name"), size=wx.DefaultSize)
|
||||
self.first_name = wx.TextCtrl(panel, -1)
|
||||
dc = wx.WindowDC(self.first_name)
|
||||
dc.SetFont(self.first_name.GetFont())
|
||||
self.first_name.SetSize(dc.GetTextExtent("a"*40))
|
||||
first_nameB = wx.BoxSizer(wx.HORIZONTAL)
|
||||
first_nameB.Add(first_nameLabel, 0, wx.ALL, 5)
|
||||
first_nameB.Add(self.first_name, 0, wx.ALL, 5)
|
||||
sizer.Add(first_nameB, 0, wx.ALL, 5)
|
||||
first_nameLabel = wx.StaticText(panel, -1, _("First Name"), size=wx.DefaultSize)
|
||||
self.first_name = wx.TextCtrl(panel, -1)
|
||||
dc = wx.WindowDC(self.first_name)
|
||||
dc.SetFont(self.first_name.GetFont())
|
||||
self.first_name.SetSize(dc.GetTextExtent("a"*40))
|
||||
first_nameB = wx.BoxSizer(wx.HORIZONTAL)
|
||||
first_nameB.Add(first_nameLabel, 0, wx.ALL, 5)
|
||||
first_nameB.Add(self.first_name, 0, wx.ALL, 5)
|
||||
sizer.Add(first_nameB, 0, wx.ALL, 5)
|
||||
|
||||
last_nameLabel = wx.StaticText(panel, -1, _("Last Name"), size=wx.DefaultSize)
|
||||
self.last_name = wx.TextCtrl(panel, -1)
|
||||
dc = wx.WindowDC(self.last_name)
|
||||
dc.SetFont(self.last_name.GetFont())
|
||||
self.last_name.SetSize(dc.GetTextExtent("a"*40))
|
||||
last_nameB = wx.BoxSizer(wx.HORIZONTAL)
|
||||
last_nameB.Add(last_nameLabel, 0, wx.ALL, 5)
|
||||
last_nameB.Add(self.last_name, 0, wx.ALL, 5)
|
||||
sizer.Add(last_nameB, 0, wx.ALL, 5)
|
||||
last_nameLabel = wx.StaticText(panel, -1, _("Last Name"), size=wx.DefaultSize)
|
||||
self.last_name = wx.TextCtrl(panel, -1)
|
||||
dc = wx.WindowDC(self.last_name)
|
||||
dc.SetFont(self.last_name.GetFont())
|
||||
self.last_name.SetSize(dc.GetTextExtent("a"*40))
|
||||
last_nameB = wx.BoxSizer(wx.HORIZONTAL)
|
||||
last_nameB.Add(last_nameLabel, 0, wx.ALL, 5)
|
||||
last_nameB.Add(self.last_name, 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)
|
||||
self.email = wx.TextCtrl(panel, -1)
|
||||
dc = wx.WindowDC(self.email)
|
||||
dc.SetFont(self.email.GetFont())
|
||||
self.email.SetSize(dc.GetTextExtent("a"*30))
|
||||
emailB = wx.BoxSizer(wx.HORIZONTAL)
|
||||
emailB.Add(emailLabel, 0, wx.ALL, 5)
|
||||
emailB.Add(self.email, 0, wx.ALL, 5)
|
||||
sizer.Add(emailB, 0, wx.ALL, 5)
|
||||
emailLabel = wx.StaticText(panel, -1, _("Email address (Will not be public)"), size=wx.DefaultSize)
|
||||
self.email = wx.TextCtrl(panel, -1)
|
||||
dc = wx.WindowDC(self.email)
|
||||
dc.SetFont(self.email.GetFont())
|
||||
self.email.SetSize(dc.GetTextExtent("a"*30))
|
||||
emailB = wx.BoxSizer(wx.HORIZONTAL)
|
||||
emailB.Add(emailLabel, 0, wx.ALL, 5)
|
||||
emailB.Add(self.email, 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)
|
||||
self.description = wx.TextCtrl(panel, -1, style=wx.TE_MULTILINE)
|
||||
dc = wx.WindowDC(self.description)
|
||||
dc.SetFont(self.description.GetFont())
|
||||
(x, y) = dc.GetMultiLineTextExtent("0"*2000)
|
||||
self.description.SetSize((x, y))
|
||||
descBox = wx.BoxSizer(wx.HORIZONTAL)
|
||||
descBox.Add(descriptionLabel, 0, wx.ALL, 5)
|
||||
descBox.Add(self.description, 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.SetValue(False)
|
||||
sizer.Add(self.agree, 0, wx.ALL, 5)
|
||||
self.ok = wx.Button(panel, wx.ID_OK, _("Send report"))
|
||||
self.ok.SetDefault()
|
||||
cancel = wx.Button(panel, wx.ID_CANCEL, _("Cancel"))
|
||||
btnBox = wx.BoxSizer(wx.HORIZONTAL)
|
||||
btnBox.Add(self.ok, 0, wx.ALL, 5)
|
||||
btnBox.Add(cancel, 0, wx.ALL, 5)
|
||||
sizer.Add(btnBox, 0, wx.ALL, 5)
|
||||
panel.SetSizer(sizer)
|
||||
self.SetClientSize(sizer.CalcMin())
|
||||
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)
|
||||
dc = wx.WindowDC(self.description)
|
||||
dc.SetFont(self.description.GetFont())
|
||||
(x, y) = dc.GetMultiLineTextExtent("0"*2000)
|
||||
self.description.SetSize((x, y))
|
||||
descBox = wx.BoxSizer(wx.HORIZONTAL)
|
||||
descBox.Add(descriptionLabel, 0, wx.ALL, 5)
|
||||
descBox.Add(self.description, 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.SetValue(False)
|
||||
sizer.Add(self.agree, 0, wx.ALL, 5)
|
||||
self.ok = wx.Button(panel, wx.ID_OK, _("Send report"))
|
||||
self.ok.SetDefault()
|
||||
cancel = wx.Button(panel, wx.ID_CANCEL, _("Cancel"))
|
||||
btnBox = wx.BoxSizer(wx.HORIZONTAL)
|
||||
btnBox.Add(self.ok, 0, wx.ALL, 5)
|
||||
btnBox.Add(cancel, 0, wx.ALL, 5)
|
||||
sizer.Add(btnBox, 0, wx.ALL, 5)
|
||||
panel.SetSizer(sizer)
|
||||
self.SetClientSize(sizer.CalcMin())
|
||||
|
||||
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()
|
||||
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()
|
||||
|
||||
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()
|
||||
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()
|
||||
|
||||
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()
|
||||
self.Destroy()
|
||||
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()
|
||||
self.Destroy()
|
||||
|
||||
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()
|
||||
self.Destroy()
|
||||
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()
|
||||
self.Destroy()
|
||||
|
||||
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.ShowModal()
|
||||
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.ShowModal()
|
||||
|
@ -5,12 +5,12 @@ log = logging.getLogger("keyring")
|
||||
keyring = None
|
||||
|
||||
def setup():
|
||||
global keyring
|
||||
if keyring == None:
|
||||
keyring = Keyring()
|
||||
log.debug("Keyring started")
|
||||
global keyring
|
||||
if keyring == None:
|
||||
keyring = Keyring()
|
||||
log.debug("Keyring started")
|
||||
|
||||
class Keyring(object):
|
||||
|
||||
def get_api_key(self):
|
||||
return "5093442"
|
||||
def get_api_key(self):
|
||||
return "5093442"
|
||||
|
@ -12,7 +12,7 @@ import gettext
|
||||
import paths
|
||||
import platform
|
||||
import application
|
||||
|
||||
|
||||
#a few Windows locale constants
|
||||
LOCALE_SLANGUAGE=0x2
|
||||
LOCALE_SLANGDISPLAYNAME=0x6f
|
||||
@ -20,195 +20,195 @@ LOCALE_SLANGDISPLAYNAME=0x6f
|
||||
curLang="en"
|
||||
|
||||
def localeNameToWindowsLCID(localeName):
|
||||
"""Retreave the Windows locale identifier (LCID) for the given locale name
|
||||
@param localeName: a string of 2letterLanguage_2letterCountry or or just 2letterLanguage
|
||||
@type localeName: string
|
||||
@returns: a Windows LCID
|
||||
@rtype: integer
|
||||
"""
|
||||
#Windows Vista is able to convert locale names to LCIDs
|
||||
func_LocaleNameToLCID=getattr(ctypes.windll.kernel32,'LocaleNameToLCID',None)
|
||||
if func_LocaleNameToLCID is not None:
|
||||
localeName=localeName.replace('_','-')
|
||||
LCID=func_LocaleNameToLCID(str(localeName),0)
|
||||
else: #Windows doesn't have this functionality, manually search Python's windows_locale dictionary for the LCID
|
||||
localeName=locale.normalize(localeName)
|
||||
if '.' in localeName:
|
||||
localeName=localeName.split('.')[0]
|
||||
LCList=[x[0] for x in locale.windows_locale.items() if x[1]==localeName]
|
||||
if len(LCList)>0:
|
||||
LCID=LCList[0]
|
||||
else:
|
||||
LCID=0
|
||||
return LCID
|
||||
"""Retreave the Windows locale identifier (LCID) for the given locale name
|
||||
@param localeName: a string of 2letterLanguage_2letterCountry or or just 2letterLanguage
|
||||
@type localeName: string
|
||||
@returns: a Windows LCID
|
||||
@rtype: integer
|
||||
"""
|
||||
#Windows Vista is able to convert locale names to LCIDs
|
||||
func_LocaleNameToLCID=getattr(ctypes.windll.kernel32,'LocaleNameToLCID',None)
|
||||
if func_LocaleNameToLCID is not None:
|
||||
localeName=localeName.replace('_','-')
|
||||
LCID=func_LocaleNameToLCID(str(localeName),0)
|
||||
else: #Windows doesn't have this functionality, manually search Python's windows_locale dictionary for the LCID
|
||||
localeName=locale.normalize(localeName)
|
||||
if '.' in localeName:
|
||||
localeName=localeName.split('.')[0]
|
||||
LCList=[x[0] for x in locale.windows_locale.items() if x[1]==localeName]
|
||||
if len(LCList)>0:
|
||||
LCID=LCList[0]
|
||||
else:
|
||||
LCID=0
|
||||
return LCID
|
||||
|
||||
def getLanguageDescription(language):
|
||||
"""Finds out the description (localized full name) of a given local name"""
|
||||
desc=None
|
||||
if platform.system() == "Windows":
|
||||
LCID=localeNameToWindowsLCID(language)
|
||||
if LCID!=0:
|
||||
buf=ctypes.create_unicode_buffer(1024)
|
||||
if '_' not in language:
|
||||
res=ctypes.windll.kernel32.GetLocaleInfoW(LCID,LOCALE_SLANGDISPLAYNAME,buf,1024)
|
||||
else:
|
||||
res=0
|
||||
if res==0:
|
||||
res=ctypes.windll.kernel32.GetLocaleInfoW(LCID,LOCALE_SLANGUAGE,buf,1024)
|
||||
desc=buf.value
|
||||
elif platform.system() == "Linux" or not desc:
|
||||
desc={
|
||||
"am":pgettext("languageName","Amharic"),
|
||||
"an":pgettext("languageName","Aragonese"),
|
||||
"es":pgettext("languageName","Spanish"),
|
||||
"pt":pgettext("languageName","Portuguese"),
|
||||
"ru":pgettext("languageName","Russian"),
|
||||
"it":pgettext("languageName","italian"),
|
||||
"tr":pgettext("languageName","Turkey"),
|
||||
"gl":pgettext("languageName","Galician"),
|
||||
"ca":pgettext("languageName","Catala"),
|
||||
"eu":pgettext("languageName","Vasque"),
|
||||
"pl":pgettext("languageName","polish"),
|
||||
"ar":pgettext("languageName","Arabic"),
|
||||
"ne":pgettext("languageName","Nepali"),
|
||||
"sr":pgettext("languageName","Serbian (Latin)"),
|
||||
"ja":pgettext("languageName","Japanese"),
|
||||
}.get(language,None)
|
||||
return desc
|
||||
"""Finds out the description (localized full name) of a given local name"""
|
||||
desc=None
|
||||
if platform.system() == "Windows":
|
||||
LCID=localeNameToWindowsLCID(language)
|
||||
if LCID!=0:
|
||||
buf=ctypes.create_unicode_buffer(1024)
|
||||
if '_' not in language:
|
||||
res=ctypes.windll.kernel32.GetLocaleInfoW(LCID,LOCALE_SLANGDISPLAYNAME,buf,1024)
|
||||
else:
|
||||
res=0
|
||||
if res==0:
|
||||
res=ctypes.windll.kernel32.GetLocaleInfoW(LCID,LOCALE_SLANGUAGE,buf,1024)
|
||||
desc=buf.value
|
||||
elif platform.system() == "Linux" or not desc:
|
||||
desc={
|
||||
"am":pgettext("languageName","Amharic"),
|
||||
"an":pgettext("languageName","Aragonese"),
|
||||
"es":pgettext("languageName","Spanish"),
|
||||
"pt":pgettext("languageName","Portuguese"),
|
||||
"ru":pgettext("languageName","Russian"),
|
||||
"it":pgettext("languageName","italian"),
|
||||
"tr":pgettext("languageName","Turkey"),
|
||||
"gl":pgettext("languageName","Galician"),
|
||||
"ca":pgettext("languageName","Catala"),
|
||||
"eu":pgettext("languageName","Vasque"),
|
||||
"pl":pgettext("languageName","polish"),
|
||||
"ar":pgettext("languageName","Arabic"),
|
||||
"ne":pgettext("languageName","Nepali"),
|
||||
"sr":pgettext("languageName","Serbian (Latin)"),
|
||||
"ja":pgettext("languageName","Japanese"),
|
||||
}.get(language,None)
|
||||
return desc
|
||||
|
||||
def getAvailableLanguages():
|
||||
"""generates a list of locale names, plus their full localized language and country names.
|
||||
@rtype: list of tuples
|
||||
"""
|
||||
#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 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
|
||||
if 'en' not in l:
|
||||
l.append('en')
|
||||
l.sort()
|
||||
#For each locale, ask Windows for its human readable display name
|
||||
d=[]
|
||||
for i in l:
|
||||
desc=getLanguageDescription(i)
|
||||
label="%s, %s"%(desc,i) if desc else i
|
||||
d.append(label)
|
||||
#include a 'user default, windows' language, which just represents the default language for this user account
|
||||
l.append("system")
|
||||
# Translators: the label for the Windows default NVDA interface language.
|
||||
d.append(_("User default"))
|
||||
#return a zipped up version of both the lists (a list with tuples of locale,label)
|
||||
return list(zip(l,d))
|
||||
"""generates a list of locale names, plus their full localized language and country names.
|
||||
@rtype: list of tuples
|
||||
"""
|
||||
#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 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
|
||||
if 'en' not in l:
|
||||
l.append('en')
|
||||
l.sort()
|
||||
#For each locale, ask Windows for its human readable display name
|
||||
d=[]
|
||||
for i in l:
|
||||
desc=getLanguageDescription(i)
|
||||
label="%s, %s"%(desc,i) if desc else i
|
||||
d.append(label)
|
||||
#include a 'user default, windows' language, which just represents the default language for this user account
|
||||
l.append("system")
|
||||
# Translators: the label for the Windows default NVDA interface language.
|
||||
d.append(_("User default"))
|
||||
#return a zipped up version of both the lists (a list with tuples of locale,label)
|
||||
return list(zip(l,d))
|
||||
|
||||
def makePgettext(translations):
|
||||
"""Obtaina pgettext function for use with a gettext translations instance.
|
||||
pgettext is used to support message contexts,
|
||||
but Python 2.7's gettext module doesn't support this,
|
||||
so NVDA must provide its own implementation.
|
||||
"""
|
||||
if isinstance(translations, gettext.GNUTranslations):
|
||||
def pgettext(context, message):
|
||||
message = str(message)
|
||||
try:
|
||||
# Look up the message with its context.
|
||||
return translations._catalog["%s\x04%s" % (context, message)]
|
||||
except KeyError:
|
||||
return message
|
||||
else:
|
||||
def pgettext(context, message):
|
||||
return str(message)
|
||||
return pgettext
|
||||
"""Obtaina pgettext function for use with a gettext translations instance.
|
||||
pgettext is used to support message contexts,
|
||||
but Python 2.7's gettext module doesn't support this,
|
||||
so NVDA must provide its own implementation.
|
||||
"""
|
||||
if isinstance(translations, gettext.GNUTranslations):
|
||||
def pgettext(context, message):
|
||||
message = str(message)
|
||||
try:
|
||||
# Look up the message with its context.
|
||||
return translations._catalog["%s\x04%s" % (context, message)]
|
||||
except KeyError:
|
||||
return message
|
||||
else:
|
||||
def pgettext(context, message):
|
||||
return str(message)
|
||||
return pgettext
|
||||
|
||||
def setLanguage(lang):
|
||||
system = platform.system()
|
||||
global curLang
|
||||
try:
|
||||
if lang=="system":
|
||||
if system == "Windows":
|
||||
windowsLCID=ctypes.windll.kernel32.GetUserDefaultUILanguage()
|
||||
localeName=locale.windows_locale[windowsLCID]
|
||||
elif system == "Darwin":
|
||||
import Foundation
|
||||
localeName = Foundation.NSLocale.currentLocale().identifier()
|
||||
elif system == "Linux":
|
||||
localeName = locale.getdefaultlocale()[0]
|
||||
trans=gettext.translation(application.short_name, localedir=paths.locale_path(), languages=[localeName])
|
||||
curLang=localeName
|
||||
# else:
|
||||
# localeName=locale.getdefaultlocale()[0]
|
||||
# trans=gettext.translation('twblue', localedir=paths.locale_path(), languages=[localeName])
|
||||
# curLang=localeName
|
||||
system = platform.system()
|
||||
global curLang
|
||||
try:
|
||||
if lang=="system":
|
||||
if system == "Windows":
|
||||
windowsLCID=ctypes.windll.kernel32.GetUserDefaultUILanguage()
|
||||
localeName=locale.windows_locale[windowsLCID]
|
||||
elif system == "Darwin":
|
||||
import Foundation
|
||||
localeName = Foundation.NSLocale.currentLocale().identifier()
|
||||
elif system == "Linux":
|
||||
localeName = locale.getdefaultlocale()[0]
|
||||
trans=gettext.translation(application.short_name, localedir=paths.locale_path(), languages=[localeName])
|
||||
curLang=localeName
|
||||
# else:
|
||||
# localeName=locale.getdefaultlocale()[0]
|
||||
# trans=gettext.translation('twblue', localedir=paths.locale_path(), languages=[localeName])
|
||||
# curLang=localeName
|
||||
|
||||
else:
|
||||
trans=gettext.translation(application.short_name, localedir=paths.locale_path(), languages=[lang])
|
||||
curLang=lang
|
||||
localeChanged=False
|
||||
#Try setting Python's locale to lang
|
||||
# try:
|
||||
if system == "Windows":
|
||||
locale.setlocale(locale.LC_ALL, langToWindowsLocale(lang))
|
||||
localeChanged=True
|
||||
else:
|
||||
locale.setlocale(locale.LC_ALL, lang)
|
||||
localeChanged=True
|
||||
# except:
|
||||
# pass
|
||||
if not localeChanged and '_' in lang:
|
||||
#Python couldn'tsupport the language_country locale, just try language.
|
||||
try:
|
||||
locale.setlocale(locale.LC_ALL, lang.split('_')[0])
|
||||
except:
|
||||
pass
|
||||
#Set the windows locale for this thread (NVDA core) to this locale.
|
||||
if system == "Windows":
|
||||
LCID=localeNameToWindowsLCID(lang)
|
||||
ctypes.windll.kernel32.SetThreadLocale(LCID)
|
||||
except IOError:
|
||||
trans=gettext.translation(application.short_name, fallback=True)
|
||||
curLang="en"
|
||||
if sys.version[0] == "3":
|
||||
trans.install()
|
||||
else:
|
||||
trans.install(unicode=True)
|
||||
# Install our pgettext function.
|
||||
# __builtin__.__dict__["pgettext"] = makePgettext(trans)
|
||||
else:
|
||||
trans=gettext.translation(application.short_name, localedir=paths.locale_path(), languages=[lang])
|
||||
curLang=lang
|
||||
localeChanged=False
|
||||
#Try setting Python's locale to lang
|
||||
# try:
|
||||
if system == "Windows":
|
||||
locale.setlocale(locale.LC_ALL, langToWindowsLocale(lang))
|
||||
localeChanged=True
|
||||
else:
|
||||
locale.setlocale(locale.LC_ALL, lang)
|
||||
localeChanged=True
|
||||
# except:
|
||||
# pass
|
||||
if not localeChanged and '_' in lang:
|
||||
#Python couldn'tsupport the language_country locale, just try language.
|
||||
try:
|
||||
locale.setlocale(locale.LC_ALL, lang.split('_')[0])
|
||||
except:
|
||||
pass
|
||||
#Set the windows locale for this thread (NVDA core) to this locale.
|
||||
if system == "Windows":
|
||||
LCID=localeNameToWindowsLCID(lang)
|
||||
ctypes.windll.kernel32.SetThreadLocale(LCID)
|
||||
except IOError:
|
||||
trans=gettext.translation(application.short_name, fallback=True)
|
||||
curLang="en"
|
||||
if sys.version[0] == "3":
|
||||
trans.install()
|
||||
else:
|
||||
trans.install(unicode=True)
|
||||
# Install our pgettext function.
|
||||
# __builtin__.__dict__["pgettext"] = makePgettext(trans)
|
||||
|
||||
def getLanguage():
|
||||
return curLang
|
||||
return curLang
|
||||
|
||||
def normalizeLanguage(lang):
|
||||
"""
|
||||
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.
|
||||
"""
|
||||
lang=lang.replace('-','_')
|
||||
ld=lang.split('_')
|
||||
ld[0]=ld[0].lower()
|
||||
#Filter out meta languages such as x-western
|
||||
if ld[0]=='x':
|
||||
return None
|
||||
if len(ld)>=2:
|
||||
ld[1]=ld[1].upper()
|
||||
return "_".join(ld)
|
||||
"""
|
||||
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.
|
||||
"""
|
||||
lang=lang.replace('-','_')
|
||||
ld=lang.split('_')
|
||||
ld[0]=ld[0].lower()
|
||||
#Filter out meta languages such as x-western
|
||||
if ld[0]=='x':
|
||||
return None
|
||||
if len(ld)>=2:
|
||||
ld[1]=ld[1].upper()
|
||||
return "_".join(ld)
|
||||
|
||||
def langToWindowsLocale(lang):
|
||||
languages = {"en": "eng",
|
||||
"ar": "ara",
|
||||
"ca": "cat",
|
||||
languages = {"en": "eng",
|
||||
"ar": "ara",
|
||||
"ca": "cat",
|
||||
"de": "deu",
|
||||
"es": "esp",
|
||||
"fi": "fin",
|
||||
"fr": "fre_FRA",
|
||||
"gl": "glc",
|
||||
"eu": "euq",
|
||||
"hu": "hun",
|
||||
"hr": "hrv",
|
||||
"it": "ita",
|
||||
"ja": "jpn",
|
||||
"pl": "plk",
|
||||
"pt": "ptb",
|
||||
"ru": "rus",
|
||||
"tr": "trk",
|
||||
"sr": "eng",
|
||||
}
|
||||
return languages[lang]
|
||||
"es": "esp",
|
||||
"fi": "fin",
|
||||
"fr": "fre_FRA",
|
||||
"gl": "glc",
|
||||
"eu": "euq",
|
||||
"hu": "hun",
|
||||
"hr": "hrv",
|
||||
"it": "ita",
|
||||
"ja": "jpn",
|
||||
"pl": "plk",
|
||||
"pt": "ptb",
|
||||
"ru": "rus",
|
||||
"tr": "trk",
|
||||
"sr": "eng",
|
||||
}
|
||||
return languages[lang]
|
||||
|
82
src/main.py
82
src/main.py
@ -15,7 +15,7 @@ import logging
|
||||
import keys
|
||||
import application
|
||||
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 wxUI import commonMessages
|
||||
|
||||
@ -24,48 +24,48 @@ log = logging.getLogger("main")
|
||||
orig_session_init = None
|
||||
|
||||
def setup():
|
||||
global orig_session_init
|
||||
log.debug("Starting Socializer %s" % (application.version,))
|
||||
config.setup()
|
||||
if config.app["app-settings"]["debug_logging"] == True:
|
||||
logger.app_handler.setLevel(logging.DEBUG)
|
||||
log.info("Using %s %s" % (platform.system(), platform.architecture()[0]))
|
||||
log.debug("Application path is %s" % (paths.app_path(),))
|
||||
log.debug("config path is %s" % (paths.config_path(),))
|
||||
output.setup()
|
||||
languageHandler.setLanguage(config.app["app-settings"]["language"])
|
||||
log.debug("Language set to %s" % (languageHandler.getLanguage()))
|
||||
keys.setup()
|
||||
app = widgetUtils.mainLoopObject()
|
||||
if config.app["app-settings"]["first_start"]:
|
||||
log.debug("Detected first time execution.")
|
||||
proxy_option = commonMessages.proxy_question()
|
||||
if proxy_option == widgetUtils.YES:
|
||||
config.app["app-settings"]["use_proxy"] = True
|
||||
log.debug("User has requested to use proxy for connecting to VK.")
|
||||
config.app["app-settings"]["first_start"] = False
|
||||
config.app.write()
|
||||
if config.app["app-settings"]["use_proxy"]:
|
||||
log.debug("Enabling proxy support... ")
|
||||
import requests
|
||||
orig_session_init=requests.sessions.Session.__init__
|
||||
requests.sessions.Session.__init__=patched_session_init
|
||||
requests.Session.__init__=patched_session_init
|
||||
from controller import mainController
|
||||
from sessionmanager import sessionManager
|
||||
global orig_session_init
|
||||
log.debug("Starting Socializer %s" % (application.version,))
|
||||
config.setup()
|
||||
if config.app["app-settings"]["debug_logging"] == True:
|
||||
logger.app_handler.setLevel(logging.DEBUG)
|
||||
log.info("Using %s %s" % (platform.system(), platform.architecture()[0]))
|
||||
log.debug("Application path is %s" % (paths.app_path(),))
|
||||
log.debug("config path is %s" % (paths.config_path(),))
|
||||
output.setup()
|
||||
languageHandler.setLanguage(config.app["app-settings"]["language"])
|
||||
log.debug("Language set to %s" % (languageHandler.getLanguage()))
|
||||
keys.setup()
|
||||
app = widgetUtils.mainLoopObject()
|
||||
if config.app["app-settings"]["first_start"]:
|
||||
log.debug("Detected first time execution.")
|
||||
proxy_option = commonMessages.proxy_question()
|
||||
if proxy_option == widgetUtils.YES:
|
||||
config.app["app-settings"]["use_proxy"] = True
|
||||
log.debug("User has requested to use proxy for connecting to VK.")
|
||||
config.app["app-settings"]["first_start"] = False
|
||||
config.app.write()
|
||||
if config.app["app-settings"]["use_proxy"]:
|
||||
log.debug("Enabling proxy support... ")
|
||||
import requests
|
||||
orig_session_init=requests.sessions.Session.__init__
|
||||
requests.sessions.Session.__init__=patched_session_init
|
||||
requests.Session.__init__=patched_session_init
|
||||
from controller import mainController
|
||||
from sessionmanager import sessionManager
|
||||
|
||||
log.debug("Created Application mainloop object")
|
||||
sm = sessionManager.sessionManagerController()
|
||||
sm.show()
|
||||
del sm
|
||||
r = mainController.Controller()
|
||||
call_threaded(r.login)
|
||||
app.run()
|
||||
log.debug("Created Application mainloop object")
|
||||
sm = sessionManager.sessionManagerController()
|
||||
sm.show()
|
||||
del sm
|
||||
r = mainController.Controller()
|
||||
call_threaded(r.login)
|
||||
app.run()
|
||||
|
||||
def patched_session_init(self):
|
||||
global orig_session_init
|
||||
orig_session_init(self)
|
||||
self.proxies={"http": "http://socializer:socializer@socializer.su:3128",
|
||||
"https": "http://socializer:socializer@socializer.su:3128"}
|
||||
global orig_session_init
|
||||
orig_session_init(self)
|
||||
self.proxies={"http": "http://socializer:socializer@socializer.su:3128",
|
||||
"https": "http://socializer:socializer@socializer.su:3128"}
|
||||
|
||||
setup()
|
||||
|
@ -5,14 +5,13 @@ import logging
|
||||
log = logging.getLogger("mysc.localization")
|
||||
|
||||
def get(rootFolder):
|
||||
log.debug("Getting documentation folder. RootFolder: %s" % (rootFolder,))
|
||||
defaultLocale = languageHandler.curLang
|
||||
if len(defaultLocale) > 2:
|
||||
defaultLocale = defaultLocale[:2]
|
||||
log.debug("Locale: %s" % (defaultLocale,))
|
||||
if os.path.exists(rootFolder+"/"+defaultLocale):
|
||||
return defaultLocale
|
||||
else:
|
||||
log.debug("The folder does not exist, using the English folder...")
|
||||
return "en"
|
||||
|
||||
log.debug("Getting documentation folder. RootFolder: %s" % (rootFolder,))
|
||||
defaultLocale = languageHandler.curLang
|
||||
if len(defaultLocale) > 2:
|
||||
defaultLocale = defaultLocale[:2]
|
||||
log.debug("Locale: %s" % (defaultLocale,))
|
||||
if os.path.exists(rootFolder+"/"+defaultLocale):
|
||||
return defaultLocale
|
||||
else:
|
||||
log.debug("The folder does not exist, using the English folder...")
|
||||
return "en"
|
||||
|
@ -4,34 +4,34 @@ import logging
|
||||
log = logging.getLogger("mysc.repeating_timer")
|
||||
|
||||
class RepeatingTimer(threading.Thread):
|
||||
"""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
|
||||
"""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
|
||||
|
||||
t = RepeatingTimer(30.0, f, args=[], kwargs={})
|
||||
t.start()
|
||||
t.cancel() # stop the timer's actions
|
||||
"""
|
||||
t = RepeatingTimer(30.0, f, args=[], kwargs={})
|
||||
t.start()
|
||||
t.cancel() # stop the timer's actions
|
||||
"""
|
||||
|
||||
def __init__(self, interval, function, daemon=True, *args, **kwargs):
|
||||
threading.Thread.__init__(self)
|
||||
self.daemon = daemon
|
||||
self.interval = float(interval)
|
||||
self.function = function
|
||||
self.args = args
|
||||
self.kwargs = kwargs
|
||||
self.finished = threading.Event()
|
||||
def __init__(self, interval, function, daemon=True, *args, **kwargs):
|
||||
threading.Thread.__init__(self)
|
||||
self.daemon = daemon
|
||||
self.interval = float(interval)
|
||||
self.function = function
|
||||
self.args = args
|
||||
self.kwargs = kwargs
|
||||
self.finished = threading.Event()
|
||||
|
||||
def cancel(self):
|
||||
"""Stop the timer if it hasn't finished yet"""
|
||||
log.debug("Stopping repeater for %s" % (self.function,))
|
||||
self.finished.set()
|
||||
stop = cancel
|
||||
def cancel(self):
|
||||
"""Stop the timer if it hasn't finished yet"""
|
||||
log.debug("Stopping repeater for %s" % (self.function,))
|
||||
self.finished.set()
|
||||
stop = cancel
|
||||
|
||||
def run(self):
|
||||
while not self.finished.is_set():
|
||||
self.finished.wait(self.interval)
|
||||
if not self.finished.is_set(): #In case someone has canceled while waiting
|
||||
try:
|
||||
self.function(*self.args, **self.kwargs)
|
||||
except:
|
||||
log.exception("Execution failed. Function: %r args: %r and kwargs: %r" % (self.function, self.args, self.kwargs))
|
||||
def run(self):
|
||||
while not self.finished.is_set():
|
||||
self.finished.wait(self.interval)
|
||||
if not self.finished.is_set(): #In case someone has canceled while waiting
|
||||
try:
|
||||
self.function(*self.args, **self.kwargs)
|
||||
except:
|
||||
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
|
||||
|
||||
def restart_program():
|
||||
""" Function that restarts the application if is executed."""
|
||||
args = sys.argv[:]
|
||||
if not hasattr(sys, "frozen"):
|
||||
args.insert(0, sys.executable)
|
||||
if sys.platform == 'win32':
|
||||
args = ['"%s"' % arg for arg in args]
|
||||
os.execv(sys.executable, args)
|
||||
""" Function that restarts the application if is executed."""
|
||||
args = sys.argv[:]
|
||||
if not hasattr(sys, "frozen"):
|
||||
args.insert(0, sys.executable)
|
||||
if sys.platform == 'win32':
|
||||
args = ['"%s"' % arg for arg in args]
|
||||
os.execv(sys.executable, args)
|
||||
|
@ -5,13 +5,13 @@ standard_library.install_aliases()
|
||||
import threading
|
||||
|
||||
def call_threaded(func, *args, **kwargs):
|
||||
#Call the given function in a daemonized thread and return the thread.
|
||||
def new_func(*a, **k):
|
||||
#Call the given function in a daemonized thread and return the thread.
|
||||
def new_func(*a, **k):
|
||||
# try:
|
||||
func(*a, **k)
|
||||
func(*a, **k)
|
||||
# except:
|
||||
# pass
|
||||
thread = threading.Thread(target=new_func, args=args, kwargs=kwargs)
|
||||
thread.daemon = True
|
||||
thread.start()
|
||||
return thread
|
||||
thread = threading.Thread(target=new_func, args=args, kwargs=kwargs)
|
||||
thread.daemon = True
|
||||
thread.start()
|
||||
return thread
|
||||
|
@ -9,34 +9,34 @@ speaker = None
|
||||
retries = 0
|
||||
|
||||
def speak(text, interrupt=0):
|
||||
global speaker, retries
|
||||
if not speaker:
|
||||
setup()
|
||||
try:
|
||||
speaker.speak(text, interrupt)
|
||||
except:
|
||||
if retries < 5:
|
||||
retries = retries + 1
|
||||
speak(text)
|
||||
global speaker, retries
|
||||
if not speaker:
|
||||
setup()
|
||||
try:
|
||||
speaker.speak(text, interrupt)
|
||||
except:
|
||||
if retries < 5:
|
||||
retries = retries + 1
|
||||
speak(text)
|
||||
# speaker.braille(text)
|
||||
|
||||
def setup ():
|
||||
global speaker
|
||||
logger.debug("Initializing output subsystem.")
|
||||
try:
|
||||
global speaker
|
||||
logger.debug("Initializing output subsystem.")
|
||||
try:
|
||||
# speaker = speech.Speaker(speech.outputs.Sapi5())
|
||||
# else:
|
||||
speaker = outputs.auto.Auto()
|
||||
except:
|
||||
logger.exception("Output: Error during initialization.")
|
||||
speaker = outputs.auto.Auto()
|
||||
except:
|
||||
logger.exception("Output: Error during initialization.")
|
||||
|
||||
def enable_sapi():
|
||||
speaker = outputs.sapi.SAPI5()
|
||||
speaker = outputs.sapi.SAPI5()
|
||||
|
||||
def copy(text):
|
||||
import win32clipboard
|
||||
#Copies text to the clipboard.
|
||||
win32clipboard.OpenClipboard()
|
||||
win32clipboard.EmptyClipboard()
|
||||
win32clipboard.SetClipboardText(text)
|
||||
win32clipboard.CloseClipboard()
|
||||
import win32clipboard
|
||||
#Copies text to the clipboard.
|
||||
win32clipboard.OpenClipboard()
|
||||
win32clipboard.EmptyClipboard()
|
||||
win32clipboard.SetClipboardText(text)
|
||||
win32clipboard.CloseClipboard()
|
||||
|
82
src/paths.py
82
src/paths.py
@ -15,58 +15,58 @@ fsencoding = sys.getfilesystemencoding()
|
||||
|
||||
#log = logging.getLogger("paths")
|
||||
if len(glob.glob("Uninstall.exe")) > 0: # installed copy
|
||||
mode= "installed"
|
||||
mode= "installed"
|
||||
|
||||
def app_path():
|
||||
return paths_.app_path()
|
||||
return paths_.app_path()
|
||||
|
||||
def config_path():
|
||||
global mode, directory
|
||||
if mode == "portable":
|
||||
if directory != None: path = os.path.join(directory, "config")
|
||||
elif directory == None: path = os.path.join(app_path(), "config")
|
||||
elif mode == "installed":
|
||||
path = os.path.join(data_path(), "config")
|
||||
if not os.path.exists(path):
|
||||
# log.debug("%s path does not exist, creating..." % (path,))
|
||||
os.mkdir(path)
|
||||
return path
|
||||
global mode, directory
|
||||
if mode == "portable":
|
||||
if directory != None: path = os.path.join(directory, "config")
|
||||
elif directory == None: path = os.path.join(app_path(), "config")
|
||||
elif mode == "installed":
|
||||
path = os.path.join(data_path(), "config")
|
||||
if not os.path.exists(path):
|
||||
# log.debug("%s path does not exist, creating..." % (path,))
|
||||
os.mkdir(path)
|
||||
return path
|
||||
|
||||
def logs_path():
|
||||
global mode, directory
|
||||
if mode == "portable":
|
||||
if directory != None: path = os.path.join(directory, "logs")
|
||||
elif directory == None: path = os.path.join(app_path(), "logs")
|
||||
elif mode == "installed":
|
||||
path = os.path.join(data_path(), "logs")
|
||||
if not os.path.exists(path):
|
||||
# log.debug("%s path does not exist, creating..." % (path,))
|
||||
os.mkdir(path)
|
||||
return path
|
||||
global mode, directory
|
||||
if mode == "portable":
|
||||
if directory != None: path = os.path.join(directory, "logs")
|
||||
elif directory == None: path = os.path.join(app_path(), "logs")
|
||||
elif mode == "installed":
|
||||
path = os.path.join(data_path(), "logs")
|
||||
if not os.path.exists(path):
|
||||
# log.debug("%s path does not exist, creating..." % (path,))
|
||||
os.mkdir(path)
|
||||
return path
|
||||
|
||||
def data_path(app_name='socializer'):
|
||||
if platform.system() == "Windows":
|
||||
data_path = os.path.join(os.getenv("AppData"), app_name)
|
||||
else:
|
||||
data_path = os.path.join(os.environ['HOME'], ".%s" % app_name)
|
||||
if not os.path.exists(data_path):
|
||||
os.mkdir(data_path)
|
||||
return data_path
|
||||
if platform.system() == "Windows":
|
||||
data_path = os.path.join(os.getenv("AppData"), app_name)
|
||||
else:
|
||||
data_path = os.path.join(os.environ['HOME'], ".%s" % app_name)
|
||||
if not os.path.exists(data_path):
|
||||
os.mkdir(data_path)
|
||||
return data_path
|
||||
|
||||
def locale_path():
|
||||
return os.path.join(app_path(), "locales")
|
||||
return os.path.join(app_path(), "locales")
|
||||
|
||||
def sound_path():
|
||||
return os.path.join(app_path(), "sounds")
|
||||
return os.path.join(app_path(), "sounds")
|
||||
|
||||
def com_path():
|
||||
global mode, directory
|
||||
if mode == "portable":
|
||||
if directory != None: path = os.path.join(directory, "com_cache")
|
||||
elif directory == None: path = os.path.join(app_path(), "com_cache")
|
||||
elif mode == "installed":
|
||||
path = os.path.join(data_path(), "com_cache")
|
||||
if not os.path.exists(path):
|
||||
# log.debug("%s path does not exist, creating..." % (path,))
|
||||
os.mkdir(path)
|
||||
return path
|
||||
global mode, directory
|
||||
if mode == "portable":
|
||||
if directory != None: path = os.path.join(directory, "com_cache")
|
||||
elif directory == None: path = os.path.join(app_path(), "com_cache")
|
||||
elif mode == "installed":
|
||||
path = os.path.join(data_path(), "com_cache")
|
||||
if not os.path.exists(path):
|
||||
# log.debug("%s path does not exist, creating..." % (path,))
|
||||
os.mkdir(path)
|
||||
return path
|
||||
|
@ -1,15 +1,15 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
""" 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.
|
||||
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:
|
||||
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.
|
||||
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).
|
||||
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.
|
||||
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.
|
||||
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.
|
||||
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.
|
||||
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.
|
||||
|
||||
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 .base import *
|
||||
@ -19,4 +19,4 @@ from .blacklist import *
|
||||
from .createPosts import *
|
||||
from .displayPosts import *
|
||||
from .configuration import *
|
||||
from .profiles import *
|
||||
from .profiles import *
|
||||
|
@ -1,19 +1,19 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
""" 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.
|
||||
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:
|
||||
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.
|
||||
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).
|
||||
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.
|
||||
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.
|
||||
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.
|
||||
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.
|
||||
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.
|
||||
|
||||
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 .audioRecorder import *
|
||||
from .postCreation import *
|
||||
from .postDisplayer import *
|
||||
from .configuration import *
|
||||
from .profiles import *
|
||||
from .profiles import *
|
||||
|
@ -15,109 +15,109 @@ from . import audioRecorder, base
|
||||
log = logging.getLogger(__file__)
|
||||
|
||||
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).
|
||||
* 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.
|
||||
* 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).
|
||||
* 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):
|
||||
""" Constructor.
|
||||
@ 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.
|
||||
"""
|
||||
super(attachPresenter, self).__init__(view=view, interactor=interactor, modulename="attach")
|
||||
self.session = session
|
||||
# Self.attachments will hold a reference to all attachments added to the dialog.
|
||||
self.attachments = list()
|
||||
self.run()
|
||||
def __init__(self, session, view, interactor, voice_messages=False):
|
||||
""" Constructor.
|
||||
@ 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.
|
||||
"""
|
||||
super(attachPresenter, self).__init__(view=view, interactor=interactor, modulename="attach")
|
||||
self.session = session
|
||||
# Self.attachments will hold a reference to all attachments added to the dialog.
|
||||
self.attachments = list()
|
||||
self.run()
|
||||
|
||||
def upload_image(self, image, description):
|
||||
""" allows uploading an image from the computer. Description will be used when posting to VK.
|
||||
"""
|
||||
imageInfo = {"type": "photo", "file": image, "description": description, "from": "local"}
|
||||
self.attachments.append(imageInfo)
|
||||
# Translators: This is the text displayed in the attachments dialog, when the user adds a photo.
|
||||
info = [_("Photo"), description]
|
||||
self.send_message("insert_attachment", attachment=info)
|
||||
self.send_message("enable_control", control="remove")
|
||||
def upload_image(self, image, description):
|
||||
""" allows uploading an image from the computer. Description will be used when posting to VK.
|
||||
"""
|
||||
imageInfo = {"type": "photo", "file": image, "description": description, "from": "local"}
|
||||
self.attachments.append(imageInfo)
|
||||
# Translators: This is the text displayed in the attachments dialog, when the user adds a photo.
|
||||
info = [_("Photo"), description]
|
||||
self.send_message("insert_attachment", attachment=info)
|
||||
self.send_message("enable_control", control="remove")
|
||||
|
||||
def upload_audio(self, audio):
|
||||
""" Allows uploading an audio file from the computer. Only mp3 files are supported. """
|
||||
if audio != None:
|
||||
# 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.
|
||||
try:
|
||||
audio_tags = ID3(audio)
|
||||
if "TIT2" in audio_tags:
|
||||
title = audio_tags["TIT2"].text[0]
|
||||
else:
|
||||
title = _("Untitled")
|
||||
if "TPE1" in audio_tags:
|
||||
artist = audio_tags["TPE1"].text[0]
|
||||
else:
|
||||
artist = _("Unknown artist")
|
||||
except ID3NoHeaderError: # File doesn't include ID3 tags so let's assume unknown artist.
|
||||
artist = _("Unknown artist")
|
||||
title = os.path.basename(audio).replace(".mp3", "")
|
||||
audioInfo = {"type": "audio", "file": audio, "from": "local", "title": title, "artist": artist}
|
||||
self.attachments.append(audioInfo)
|
||||
# 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)]
|
||||
self.send_message("insert_attachment", attachment=info)
|
||||
self.send_message("enable_control", control="remove")
|
||||
def upload_audio(self, audio):
|
||||
""" Allows uploading an audio file from the computer. Only mp3 files are supported. """
|
||||
if audio != None:
|
||||
# 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.
|
||||
try:
|
||||
audio_tags = ID3(audio)
|
||||
if "TIT2" in audio_tags:
|
||||
title = audio_tags["TIT2"].text[0]
|
||||
else:
|
||||
title = _("Untitled")
|
||||
if "TPE1" in audio_tags:
|
||||
artist = audio_tags["TPE1"].text[0]
|
||||
else:
|
||||
artist = _("Unknown artist")
|
||||
except ID3NoHeaderError: # File doesn't include ID3 tags so let's assume unknown artist.
|
||||
artist = _("Unknown artist")
|
||||
title = os.path.basename(audio).replace(".mp3", "")
|
||||
audioInfo = {"type": "audio", "file": audio, "from": "local", "title": title, "artist": artist}
|
||||
self.attachments.append(audioInfo)
|
||||
# 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)]
|
||||
self.send_message("insert_attachment", attachment=info)
|
||||
self.send_message("enable_control", control="remove")
|
||||
|
||||
def upload_document(self, document):
|
||||
""" allows uploading a document from the computer.
|
||||
"""
|
||||
doc_info = {"type": "document", "file": document, "from": "local", "title": os.path.basename(os.path.splitext(document)[0])}
|
||||
self.attachments.append(doc_info)
|
||||
# Translators: This is the text displayed in the attachments dialog, when the user adds a document.
|
||||
info = [_("Document"), os.path.basename(document)]
|
||||
self.send_message("insert_attachment", attachment=info)
|
||||
self.send_message("enable_control", control="remove")
|
||||
def upload_document(self, document):
|
||||
""" allows uploading a document from the computer.
|
||||
"""
|
||||
doc_info = {"type": "document", "file": document, "from": "local", "title": os.path.basename(os.path.splitext(document)[0])}
|
||||
self.attachments.append(doc_info)
|
||||
# Translators: This is the text displayed in the attachments dialog, when the user adds a document.
|
||||
info = [_("Document"), os.path.basename(document)]
|
||||
self.send_message("insert_attachment", attachment=info)
|
||||
self.send_message("enable_control", control="remove")
|
||||
|
||||
def upload_voice_message(self):
|
||||
a = audioRecorder.audioRecorderPresenter(view=views.audioRecorderDialog(), interactor=interactors.audioRecorderInteractor())
|
||||
if a.file != None and a.duration != 0:
|
||||
audioInfo = {"type": "voice_message", "file": a.file, "from": "local"}
|
||||
self.attachments.append(audioInfo)
|
||||
# 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,)]
|
||||
self.send_message("insert_attachment", attachment=info)
|
||||
self.send_message("enable_control", control="remove")
|
||||
def upload_voice_message(self):
|
||||
a = audioRecorder.audioRecorderPresenter(view=views.audioRecorderDialog(), interactor=interactors.audioRecorderInteractor())
|
||||
if a.file != None and a.duration != 0:
|
||||
audioInfo = {"type": "voice_message", "file": a.file, "from": "local"}
|
||||
self.attachments.append(audioInfo)
|
||||
# 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,)]
|
||||
self.send_message("insert_attachment", attachment=info)
|
||||
self.send_message("enable_control", control="remove")
|
||||
|
||||
####### ToDo: replace this with selector presenter when finished.
|
||||
def get_available_audios(self):
|
||||
# Let's reuse the already downloaded audios.
|
||||
list_of_audios = self.session.db["me_audio"]["items"]
|
||||
audios = []
|
||||
for i in list_of_audios:
|
||||
audios.append("{0}, {1}".format(i["title"], i["artist"]))
|
||||
return audios
|
||||
####### ToDo: replace this with selector presenter when finished.
|
||||
def get_available_audios(self):
|
||||
# Let's reuse the already downloaded audios.
|
||||
list_of_audios = self.session.db["me_audio"]["items"]
|
||||
audios = []
|
||||
for i in list_of_audios:
|
||||
audios.append("{0}, {1}".format(i["title"], i["artist"]))
|
||||
return audios
|
||||
|
||||
def take_audios(self, audios_list):
|
||||
list_of_audios = self.session.db["me_audio"]["items"]
|
||||
for i in audios_list:
|
||||
info = dict(type="audio", id=list_of_audios[i]["id"], owner_id=list_of_audios[i]["owner_id"])
|
||||
info["from"] = "online"
|
||||
self.attachments.append(info)
|
||||
# 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"])]
|
||||
self.send_message("insert_attachment", attachment=info2)
|
||||
self.check_remove_status()
|
||||
def take_audios(self, audios_list):
|
||||
list_of_audios = self.session.db["me_audio"]["items"]
|
||||
for i in audios_list:
|
||||
info = dict(type="audio", id=list_of_audios[i]["id"], owner_id=list_of_audios[i]["owner_id"])
|
||||
info["from"] = "online"
|
||||
self.attachments.append(info)
|
||||
# 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"])]
|
||||
self.send_message("insert_attachment", attachment=info2)
|
||||
self.check_remove_status()
|
||||
|
||||
def remove_attachment(self, item_index):
|
||||
""" Remove the currently focused item from the attachments list."""
|
||||
log.debug("Removing item %d" % (item_index,))
|
||||
if item_index == -1: item_index = 0
|
||||
self.attachments.pop(item_index)
|
||||
self.send_message("remove_attachment", attachment=item_index)
|
||||
self.check_remove_status()
|
||||
log.debug("Removed")
|
||||
def remove_attachment(self, item_index):
|
||||
""" Remove the currently focused item from the attachments list."""
|
||||
log.debug("Removing item %d" % (item_index,))
|
||||
if item_index == -1: item_index = 0
|
||||
self.attachments.pop(item_index)
|
||||
self.send_message("remove_attachment", attachment=item_index)
|
||||
self.check_remove_status()
|
||||
log.debug("Removed")
|
||||
|
||||
def check_remove_status(self):
|
||||
""" Checks whether the remove button should remain enabled."""
|
||||
if len(self.attachments) == 0:
|
||||
self.send_message("disable_control", control="remove")
|
||||
def check_remove_status(self):
|
||||
""" Checks whether the remove button should remain enabled."""
|
||||
if len(self.attachments) == 0:
|
||||
self.send_message("disable_control", control="remove")
|
||||
|
@ -10,102 +10,102 @@ from mysc.thread_utils import call_threaded
|
||||
from . import base
|
||||
|
||||
class audioRecorderPresenter(base.basePresenter):
|
||||
def __init__(self, view, interactor):
|
||||
super(audioRecorderPresenter, self).__init__(view=view, interactor=interactor, modulename="audiorecorder")
|
||||
self.recorded = False
|
||||
self.recording = None
|
||||
self.duration = 0
|
||||
self.playing = None
|
||||
self.file = None
|
||||
self.run()
|
||||
def __init__(self, view, interactor):
|
||||
super(audioRecorderPresenter, self).__init__(view=view, interactor=interactor, modulename="audiorecorder")
|
||||
self.recorded = False
|
||||
self.recording = None
|
||||
self.duration = 0
|
||||
self.playing = None
|
||||
self.file = None
|
||||
self.run()
|
||||
|
||||
def toggle_recording(self, *args, **kwargs):
|
||||
if self.recording != None:
|
||||
self.stop_recording()
|
||||
else:
|
||||
self.start_recording()
|
||||
def toggle_recording(self, *args, **kwargs):
|
||||
if self.recording != None:
|
||||
self.stop_recording()
|
||||
else:
|
||||
self.start_recording()
|
||||
|
||||
def start_recording(self):
|
||||
self.file = tempfile.mktemp(suffix='.wav')
|
||||
self.recording = sound.get_recording(self.file)
|
||||
self.duration = time.time()
|
||||
self.recording.play()
|
||||
self.send_message("set_label", control="record", label=_("&Stop"))
|
||||
output.speak(_("Recording"))
|
||||
self.send_message("disable_control", control="ok")
|
||||
def start_recording(self):
|
||||
self.file = tempfile.mktemp(suffix='.wav')
|
||||
self.recording = sound.get_recording(self.file)
|
||||
self.duration = time.time()
|
||||
self.recording.play()
|
||||
self.send_message("set_label", control="record", label=_("&Stop"))
|
||||
output.speak(_("Recording"))
|
||||
self.send_message("disable_control", control="ok")
|
||||
|
||||
def stop_recording(self):
|
||||
self.recording.stop()
|
||||
self.duration = int(time.time()-self.duration)
|
||||
self.recording.free()
|
||||
output.speak(_("Stopped"))
|
||||
self.recorded = True
|
||||
self.send_message("set_label", control="record", label=_("&Record"))
|
||||
self.send_message("disable_control", control="record")
|
||||
self.send_message("enable_control", control="play")
|
||||
self.send_message("enable_control", control="discard")
|
||||
self.send_message("enable_control", control="ok")
|
||||
self.send_message("focus_control", control="play")
|
||||
def stop_recording(self):
|
||||
self.recording.stop()
|
||||
self.duration = int(time.time()-self.duration)
|
||||
self.recording.free()
|
||||
output.speak(_("Stopped"))
|
||||
self.recorded = True
|
||||
self.send_message("set_label", control="record", label=_("&Record"))
|
||||
self.send_message("disable_control", control="record")
|
||||
self.send_message("enable_control", control="play")
|
||||
self.send_message("enable_control", control="discard")
|
||||
self.send_message("enable_control", control="ok")
|
||||
self.send_message("focus_control", control="play")
|
||||
|
||||
def discard_recording(self, *args, **kwargs):
|
||||
if self.playing:
|
||||
self._stop()
|
||||
if self.recording != None:
|
||||
self.cleanup()
|
||||
self.send_message("disable_control", control="play")
|
||||
self.send_message("disable_control", control="ok")
|
||||
self.file = None
|
||||
self.send_message("enable_control", control="record")
|
||||
self.send_message("focus_control", control="record")
|
||||
self.send_message("disable_control", control="discard")
|
||||
self.recording = None
|
||||
output.speak(_("Discarded"))
|
||||
def discard_recording(self, *args, **kwargs):
|
||||
if self.playing:
|
||||
self._stop()
|
||||
if self.recording != None:
|
||||
self.cleanup()
|
||||
self.send_message("disable_control", control="play")
|
||||
self.send_message("disable_control", control="ok")
|
||||
self.file = None
|
||||
self.send_message("enable_control", control="record")
|
||||
self.send_message("focus_control", control="record")
|
||||
self.send_message("disable_control", control="discard")
|
||||
self.recording = None
|
||||
output.speak(_("Discarded"))
|
||||
|
||||
def play(self, *args, **kwargs):
|
||||
if not self.playing:
|
||||
call_threaded(self._play)
|
||||
else:
|
||||
self._stop()
|
||||
def play(self, *args, **kwargs):
|
||||
if not self.playing:
|
||||
call_threaded(self._play)
|
||||
else:
|
||||
self._stop()
|
||||
|
||||
def _play(self):
|
||||
output.speak(_("Playing..."))
|
||||
def _play(self):
|
||||
output.speak(_("Playing..."))
|
||||
# try:
|
||||
self.playing = sound_lib.stream.FileStream(file=str(self.file), flags=sound_lib.stream.BASS_UNICODE)
|
||||
self.playing.play()
|
||||
self.send_message("set_label", control="play", label=_("&Stop"))
|
||||
try:
|
||||
while self.playing.is_playing:
|
||||
pass
|
||||
self.send_message("set_label", control="play", label=_("&Play"))
|
||||
self.playing.free()
|
||||
self.playing = None
|
||||
except:
|
||||
pass
|
||||
self.playing = sound_lib.stream.FileStream(file=str(self.file), flags=sound_lib.stream.BASS_UNICODE)
|
||||
self.playing.play()
|
||||
self.send_message("set_label", control="play", label=_("&Stop"))
|
||||
try:
|
||||
while self.playing.is_playing:
|
||||
pass
|
||||
self.send_message("set_label", control="play", label=_("&Play"))
|
||||
self.playing.free()
|
||||
self.playing = None
|
||||
except:
|
||||
pass
|
||||
|
||||
def _stop(self):
|
||||
output.speak(_("Stopped"))
|
||||
self.playing.stop()
|
||||
self.playing.free()
|
||||
self.send_message("set_label", control="play", label=_("&Play"))
|
||||
self.playing = None
|
||||
def _stop(self):
|
||||
output.speak(_("Stopped"))
|
||||
self.playing.stop()
|
||||
self.playing.free()
|
||||
self.send_message("set_label", control="play", label=_("&Play"))
|
||||
self.playing = None
|
||||
|
||||
def postprocess(self):
|
||||
if self.file.lower().endswith('.wav'):
|
||||
output.speak(_("Recoding audio..."))
|
||||
sound.recode_audio(self.file)
|
||||
self.wav_file = self.file
|
||||
self.file = '%s.ogg' % self.file[:-4]
|
||||
self.cleanup()
|
||||
def postprocess(self):
|
||||
if self.file.lower().endswith('.wav'):
|
||||
output.speak(_("Recoding audio..."))
|
||||
sound.recode_audio(self.file)
|
||||
self.wav_file = self.file
|
||||
self.file = '%s.ogg' % self.file[:-4]
|
||||
self.cleanup()
|
||||
|
||||
def cleanup(self):
|
||||
if self.playing and self.playing.is_playing:
|
||||
self.playing.stop()
|
||||
if self.recording != None:
|
||||
if self.recording.is_playing:
|
||||
self.recording.stop()
|
||||
try:
|
||||
self.recording.free()
|
||||
except:
|
||||
pass
|
||||
if hasattr(self, 'wav_file'):
|
||||
os.remove(self.wav_file)
|
||||
def cleanup(self):
|
||||
if self.playing and self.playing.is_playing:
|
||||
self.playing.stop()
|
||||
if self.recording != None:
|
||||
if self.recording.is_playing:
|
||||
self.recording.stop()
|
||||
try:
|
||||
self.recording.free()
|
||||
except:
|
||||
pass
|
||||
if hasattr(self, 'wav_file'):
|
||||
os.remove(self.wav_file)
|
||||
|
@ -5,15 +5,15 @@ from interactors import configuration as interactor
|
||||
|
||||
class basePresenter(object):
|
||||
|
||||
def __init__(self, view, interactor, modulename):
|
||||
self.modulename = modulename
|
||||
self.interactor = interactor
|
||||
self.view = view
|
||||
self.interactor.install(view=view, presenter=self, modulename=modulename)
|
||||
def __init__(self, view, interactor, modulename):
|
||||
self.modulename = modulename
|
||||
self.interactor = interactor
|
||||
self.view = view
|
||||
self.interactor.install(view=view, presenter=self, modulename=modulename)
|
||||
|
||||
def run(self):
|
||||
self.interactor.start()
|
||||
self.interactor.uninstall()
|
||||
def run(self):
|
||||
self.interactor.start()
|
||||
self.interactor.uninstall()
|
||||
|
||||
def send_message(self, msg, *args, **kwargs):
|
||||
pub.sendMessage(self.modulename+"_"+msg, *args, **kwargs)
|
||||
def send_message(self, msg, *args, **kwargs):
|
||||
pub.sendMessage(self.modulename+"_"+msg, *args, **kwargs)
|
||||
|
@ -5,26 +5,26 @@ from . import base
|
||||
|
||||
class blacklistPresenter(base.basePresenter):
|
||||
|
||||
def __init__(self, session, view, interactor):
|
||||
self.session = session
|
||||
super(blacklistPresenter, self).__init__(view=view, interactor=interactor, modulename="blacklist")
|
||||
self.worker = threading.Thread(target=self.load_information)
|
||||
self.worker.finished = threading.Event()
|
||||
self.worker.start()
|
||||
self.run()
|
||||
def __init__(self, session, view, interactor):
|
||||
self.session = session
|
||||
super(blacklistPresenter, self).__init__(view=view, interactor=interactor, modulename="blacklist")
|
||||
self.worker = threading.Thread(target=self.load_information)
|
||||
self.worker.finished = threading.Event()
|
||||
self.worker.start()
|
||||
self.run()
|
||||
|
||||
def load_information(self):
|
||||
banned_users = self.session.vk.client.account.getBanned(count=200)
|
||||
self.users = banned_users["profiles"]
|
||||
items = []
|
||||
for i in self.users:
|
||||
str_user = "{first_name} {last_name}".format(first_name=i["first_name"], last_name=i["last_name"])
|
||||
items.append([str_user])
|
||||
self.send_message("add_items", control="persons", items=items)
|
||||
def load_information(self):
|
||||
banned_users = self.session.vk.client.account.getBanned(count=200)
|
||||
self.users = banned_users["profiles"]
|
||||
items = []
|
||||
for i in self.users:
|
||||
str_user = "{first_name} {last_name}".format(first_name=i["first_name"], last_name=i["last_name"])
|
||||
items.append([str_user])
|
||||
self.send_message("add_items", control="persons", items=items)
|
||||
|
||||
def unblock_person(self, item):
|
||||
result = self.session.vk.client.account.unban(owner_id=self.users[item]["id"])
|
||||
if result == 1:
|
||||
msg = _("You've unblocked {user1_nom} from your friends.").format(**self.session.get_user(self.users[item]["id"]),)
|
||||
pub.sendMessage("notify", message=msg)
|
||||
return result
|
||||
def unblock_person(self, item):
|
||||
result = self.session.vk.client.account.unban(owner_id=self.users[item]["id"])
|
||||
if result == 1:
|
||||
msg = _("You've unblocked {user1_nom} from your friends.").format(**self.session.get_user(self.users[item]["id"]),)
|
||||
pub.sendMessage("notify", message=msg)
|
||||
return result
|
||||
|
@ -8,97 +8,97 @@ from . import base
|
||||
|
||||
class configurationPresenter(base.basePresenter):
|
||||
|
||||
def __init__(self, session, view, interactor):
|
||||
self.session = session
|
||||
super(configurationPresenter, self).__init__(view=view, interactor=interactor, modulename="configuration")
|
||||
# Control requirement for a restart of the application.
|
||||
self.needs_restart = False
|
||||
self.create_config()
|
||||
self.run()
|
||||
def __init__(self, session, view, interactor):
|
||||
self.session = session
|
||||
super(configurationPresenter, self).__init__(view=view, interactor=interactor, modulename="configuration")
|
||||
# Control requirement for a restart of the application.
|
||||
self.needs_restart = False
|
||||
self.create_config()
|
||||
self.run()
|
||||
|
||||
def get_notification_label(self, value):
|
||||
if value == "native":
|
||||
return _("Native")
|
||||
else:
|
||||
return _("Custom")
|
||||
def get_notification_label(self, value):
|
||||
if value == "native":
|
||||
return _("Native")
|
||||
else:
|
||||
return _("Custom")
|
||||
|
||||
def get_update_channel_label(self, value):
|
||||
if value == "stable":
|
||||
return _("Stable")
|
||||
elif value == "weekly":
|
||||
return _("Weekly")
|
||||
else:
|
||||
return _("Alpha")
|
||||
def get_update_channel_label(self, value):
|
||||
if value == "stable":
|
||||
return _("Stable")
|
||||
elif value == "weekly":
|
||||
return _("Weekly")
|
||||
else:
|
||||
return _("Alpha")
|
||||
|
||||
def get_notification_type(self, value):
|
||||
if value == _("Native"):
|
||||
return "native"
|
||||
else:
|
||||
return "custom"
|
||||
def get_notification_type(self, value):
|
||||
if value == _("Native"):
|
||||
return "native"
|
||||
else:
|
||||
return "custom"
|
||||
|
||||
def get_update_channel_type(self, value):
|
||||
if value == _("Stable"):
|
||||
return "stable"
|
||||
elif value == _("Weekly"):
|
||||
return "weekly"
|
||||
else:
|
||||
return "alpha"
|
||||
def get_update_channel_type(self, value):
|
||||
if value == _("Stable"):
|
||||
return "stable"
|
||||
elif value == _("Weekly"):
|
||||
return "weekly"
|
||||
else:
|
||||
return "alpha"
|
||||
|
||||
def create_config(self):
|
||||
self.langs = languageHandler.getAvailableLanguages()
|
||||
langs = [i[1] for i in self.langs]
|
||||
self.codes = [i[0] for i in self.langs]
|
||||
id = self.codes.index(config.app["app-settings"]["language"])
|
||||
self.send_message("create_tab", tab="general", arglist=dict(languages=langs))
|
||||
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="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="update_channel", value=self.get_update_channel_label(self.session.settings["general"]["update_channel"]))
|
||||
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="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("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_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("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="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.input_devices = sound_lib.input.Input.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("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"])
|
||||
def create_config(self):
|
||||
self.langs = languageHandler.getAvailableLanguages()
|
||||
langs = [i[1] for i in self.langs]
|
||||
self.codes = [i[0] for i in self.langs]
|
||||
id = self.codes.index(config.app["app-settings"]["language"])
|
||||
self.send_message("create_tab", tab="general", arglist=dict(languages=langs))
|
||||
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="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="update_channel", value=self.get_update_channel_label(self.session.settings["general"]["update_channel"]))
|
||||
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="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("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_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("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="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.input_devices = sound_lib.input.Input.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("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"])
|
||||
|
||||
def update_setting(self, section, setting, value):
|
||||
if section not in self.session.settings:
|
||||
raise AttributeError("The configuration section is not present in the spec file.")
|
||||
if setting not in self.session.settings[section]:
|
||||
raise AttributeError("The setting you specified is not present in the config file.")
|
||||
self.session.settings[section][setting] = value
|
||||
def update_setting(self, section, setting, value):
|
||||
if section not in self.session.settings:
|
||||
raise AttributeError("The configuration section is not present in the spec file.")
|
||||
if setting not in self.session.settings[section]:
|
||||
raise AttributeError("The setting you specified is not present in the config file.")
|
||||
self.session.settings[section][setting] = value
|
||||
|
||||
def save_settings_file(self):
|
||||
self.session.settings.write()
|
||||
def save_settings_file(self):
|
||||
self.session.settings.write()
|
||||
|
||||
def update_app_setting(self, section, setting, value):
|
||||
if section not in config.app:
|
||||
raise AttributeError("The configuration section is not present in the spec file.")
|
||||
if setting not in config.app[section]:
|
||||
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.
|
||||
# List of app settings that require a restart after being changed.
|
||||
settings_needing_restart = ["language", "use_proxy", "input_device", "output_device", "debug_logging"]
|
||||
if value != config.app[section][setting] and setting in settings_needing_restart:
|
||||
self.needs_restart = True
|
||||
config.app[section][setting] = value
|
||||
def update_app_setting(self, section, setting, value):
|
||||
if section not in config.app:
|
||||
raise AttributeError("The configuration section is not present in the spec file.")
|
||||
if setting not in config.app[section]:
|
||||
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.
|
||||
# List of app settings that require a restart after being changed.
|
||||
settings_needing_restart = ["language", "use_proxy", "input_device", "output_device", "debug_logging"]
|
||||
if value != config.app[section][setting] and setting in settings_needing_restart:
|
||||
self.needs_restart = True
|
||||
config.app[section][setting] = value
|
||||
|
||||
def save_app_settings_file(self):
|
||||
config.app.write()
|
||||
if self.needs_restart:
|
||||
self.send_message("restart_program")
|
||||
def save_app_settings_file(self):
|
||||
config.app.write()
|
||||
if self.needs_restart:
|
||||
self.send_message("restart_program")
|
||||
|
||||
def restart_application(self):
|
||||
restart.restart_program()
|
||||
def restart_application(self):
|
||||
restart.restart_program()
|
||||
|
@ -1,2 +1,2 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from .basePost import *
|
||||
from .basePost import *
|
||||
|
@ -14,45 +14,45 @@ log = getLogger("controller.message")
|
||||
|
||||
class createPostPresenter(base.basePresenter):
|
||||
|
||||
def __init__(self, session, view, interactor):
|
||||
super(createPostPresenter, self).__init__(view=view, interactor=interactor, modulename="create_post")
|
||||
self.session = session
|
||||
self.images = []
|
||||
self.tagged_people = []
|
||||
self.run()
|
||||
def __init__(self, session, view, interactor):
|
||||
super(createPostPresenter, self).__init__(view=view, interactor=interactor, modulename="create_post")
|
||||
self.session = session
|
||||
self.images = []
|
||||
self.tagged_people = []
|
||||
self.run()
|
||||
|
||||
def get_friends(self):
|
||||
try:
|
||||
fields = "id, first_name, last_name"
|
||||
self.friends = self.session.vk.client.friends.get(count=5000, fields=fields)
|
||||
except AttributeError:
|
||||
time.sleep(2)
|
||||
log.exception("Error retrieving friends...")
|
||||
return []
|
||||
self.users = []
|
||||
for i in self.friends["items"]:
|
||||
self.users.append("{0} {1}".format(i["first_name"], i["last_name"]))
|
||||
return self.users
|
||||
def get_friends(self):
|
||||
try:
|
||||
fields = "id, first_name, last_name"
|
||||
self.friends = self.session.vk.client.friends.get(count=5000, fields=fields)
|
||||
except AttributeError:
|
||||
time.sleep(2)
|
||||
log.exception("Error retrieving friends...")
|
||||
return []
|
||||
self.users = []
|
||||
for i in self.friends["items"]:
|
||||
self.users.append("{0} {1}".format(i["first_name"], i["last_name"]))
|
||||
return self.users
|
||||
|
||||
def add_tagged_users(self, tagged_users):
|
||||
self.tagged_people = []
|
||||
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.send_message("add_tagged_users", users=self.tagged_people)
|
||||
def add_tagged_users(self, tagged_users):
|
||||
self.tagged_people = []
|
||||
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.send_message("add_tagged_users", users=self.tagged_people)
|
||||
|
||||
def translate(self, text, language):
|
||||
msg = translator.translator.translate(text, language)
|
||||
self.send_message("set", control="text", value=msg)
|
||||
self.send_message("focus_control", control="text")
|
||||
output.speak(_("Translated"))
|
||||
def translate(self, text, language):
|
||||
msg = translator.translator.translate(text, language)
|
||||
self.send_message("set", control="text", value=msg)
|
||||
self.send_message("focus_control", control="text")
|
||||
output.speak(_("Translated"))
|
||||
|
||||
def spellcheck(self, text):
|
||||
checker = SpellChecker.spellchecker.spellChecker(text)
|
||||
if hasattr(checker, "fixed_text"):
|
||||
self.send_message("set", control="text", value=checker.fixed_text)
|
||||
self.send_message("focus_control", control="text")
|
||||
def spellcheck(self, text):
|
||||
checker = SpellChecker.spellchecker.spellChecker(text)
|
||||
if hasattr(checker, "fixed_text"):
|
||||
self.send_message("set", control="text", value=checker.fixed_text)
|
||||
self.send_message("focus_control", control="text")
|
||||
|
||||
def add_attachments(self):
|
||||
a = attach.attachPresenter(session=self.session, view=views.attachDialog(), interactor=interactors.attachInteractor())
|
||||
if len(a.attachments) != 0:
|
||||
self.attachments = a.attachments
|
||||
def add_attachments(self):
|
||||
a = attach.attachPresenter(session=self.session, view=views.attachDialog(), interactor=interactors.attachInteractor())
|
||||
if len(a.attachments) != 0:
|
||||
self.attachments = a.attachments
|
||||
|
@ -6,4 +6,4 @@ from .comment import *
|
||||
from .peopleList import *
|
||||
from .poll import *
|
||||
from .topic import *
|
||||
from .topicComment import *
|
||||
from .topicComment import *
|
||||
|
@ -10,38 +10,38 @@ from presenters import base
|
||||
log = logging.getLogger(__file__)
|
||||
|
||||
class displayArticlePresenter(base.basePresenter):
|
||||
def __init__(self, session, postObject, view, interactor):
|
||||
super(displayArticlePresenter, self).__init__(view=view, interactor=interactor, modulename="display_article")
|
||||
self.session = session
|
||||
self.post = postObject
|
||||
self.load_article()
|
||||
self.run()
|
||||
def __init__(self, session, postObject, view, interactor):
|
||||
super(displayArticlePresenter, self).__init__(view=view, interactor=interactor, modulename="display_article")
|
||||
self.session = session
|
||||
self.post = postObject
|
||||
self.load_article()
|
||||
self.run()
|
||||
|
||||
def load_article(self):
|
||||
""" 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 is needed because there are no public API for articles so far.
|
||||
"""
|
||||
article = self.post[0]
|
||||
# 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"])
|
||||
# Parse and extract text from all paragraphs.
|
||||
# ToDo: Extract all links and set those as attachments.
|
||||
soup = BeautifulSoup(article_body.text, "lxml")
|
||||
# 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 = "\n\n".join(msg)
|
||||
self.send_message("set", control="article_view", value=msg)
|
||||
self.send_message("set_title", value=article["title"])
|
||||
# Retrieve views count
|
||||
views = soup.find("div", class_="articleView__views_info")
|
||||
# This might return None if VK changes anything, so let's avoid errors.
|
||||
if views == None:
|
||||
views = str(-1)
|
||||
else:
|
||||
views = views.text
|
||||
# Find the integer and remove the words from the string.
|
||||
numbers = re.findall(r'\d+', views)
|
||||
if len(numbers) != 0:
|
||||
views = numbers[0]
|
||||
self.send_message("set", control="views", value=views)
|
||||
def load_article(self):
|
||||
""" 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 is needed because there are no public API for articles so far.
|
||||
"""
|
||||
article = self.post[0]
|
||||
# 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"])
|
||||
# Parse and extract text from all paragraphs.
|
||||
# ToDo: Extract all links and set those as attachments.
|
||||
soup = BeautifulSoup(article_body.text, "lxml")
|
||||
# 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 = "\n\n".join(msg)
|
||||
self.send_message("set", control="article_view", value=msg)
|
||||
self.send_message("set_title", value=article["title"])
|
||||
# Retrieve views count
|
||||
views = soup.find("div", class_="articleView__views_info")
|
||||
# This might return None if VK changes anything, so let's avoid errors.
|
||||
if views == None:
|
||||
views = str(-1)
|
||||
else:
|
||||
views = views.text
|
||||
# Find the integer and remove the words from the string.
|
||||
numbers = re.findall(r'\d+', views)
|
||||
if len(numbers) != 0:
|
||||
views = numbers[0]
|
||||
self.send_message("set", control="views", value=views)
|
||||
|
@ -8,93 +8,93 @@ from presenters import base, player
|
||||
log = logging.getLogger(__file__)
|
||||
|
||||
class displayAudioPresenter(base.basePresenter):
|
||||
def __init__(self, session, postObject, view, interactor):
|
||||
super(displayAudioPresenter, self).__init__(view=view, interactor=interactor, modulename="display_audio")
|
||||
self.added_audios = {}
|
||||
self.session = session
|
||||
self.post = postObject
|
||||
self.load_audios()
|
||||
self.fill_information(0)
|
||||
self.run()
|
||||
def __init__(self, session, postObject, view, interactor):
|
||||
super(displayAudioPresenter, self).__init__(view=view, interactor=interactor, modulename="display_audio")
|
||||
self.added_audios = {}
|
||||
self.session = session
|
||||
self.post = postObject
|
||||
self.load_audios()
|
||||
self.fill_information(0)
|
||||
self.run()
|
||||
|
||||
def add_to_library(self, audio_index):
|
||||
post = self.post[audio_index]
|
||||
args = {}
|
||||
args["audio_id"] = post["id"]
|
||||
if "album_id" in post:
|
||||
args["album_id"] = post["album_id"]
|
||||
args["owner_id"] = post["owner_id"]
|
||||
audio = self.session.vk.client.audio.add(**args)
|
||||
if audio != None and int(audio) > 21:
|
||||
self.added_audios[post["id"]] = audio
|
||||
self.send_message("disable_control", control="add")
|
||||
self.send_message("enable_control", control="remove")
|
||||
def add_to_library(self, audio_index):
|
||||
post = self.post[audio_index]
|
||||
args = {}
|
||||
args["audio_id"] = post["id"]
|
||||
if "album_id" in post:
|
||||
args["album_id"] = post["album_id"]
|
||||
args["owner_id"] = post["owner_id"]
|
||||
audio = self.session.vk.client.audio.add(**args)
|
||||
if audio != None and int(audio) > 21:
|
||||
self.added_audios[post["id"]] = audio
|
||||
self.send_message("disable_control", control="add")
|
||||
self.send_message("enable_control", control="remove")
|
||||
|
||||
def remove_from_library(self, audio_index):
|
||||
post = self.post[audio_index]
|
||||
args = {}
|
||||
if post["id"] in self.added_audios:
|
||||
args["audio_id"] = self.added_audios[post["id"]]
|
||||
args["owner_id"] = self.session.user_id
|
||||
else:
|
||||
args["audio_id"] = post["id"]
|
||||
args["owner_id"] = post["owner_id"]
|
||||
result = self.session.vk.client.audio.delete(**args)
|
||||
if int(result) == 1:
|
||||
self.send_message("enable_control", control="add")
|
||||
self.send_message("disable_control", control="remove")
|
||||
if post["id"] in self.added_audios:
|
||||
self.added_audios.pop(post["id"])
|
||||
def remove_from_library(self, audio_index):
|
||||
post = self.post[audio_index]
|
||||
args = {}
|
||||
if post["id"] in self.added_audios:
|
||||
args["audio_id"] = self.added_audios[post["id"]]
|
||||
args["owner_id"] = self.session.user_id
|
||||
else:
|
||||
args["audio_id"] = post["id"]
|
||||
args["owner_id"] = post["owner_id"]
|
||||
result = self.session.vk.client.audio.delete(**args)
|
||||
if int(result) == 1:
|
||||
self.send_message("enable_control", control="add")
|
||||
self.send_message("disable_control", control="remove")
|
||||
if post["id"] in self.added_audios:
|
||||
self.added_audios.pop(post["id"])
|
||||
|
||||
def fill_information(self, index):
|
||||
post = self.post[index]
|
||||
if "artist" in post:
|
||||
self.send_message("set", control="artist", value=post["artist"])
|
||||
if "title" in post:
|
||||
self.send_message("set", control="title", value=post["title"])
|
||||
if "duration" in post:
|
||||
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"]))
|
||||
call_threaded(self.get_lyrics, index)
|
||||
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("disable_control", control="add")
|
||||
else:
|
||||
self.send_message("enable_control", control="add")
|
||||
self.send_message("disable_control", control="remove")
|
||||
def fill_information(self, index):
|
||||
post = self.post[index]
|
||||
if "artist" in post:
|
||||
self.send_message("set", control="artist", value=post["artist"])
|
||||
if "title" in post:
|
||||
self.send_message("set", control="title", value=post["title"])
|
||||
if "duration" in post:
|
||||
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"]))
|
||||
call_threaded(self.get_lyrics, index)
|
||||
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("disable_control", control="add")
|
||||
else:
|
||||
self.send_message("enable_control", control="add")
|
||||
self.send_message("disable_control", control="remove")
|
||||
|
||||
def get_lyrics(self, audio_index):
|
||||
post = self.post[audio_index]
|
||||
if "lyrics_id" in post:
|
||||
l = self.session.vk.client.audio.getLyrics(lyrics_id=int(post["lyrics_id"]))
|
||||
self.send_message("set", control="lyric", value=l["text"])
|
||||
else:
|
||||
self.send_message("disable_control", control="lyric")
|
||||
def get_lyrics(self, audio_index):
|
||||
post = self.post[audio_index]
|
||||
if "lyrics_id" in post:
|
||||
l = self.session.vk.client.audio.getLyrics(lyrics_id=int(post["lyrics_id"]))
|
||||
self.send_message("set", control="lyric", value=l["text"])
|
||||
else:
|
||||
self.send_message("disable_control", control="lyric")
|
||||
|
||||
def get_suggested_filename(self, audio_index):
|
||||
post = self.post[audio_index]
|
||||
return utils.safe_filename("{0} - {1}.mp3".format(post["title"], post["artist"]))
|
||||
def get_suggested_filename(self, audio_index):
|
||||
post = self.post[audio_index]
|
||||
return utils.safe_filename("{0} - {1}.mp3".format(post["title"], post["artist"]))
|
||||
|
||||
def download(self, audio_index, path):
|
||||
post = self.post[audio_index]
|
||||
if path != None:
|
||||
pub.sendMessage("download-file", url=post["url"], filename=path)
|
||||
def download(self, audio_index, path):
|
||||
post = self.post[audio_index]
|
||||
if path != None:
|
||||
pub.sendMessage("download-file", url=post["url"], filename=path)
|
||||
|
||||
def play(self, audio_index):
|
||||
post = self.post[audio_index]
|
||||
if player.player.check_is_playing() == True:
|
||||
return pub.sendMessage("stop")
|
||||
pub.sendMessage("play", object=post)
|
||||
def play(self, audio_index):
|
||||
post = self.post[audio_index]
|
||||
if player.player.check_is_playing() == True:
|
||||
return pub.sendMessage("stop")
|
||||
pub.sendMessage("play", object=post)
|
||||
|
||||
def load_audios(self):
|
||||
audios = []
|
||||
for i in self.post:
|
||||
s = "{0} - {1}. {2}".format(i["title"], i["artist"], utils.seconds_to_string(i["duration"]))
|
||||
audios.append(s)
|
||||
self.send_message("add_items", control="list", items=audios)
|
||||
if len(self.post) == 1:
|
||||
self.send_message("disable_control", control="list")
|
||||
self.send_message("focus_control", control="title")
|
||||
def load_audios(self):
|
||||
audios = []
|
||||
for i in self.post:
|
||||
s = "{0} - {1}. {2}".format(i["title"], i["artist"], utils.seconds_to_string(i["duration"]))
|
||||
audios.append(s)
|
||||
self.send_message("add_items", control="list", items=audios)
|
||||
if len(self.post) == 1:
|
||||
self.send_message("disable_control", control="list")
|
||||
self.send_message("focus_control", control="title")
|
||||
|
||||
def handle_changes(self, audio_index):
|
||||
self.fill_information(audio_index)
|
||||
def handle_changes(self, audio_index):
|
||||
self.fill_information(audio_index)
|
||||
|
@ -20,359 +20,359 @@ from . import audio, poll, article
|
||||
log = logging.getLogger(__file__)
|
||||
|
||||
def get_message(status):
|
||||
message = ""
|
||||
if "text" in status:
|
||||
message = utils.clean_text(status["text"])
|
||||
return message
|
||||
message = ""
|
||||
if "text" in status:
|
||||
message = utils.clean_text(status["text"])
|
||||
return message
|
||||
|
||||
class displayPostPresenter(base.basePresenter):
|
||||
""" Base class for post representation."""
|
||||
""" Base class for post representation."""
|
||||
|
||||
def __init__(self, session, postObject, view, interactor):
|
||||
super(displayPostPresenter, self).__init__(view=view, interactor=interactor, modulename="display_post")
|
||||
self.type = "post"
|
||||
self.session = session
|
||||
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.
|
||||
if "source_id" in self.post:
|
||||
self.user_identifier = "source_id"
|
||||
self.post_identifier = "post_id"
|
||||
else:
|
||||
# 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.
|
||||
if "owner_id" not in self.post:
|
||||
self.user_identifier = "from_id"
|
||||
else:
|
||||
self.user_identifier = "owner_id"
|
||||
self.post_identifier = "id"
|
||||
self.attachments = []
|
||||
self.load_images = False
|
||||
# We'll put images here, so it will be easier to work with them.
|
||||
self.images = []
|
||||
self.imageIndex = 0
|
||||
result = self.get_post_information()
|
||||
# Stop loading everything else if post was deleted.
|
||||
if result == False:
|
||||
self.interactor.uninstall()
|
||||
return
|
||||
self.worker = threading.Thread(target=self.load_all_components)
|
||||
self.worker.finished = threading.Event()
|
||||
self.worker.start()
|
||||
# connect here the pubsub event for successful posting of comments.
|
||||
pub.subscribe(self.posted, "posted")
|
||||
self.run()
|
||||
pub.unsubscribe(self.posted, "posted")
|
||||
def __init__(self, session, postObject, view, interactor):
|
||||
super(displayPostPresenter, self).__init__(view=view, interactor=interactor, modulename="display_post")
|
||||
self.type = "post"
|
||||
self.session = session
|
||||
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.
|
||||
if "source_id" in self.post:
|
||||
self.user_identifier = "source_id"
|
||||
self.post_identifier = "post_id"
|
||||
else:
|
||||
# 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.
|
||||
if "owner_id" not in self.post:
|
||||
self.user_identifier = "from_id"
|
||||
else:
|
||||
self.user_identifier = "owner_id"
|
||||
self.post_identifier = "id"
|
||||
self.attachments = []
|
||||
self.load_images = False
|
||||
# We'll put images here, so it will be easier to work with them.
|
||||
self.images = []
|
||||
self.imageIndex = 0
|
||||
result = self.get_post_information()
|
||||
# Stop loading everything else if post was deleted.
|
||||
if result == False:
|
||||
self.interactor.uninstall()
|
||||
return
|
||||
self.worker = threading.Thread(target=self.load_all_components)
|
||||
self.worker.finished = threading.Event()
|
||||
self.worker.start()
|
||||
# connect here the pubsub event for successful posting of comments.
|
||||
pub.subscribe(self.posted, "posted")
|
||||
self.run()
|
||||
pub.unsubscribe(self.posted, "posted")
|
||||
|
||||
def posted(self, from_buffer=None):
|
||||
self.clear_comments_list()
|
||||
def posted(self, from_buffer=None):
|
||||
self.clear_comments_list()
|
||||
|
||||
def get_comments(self):
|
||||
""" Get comments and insert them in a list."""
|
||||
user = self.post[self.user_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)
|
||||
self.comments = dict(items=[], profiles=comments_data["profiles"])
|
||||
for i in comments_data["items"]:
|
||||
self.comments["items"].append(i)
|
||||
if i.get("thread") != None and i["thread"].get("count") > 0:
|
||||
for newI in i["thread"]["items"]:
|
||||
self.comments["items"].append(newI)
|
||||
comments_ = []
|
||||
# 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.
|
||||
# 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"])
|
||||
self.session.process_usernames(data)
|
||||
for i in self.comments["items"]:
|
||||
# If comment has a "deleted" key it should not be displayed, obviously.
|
||||
if "deleted" in i:
|
||||
continue
|
||||
from_ = self.session.get_user(i["from_id"])["user1_nom"]
|
||||
if "reply_to_user" in i:
|
||||
extra_info = self.session.get_user(i["reply_to_user"])["user1_nom"]
|
||||
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.
|
||||
fixed_text = utils.clean_text(i["text"])
|
||||
if len(fixed_text) > 140:
|
||||
text = fixed_text[:141]
|
||||
else:
|
||||
text = fixed_text
|
||||
original_date = arrow.get(i["date"])
|
||||
created_at = original_date.humanize(locale=languageHandler.curLang[:2])
|
||||
likes = str(i["likes"]["count"])
|
||||
comments_.append((from_, text, created_at, likes))
|
||||
self.send_message("add_items", control="comments", items=comments_)
|
||||
def get_comments(self):
|
||||
""" Get comments and insert them in a list."""
|
||||
user = self.post[self.user_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)
|
||||
self.comments = dict(items=[], profiles=comments_data["profiles"])
|
||||
for i in comments_data["items"]:
|
||||
self.comments["items"].append(i)
|
||||
if i.get("thread") != None and i["thread"].get("count") > 0:
|
||||
for newI in i["thread"]["items"]:
|
||||
self.comments["items"].append(newI)
|
||||
comments_ = []
|
||||
# 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.
|
||||
# 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"])
|
||||
self.session.process_usernames(data)
|
||||
for i in self.comments["items"]:
|
||||
# If comment has a "deleted" key it should not be displayed, obviously.
|
||||
if "deleted" in i:
|
||||
continue
|
||||
from_ = self.session.get_user(i["from_id"])["user1_nom"]
|
||||
if "reply_to_user" in i:
|
||||
extra_info = self.session.get_user(i["reply_to_user"])["user1_nom"]
|
||||
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.
|
||||
fixed_text = utils.clean_text(i["text"])
|
||||
if len(fixed_text) > 140:
|
||||
text = fixed_text[:141]
|
||||
else:
|
||||
text = fixed_text
|
||||
original_date = arrow.get(i["date"])
|
||||
created_at = original_date.humanize(locale=languageHandler.curLang[:2])
|
||||
likes = str(i["likes"]["count"])
|
||||
comments_.append((from_, text, created_at, likes))
|
||||
self.send_message("add_items", control="comments", items=comments_)
|
||||
|
||||
def get_post_information(self):
|
||||
from_ = self.session.get_user(self.post[self.user_identifier])
|
||||
if "copy_history" in self.post:
|
||||
title = _("repost from {user1_nom}").format(**from_)
|
||||
else:
|
||||
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.
|
||||
user2 = self.session.get_user(self.post["owner_id"], "user2")
|
||||
user2.update(from_)
|
||||
title = _("Post from {user1_nom} in the {user2_nom}'s wall").format(**user2)
|
||||
else:
|
||||
title = _("Post from {user1_nom}").format(**from_)
|
||||
self.send_message("set_title", value=title)
|
||||
message = ""
|
||||
# Retrieve again the post, so we'll make sure to get the most up to date information.
|
||||
# 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]))
|
||||
# If this post has been deleted, let's send an event to the interactor so it won't be displayed.
|
||||
if len(post) == 0:
|
||||
self.send_message("post_deleted")
|
||||
return False
|
||||
self.post = post[0]
|
||||
if "views" in self.post and self.post["views"]["count"] > 0:
|
||||
self.send_message("set", control="views", value=str(self.post["views"]["count"]))
|
||||
else:
|
||||
self.send_message("disable_control", control="views")
|
||||
if "owner_id" not in self.post:
|
||||
self.user_identifier = "from_id"
|
||||
else:
|
||||
self.user_identifier = "owner_id"
|
||||
self.post_identifier = "id"
|
||||
message = get_message(self.post)
|
||||
if "copy_history" in self.post:
|
||||
nm = "\n"
|
||||
for i in self.post["copy_history"]:
|
||||
u = self.session.get_user(i["from_id"])
|
||||
u.update(message=get_message(i))
|
||||
nm += "{user1_nom}: {message}\n\n".format(**u)
|
||||
self.get_attachments(i, get_message(i))
|
||||
message += nm
|
||||
self.send_message("set", control="post_view", value=message)
|
||||
self.get_attachments(self.post, message)
|
||||
self.check_image_load()
|
||||
def get_post_information(self):
|
||||
from_ = self.session.get_user(self.post[self.user_identifier])
|
||||
if "copy_history" in self.post:
|
||||
title = _("repost from {user1_nom}").format(**from_)
|
||||
else:
|
||||
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.
|
||||
user2 = self.session.get_user(self.post["owner_id"], "user2")
|
||||
user2.update(from_)
|
||||
title = _("Post from {user1_nom} in the {user2_nom}'s wall").format(**user2)
|
||||
else:
|
||||
title = _("Post from {user1_nom}").format(**from_)
|
||||
self.send_message("set_title", value=title)
|
||||
message = ""
|
||||
# Retrieve again the post, so we'll make sure to get the most up to date information.
|
||||
# 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]))
|
||||
# If this post has been deleted, let's send an event to the interactor so it won't be displayed.
|
||||
if len(post) == 0:
|
||||
self.send_message("post_deleted")
|
||||
return False
|
||||
self.post = post[0]
|
||||
if "views" in self.post and self.post["views"]["count"] > 0:
|
||||
self.send_message("set", control="views", value=str(self.post["views"]["count"]))
|
||||
else:
|
||||
self.send_message("disable_control", control="views")
|
||||
if "owner_id" not in self.post:
|
||||
self.user_identifier = "from_id"
|
||||
else:
|
||||
self.user_identifier = "owner_id"
|
||||
self.post_identifier = "id"
|
||||
message = get_message(self.post)
|
||||
if "copy_history" in self.post:
|
||||
nm = "\n"
|
||||
for i in self.post["copy_history"]:
|
||||
u = self.session.get_user(i["from_id"])
|
||||
u.update(message=get_message(i))
|
||||
nm += "{user1_nom}: {message}\n\n".format(**u)
|
||||
self.get_attachments(i, get_message(i))
|
||||
message += nm
|
||||
self.send_message("set", control="post_view", value=message)
|
||||
self.get_attachments(self.post, message)
|
||||
self.check_image_load()
|
||||
|
||||
def get_attachments(self, post, text):
|
||||
attachments = []
|
||||
self.attachments = []
|
||||
if "attachments" in post:
|
||||
for i in post["attachments"]:
|
||||
# We don't need the photos_list attachment, so skip it.
|
||||
if i["type"] == "photos_list":
|
||||
continue
|
||||
if i["type"] == "photo":
|
||||
if self.load_images == False: self.load_images = True
|
||||
self.images.append(i)
|
||||
attachments.append(renderers.add_attachment(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
|
||||
# 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)
|
||||
if len(urls) > 0:
|
||||
links = []
|
||||
for i in urls:
|
||||
links.append({"link": {"title": _("Untitled link"), "url": i}, "type": "link"})
|
||||
for i in links:
|
||||
attachments.append(renderers.add_attachment(i))
|
||||
self.attachments.append(i)
|
||||
if len(self.attachments) > 0:
|
||||
self.send_message("enable_attachments")
|
||||
self.send_message("add_items", control="attachments", items=attachments)
|
||||
else:
|
||||
self.interactor.view.attachments.list.Enable(False)
|
||||
def get_attachments(self, post, text):
|
||||
attachments = []
|
||||
self.attachments = []
|
||||
if "attachments" in post:
|
||||
for i in post["attachments"]:
|
||||
# We don't need the photos_list attachment, so skip it.
|
||||
if i["type"] == "photos_list":
|
||||
continue
|
||||
if i["type"] == "photo":
|
||||
if self.load_images == False: self.load_images = True
|
||||
self.images.append(i)
|
||||
attachments.append(renderers.add_attachment(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
|
||||
# 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)
|
||||
if len(urls) > 0:
|
||||
links = []
|
||||
for i in urls:
|
||||
links.append({"link": {"title": _("Untitled link"), "url": i}, "type": "link"})
|
||||
for i in links:
|
||||
attachments.append(renderers.add_attachment(i))
|
||||
self.attachments.append(i)
|
||||
if len(self.attachments) > 0:
|
||||
self.send_message("enable_attachments")
|
||||
self.send_message("add_items", control="attachments", items=attachments)
|
||||
else:
|
||||
self.interactor.view.attachments.list.Enable(False)
|
||||
|
||||
def check_image_load(self):
|
||||
if self.load_images and len(self.images) > 0 and self.session.settings["general"]["load_images"]:
|
||||
self.send_message("enable_control", control="image")
|
||||
nav = False # Disable navigation controls in photos
|
||||
if len(self.images) > 1:
|
||||
nav = True
|
||||
self.send_message("enable_photo_controls", navigation=nav)
|
||||
self.set_image(0)
|
||||
def check_image_load(self):
|
||||
if self.load_images and len(self.images) > 0 and self.session.settings["general"]["load_images"]:
|
||||
self.send_message("enable_control", control="image")
|
||||
nav = False # Disable navigation controls in photos
|
||||
if len(self.images) > 1:
|
||||
nav = True
|
||||
self.send_message("enable_photo_controls", navigation=nav)
|
||||
self.set_image(0)
|
||||
|
||||
def set_next_image(self, *args, **kwargs):
|
||||
if self.imageIndex < -1 or self.imageIndex == len(self.images)-1:
|
||||
self.imageIndex = -1
|
||||
if len(self.images) <= self.imageIndex+1:
|
||||
self.imageIndex = 0
|
||||
else:
|
||||
self.imageIndex = self.imageIndex + 1
|
||||
self.set_image(self.imageIndex)
|
||||
def set_next_image(self, *args, **kwargs):
|
||||
if self.imageIndex < -1 or self.imageIndex == len(self.images)-1:
|
||||
self.imageIndex = -1
|
||||
if len(self.images) <= self.imageIndex+1:
|
||||
self.imageIndex = 0
|
||||
else:
|
||||
self.imageIndex = self.imageIndex + 1
|
||||
self.set_image(self.imageIndex)
|
||||
|
||||
def set_previous_image(self, *args, **kwargs):
|
||||
if self.imageIndex <= 0:
|
||||
self.imageIndex = len(self.images)
|
||||
self.imageIndex = self.imageIndex - 1
|
||||
self.set_image(self.imageIndex)
|
||||
def set_previous_image(self, *args, **kwargs):
|
||||
if self.imageIndex <= 0:
|
||||
self.imageIndex = len(self.images)
|
||||
self.imageIndex = self.imageIndex - 1
|
||||
self.set_image(self.imageIndex)
|
||||
|
||||
def set_image(self, index):
|
||||
if len(self.images) < index-1:
|
||||
return
|
||||
# Get's photo URL.
|
||||
url = self.get_photo_url(self.images[index]["photo"], "x")
|
||||
if url != "":
|
||||
img = requests.get(url)
|
||||
self.send_message("load_image", image=img)
|
||||
# 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)))
|
||||
return
|
||||
def set_image(self, index):
|
||||
if len(self.images) < index-1:
|
||||
return
|
||||
# Get's photo URL.
|
||||
url = self.get_photo_url(self.images[index]["photo"], "x")
|
||||
if url != "":
|
||||
img = requests.get(url)
|
||||
self.send_message("load_image", image=img)
|
||||
# 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)))
|
||||
return
|
||||
|
||||
def get_photo_url(self, photo, size="x"):
|
||||
url = ""
|
||||
for i in photo["sizes"]:
|
||||
if i["type"] == size:
|
||||
url = i["url"]
|
||||
break
|
||||
return url
|
||||
def get_photo_url(self, photo, size="x"):
|
||||
url = ""
|
||||
for i in photo["sizes"]:
|
||||
if i["type"] == size:
|
||||
url = i["url"]
|
||||
break
|
||||
return url
|
||||
|
||||
def load_all_components(self):
|
||||
self.get_likes()
|
||||
self.get_reposts()
|
||||
self.get_comments()
|
||||
if self.post["comments"]["can_post"] == 0:
|
||||
self.send_message("disable_control", control="comment")
|
||||
if self.post["likes"]["can_like"] == 0 and self.post["likes"]["user_likes"] == 0:
|
||||
self.send_message("disable_control", "like")
|
||||
elif self.post["likes"]["user_likes"] == 1:
|
||||
self.send_message("set_label", control="like", label=_("&Dislike"))
|
||||
if self.post["likes"]["can_publish"] == 0:
|
||||
self.send_message("disable_control", control="repost")
|
||||
def load_all_components(self):
|
||||
self.get_likes()
|
||||
self.get_reposts()
|
||||
self.get_comments()
|
||||
if self.post["comments"]["can_post"] == 0:
|
||||
self.send_message("disable_control", control="comment")
|
||||
if self.post["likes"]["can_like"] == 0 and self.post["likes"]["user_likes"] == 0:
|
||||
self.send_message("disable_control", "like")
|
||||
elif self.post["likes"]["user_likes"] == 1:
|
||||
self.send_message("set_label", control="like", label=_("&Dislike"))
|
||||
if self.post["likes"]["can_publish"] == 0:
|
||||
self.send_message("disable_control", control="repost")
|
||||
|
||||
def post_like(self):
|
||||
if ("owner_id" in self.post) == False:
|
||||
user = int(self.post[self.user_identifier])
|
||||
else:
|
||||
user = int(self.post["owner_id"])
|
||||
id = int(self.post[self.post_identifier])
|
||||
if "type" in self.post:
|
||||
type_ = self.post["type"]
|
||||
else:
|
||||
type_ = self.type
|
||||
if self.post["likes"]["user_likes"] == 1:
|
||||
l = self.session.vk.client.likes.delete(owner_id=user, item_id=id, type=type_)
|
||||
output.speak(_("You don't like this"))
|
||||
self.post["likes"]["count"] = l["likes"]
|
||||
self.post["likes"]["user_likes"] = 2
|
||||
self.get_likes()
|
||||
self.send_message("set_label", control="like", label=_("&Like"))
|
||||
else:
|
||||
l = self.session.vk.client.likes.add(owner_id=user, item_id=id, type=type_)
|
||||
output.speak(_("You liked this"))
|
||||
self.send_message("set_label", control="like", label=_("&Dislike"))
|
||||
self.post["likes"]["count"] = l["likes"]
|
||||
self.post["likes"]["user_likes"] = 1
|
||||
self.get_likes()
|
||||
def post_like(self):
|
||||
if ("owner_id" in self.post) == False:
|
||||
user = int(self.post[self.user_identifier])
|
||||
else:
|
||||
user = int(self.post["owner_id"])
|
||||
id = int(self.post[self.post_identifier])
|
||||
if "type" in self.post:
|
||||
type_ = self.post["type"]
|
||||
else:
|
||||
type_ = self.type
|
||||
if self.post["likes"]["user_likes"] == 1:
|
||||
l = self.session.vk.client.likes.delete(owner_id=user, item_id=id, type=type_)
|
||||
output.speak(_("You don't like this"))
|
||||
self.post["likes"]["count"] = l["likes"]
|
||||
self.post["likes"]["user_likes"] = 2
|
||||
self.get_likes()
|
||||
self.send_message("set_label", control="like", label=_("&Like"))
|
||||
else:
|
||||
l = self.session.vk.client.likes.add(owner_id=user, item_id=id, type=type_)
|
||||
output.speak(_("You liked this"))
|
||||
self.send_message("set_label", control="like", label=_("&Dislike"))
|
||||
self.post["likes"]["count"] = l["likes"]
|
||||
self.post["likes"]["user_likes"] = 1
|
||||
self.get_likes()
|
||||
|
||||
def post_repost(self):
|
||||
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"))
|
||||
if hasattr(p, "text") or hasattr(p, "privacy"):
|
||||
post_arguments = dict(object=object_id, message=p.text)
|
||||
attachments = []
|
||||
if hasattr(p, "attachments"):
|
||||
attachments = p.attachments
|
||||
call_threaded(pub.sendMessage, "post", parent_endpoint="wall", child_endpoint="repost", attachments_list=attachments, post_arguments=post_arguments)
|
||||
def post_repost(self):
|
||||
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"))
|
||||
if hasattr(p, "text") or hasattr(p, "privacy"):
|
||||
post_arguments = dict(object=object_id, message=p.text)
|
||||
attachments = []
|
||||
if hasattr(p, "attachments"):
|
||||
attachments = p.attachments
|
||||
call_threaded(pub.sendMessage, "post", parent_endpoint="wall", child_endpoint="repost", attachments_list=attachments, post_arguments=post_arguments)
|
||||
|
||||
def get_likes(self):
|
||||
self.send_message("set_label", control="likes", label=_("{0} people like this").format(self.post["likes"]["count"],))
|
||||
def get_likes(self):
|
||||
self.send_message("set_label", control="likes", label=_("{0} people like this").format(self.post["likes"]["count"],))
|
||||
|
||||
def get_reposts(self):
|
||||
self.send_message("set_label", control="shares", label=_("Shared {0} times").format(self.post["reposts"]["count"],))
|
||||
def get_reposts(self):
|
||||
self.send_message("set_label", control="shares", label=_("Shared {0} times").format(self.post["reposts"]["count"],))
|
||||
|
||||
def add_comment(self):
|
||||
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"):
|
||||
owner_id = self.post[self.user_identifier]
|
||||
post_id = self.post[self.post_identifier]
|
||||
post_arguments=dict(message=comment.text, owner_id=owner_id, post_id=post_id)
|
||||
attachments = []
|
||||
if hasattr(comment, "attachments"):
|
||||
attachments = comment.attachments
|
||||
call_threaded(pub.sendMessage, "post", parent_endpoint="wall", child_endpoint="createComment", attachments_list=attachments, post_arguments=post_arguments)
|
||||
def add_comment(self):
|
||||
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"):
|
||||
owner_id = self.post[self.user_identifier]
|
||||
post_id = self.post[self.post_identifier]
|
||||
post_arguments=dict(message=comment.text, owner_id=owner_id, post_id=post_id)
|
||||
attachments = []
|
||||
if hasattr(comment, "attachments"):
|
||||
attachments = comment.attachments
|
||||
call_threaded(pub.sendMessage, "post", parent_endpoint="wall", child_endpoint="createComment", attachments_list=attachments, post_arguments=post_arguments)
|
||||
|
||||
def reply(self, 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"))
|
||||
if hasattr(comment, "text") or hasattr(comment, "privacy"):
|
||||
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"])
|
||||
attachments = []
|
||||
if hasattr(comment, "attachments"):
|
||||
attachments = comment.attachments
|
||||
call_threaded(pub.sendMessage, "post", parent_endpoint="wall", child_endpoint="createComment", attachments_list=attachments, post_arguments=post_arguments)
|
||||
def reply(self, 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"))
|
||||
if hasattr(comment, "text") or hasattr(comment, "privacy"):
|
||||
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"])
|
||||
attachments = []
|
||||
if hasattr(comment, "attachments"):
|
||||
attachments = comment.attachments
|
||||
call_threaded(pub.sendMessage, "post", parent_endpoint="wall", child_endpoint="createComment", attachments_list=attachments, post_arguments=post_arguments)
|
||||
|
||||
def show_comment(self, comment_index):
|
||||
from . import comment
|
||||
c = self.comments["items"][comment_index]
|
||||
c["post_id"] = self.post[self.post_identifier]
|
||||
a = comment.displayCommentPresenter(session=self.session, postObject=c, interactor=interactors.displayPostInteractor(), view=views.displayComment())
|
||||
def show_comment(self, comment_index):
|
||||
from . import comment
|
||||
c = self.comments["items"][comment_index]
|
||||
c["post_id"] = self.post[self.post_identifier]
|
||||
a = comment.displayCommentPresenter(session=self.session, postObject=c, interactor=interactors.displayPostInteractor(), view=views.displayComment())
|
||||
|
||||
def translate(self, text, language):
|
||||
msg = translator.translator.translate(text, language)
|
||||
self.send_message("set", control="post_view", value=msg)
|
||||
self.send_message("focus_control", control="post_view")
|
||||
output.speak(_("Translated"))
|
||||
def translate(self, text, language):
|
||||
msg = translator.translator.translate(text, language)
|
||||
self.send_message("set", control="post_view", value=msg)
|
||||
self.send_message("focus_control", control="post_view")
|
||||
output.speak(_("Translated"))
|
||||
|
||||
def spellcheck(self, text):
|
||||
checker = SpellChecker.spellchecker.spellChecker(text)
|
||||
if hasattr(checker, "fixed_text"):
|
||||
self.send_message("set", control="post_view", value=checker.fixed_text)
|
||||
self.send_message("focus_control", control="post_view")
|
||||
def spellcheck(self, text):
|
||||
checker = SpellChecker.spellchecker.spellChecker(text)
|
||||
if hasattr(checker, "fixed_text"):
|
||||
self.send_message("set", control="post_view", value=checker.fixed_text)
|
||||
self.send_message("focus_control", control="post_view")
|
||||
|
||||
def open_attachment(self, index):
|
||||
attachment = self.attachments[index]
|
||||
if attachment["type"] == "audio":
|
||||
a = audio.displayAudioPresenter(session=self.session, postObject=[attachment["audio"]], interactor=interactors.displayAudioInteractor(), view=views.displayAudio())
|
||||
elif attachment["type"] == "link":
|
||||
output.speak(_("Opening URL..."), True)
|
||||
webbrowser.open_new_tab(attachment["link"]["url"])
|
||||
elif attachment["type"] == "doc":
|
||||
output.speak(_("Opening document in web browser..."))
|
||||
webbrowser.open(attachment["doc"]["url"])
|
||||
elif attachment["type"] == "video":
|
||||
# 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.
|
||||
# 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.
|
||||
# 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.
|
||||
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 = video_object["items"][0]
|
||||
output.speak(_("Opening video in web browser..."), True)
|
||||
webbrowser.open_new_tab(video_object["player"])
|
||||
elif attachment["type"] == "photo":
|
||||
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_sizes = [1280, 604, 130, 75]
|
||||
url = ""
|
||||
for i in possible_sizes:
|
||||
if "photo_{0}".format(i,) in attachment["photo"]:
|
||||
url = attachment["photo"]["photo_{0}".format(i,)]
|
||||
break
|
||||
if url != "":
|
||||
webbrowser.open_new_tab(url)
|
||||
elif attachment["type"] == "poll":
|
||||
a = poll.displayPollPresenter(session=self.session, poll=attachment, interactor=interactors.displayPollInteractor(), view=views.displayPoll())
|
||||
elif attachment["type"] == "article":
|
||||
a = article.displayArticlePresenter(session=self.session, postObject=[attachment["article"]], interactor=interactors.displayArticleInteractor(), view=views.displayArticle())
|
||||
else:
|
||||
log.error("Unhandled attachment: %r" % (attachment,))
|
||||
def open_attachment(self, index):
|
||||
attachment = self.attachments[index]
|
||||
if attachment["type"] == "audio":
|
||||
a = audio.displayAudioPresenter(session=self.session, postObject=[attachment["audio"]], interactor=interactors.displayAudioInteractor(), view=views.displayAudio())
|
||||
elif attachment["type"] == "link":
|
||||
output.speak(_("Opening URL..."), True)
|
||||
webbrowser.open_new_tab(attachment["link"]["url"])
|
||||
elif attachment["type"] == "doc":
|
||||
output.speak(_("Opening document in web browser..."))
|
||||
webbrowser.open(attachment["doc"]["url"])
|
||||
elif attachment["type"] == "video":
|
||||
# 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.
|
||||
# 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.
|
||||
# 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.
|
||||
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 = video_object["items"][0]
|
||||
output.speak(_("Opening video in web browser..."), True)
|
||||
webbrowser.open_new_tab(video_object["player"])
|
||||
elif attachment["type"] == "photo":
|
||||
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_sizes = [1280, 604, 130, 75]
|
||||
url = ""
|
||||
for i in possible_sizes:
|
||||
if "photo_{0}".format(i,) in attachment["photo"]:
|
||||
url = attachment["photo"]["photo_{0}".format(i,)]
|
||||
break
|
||||
if url != "":
|
||||
webbrowser.open_new_tab(url)
|
||||
elif attachment["type"] == "poll":
|
||||
a = poll.displayPollPresenter(session=self.session, poll=attachment, interactor=interactors.displayPollInteractor(), view=views.displayPoll())
|
||||
elif attachment["type"] == "article":
|
||||
a = article.displayArticlePresenter(session=self.session, postObject=[attachment["article"]], interactor=interactors.displayArticleInteractor(), view=views.displayArticle())
|
||||
else:
|
||||
log.error("Unhandled attachment: %r" % (attachment,))
|
||||
|
||||
def __del__(self):
|
||||
if hasattr(self, "worker"):
|
||||
self.worker.finished.set()
|
||||
def __del__(self):
|
||||
if hasattr(self, "worker"):
|
||||
self.worker.finished.set()
|
||||
|
||||
def clear_comments_list(self):
|
||||
self.send_message("clean_list", list="comments")
|
||||
self.get_comments()
|
||||
def clear_comments_list(self):
|
||||
self.send_message("clean_list", list="comments")
|
||||
self.get_comments()
|
||||
|
||||
def show_likes(self):
|
||||
""" 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)
|
||||
result = self.session.vk.client.likes.getList(**data)
|
||||
if result["count"] > 0:
|
||||
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")))
|
||||
def show_likes(self):
|
||||
""" 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)
|
||||
result = self.session.vk.client.likes.getList(**data)
|
||||
if result["count"] > 0:
|
||||
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")))
|
||||
|
||||
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")
|
||||
result = self.session.vk.client.likes.getList(**data)
|
||||
if result["count"] > 0:
|
||||
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")))
|
||||
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")
|
||||
result = self.session.vk.client.likes.getList(**data)
|
||||
if result["count"] > 0:
|
||||
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")))
|
||||
|
@ -15,75 +15,75 @@ from . import basePost
|
||||
log = logging.getLogger(__file__)
|
||||
|
||||
def get_message(status):
|
||||
message = ""
|
||||
if "text" in status:
|
||||
message = utils.clean_text(status["text"])
|
||||
return message
|
||||
message = ""
|
||||
if "text" in status:
|
||||
message = utils.clean_text(status["text"])
|
||||
return message
|
||||
|
||||
class displayCommentPresenter(basePost.displayPostPresenter):
|
||||
|
||||
def __init__(self, session, postObject, view, interactor):
|
||||
self.type = "comment"
|
||||
self.modulename = "display_comment"
|
||||
self.interactor = interactor
|
||||
self.view = view
|
||||
self.interactor.install(view=view, presenter=self, modulename=self.modulename)
|
||||
self.session = session
|
||||
self.post = postObject
|
||||
self.user_identifier = "from_id"
|
||||
self.post_identifier = "id"
|
||||
self.worker = threading.Thread(target=self.load_all_components)
|
||||
self.worker.finished = threading.Event()
|
||||
self.worker.start()
|
||||
self.attachments = []
|
||||
self.load_images = False
|
||||
# We'll put images here, so it will be easier to work with them.
|
||||
self.images = []
|
||||
self.imageIndex = 0
|
||||
# connect here the pubsub event for successful posting of comments.
|
||||
pub.subscribe(self.posted, "posted")
|
||||
self.run()
|
||||
pub.unsubscribe(self.posted, "posted")
|
||||
def __init__(self, session, postObject, view, interactor):
|
||||
self.type = "comment"
|
||||
self.modulename = "display_comment"
|
||||
self.interactor = interactor
|
||||
self.view = view
|
||||
self.interactor.install(view=view, presenter=self, modulename=self.modulename)
|
||||
self.session = session
|
||||
self.post = postObject
|
||||
self.user_identifier = "from_id"
|
||||
self.post_identifier = "id"
|
||||
self.worker = threading.Thread(target=self.load_all_components)
|
||||
self.worker.finished = threading.Event()
|
||||
self.worker.start()
|
||||
self.attachments = []
|
||||
self.load_images = False
|
||||
# We'll put images here, so it will be easier to work with them.
|
||||
self.images = []
|
||||
self.imageIndex = 0
|
||||
# connect here the pubsub event for successful posting of comments.
|
||||
pub.subscribe(self.posted, "posted")
|
||||
self.run()
|
||||
pub.unsubscribe(self.posted, "posted")
|
||||
|
||||
def load_all_components(self):
|
||||
self.get_post_information()
|
||||
self.get_likes()
|
||||
self.send_message("disable_control", control="comment")
|
||||
if self.post["likes"]["can_like"] == 0 and self.post["likes"]["user_likes"] == 0:
|
||||
self.send_message("disable_control", "like")
|
||||
elif self.post["likes"]["user_likes"] == 1:
|
||||
self.send_message("set_label", control="like", label=_("&Dislike"))
|
||||
def load_all_components(self):
|
||||
self.get_post_information()
|
||||
self.get_likes()
|
||||
self.send_message("disable_control", control="comment")
|
||||
if self.post["likes"]["can_like"] == 0 and self.post["likes"]["user_likes"] == 0:
|
||||
self.send_message("disable_control", "like")
|
||||
elif self.post["likes"]["user_likes"] == 1:
|
||||
self.send_message("set_label", control="like", label=_("&Dislike"))
|
||||
|
||||
def get_post_information(self):
|
||||
from_ = self.session.get_user(self.post[self.user_identifier])
|
||||
if ("from_id" in self.post and "owner_id" in self.post):
|
||||
user2 = self.session.get_user(self.post["owner_id"], "user2")
|
||||
user2.update(from_)
|
||||
title = _("Comment from {user1_nom} in the {user2_nom}'s post").format(**user2)
|
||||
self.send_message("set_title", value=title)
|
||||
message = ""
|
||||
message = get_message(self.post)
|
||||
self.send_message("set", control="post_view", value=message)
|
||||
self.get_attachments(self.post, message)
|
||||
self.check_image_load()
|
||||
def get_post_information(self):
|
||||
from_ = self.session.get_user(self.post[self.user_identifier])
|
||||
if ("from_id" in self.post and "owner_id" in self.post):
|
||||
user2 = self.session.get_user(self.post["owner_id"], "user2")
|
||||
user2.update(from_)
|
||||
title = _("Comment from {user1_nom} in the {user2_nom}'s post").format(**user2)
|
||||
self.send_message("set_title", value=title)
|
||||
message = ""
|
||||
message = get_message(self.post)
|
||||
self.send_message("set", control="post_view", value=message)
|
||||
self.get_attachments(self.post, message)
|
||||
self.check_image_load()
|
||||
|
||||
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"))
|
||||
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)
|
||||
attachments = []
|
||||
if hasattr(comment, "attachments"):
|
||||
attachments = comment.attachments
|
||||
call_threaded(pub.sendMessage, "post", parent_endpoint="wall", child_endpoint="createComment", attachments_list=attachments, post_arguments=post_arguments)
|
||||
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"))
|
||||
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)
|
||||
attachments = []
|
||||
if hasattr(comment, "attachments"):
|
||||
attachments = comment.attachments
|
||||
call_threaded(pub.sendMessage, "post", parent_endpoint="wall", child_endpoint="createComment", attachments_list=attachments, post_arguments=post_arguments)
|
||||
|
||||
def show_likes(self):
|
||||
""" 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)
|
||||
result = self.session.vk.client.likes.getList(**data)
|
||||
if result["count"] > 0:
|
||||
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")))
|
||||
def show_likes(self):
|
||||
""" 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)
|
||||
result = self.session.vk.client.likes.getList(**data)
|
||||
if result["count"] > 0:
|
||||
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")))
|
||||
|
||||
def posted(self, from_buffer=None):
|
||||
self.interactor.uninstall()
|
||||
return
|
||||
def posted(self, from_buffer=None):
|
||||
self.interactor.uninstall()
|
||||
return
|
||||
|
@ -8,43 +8,43 @@ log = logging.getLogger(__file__)
|
||||
|
||||
class displayFriendshipPresenter(base.basePresenter):
|
||||
|
||||
def __init__(self, session, postObject, view, interactor, caption=""):
|
||||
self.session = session
|
||||
self.post = postObject
|
||||
super(displayFriendshipPresenter, self).__init__(view=view, interactor=interactor, modulename="display_friendship")
|
||||
list_of_friends = self.get_friend_names()
|
||||
from_ = self.session.get_user(self.post["source_id"])
|
||||
title = caption.format(**from_)
|
||||
self.send_message("set_title", value=title)
|
||||
self.set_friends_list(list_of_friends)
|
||||
self.run()
|
||||
def __init__(self, session, postObject, view, interactor, caption=""):
|
||||
self.session = session
|
||||
self.post = postObject
|
||||
super(displayFriendshipPresenter, self).__init__(view=view, interactor=interactor, modulename="display_friendship")
|
||||
list_of_friends = self.get_friend_names()
|
||||
from_ = self.session.get_user(self.post["source_id"])
|
||||
title = caption.format(**from_)
|
||||
self.send_message("set_title", value=title)
|
||||
self.set_friends_list(list_of_friends)
|
||||
self.run()
|
||||
|
||||
def get_friend_names(self):
|
||||
self.friends = self.post["friends"]["items"]
|
||||
friends = list()
|
||||
for i in self.friends:
|
||||
if "user_id" in i:
|
||||
friends.append(self.session.get_user(i["user_id"])["user1_nom"])
|
||||
else:
|
||||
friends.append(self.session.get_user(i["id"])["user1_nom"])
|
||||
return friends
|
||||
def get_friend_names(self):
|
||||
self.friends = self.post["friends"]["items"]
|
||||
friends = list()
|
||||
for i in self.friends:
|
||||
if "user_id" in i:
|
||||
friends.append(self.session.get_user(i["user_id"])["user1_nom"])
|
||||
else:
|
||||
friends.append(self.session.get_user(i["id"])["user1_nom"])
|
||||
return friends
|
||||
|
||||
def set_friends_list(self, friendslist):
|
||||
self.send_message("add_items", control="friends", items=friendslist)
|
||||
def set_friends_list(self, friendslist):
|
||||
self.send_message("add_items", control="friends", items=friendslist)
|
||||
|
||||
def view_profile(self, item):
|
||||
user = self.friends[item]
|
||||
if "user_id" in user:
|
||||
id = user["user_id"]
|
||||
else:
|
||||
id = user["id"]
|
||||
pub.sendMessage("user-profile", person=id)
|
||||
def view_profile(self, item):
|
||||
user = self.friends[item]
|
||||
if "user_id" in user:
|
||||
id = user["user_id"]
|
||||
else:
|
||||
id = user["id"]
|
||||
pub.sendMessage("user-profile", person=id)
|
||||
|
||||
def open_in_browser(self, item):
|
||||
user = self.friends[item]
|
||||
if "user_id" in user:
|
||||
id = user["user_id"]
|
||||
else:
|
||||
id = user["id"]
|
||||
url = "https://vk.com/id{user_id}".format(user_id=id)
|
||||
webbrowser.open_new_tab(url)
|
||||
def open_in_browser(self, item):
|
||||
user = self.friends[item]
|
||||
if "user_id" in user:
|
||||
id = user["user_id"]
|
||||
else:
|
||||
id = user["id"]
|
||||
url = "https://vk.com/id{user_id}".format(user_id=id)
|
||||
webbrowser.open_new_tab(url)
|
||||
|
@ -7,49 +7,49 @@ log = logging.getLogger(__file__)
|
||||
|
||||
class displayPollPresenter(base.basePresenter):
|
||||
|
||||
def __init__(self, session, poll, view, interactor, show_results=False):
|
||||
super(displayPollPresenter, self).__init__(view=view, interactor=interactor, modulename="display_poll")
|
||||
self.poll = poll["poll"]
|
||||
self.session = session
|
||||
self.get_poll()
|
||||
self.load_poll(show_results)
|
||||
self.run()
|
||||
def __init__(self, session, poll, view, interactor, show_results=False):
|
||||
super(displayPollPresenter, self).__init__(view=view, interactor=interactor, modulename="display_poll")
|
||||
self.poll = poll["poll"]
|
||||
self.session = session
|
||||
self.get_poll()
|
||||
self.load_poll(show_results)
|
||||
self.run()
|
||||
|
||||
def get_poll(self):
|
||||
# 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"])
|
||||
self.poll = self.session.vk.client.polls.getById(**data)
|
||||
def get_poll(self):
|
||||
# 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"])
|
||||
self.poll = self.session.vk.client.polls.getById(**data)
|
||||
|
||||
def load_poll(self, load_results=False):
|
||||
user = self.session.get_user(self.poll["author_id"])
|
||||
title = _("Poll from {user1_nom}").format(**user)
|
||||
self.send_message("set_title", value=title)
|
||||
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):
|
||||
options = []
|
||||
for i in self.poll["answers"]:
|
||||
options.append((i["text"], i["votes"], i["rate"]))
|
||||
self.send_message("add_options", options=options, multiple=self.poll["multiple"])
|
||||
self.send_message("done")
|
||||
self.send_message("disable_control", control="ok")
|
||||
else:
|
||||
options = []
|
||||
for i in self.poll["answers"]:
|
||||
options.append(i["text"])
|
||||
self.send_message("add_options", options=options, multiple=self.poll["multiple"])
|
||||
self.send_message("done")
|
||||
def load_poll(self, load_results=False):
|
||||
user = self.session.get_user(self.poll["author_id"])
|
||||
title = _("Poll from {user1_nom}").format(**user)
|
||||
self.send_message("set_title", value=title)
|
||||
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):
|
||||
options = []
|
||||
for i in self.poll["answers"]:
|
||||
options.append((i["text"], i["votes"], i["rate"]))
|
||||
self.send_message("add_options", options=options, multiple=self.poll["multiple"])
|
||||
self.send_message("done")
|
||||
self.send_message("disable_control", control="ok")
|
||||
else:
|
||||
options = []
|
||||
for i in self.poll["answers"]:
|
||||
options.append(i["text"])
|
||||
self.send_message("add_options", options=options, multiple=self.poll["multiple"])
|
||||
self.send_message("done")
|
||||
|
||||
def vote(self, answers):
|
||||
ids = ""
|
||||
for i in range(0, len(self.poll["answers"])):
|
||||
if answers[i] == True:
|
||||
ids = ids+"{answer_id},".format(answer_id=self.poll["answers"][i]["id"])
|
||||
if self.poll["multiple"] == False:
|
||||
break
|
||||
if ids == "":
|
||||
log.exception("An error occurred when retrieving answer IDS for the following poll: %r. Provided answer list: %r" % (self.poll, answers))
|
||||
return
|
||||
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)
|
||||
if result == 1:
|
||||
output.speak(_("Your vote has been added to this poll."))
|
||||
def vote(self, answers):
|
||||
ids = ""
|
||||
for i in range(0, len(self.poll["answers"])):
|
||||
if answers[i] == True:
|
||||
ids = ids+"{answer_id},".format(answer_id=self.poll["answers"][i]["id"])
|
||||
if self.poll["multiple"] == False:
|
||||
break
|
||||
if ids == "":
|
||||
log.exception("An error occurred when retrieving answer IDS for the following poll: %r. Provided answer list: %r" % (self.poll, answers))
|
||||
return
|
||||
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)
|
||||
if result == 1:
|
||||
output.speak(_("Your vote has been added to this poll."))
|
||||
|
@ -18,151 +18,151 @@ log = logging.getLogger(__file__)
|
||||
|
||||
class displayTopicPresenter(basePost.displayPostPresenter):
|
||||
|
||||
def __init__(self, session, postObject, group_id, view, interactor):
|
||||
self.type = "topic"
|
||||
self.modulename = "display_topic"
|
||||
self.interactor = interactor
|
||||
self.view = view
|
||||
self.interactor.install(view=view, presenter=self, modulename=self.modulename)
|
||||
self.session = session
|
||||
self.post = postObject
|
||||
self.group_id = group_id
|
||||
self.load_images = False
|
||||
# We'll put images here, so it will be easier to work with them.
|
||||
self.images = []
|
||||
self.imageIndex = 0
|
||||
result = self.get_post_information()
|
||||
# Stop loading everything else if post was deleted.
|
||||
if result == False:
|
||||
self.interactor.uninstall()
|
||||
return
|
||||
self.worker = threading.Thread(target=self.load_all_components)
|
||||
self.worker.finished = threading.Event()
|
||||
self.worker.start()
|
||||
self.attachments = []
|
||||
# connect pubsub event for posted comments.
|
||||
pub.subscribe(self.posted, "posted")
|
||||
self.run()
|
||||
pub.unsubscribe(self.posted, "posted")
|
||||
def __init__(self, session, postObject, group_id, view, interactor):
|
||||
self.type = "topic"
|
||||
self.modulename = "display_topic"
|
||||
self.interactor = interactor
|
||||
self.view = view
|
||||
self.interactor.install(view=view, presenter=self, modulename=self.modulename)
|
||||
self.session = session
|
||||
self.post = postObject
|
||||
self.group_id = group_id
|
||||
self.load_images = False
|
||||
# We'll put images here, so it will be easier to work with them.
|
||||
self.images = []
|
||||
self.imageIndex = 0
|
||||
result = self.get_post_information()
|
||||
# Stop loading everything else if post was deleted.
|
||||
if result == False:
|
||||
self.interactor.uninstall()
|
||||
return
|
||||
self.worker = threading.Thread(target=self.load_all_components)
|
||||
self.worker.finished = threading.Event()
|
||||
self.worker.start()
|
||||
self.attachments = []
|
||||
# connect pubsub event for posted comments.
|
||||
pub.subscribe(self.posted, "posted")
|
||||
self.run()
|
||||
pub.unsubscribe(self.posted, "posted")
|
||||
|
||||
def load_all_components(self):
|
||||
self.get_comments()
|
||||
def load_all_components(self):
|
||||
self.get_comments()
|
||||
|
||||
def get_post_information(self):
|
||||
title = self.post["title"]
|
||||
self.send_message("set_title", value=title)
|
||||
return True
|
||||
def get_post_information(self):
|
||||
title = self.post["title"]
|
||||
self.send_message("set_title", value=title)
|
||||
return True
|
||||
|
||||
def get_comments(self):
|
||||
""" 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")
|
||||
comments_ = []
|
||||
data = dict(profiles=self.comments["profiles"], groups=[])
|
||||
self.session.process_usernames(data)
|
||||
self.comments["items"].reverse()
|
||||
# If there are less than 100 comments in the topic we should disable the "load previous" button.
|
||||
if self.comments["count"] <= 100:
|
||||
self.send_message("disable_control", control="load_more_comments")
|
||||
else:
|
||||
left_comments = self.comments["count"]-len(self.comments["items"])
|
||||
if left_comments > 100:
|
||||
left_comments = 100
|
||||
self.send_message("set_label", control="load_more_comments", label=_("Load {comments} previous comments").format(comments=left_comments))
|
||||
for i in self.comments["items"]:
|
||||
# If comment has a "deleted" key it should not be displayed, obviously.
|
||||
if "deleted" in i:
|
||||
continue
|
||||
from_ = self.session.get_user(i["from_id"])["user1_nom"]
|
||||
# match user mentions inside text comment.
|
||||
original_date = arrow.get(i["date"])
|
||||
created_at = original_date.humanize(locale=languageHandler.curLang[:2])
|
||||
likes = str(i["likes"]["count"])
|
||||
text = utils.clean_text(text=i["text"])
|
||||
comments_.append((from_, text, created_at, likes))
|
||||
self.send_message("add_items", control="comments", items=comments_)
|
||||
def get_comments(self):
|
||||
""" 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")
|
||||
comments_ = []
|
||||
data = dict(profiles=self.comments["profiles"], groups=[])
|
||||
self.session.process_usernames(data)
|
||||
self.comments["items"].reverse()
|
||||
# If there are less than 100 comments in the topic we should disable the "load previous" button.
|
||||
if self.comments["count"] <= 100:
|
||||
self.send_message("disable_control", control="load_more_comments")
|
||||
else:
|
||||
left_comments = self.comments["count"]-len(self.comments["items"])
|
||||
if left_comments > 100:
|
||||
left_comments = 100
|
||||
self.send_message("set_label", control="load_more_comments", label=_("Load {comments} previous comments").format(comments=left_comments))
|
||||
for i in self.comments["items"]:
|
||||
# If comment has a "deleted" key it should not be displayed, obviously.
|
||||
if "deleted" in i:
|
||||
continue
|
||||
from_ = self.session.get_user(i["from_id"])["user1_nom"]
|
||||
# match user mentions inside text comment.
|
||||
original_date = arrow.get(i["date"])
|
||||
created_at = original_date.humanize(locale=languageHandler.curLang[:2])
|
||||
likes = str(i["likes"]["count"])
|
||||
text = utils.clean_text(text=i["text"])
|
||||
comments_.append((from_, text, created_at, likes))
|
||||
self.send_message("add_items", control="comments", items=comments_)
|
||||
|
||||
def post_like(self):
|
||||
c = self.interactor.view.comments.get_selected()
|
||||
id = self.comments["items"][c]["id"]
|
||||
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")
|
||||
output.speak(_("You don't like this"))
|
||||
self.comments["items"][c]["likes"]["count"] = l["likes"]
|
||||
self.comments["items"][c]["likes"]["user_likes"] = 2
|
||||
self.send_message("set_label", control="like", label=_("&Like"))
|
||||
else:
|
||||
l = self.session.vk.client.likes.add(owner_id=-1*self.group_id, item_id=id, type="topic_comment")
|
||||
output.speak(_("You liked this"))
|
||||
self.send_message("set_label", control="like", label=_("&Dislike"))
|
||||
self.comments["items"][c]["likes"]["count"] = l["likes"]
|
||||
self.comments["items"][c]["likes"]["user_likes"] = 1
|
||||
self.clear_comments_list()
|
||||
def post_like(self):
|
||||
c = self.interactor.view.comments.get_selected()
|
||||
id = self.comments["items"][c]["id"]
|
||||
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")
|
||||
output.speak(_("You don't like this"))
|
||||
self.comments["items"][c]["likes"]["count"] = l["likes"]
|
||||
self.comments["items"][c]["likes"]["user_likes"] = 2
|
||||
self.send_message("set_label", control="like", label=_("&Like"))
|
||||
else:
|
||||
l = self.session.vk.client.likes.add(owner_id=-1*self.group_id, item_id=id, type="topic_comment")
|
||||
output.speak(_("You liked this"))
|
||||
self.send_message("set_label", control="like", label=_("&Dislike"))
|
||||
self.comments["items"][c]["likes"]["count"] = l["likes"]
|
||||
self.comments["items"][c]["likes"]["user_likes"] = 1
|
||||
self.clear_comments_list()
|
||||
|
||||
def change_comment(self, comment):
|
||||
comment = self.comments["items"][comment]
|
||||
self.send_message("clean_list", list="attachments")
|
||||
self.get_attachments(comment, "")
|
||||
if comment["likes"]["user_likes"] == 1:
|
||||
self.send_message("set_label", control="like", label=_("&Dislike"))
|
||||
else:
|
||||
self.send_message("set_label", control="like", label=_("&Like"))
|
||||
def change_comment(self, comment):
|
||||
comment = self.comments["items"][comment]
|
||||
self.send_message("clean_list", list="attachments")
|
||||
self.get_attachments(comment, "")
|
||||
if comment["likes"]["user_likes"] == 1:
|
||||
self.send_message("set_label", control="like", label=_("&Dislike"))
|
||||
else:
|
||||
self.send_message("set_label", control="like", label=_("&Like"))
|
||||
|
||||
def add_comment(self):
|
||||
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"):
|
||||
post_arguments = dict(group_id=self.group_id, topic_id=self.post["id"], message=comment.text)
|
||||
attachments = []
|
||||
if hasattr(comment, "attachments"):
|
||||
attachments = comment.attachments
|
||||
call_threaded(pub.sendMessage, "post", parent_endpoint="board", child_endpoint="createComment", attachments_list=attachments, post_arguments=post_arguments)
|
||||
def add_comment(self):
|
||||
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"):
|
||||
post_arguments = dict(group_id=self.group_id, topic_id=self.post["id"], message=comment.text)
|
||||
attachments = []
|
||||
if hasattr(comment, "attachments"):
|
||||
attachments = comment.attachments
|
||||
call_threaded(pub.sendMessage, "post", parent_endpoint="board", child_endpoint="createComment", attachments_list=attachments, post_arguments=post_arguments)
|
||||
|
||||
def reply(self, 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"))
|
||||
if hasattr(comment, "text") or hasattr(comment, "privacy"):
|
||||
user = self.session.get_user(c["from_id"])
|
||||
name = user["user1_nom"].split(" ")[0]
|
||||
comment.text = "[post{post_id}|{name}], {text}".format(post_id=c["id"], text=comment.text, name=name)
|
||||
group_id = self.group_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)
|
||||
attachments = []
|
||||
if hasattr(comment, "attachments"):
|
||||
attachments = comment.attachments
|
||||
call_threaded(pub.sendMessage, "post", parent_endpoint="board", child_endpoint="createComment", attachments_list=attachments, post_arguments=post_arguments)
|
||||
def reply(self, 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"))
|
||||
if hasattr(comment, "text") or hasattr(comment, "privacy"):
|
||||
user = self.session.get_user(c["from_id"])
|
||||
name = user["user1_nom"].split(" ")[0]
|
||||
comment.text = "[post{post_id}|{name}], {text}".format(post_id=c["id"], text=comment.text, name=name)
|
||||
group_id = self.group_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)
|
||||
attachments = []
|
||||
if hasattr(comment, "attachments"):
|
||||
attachments = comment.attachments
|
||||
call_threaded(pub.sendMessage, "post", parent_endpoint="board", child_endpoint="createComment", attachments_list=attachments, post_arguments=post_arguments)
|
||||
|
||||
def show_comment(self, comment_index):
|
||||
c = self.comments["items"][comment_index]
|
||||
c["post_id"] = self.post["id"]
|
||||
c["group_id"] = -1*self.group_id
|
||||
a = displayTopicCommentPresenter(session=self.session, postObject=c, interactor=interactors.displayPostInteractor(), view=views.displayComment())
|
||||
def show_comment(self, comment_index):
|
||||
c = self.comments["items"][comment_index]
|
||||
c["post_id"] = self.post["id"]
|
||||
c["group_id"] = -1*self.group_id
|
||||
a = displayTopicCommentPresenter(session=self.session, postObject=c, interactor=interactors.displayPostInteractor(), view=views.displayComment())
|
||||
|
||||
def load_more_comments(self):
|
||||
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)
|
||||
data = dict(profiles=comments["profiles"], groups=[])
|
||||
self.session.process_usernames(data)
|
||||
# If there are less than 100 comments in the topic we should disable the "load previous" button.
|
||||
for i in comments["items"]:
|
||||
self.comments["items"].insert(0, i)
|
||||
for i in comments["items"]:
|
||||
# If comment has a "deleted" key it should not be displayed, obviously.
|
||||
if "deleted" in i:
|
||||
continue
|
||||
from_ = self.session.get_user(i["from_id"])["user1_nom"]
|
||||
# match user mentions inside text comment.
|
||||
original_date = arrow.get(i["date"])
|
||||
created_at = original_date.humanize(locale=languageHandler.curLang[:2])
|
||||
likes = str(i["likes"]["count"])
|
||||
text = utils.clean_text(text=i["text"])
|
||||
self.send_message("add_item", control="comments", item=(from_, text, created_at, likes), reversed=True)
|
||||
if len(self.comments["items"]) == self.comments["count"]:
|
||||
self.send_message("disable_control", control="load_more_comments")
|
||||
else:
|
||||
left_comments = self.comments["count"]-len(self.comments["items"])
|
||||
if left_comments > 100:
|
||||
left_comments = 100
|
||||
self.send_message("set_label", control="load_more_comments", label=_("Load {comments} previous comments").format(comments=left_comments))
|
||||
def load_more_comments(self):
|
||||
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)
|
||||
data = dict(profiles=comments["profiles"], groups=[])
|
||||
self.session.process_usernames(data)
|
||||
# If there are less than 100 comments in the topic we should disable the "load previous" button.
|
||||
for i in comments["items"]:
|
||||
self.comments["items"].insert(0, i)
|
||||
for i in comments["items"]:
|
||||
# If comment has a "deleted" key it should not be displayed, obviously.
|
||||
if "deleted" in i:
|
||||
continue
|
||||
from_ = self.session.get_user(i["from_id"])["user1_nom"]
|
||||
# match user mentions inside text comment.
|
||||
original_date = arrow.get(i["date"])
|
||||
created_at = original_date.humanize(locale=languageHandler.curLang[:2])
|
||||
likes = str(i["likes"]["count"])
|
||||
text = utils.clean_text(text=i["text"])
|
||||
self.send_message("add_item", control="comments", item=(from_, text, created_at, likes), reversed=True)
|
||||
if len(self.comments["items"]) == self.comments["count"]:
|
||||
self.send_message("disable_control", control="load_more_comments")
|
||||
else:
|
||||
left_comments = self.comments["count"]-len(self.comments["items"])
|
||||
if left_comments > 100:
|
||||
left_comments = 100
|
||||
self.send_message("set_label", control="load_more_comments", label=_("Load {comments} previous comments").format(comments=left_comments))
|
||||
|
||||
def posted(self, from_buffer=None):
|
||||
self.clear_comments_list()
|
||||
def posted(self, from_buffer=None):
|
||||
self.clear_comments_list()
|
||||
|
@ -10,44 +10,44 @@ from . import comment
|
||||
log = logging.getLogger(__file__)
|
||||
|
||||
def get_message(status):
|
||||
message = ""
|
||||
if "text" in status:
|
||||
message = utils.clean_text(status["text"])
|
||||
return message
|
||||
message = ""
|
||||
if "text" in status:
|
||||
message = utils.clean_text(status["text"])
|
||||
return message
|
||||
|
||||
class displayTopicCommentPresenter(comment.displayCommentPresenter):
|
||||
|
||||
def get_post_information(self):
|
||||
from_ = self.session.get_user(self.post[self.user_identifier])
|
||||
title = from_["user1_nom"]
|
||||
self.send_message("set_title", value=title)
|
||||
message = ""
|
||||
message = get_message(self.post)
|
||||
self.send_message("set", control="post_view", value=message)
|
||||
self.get_attachments(self.post, message)
|
||||
self.check_image_load()
|
||||
self.send_message("disable_control", control="reply")
|
||||
def get_post_information(self):
|
||||
from_ = self.session.get_user(self.post[self.user_identifier])
|
||||
title = from_["user1_nom"]
|
||||
self.send_message("set_title", value=title)
|
||||
message = ""
|
||||
message = get_message(self.post)
|
||||
self.send_message("set", control="post_view", value=message)
|
||||
self.get_attachments(self.post, message)
|
||||
self.check_image_load()
|
||||
self.send_message("disable_control", control="reply")
|
||||
|
||||
def post_like(self):
|
||||
id = self.post["id"]
|
||||
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")
|
||||
output.speak(_("You don't like this"))
|
||||
self.post["likes"]["count"] = l["likes"]
|
||||
self.post["likes"]["user_likes"] = 2
|
||||
self.send_message("set_label", control="like", label=_("&Like"))
|
||||
else:
|
||||
l = self.session.vk.client.likes.add(owner_id=self.post["group_id"], item_id=id, type="topic_comment")
|
||||
output.speak(_("You liked this"))
|
||||
self.send_message("set_label", control="like", label=_("&Dislike"))
|
||||
self.post["likes"]["count"] = l["likes"]
|
||||
self.post["likes"]["user_likes"] = 1
|
||||
self.get_likes()
|
||||
def post_like(self):
|
||||
id = self.post["id"]
|
||||
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")
|
||||
output.speak(_("You don't like this"))
|
||||
self.post["likes"]["count"] = l["likes"]
|
||||
self.post["likes"]["user_likes"] = 2
|
||||
self.send_message("set_label", control="like", label=_("&Like"))
|
||||
else:
|
||||
l = self.session.vk.client.likes.add(owner_id=self.post["group_id"], item_id=id, type="topic_comment")
|
||||
output.speak(_("You liked this"))
|
||||
self.send_message("set_label", control="like", label=_("&Dislike"))
|
||||
self.post["likes"]["count"] = l["likes"]
|
||||
self.post["likes"]["user_likes"] = 1
|
||||
self.get_likes()
|
||||
|
||||
def show_likes(self):
|
||||
""" 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)
|
||||
result = self.session.vk.client.likes.getList(**data)
|
||||
if result["count"] > 0:
|
||||
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")))
|
||||
def show_likes(self):
|
||||
""" 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)
|
||||
result = self.session.vk.client.likes.getList(**data)
|
||||
if result["count"] > 0:
|
||||
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")))
|
||||
|
@ -8,22 +8,22 @@ from logging import getLogger
|
||||
log = getLogger("controller.longpolThread")
|
||||
|
||||
class worker(threading.Thread):
|
||||
def __init__(self, session):
|
||||
super(worker, self).__init__()
|
||||
log.debug("Instantiating longPoll server")
|
||||
self.session = session
|
||||
self.longpoll = VkLongPoll(self.session.vk.session_object)
|
||||
def __init__(self, session):
|
||||
super(worker, self).__init__()
|
||||
log.debug("Instantiating longPoll server")
|
||||
self.session = session
|
||||
self.longpoll = VkLongPoll(self.session.vk.session_object)
|
||||
|
||||
def run(self):
|
||||
try:
|
||||
for event in self.longpoll.listen():
|
||||
if event.type == VkEventType.MESSAGE_NEW:
|
||||
pub.sendMessage("order-sent-message", obj=event)
|
||||
elif event.type == VkEventType.USER_ONLINE:
|
||||
pub.sendMessage("user-online", event=event)
|
||||
elif event.type == VkEventType.USER_OFFLINE:
|
||||
pub.sendMessage("user-offline", event=event)
|
||||
elif event.type == VkEventType.USER_TYPING:
|
||||
pub.sendMessage("user-typing", obj=event)
|
||||
except:
|
||||
pub.sendMessage("longpoll-read-timeout")
|
||||
def run(self):
|
||||
try:
|
||||
for event in self.longpoll.listen():
|
||||
if event.type == VkEventType.MESSAGE_NEW:
|
||||
pub.sendMessage("order-sent-message", obj=event)
|
||||
elif event.type == VkEventType.USER_ONLINE:
|
||||
pub.sendMessage("user-online", event=event)
|
||||
elif event.type == VkEventType.USER_OFFLINE:
|
||||
pub.sendMessage("user-offline", event=event)
|
||||
elif event.type == VkEventType.USER_TYPING:
|
||||
pub.sendMessage("user-typing", obj=event)
|
||||
except:
|
||||
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")
|
||||
|
||||
def setup():
|
||||
global player
|
||||
if player == None:
|
||||
player = audioPlayer()
|
||||
global player
|
||||
if player == None:
|
||||
player = audioPlayer()
|
||||
|
||||
class audioPlayer(object):
|
||||
""" A media player which will play all passed URLS."""
|
||||
""" A media player which will play all passed URLS."""
|
||||
|
||||
def __init__(self):
|
||||
# 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.
|
||||
self.is_playing = False
|
||||
# This will be the URLStream handler
|
||||
self.stream = None
|
||||
self.message = None
|
||||
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.
|
||||
self.is_working = False
|
||||
# Playback queue.
|
||||
self.queue = []
|
||||
# Index of the currently playing track.
|
||||
self.playing_track = 0
|
||||
self.playing_all = False
|
||||
self.worker = RepeatingTimer(5, self.player_function)
|
||||
self.worker.start()
|
||||
# Status of the player.
|
||||
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.
|
||||
bassconfig = BassConfig()
|
||||
# Set timeout connection to 30 seconds.
|
||||
bassconfig["net_timeout"] = 30000
|
||||
# subscribe all pubsub events.
|
||||
pub.subscribe(self.play, "play")
|
||||
pub.subscribe(self.play_message, "play-message")
|
||||
pub.subscribe(self.play_all, "play-all")
|
||||
pub.subscribe(self.pause, "pause")
|
||||
pub.subscribe(self.stop, "stop")
|
||||
pub.subscribe(self.play_next, "play-next")
|
||||
pub.subscribe(self.play_previous, "play-previous")
|
||||
pub.subscribe(self.seek, "seek")
|
||||
def __init__(self):
|
||||
# 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.
|
||||
self.is_playing = False
|
||||
# This will be the URLStream handler
|
||||
self.stream = None
|
||||
self.message = None
|
||||
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.
|
||||
self.is_working = False
|
||||
# Playback queue.
|
||||
self.queue = []
|
||||
# Index of the currently playing track.
|
||||
self.playing_track = 0
|
||||
self.playing_all = False
|
||||
self.worker = RepeatingTimer(5, self.player_function)
|
||||
self.worker.start()
|
||||
# Status of the player.
|
||||
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.
|
||||
bassconfig = BassConfig()
|
||||
# Set timeout connection to 30 seconds.
|
||||
bassconfig["net_timeout"] = 30000
|
||||
# subscribe all pubsub events.
|
||||
pub.subscribe(self.play, "play")
|
||||
pub.subscribe(self.play_message, "play-message")
|
||||
pub.subscribe(self.play_all, "play-all")
|
||||
pub.subscribe(self.pause, "pause")
|
||||
pub.subscribe(self.stop, "stop")
|
||||
pub.subscribe(self.play_next, "play-next")
|
||||
pub.subscribe(self.play_previous, "play-previous")
|
||||
pub.subscribe(self.seek, "seek")
|
||||
|
||||
# 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.
|
||||
# this is useful for changing labels between play and pause, and so on, in buttons.
|
||||
@property
|
||||
def stopped(self):
|
||||
return self._stopped
|
||||
# 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.
|
||||
# this is useful for changing labels between play and pause, and so on, in buttons.
|
||||
@property
|
||||
def stopped(self):
|
||||
return self._stopped
|
||||
|
||||
@stopped.setter
|
||||
def stopped(self, value):
|
||||
self._stopped = value
|
||||
pub.sendMessage("playback-changed", stopped=value)
|
||||
@stopped.setter
|
||||
def stopped(self, value):
|
||||
self._stopped = value
|
||||
pub.sendMessage("playback-changed", stopped=value)
|
||||
|
||||
def play(self, object, set_info=True, fresh=False):
|
||||
""" 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.
|
||||
@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."""
|
||||
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"))
|
||||
return
|
||||
if self.stream != None and (self.stream.is_playing == True or self.stream.is_stalled == True):
|
||||
try:
|
||||
self.stream.stop()
|
||||
except BassError:
|
||||
log.exception("error when stopping the file")
|
||||
self.stream = None
|
||||
self.stopped = True
|
||||
if fresh == True:
|
||||
self.queue = []
|
||||
# Make sure that there are no other sounds trying to be played.
|
||||
if self.is_working == False:
|
||||
self.is_working = True
|
||||
url_ = utils.transform_audio_url(object["url"])
|
||||
try:
|
||||
self.stream = URLStream(url=url_)
|
||||
except:
|
||||
log.error("Unable to play URL %s" % (url_))
|
||||
return
|
||||
# Translators: {0} will be replaced with a song's title and {1} with the artist.
|
||||
if set_info:
|
||||
msg = _("Playing {0} by {1}").format(object["title"], object["artist"])
|
||||
pub.sendMessage("update-status-bar", status=msg)
|
||||
self.stream.volume = self.vol/100.0
|
||||
self.stream.play()
|
||||
self.stopped = False
|
||||
self.is_working = False
|
||||
def play(self, object, set_info=True, fresh=False):
|
||||
""" 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.
|
||||
@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."""
|
||||
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"))
|
||||
return
|
||||
if self.stream != None and (self.stream.is_playing == True or self.stream.is_stalled == True):
|
||||
try:
|
||||
self.stream.stop()
|
||||
except BassError:
|
||||
log.exception("error when stopping the file")
|
||||
self.stream = None
|
||||
self.stopped = True
|
||||
if fresh == True:
|
||||
self.queue = []
|
||||
# Make sure that there are no other sounds trying to be played.
|
||||
if self.is_working == False:
|
||||
self.is_working = True
|
||||
url_ = utils.transform_audio_url(object["url"])
|
||||
try:
|
||||
self.stream = URLStream(url=url_)
|
||||
except:
|
||||
log.error("Unable to play URL %s" % (url_))
|
||||
return
|
||||
# Translators: {0} will be replaced with a song's title and {1} with the artist.
|
||||
if set_info:
|
||||
msg = _("Playing {0} by {1}").format(object["title"], object["artist"])
|
||||
pub.sendMessage("update-status-bar", status=msg)
|
||||
self.stream.volume = self.vol/100.0
|
||||
self.stream.play()
|
||||
self.stopped = False
|
||||
self.is_working = False
|
||||
|
||||
def play_message(self, message_url):
|
||||
if self.message != None and (self.message.is_playing == True or self.message.is_stalled == True):
|
||||
return self.stop_message()
|
||||
output.speak(_("Playing..."))
|
||||
url_ = utils.transform_audio_url(message_url)
|
||||
try:
|
||||
self.message = URLStream(url=url_)
|
||||
except:
|
||||
log.error("Unable to play URL %s" % (url_))
|
||||
return
|
||||
self.message.volume = self.vol/100.0
|
||||
self.message.play()
|
||||
volume_percent = self.volume*0.25
|
||||
volume_step = self.volume*0.15
|
||||
while self.stream.volume*100 > volume_percent:
|
||||
self.stream.volume = self.stream.volume-(volume_step/100)
|
||||
time.sleep(0.1)
|
||||
def play_message(self, message_url):
|
||||
if self.message != None and (self.message.is_playing == True or self.message.is_stalled == True):
|
||||
return self.stop_message()
|
||||
output.speak(_("Playing..."))
|
||||
url_ = utils.transform_audio_url(message_url)
|
||||
try:
|
||||
self.message = URLStream(url=url_)
|
||||
except:
|
||||
log.error("Unable to play URL %s" % (url_))
|
||||
return
|
||||
self.message.volume = self.vol/100.0
|
||||
self.message.play()
|
||||
volume_percent = self.volume*0.25
|
||||
volume_step = self.volume*0.15
|
||||
while self.stream.volume*100 > volume_percent:
|
||||
self.stream.volume = self.stream.volume-(volume_step/100)
|
||||
time.sleep(0.1)
|
||||
|
||||
def stop(self):
|
||||
""" Stop audio playback. """
|
||||
if self.stream != None and self.stream.is_playing == True:
|
||||
self.stream.stop()
|
||||
self.stopped = True
|
||||
self.queue = []
|
||||
def stop(self):
|
||||
""" Stop audio playback. """
|
||||
if self.stream != None and self.stream.is_playing == True:
|
||||
self.stream.stop()
|
||||
self.stopped = True
|
||||
self.queue = []
|
||||
|
||||
def stop_message(self):
|
||||
if hasattr(self, "message") and self.message != None and self.message.is_playing == True:
|
||||
self.message.stop()
|
||||
volume_step = self.volume*0.15
|
||||
while self.stream.volume*100 < self.volume:
|
||||
self.stream.volume = self.stream.volume+(volume_step/100)
|
||||
time.sleep(0.1)
|
||||
self.message = None
|
||||
def stop_message(self):
|
||||
if hasattr(self, "message") and self.message != None and self.message.is_playing == True:
|
||||
self.message.stop()
|
||||
volume_step = self.volume*0.15
|
||||
while self.stream.volume*100 < self.volume:
|
||||
self.stream.volume = self.stream.volume+(volume_step/100)
|
||||
time.sleep(0.1)
|
||||
self.message = None
|
||||
|
||||
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. """
|
||||
if self.stream != None:
|
||||
if self.stream.is_playing == True:
|
||||
self.stream.pause()
|
||||
self.stopped = True
|
||||
else:
|
||||
try:
|
||||
self.stream.play()
|
||||
self.stopped = False
|
||||
except BassError:
|
||||
pass
|
||||
if self.playing_all == False and len(self.queue) > 0:
|
||||
self.playing_all = True
|
||||
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. """
|
||||
if self.stream != None:
|
||||
if self.stream.is_playing == True:
|
||||
self.stream.pause()
|
||||
self.stopped = True
|
||||
else:
|
||||
try:
|
||||
self.stream.play()
|
||||
self.stopped = False
|
||||
except BassError:
|
||||
pass
|
||||
if self.playing_all == False and len(self.queue) > 0:
|
||||
self.playing_all = True
|
||||
|
||||
@property
|
||||
def volume(self):
|
||||
return self.vol
|
||||
@property
|
||||
def volume(self):
|
||||
return self.vol
|
||||
|
||||
@volume.setter
|
||||
def volume(self, vol):
|
||||
if vol <= 100 and vol >= 0:
|
||||
self.vol = vol
|
||||
elif vol < 0:
|
||||
self.vol = 0
|
||||
elif vol > 100:
|
||||
self.vol = 100
|
||||
if self.stream != None:
|
||||
if self.message != None and self.message.is_playing:
|
||||
self.stream.volume = (self.vol*0.25)/100.0
|
||||
self.message.volume = self.vol/100.0
|
||||
else:
|
||||
self.stream.volume = self.vol/100.0
|
||||
@volume.setter
|
||||
def volume(self, vol):
|
||||
if vol <= 100 and vol >= 0:
|
||||
self.vol = vol
|
||||
elif vol < 0:
|
||||
self.vol = 0
|
||||
elif vol > 100:
|
||||
self.vol = 100
|
||||
if self.stream != None:
|
||||
if self.message != None and self.message.is_playing:
|
||||
self.stream.volume = (self.vol*0.25)/100.0
|
||||
self.message.volume = self.vol/100.0
|
||||
else:
|
||||
self.stream.volume = self.vol/100.0
|
||||
|
||||
def play_all(self, list_of_songs, shuffle=False):
|
||||
""" Play all passed songs and adds all of those to the queue.
|
||||
@list_of_songs list: A list of audio objects returned by VK.
|
||||
@shuffle bool: If True, the files will be played randomly."""
|
||||
if self.is_working:
|
||||
return
|
||||
self.playing_track = 0
|
||||
self.stop()
|
||||
# Skip all country restricted tracks as they are not playable here.
|
||||
self.queue = [i for i in list_of_songs if i["url"] != ""]
|
||||
if shuffle:
|
||||
random.shuffle(self.queue)
|
||||
call_threaded(self.play, self.queue[self.playing_track])
|
||||
self.playing_all = True
|
||||
def play_all(self, list_of_songs, shuffle=False):
|
||||
""" Play all passed songs and adds all of those to the queue.
|
||||
@list_of_songs list: A list of audio objects returned by VK.
|
||||
@shuffle bool: If True, the files will be played randomly."""
|
||||
if self.is_working:
|
||||
return
|
||||
self.playing_track = 0
|
||||
self.stop()
|
||||
# Skip all country restricted tracks as they are not playable here.
|
||||
self.queue = [i for i in list_of_songs if i["url"] != ""]
|
||||
if shuffle:
|
||||
random.shuffle(self.queue)
|
||||
call_threaded(self.play, self.queue[self.playing_track])
|
||||
self.playing_all = True
|
||||
|
||||
def player_function(self):
|
||||
""" 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:
|
||||
volume_step = self.volume*0.15
|
||||
while self.stream != None and self.stream.volume*100 < self.volume:
|
||||
self.stream.volume = self.stream.volume+(volume_step/100)
|
||||
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.playing_track >= len(self.queue):
|
||||
self.stopped = True
|
||||
self.playing_all = False
|
||||
return
|
||||
elif self.playing_all == False:
|
||||
self.stopped = True
|
||||
return
|
||||
elif self.playing_track < len(self.queue):
|
||||
self.playing_track += 1
|
||||
self.play(self.queue[self.playing_track])
|
||||
def player_function(self):
|
||||
""" 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:
|
||||
volume_step = self.volume*0.15
|
||||
while self.stream != None and self.stream.volume*100 < self.volume:
|
||||
self.stream.volume = self.stream.volume+(volume_step/100)
|
||||
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.playing_track >= len(self.queue):
|
||||
self.stopped = True
|
||||
self.playing_all = False
|
||||
return
|
||||
elif self.playing_all == False:
|
||||
self.stopped = True
|
||||
return
|
||||
elif self.playing_track < len(self.queue):
|
||||
self.playing_track += 1
|
||||
self.play(self.queue[self.playing_track])
|
||||
|
||||
def play_next(self):
|
||||
""" Play the next song in the queue. """
|
||||
if len(self.queue) == 0:
|
||||
return
|
||||
if self.is_working:
|
||||
return
|
||||
if self.playing_track < len(self.queue)-1:
|
||||
self.playing_track += 1
|
||||
else:
|
||||
self.playing_track = 0
|
||||
call_threaded(self.play, self.queue[self.playing_track])
|
||||
def play_next(self):
|
||||
""" Play the next song in the queue. """
|
||||
if len(self.queue) == 0:
|
||||
return
|
||||
if self.is_working:
|
||||
return
|
||||
if self.playing_track < len(self.queue)-1:
|
||||
self.playing_track += 1
|
||||
else:
|
||||
self.playing_track = 0
|
||||
call_threaded(self.play, self.queue[self.playing_track])
|
||||
|
||||
def play_previous(self):
|
||||
""" Play the previous song in the queue. """
|
||||
if len(self.queue) == 0:
|
||||
return
|
||||
if self.is_working:
|
||||
return
|
||||
if self.playing_track <= 0:
|
||||
self.playing_track = len(self.queue)-1
|
||||
else:
|
||||
self.playing_track -= 1
|
||||
call_threaded(self.play, self.queue[self.playing_track])
|
||||
def play_previous(self):
|
||||
""" Play the previous song in the queue. """
|
||||
if len(self.queue) == 0:
|
||||
return
|
||||
if self.is_working:
|
||||
return
|
||||
if self.playing_track <= 0:
|
||||
self.playing_track = len(self.queue)-1
|
||||
else:
|
||||
self.playing_track -= 1
|
||||
call_threaded(self.play, self.queue[self.playing_track])
|
||||
|
||||
def seek(self, ms=0):
|
||||
if self.check_is_playing():
|
||||
if self.stream.position < 500000 and ms < 0:
|
||||
self.stream.position = 0
|
||||
else:
|
||||
try:
|
||||
self.stream.position = self.stream.position+ms
|
||||
except:
|
||||
pass
|
||||
def seek(self, ms=0):
|
||||
if self.check_is_playing():
|
||||
if self.stream.position < 500000 and ms < 0:
|
||||
self.stream.position = 0
|
||||
else:
|
||||
try:
|
||||
self.stream.position = self.stream.position+ms
|
||||
except:
|
||||
pass
|
||||
|
||||
def check_is_playing(self):
|
||||
""" check if the player is already playing a stream. """
|
||||
if self.stream == None:
|
||||
return False
|
||||
if self.stream != None and self.stream.is_playing == False and self.stream.is_stalled == False:
|
||||
return False
|
||||
else:
|
||||
return True
|
||||
def check_is_playing(self):
|
||||
""" check if the player is already playing a stream. """
|
||||
if self.stream == None:
|
||||
return False
|
||||
if self.stream != None and self.stream.is_playing == False and self.stream.is_stalled == False:
|
||||
return False
|
||||
else:
|
||||
return True
|
||||
|
@ -15,154 +15,154 @@ log = logging.getLogger("controller.profiles")
|
||||
|
||||
class userProfilePresenter(base.basePresenter):
|
||||
|
||||
def __init__(self, session, user_id, view, interactor):
|
||||
""" Default constructor:
|
||||
@session vk.session: The main session object, capable of calling VK methods.
|
||||
@user_id integer: User ID to retrieve information of.
|
||||
At the current time, only users (and not communities) are supported.
|
||||
"""
|
||||
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 = None
|
||||
self.session = session
|
||||
self.user_id = user_id
|
||||
# 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,
|
||||
# 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.
|
||||
call_threaded(self.get_basic_information)
|
||||
self.run()
|
||||
def __init__(self, session, user_id, view, interactor):
|
||||
""" Default constructor:
|
||||
@session vk.session: The main session object, capable of calling VK methods.
|
||||
@user_id integer: User ID to retrieve information of.
|
||||
At the current time, only users (and not communities) are supported.
|
||||
"""
|
||||
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 = None
|
||||
self.session = session
|
||||
self.user_id = user_id
|
||||
# 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,
|
||||
# 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.
|
||||
call_threaded(self.get_basic_information)
|
||||
self.run()
|
||||
|
||||
def get_basic_information(self):
|
||||
""" Gets and inserts basic user information.
|
||||
See https://vk.com/dev/users.get"""
|
||||
# List of fields (information) to retrieve. For a list of fields available for user objects,
|
||||
# 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"
|
||||
# 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)
|
||||
# If VK does not return anything it is very likely we have found a community.
|
||||
if len(person) == 0:
|
||||
return output.speak(_("Information for groups is not supported, yet."))
|
||||
person = person[0]
|
||||
# toDo: remove this print when I will be done with creation of profile viewer logic.
|
||||
# print(person)
|
||||
# From this part we will format data from VK so users will see it in the GUI control.
|
||||
# Format full name.
|
||||
n = "{0} {1}".format(person["first_name"], person["last_name"])
|
||||
# format phones
|
||||
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("set", tab="main_info", control="mobile_phone", value=person["mobile_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("set", tab="main_info", control="home_phone", value=person["home_phone"])
|
||||
# Format birthdate.
|
||||
if "bdate" in person and person["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.
|
||||
if len(person["bdate"]) <= 5: # dd.mm
|
||||
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]))
|
||||
else: # mm.dd.yyyy
|
||||
d = arrow.get(person["bdate"], "D.M.YYYY")
|
||||
# Calculate user's years.
|
||||
now = arrow.get()
|
||||
timedelta = now-d
|
||||
years = int(timedelta.days/365)
|
||||
date = d.format(_("MMMM D, YYYY"), locale=languageHandler.curLang[:2])
|
||||
msg = _("{date} ({age} years)").format(date=date, age=years)
|
||||
self.send_message("set", tab="main_info", control="bdate", value=msg)
|
||||
# Format current city and home town
|
||||
city = ""
|
||||
if "home_town" in person and person["home_town"] != "":
|
||||
home_town = person["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)
|
||||
if "city" in person and len(person["city"]) > 0:
|
||||
city = person["city"]["title"]
|
||||
if "country" in person and person["country"] != "":
|
||||
if city != "":
|
||||
city = city+", {0}".format(person["country"]["title"])
|
||||
else:
|
||||
city = person["country"]["title"]
|
||||
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="name", value=n)
|
||||
# Format title
|
||||
user = self.session.get_user(person["id"])
|
||||
self.send_message("set_title", value=_("{user1_nom}'s profile").format(**user))
|
||||
# Format website (or websites, if there are multiple of them).
|
||||
if "site" in person and person["site"] != "":
|
||||
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("enable_control", tab="main_info", control="go_site")
|
||||
# Format status message.
|
||||
if "status" in person and person["status"] != "":
|
||||
self.send_message("enable_control", tab="main_info", control="status")
|
||||
self.send_message("set", tab="main_info", control="status", value=person["status"])
|
||||
# Format occupation.
|
||||
# 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 person["occupation"]["type"] == "work": c1 = _("Work ")
|
||||
elif person["occupation"]["type"] == "school": c1 = _("Student ")
|
||||
elif person["occupation"]["type"] == "university": c1 = _("Student ")
|
||||
if "name" in person["occupation"] and person["occupation"]["name"] != "":
|
||||
c2 = _("In {0}").format(person["occupation"]["name"],)
|
||||
else:
|
||||
c2 = ""
|
||||
self.send_message("enable_control", tab="main_info", control="occupation")
|
||||
self.send_message("set", tab="main_info", control="occupation", value=c1+c2)
|
||||
# format relationship status.
|
||||
# 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 person["relation"] == 1:
|
||||
r = _("Single")
|
||||
elif person["relation"] == 2:
|
||||
if "relation_partner" in person:
|
||||
r = _("Dating with {0} {1}").format(person["relation_partner"]["first_name"], person["relation_partner"]["last_name"])
|
||||
else:
|
||||
r = _("Dating")
|
||||
elif person["relation"] == 3:
|
||||
r = _("Engaged with {0} {1}").format(person["relation_partner"]["first_name"], person["relation_partner"]["last_name"])
|
||||
elif person["relation"] == 4:
|
||||
if "relation_partner" in person:
|
||||
r = _("Married to {0} {1}").format(person["relation_partner"]["first_name"], person["relation_partner"]["last_name"])
|
||||
else:
|
||||
r = _("Married")
|
||||
elif person["relation"] == 5:
|
||||
r = _("It's complicated")
|
||||
elif person["relation"] == 6:
|
||||
r = _("Actively searching")
|
||||
elif person["relation"] == 7:
|
||||
r = _("In love")
|
||||
self.send_message("enable_control", tab="main_info", control="relation")
|
||||
self.send_message("set_label", tab="main_info", control="relation", value=_("Relationship: ")+r)
|
||||
# format last seen.
|
||||
if "last_seen" in person and person["last_seen"] != False:
|
||||
original_date = arrow.get(person["last_seen"]["time"])
|
||||
# Translators: This is the date of last seen
|
||||
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("set", tab="main_info", control="last_seen", value=last_seen)
|
||||
self.person = person
|
||||
# Adds photo to the dialog.
|
||||
# ToDo: Need to ask if this has a visible effect in the dialog.
|
||||
if "photo_200_orig" in person:
|
||||
img = requests.get(person["photo_200_orig"])
|
||||
self.send_message("load_image", image=requests.get(person["photo_200_orig"]))
|
||||
output.speak(_("Profile loaded"))
|
||||
def get_basic_information(self):
|
||||
""" Gets and inserts basic user information.
|
||||
See https://vk.com/dev/users.get"""
|
||||
# List of fields (information) to retrieve. For a list of fields available for user objects,
|
||||
# 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"
|
||||
# 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)
|
||||
# If VK does not return anything it is very likely we have found a community.
|
||||
if len(person) == 0:
|
||||
return output.speak(_("Information for groups is not supported, yet."))
|
||||
person = person[0]
|
||||
# toDo: remove this print when I will be done with creation of profile viewer logic.
|
||||
# print(person)
|
||||
# From this part we will format data from VK so users will see it in the GUI control.
|
||||
# Format full name.
|
||||
n = "{0} {1}".format(person["first_name"], person["last_name"])
|
||||
# format phones
|
||||
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("set", tab="main_info", control="mobile_phone", value=person["mobile_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("set", tab="main_info", control="home_phone", value=person["home_phone"])
|
||||
# Format birthdate.
|
||||
if "bdate" in person and person["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.
|
||||
if len(person["bdate"]) <= 5: # dd.mm
|
||||
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]))
|
||||
else: # mm.dd.yyyy
|
||||
d = arrow.get(person["bdate"], "D.M.YYYY")
|
||||
# Calculate user's years.
|
||||
now = arrow.get()
|
||||
timedelta = now-d
|
||||
years = int(timedelta.days/365)
|
||||
date = d.format(_("MMMM D, YYYY"), locale=languageHandler.curLang[:2])
|
||||
msg = _("{date} ({age} years)").format(date=date, age=years)
|
||||
self.send_message("set", tab="main_info", control="bdate", value=msg)
|
||||
# Format current city and home town
|
||||
city = ""
|
||||
if "home_town" in person and person["home_town"] != "":
|
||||
home_town = person["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)
|
||||
if "city" in person and len(person["city"]) > 0:
|
||||
city = person["city"]["title"]
|
||||
if "country" in person and person["country"] != "":
|
||||
if city != "":
|
||||
city = city+", {0}".format(person["country"]["title"])
|
||||
else:
|
||||
city = person["country"]["title"]
|
||||
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="name", value=n)
|
||||
# Format title
|
||||
user = self.session.get_user(person["id"])
|
||||
self.send_message("set_title", value=_("{user1_nom}'s profile").format(**user))
|
||||
# Format website (or websites, if there are multiple of them).
|
||||
if "site" in person and person["site"] != "":
|
||||
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("enable_control", tab="main_info", control="go_site")
|
||||
# Format status message.
|
||||
if "status" in person and person["status"] != "":
|
||||
self.send_message("enable_control", tab="main_info", control="status")
|
||||
self.send_message("set", tab="main_info", control="status", value=person["status"])
|
||||
# Format occupation.
|
||||
# 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 person["occupation"]["type"] == "work": c1 = _("Work ")
|
||||
elif person["occupation"]["type"] == "school": c1 = _("Student ")
|
||||
elif person["occupation"]["type"] == "university": c1 = _("Student ")
|
||||
if "name" in person["occupation"] and person["occupation"]["name"] != "":
|
||||
c2 = _("In {0}").format(person["occupation"]["name"],)
|
||||
else:
|
||||
c2 = ""
|
||||
self.send_message("enable_control", tab="main_info", control="occupation")
|
||||
self.send_message("set", tab="main_info", control="occupation", value=c1+c2)
|
||||
# format relationship status.
|
||||
# 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 person["relation"] == 1:
|
||||
r = _("Single")
|
||||
elif person["relation"] == 2:
|
||||
if "relation_partner" in person:
|
||||
r = _("Dating with {0} {1}").format(person["relation_partner"]["first_name"], person["relation_partner"]["last_name"])
|
||||
else:
|
||||
r = _("Dating")
|
||||
elif person["relation"] == 3:
|
||||
r = _("Engaged with {0} {1}").format(person["relation_partner"]["first_name"], person["relation_partner"]["last_name"])
|
||||
elif person["relation"] == 4:
|
||||
if "relation_partner" in person:
|
||||
r = _("Married to {0} {1}").format(person["relation_partner"]["first_name"], person["relation_partner"]["last_name"])
|
||||
else:
|
||||
r = _("Married")
|
||||
elif person["relation"] == 5:
|
||||
r = _("It's complicated")
|
||||
elif person["relation"] == 6:
|
||||
r = _("Actively searching")
|
||||
elif person["relation"] == 7:
|
||||
r = _("In love")
|
||||
self.send_message("enable_control", tab="main_info", control="relation")
|
||||
self.send_message("set_label", tab="main_info", control="relation", value=_("Relationship: ")+r)
|
||||
# format last seen.
|
||||
if "last_seen" in person and person["last_seen"] != False:
|
||||
original_date = arrow.get(person["last_seen"]["time"])
|
||||
# Translators: This is the date of last seen
|
||||
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("set", tab="main_info", control="last_seen", value=last_seen)
|
||||
self.person = person
|
||||
# Adds photo to the dialog.
|
||||
# ToDo: Need to ask if this has a visible effect in the dialog.
|
||||
if "photo_200_orig" in person:
|
||||
img = requests.get(person["photo_200_orig"])
|
||||
self.send_message("load_image", image=requests.get(person["photo_200_orig"]))
|
||||
output.speak(_("Profile loaded"))
|
||||
|
||||
def get_urls(self, *args, **kwargs):
|
||||
""" Allows to visit an user's website. """
|
||||
text = self.person["site"]
|
||||
# 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)
|
||||
if len(urls) == 0:
|
||||
output.speak(_("No URL addresses were detected."))
|
||||
return
|
||||
return urls
|
||||
def get_urls(self, *args, **kwargs):
|
||||
""" Allows to visit an user's website. """
|
||||
text = self.person["site"]
|
||||
# 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)
|
||||
if len(urls) == 0:
|
||||
output.speak(_("No URL addresses were detected."))
|
||||
return
|
||||
return urls
|
||||
|
||||
def visit_url(self, url):
|
||||
output.speak(_("Opening URL..."))
|
||||
webbrowser.open_new_tab(url)
|
||||
def visit_url(self, url):
|
||||
output.speak(_("Opening URL..."))
|
||||
webbrowser.open_new_tab(url)
|
||||
|
@ -19,4 +19,4 @@ for t in testmodules:
|
||||
# else, just load all the test cases from the module.
|
||||
suite.addTest(unittest.defaultTestLoader.loadTestsFromName(t))
|
||||
|
||||
unittest.TextTestRunner(verbosity=2).run(suite)
|
||||
unittest.TextTestRunner(verbosity=2).run(suite)
|
||||
|
@ -5,42 +5,42 @@ from validate import Validator, VdtValueError
|
||||
import os
|
||||
|
||||
class ConfigurationResetException(Exception):
|
||||
pass
|
||||
pass
|
||||
|
||||
class Configuration (UserDict):
|
||||
|
||||
def __init__ (self, file=None, spec=None, *args, **kwargs):
|
||||
self.file = file
|
||||
self.spec = spec
|
||||
self.validator = Validator()
|
||||
self.setup_config(file=file, spec=spec)
|
||||
self.validated = self.config.validate(self.validator, copy=True)
|
||||
if self.validated:
|
||||
self.write()
|
||||
UserDict.__init__(self, self.config)
|
||||
def __init__ (self, file=None, spec=None, *args, **kwargs):
|
||||
self.file = file
|
||||
self.spec = spec
|
||||
self.validator = Validator()
|
||||
self.setup_config(file=file, spec=spec)
|
||||
self.validated = self.config.validate(self.validator, copy=True)
|
||||
if self.validated:
|
||||
self.write()
|
||||
UserDict.__init__(self, self.config)
|
||||
|
||||
def setup_config (self, file, spec):
|
||||
spec = ConfigObj(spec, list_values=False, encoding="utf-8")
|
||||
try:
|
||||
self.config = ConfigObj(infile=file, configspec=spec, create_empty=True, stringify=True, encoding="utf-8")
|
||||
except ParseError:
|
||||
os.remove(file)
|
||||
self.config = ConfigObj(infile=file, configspec=spec, create_empty=True, stringify=True)
|
||||
raise ConfigurationResetException
|
||||
def setup_config (self, file, spec):
|
||||
spec = ConfigObj(spec, list_values=False, encoding="utf-8")
|
||||
try:
|
||||
self.config = ConfigObj(infile=file, configspec=spec, create_empty=True, stringify=True, encoding="utf-8")
|
||||
except ParseError:
|
||||
os.remove(file)
|
||||
self.config = ConfigObj(infile=file, configspec=spec, create_empty=True, stringify=True)
|
||||
raise ConfigurationResetException
|
||||
|
||||
def __getitem__ (self, *args, **kwargs):
|
||||
return dict(self.config).__getitem__(*args, **kwargs)
|
||||
def __getitem__ (self, *args, **kwargs):
|
||||
return dict(self.config).__getitem__(*args, **kwargs)
|
||||
|
||||
def __setitem__ (self, *args, **kwargs):
|
||||
self.config.__setitem__(*args, **kwargs)
|
||||
UserDict.__setitem__(self, *args, **kwargs)
|
||||
def __setitem__ (self, *args, **kwargs):
|
||||
self.config.__setitem__(*args, **kwargs)
|
||||
UserDict.__setitem__(self, *args, **kwargs)
|
||||
|
||||
def write (self):
|
||||
if hasattr(self.config, 'write'):
|
||||
self.config.write()
|
||||
def write (self):
|
||||
if hasattr(self.config, 'write'):
|
||||
self.config.write()
|
||||
|
||||
class SessionConfiguration (Configuration):
|
||||
def setup_config (self, file, spec):
|
||||
#No infile required.
|
||||
spec = ConfigObj(spec, list_values=False)
|
||||
self.config = ConfigObj(configspec=spec, stringify=True)
|
||||
def setup_config (self, file, spec):
|
||||
#No infile required.
|
||||
spec = ConfigObj(spec, list_values=False)
|
||||
self.config = ConfigObj(configspec=spec, stringify=True)
|
||||
|
@ -12,296 +12,296 @@ log = logging.getLogger(__file__)
|
||||
### Some util functions
|
||||
|
||||
def extract_attachment(attachment):
|
||||
""" 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:
|
||||
'website: http://url.com'.
|
||||
'photo: A forest'."""
|
||||
msg = ""
|
||||
if attachment["type"] == "link":
|
||||
msg = "{0}: {1}".format(attachment["link"]["title"], attachment["link"]["url"])
|
||||
elif attachment["type"] == "photo":
|
||||
msg = attachment["photo"]["text"]
|
||||
if msg == "":
|
||||
return _("photo with no description available")
|
||||
elif attachment["type"] == "video":
|
||||
msg = _("video: {0}").format(attachment["video"]["title"],)
|
||||
return msg
|
||||
""" 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:
|
||||
'website: http://url.com'.
|
||||
'photo: A forest'."""
|
||||
msg = ""
|
||||
if attachment["type"] == "link":
|
||||
msg = "{0}: {1}".format(attachment["link"]["title"], attachment["link"]["url"])
|
||||
elif attachment["type"] == "photo":
|
||||
msg = attachment["photo"]["text"]
|
||||
if msg == "":
|
||||
return _("photo with no description available")
|
||||
elif attachment["type"] == "video":
|
||||
msg = _("video: {0}").format(attachment["video"]["title"],)
|
||||
return msg
|
||||
|
||||
def short_text(status):
|
||||
""" This shorts the text to 140 characters for displaying it in the list control of buffers."""
|
||||
message = ""
|
||||
# copy_story indicates that the post is a shared repost.
|
||||
if "copy_history" in status:
|
||||
txt = status["copy_history"][0]["text"]
|
||||
else:
|
||||
txt = status["text"]
|
||||
if len(txt) < 140:
|
||||
message = clean_text(txt)
|
||||
else:
|
||||
message = clean_text(txt[:139])
|
||||
return message
|
||||
""" This shorts the text to 140 characters for displaying it in the list control of buffers."""
|
||||
message = ""
|
||||
# copy_story indicates that the post is a shared repost.
|
||||
if "copy_history" in status:
|
||||
txt = status["copy_history"][0]["text"]
|
||||
else:
|
||||
txt = status["text"]
|
||||
if len(txt) < 140:
|
||||
message = clean_text(txt)
|
||||
else:
|
||||
message = clean_text(txt[:139])
|
||||
return message
|
||||
|
||||
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."""
|
||||
for i in audio["items"][:]:
|
||||
if type(i) == bool:
|
||||
audio["items"].remove(i)
|
||||
audio["count"] = audio["count"] -1
|
||||
return 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."""
|
||||
for i in audio["items"][:]:
|
||||
if type(i) == bool:
|
||||
audio["items"].remove(i)
|
||||
audio["count"] = audio["count"] -1
|
||||
return audio
|
||||
|
||||
def add_attachment(attachment):
|
||||
msg = ""
|
||||
tpe = ""
|
||||
if attachment["type"] == "link":
|
||||
msg = "{0}: {1}".format(attachment["link"]["title"], attachment["link"]["url"])
|
||||
tpe = _("Link")
|
||||
elif attachment["type"] == "photo":
|
||||
tpe = _("Photo")
|
||||
msg = attachment["photo"]["text"]
|
||||
if msg == "":
|
||||
msg = _("no description available")
|
||||
elif attachment["type"] == "video":
|
||||
msg = "{0}".format(attachment["video"]["title"],)
|
||||
tpe = _("Video")
|
||||
elif attachment["type"] == "audio":
|
||||
msg = "{0}".format(" ".join(render_audio(attachment["audio"])))
|
||||
tpe = _("Audio")
|
||||
elif attachment["type"] == "doc":
|
||||
msg = "{0}".format(attachment["doc"]["title"])
|
||||
tpe = _("{0} file").format(attachment["doc"]["ext"])
|
||||
elif attachment["type"] == "audio_message":
|
||||
msg = "{0}".format(" ".join(render_audio_message(attachment["audio_message"])))
|
||||
tpe = _("Voice message")
|
||||
elif attachment["type"] == "poll":
|
||||
tpe = _("Poll")
|
||||
msg = attachment["poll"]["question"]
|
||||
elif attachment["type"] == "wall":
|
||||
tpe = _("Post")
|
||||
user = attachment["wall"]["from"]["name"]
|
||||
if len(attachment["wall"]["text"]) > 140:
|
||||
text = attachment["wall"]["text"][:145]+"..."
|
||||
else:
|
||||
text = attachment["wall"]["text"]
|
||||
msg = _("{user}: {post}").format(user=user, post=text)
|
||||
elif attachment["type"] == "article":
|
||||
tpe = _("Article")
|
||||
msg = "{author}: {article}".format(author=attachment["article"]["owner_name"], article=attachment["article"]["title"])
|
||||
else:
|
||||
print(attachment)
|
||||
return [tpe, msg]
|
||||
msg = ""
|
||||
tpe = ""
|
||||
if attachment["type"] == "link":
|
||||
msg = "{0}: {1}".format(attachment["link"]["title"], attachment["link"]["url"])
|
||||
tpe = _("Link")
|
||||
elif attachment["type"] == "photo":
|
||||
tpe = _("Photo")
|
||||
msg = attachment["photo"]["text"]
|
||||
if msg == "":
|
||||
msg = _("no description available")
|
||||
elif attachment["type"] == "video":
|
||||
msg = "{0}".format(attachment["video"]["title"],)
|
||||
tpe = _("Video")
|
||||
elif attachment["type"] == "audio":
|
||||
msg = "{0}".format(" ".join(render_audio(attachment["audio"])))
|
||||
tpe = _("Audio")
|
||||
elif attachment["type"] == "doc":
|
||||
msg = "{0}".format(attachment["doc"]["title"])
|
||||
tpe = _("{0} file").format(attachment["doc"]["ext"])
|
||||
elif attachment["type"] == "audio_message":
|
||||
msg = "{0}".format(" ".join(render_audio_message(attachment["audio_message"])))
|
||||
tpe = _("Voice message")
|
||||
elif attachment["type"] == "poll":
|
||||
tpe = _("Poll")
|
||||
msg = attachment["poll"]["question"]
|
||||
elif attachment["type"] == "wall":
|
||||
tpe = _("Post")
|
||||
user = attachment["wall"]["from"]["name"]
|
||||
if len(attachment["wall"]["text"]) > 140:
|
||||
text = attachment["wall"]["text"][:145]+"..."
|
||||
else:
|
||||
text = attachment["wall"]["text"]
|
||||
msg = _("{user}: {post}").format(user=user, post=text)
|
||||
elif attachment["type"] == "article":
|
||||
tpe = _("Article")
|
||||
msg = "{author}: {article}".format(author=attachment["article"]["owner_name"], article=attachment["article"]["title"])
|
||||
else:
|
||||
print(attachment)
|
||||
return [tpe, msg]
|
||||
|
||||
### Render functions
|
||||
|
||||
def render_person(status, session):
|
||||
""" Render users in people buffers such as everything related to friendships or buffers created with only people.
|
||||
Example result: ["John Doe", "An hour ago"]
|
||||
Reference: https://vk.com/dev/fields"""
|
||||
# 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?
|
||||
online_status = ""
|
||||
if "last_seen" in status:
|
||||
original_date = arrow.get(status["last_seen"]["time"])
|
||||
now = arrow.now()
|
||||
original_date.to(now.tzinfo)
|
||||
diffdate = now-original_date
|
||||
if diffdate.days == 0 and diffdate.seconds <= 360:
|
||||
online_status = _("Online")
|
||||
else:
|
||||
# Translators: This is the date of last seen
|
||||
online_status = _("Last seen {0}").format(original_date.humanize(locale=languageHandler.curLang[:2]),)
|
||||
# Account suspended or deleted.
|
||||
elif ("last_seen" in status) == False and "deactivated" in status:
|
||||
online_status = _("Account deactivated")
|
||||
return ["{0} {1}".format(status["first_name"], status["last_name"]), online_status]
|
||||
""" Render users in people buffers such as everything related to friendships or buffers created with only people.
|
||||
Example result: ["John Doe", "An hour ago"]
|
||||
Reference: https://vk.com/dev/fields"""
|
||||
# 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?
|
||||
online_status = ""
|
||||
if "last_seen" in status:
|
||||
original_date = arrow.get(status["last_seen"]["time"])
|
||||
now = arrow.now()
|
||||
original_date.to(now.tzinfo)
|
||||
diffdate = now-original_date
|
||||
if diffdate.days == 0 and diffdate.seconds <= 360:
|
||||
online_status = _("Online")
|
||||
else:
|
||||
# Translators: This is the date of last seen
|
||||
online_status = _("Last seen {0}").format(original_date.humanize(locale=languageHandler.curLang[:2]),)
|
||||
# Account suspended or deleted.
|
||||
elif ("last_seen" in status) == False and "deactivated" in status:
|
||||
online_status = _("Account deactivated")
|
||||
return ["{0} {1}".format(status["first_name"], status["last_name"]), online_status]
|
||||
|
||||
def render_newsfeed_item(status, session):
|
||||
""" This me☻thod is used to render an item of the news feed.
|
||||
References:
|
||||
https://vk.com/dev/newsfeed.get
|
||||
https://vk.com/dev/post_source
|
||||
https://vk.com/dev/post
|
||||
"""
|
||||
user = session.get_user(status["source_id"], key="user1")
|
||||
# See if this is a post or repost.
|
||||
if "copy_history" in status:
|
||||
# Get the second user (whose post is been shared).
|
||||
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.
|
||||
user2.update(user)
|
||||
user = dict(user1_nom=_("{user1_nom} has shared the {user2_nom}'s post").format(**user2))
|
||||
message = ""
|
||||
original_date = arrow.get(status["date"])
|
||||
created_at = original_date.humanize(locale=languageHandler.curLang[:2])
|
||||
# handle status updates.
|
||||
if status["type"] == "post":
|
||||
message += short_text(status)
|
||||
if "attachment" in status and len(status["attachment"]) > 0:
|
||||
message += extract_attachment(status["attachment"])
|
||||
# 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.
|
||||
if message == "":
|
||||
message = "no description available"
|
||||
# Handle audio rendering.
|
||||
elif status["type"] == "audio" and "audio" in status:
|
||||
# removes deleted audios.
|
||||
status["audio"] = clean_audio(status["audio"])
|
||||
if status["audio"]["count"] == 1:
|
||||
data = dict(audio_file=", ".join(render_audio(status["audio"]["items"][0], session)))
|
||||
data.update(user)
|
||||
message = _("{user1_nom} has added an audio: {audio_file}").format(**data)
|
||||
else:
|
||||
prem = ""
|
||||
for i in range(0, status["audio"]["count"]):
|
||||
composed_audio = render_audio(status["audio"]["items"][i], session)
|
||||
prem += "{0} - {1}, ".format(composed_audio[0], composed_audio[1])
|
||||
data = dict(audio_files=prem, total_audio_files=status["audio"]["count"])
|
||||
data.update(user)
|
||||
message = _("{user1_nom} has added {total_audio_files} audios: {audio_files}").format(**data)
|
||||
# Handle audio playlists
|
||||
elif status["type"] == "audio_playlist":
|
||||
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.update(user)
|
||||
message = _("{user1_nom} has added an audio album: {audio_album}, {audio_album_description}").format(**data)
|
||||
else:
|
||||
prestring = ""
|
||||
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"])
|
||||
data = dict(audio_albums=prestring, total_audio_albums=status["audio_playlist"]["count"])
|
||||
data.update(user)
|
||||
message = _("{user1_nom} has added {total_audio_albums} audio albums: {audio_albums}").format(**data)
|
||||
# handle new friends for people in the news buffer.
|
||||
elif status["type"] == "friend":
|
||||
msg_users = ""
|
||||
if "friends" in status:
|
||||
for i in status["friends"]["items"]:
|
||||
msg_users = msg_users + "{0}, ".format(session.get_user(i["user_id"])["user1_nom"])
|
||||
else:
|
||||
print(list(status.keys()))
|
||||
data = dict(friends=msg_users)
|
||||
data.update(user)
|
||||
message = _("{user1_nom} added friends: {friends}").format(**data)
|
||||
elif status["type"] == "video":
|
||||
if status["video"]["count"] == 1:
|
||||
data = dict(video=", ".join(render_video(status["video"]["items"][0], session)))
|
||||
data.update(user)
|
||||
message = _("{user1_nom} has added a video: {video}").format(**data)
|
||||
else:
|
||||
prem = ""
|
||||
for i in range(0, status["video"]["count"]):
|
||||
composed_video = render_video(status["video"]["items"][i], session)
|
||||
prem += "{0} - {1}, ".format(composed_video[0], composed_video[1])
|
||||
data = dict(videos=prem, total_videos=status["video"]["count"])
|
||||
data.update(user)
|
||||
message = _("{user1_nom} has added {total_videos} videos: {videos}").format(**data)
|
||||
else:
|
||||
if status["type"] != "post": print(status)
|
||||
return [user["user1_nom"], message, created_at]
|
||||
""" This me☻thod is used to render an item of the news feed.
|
||||
References:
|
||||
https://vk.com/dev/newsfeed.get
|
||||
https://vk.com/dev/post_source
|
||||
https://vk.com/dev/post
|
||||
"""
|
||||
user = session.get_user(status["source_id"], key="user1")
|
||||
# See if this is a post or repost.
|
||||
if "copy_history" in status:
|
||||
# Get the second user (whose post is been shared).
|
||||
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.
|
||||
user2.update(user)
|
||||
user = dict(user1_nom=_("{user1_nom} has shared the {user2_nom}'s post").format(**user2))
|
||||
message = ""
|
||||
original_date = arrow.get(status["date"])
|
||||
created_at = original_date.humanize(locale=languageHandler.curLang[:2])
|
||||
# handle status updates.
|
||||
if status["type"] == "post":
|
||||
message += short_text(status)
|
||||
if "attachment" in status and len(status["attachment"]) > 0:
|
||||
message += extract_attachment(status["attachment"])
|
||||
# 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.
|
||||
if message == "":
|
||||
message = "no description available"
|
||||
# Handle audio rendering.
|
||||
elif status["type"] == "audio" and "audio" in status:
|
||||
# removes deleted audios.
|
||||
status["audio"] = clean_audio(status["audio"])
|
||||
if status["audio"]["count"] == 1:
|
||||
data = dict(audio_file=", ".join(render_audio(status["audio"]["items"][0], session)))
|
||||
data.update(user)
|
||||
message = _("{user1_nom} has added an audio: {audio_file}").format(**data)
|
||||
else:
|
||||
prem = ""
|
||||
for i in range(0, status["audio"]["count"]):
|
||||
composed_audio = render_audio(status["audio"]["items"][i], session)
|
||||
prem += "{0} - {1}, ".format(composed_audio[0], composed_audio[1])
|
||||
data = dict(audio_files=prem, total_audio_files=status["audio"]["count"])
|
||||
data.update(user)
|
||||
message = _("{user1_nom} has added {total_audio_files} audios: {audio_files}").format(**data)
|
||||
# Handle audio playlists
|
||||
elif status["type"] == "audio_playlist":
|
||||
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.update(user)
|
||||
message = _("{user1_nom} has added an audio album: {audio_album}, {audio_album_description}").format(**data)
|
||||
else:
|
||||
prestring = ""
|
||||
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"])
|
||||
data = dict(audio_albums=prestring, total_audio_albums=status["audio_playlist"]["count"])
|
||||
data.update(user)
|
||||
message = _("{user1_nom} has added {total_audio_albums} audio albums: {audio_albums}").format(**data)
|
||||
# handle new friends for people in the news buffer.
|
||||
elif status["type"] == "friend":
|
||||
msg_users = ""
|
||||
if "friends" in status:
|
||||
for i in status["friends"]["items"]:
|
||||
msg_users = msg_users + "{0}, ".format(session.get_user(i["user_id"])["user1_nom"])
|
||||
else:
|
||||
print(list(status.keys()))
|
||||
data = dict(friends=msg_users)
|
||||
data.update(user)
|
||||
message = _("{user1_nom} added friends: {friends}").format(**data)
|
||||
elif status["type"] == "video":
|
||||
if status["video"]["count"] == 1:
|
||||
data = dict(video=", ".join(render_video(status["video"]["items"][0], session)))
|
||||
data.update(user)
|
||||
message = _("{user1_nom} has added a video: {video}").format(**data)
|
||||
else:
|
||||
prem = ""
|
||||
for i in range(0, status["video"]["count"]):
|
||||
composed_video = render_video(status["video"]["items"][i], session)
|
||||
prem += "{0} - {1}, ".format(composed_video[0], composed_video[1])
|
||||
data = dict(videos=prem, total_videos=status["video"]["count"])
|
||||
data.update(user)
|
||||
message = _("{user1_nom} has added {total_videos} videos: {videos}").format(**data)
|
||||
else:
|
||||
if status["type"] != "post": print(status)
|
||||
return [user["user1_nom"], message, created_at]
|
||||
|
||||
def render_message(message, session):
|
||||
""" Render a message posted in a private conversation.
|
||||
Reference: https://vk.com/dev/message"""
|
||||
user = session.get_user(message["from_id"], key="user1")
|
||||
original_date = arrow.get(message["date"])
|
||||
now = arrow.now()
|
||||
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.
|
||||
if original_date.day == now.day:
|
||||
created_at = original_date.format(_("H:mm."), locale=languageHandler.curLang[:2])
|
||||
else:
|
||||
created_at = original_date.format(_("H:mm. dddd, MMMM D, YYYY"), locale=languageHandler.curLang[:2])
|
||||
# No idea why some messages send "text" instead "body"
|
||||
if "body" in message:
|
||||
body = message["body"]
|
||||
else:
|
||||
body = message["text"]
|
||||
data = dict(body=body, created_at=created_at)
|
||||
data.update(user)
|
||||
return ["{user1_nom}, {body} {created_at}".format(**data)]
|
||||
""" Render a message posted in a private conversation.
|
||||
Reference: https://vk.com/dev/message"""
|
||||
user = session.get_user(message["from_id"], key="user1")
|
||||
original_date = arrow.get(message["date"])
|
||||
now = arrow.now()
|
||||
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.
|
||||
if original_date.day == now.day:
|
||||
created_at = original_date.format(_("H:mm."), locale=languageHandler.curLang[:2])
|
||||
else:
|
||||
created_at = original_date.format(_("H:mm. dddd, MMMM D, YYYY"), locale=languageHandler.curLang[:2])
|
||||
# No idea why some messages send "text" instead "body"
|
||||
if "body" in message:
|
||||
body = message["body"]
|
||||
else:
|
||||
body = message["text"]
|
||||
data = dict(body=body, created_at=created_at)
|
||||
data.update(user)
|
||||
return ["{user1_nom}, {body} {created_at}".format(**data)]
|
||||
|
||||
def render_status(status, session):
|
||||
""" Render a wall post (shown in user's wall, not in newsfeed).
|
||||
Reference: https://vk.com/dev/post"""
|
||||
user = session.get_user(status["from_id"], key="user1")
|
||||
if "copy_history" in status:
|
||||
user2 = session.get_user(status["copy_history"][0]["owner_id"], key="user2")
|
||||
user2.update(user)
|
||||
user = dict(user1_nom=_("{user1_nom} has shared the {user2_nom}'s post").format(**user2))
|
||||
message = ""
|
||||
original_date = arrow.get(status["date"])
|
||||
created_at = original_date.humanize(locale=languageHandler.curLang[:2])
|
||||
if "copy_owner_id" in status:
|
||||
user2 = session.get_user(status["copy_owner_id"], key="user2")
|
||||
user2.update(user)
|
||||
user = _("{user1_nom} has shared the {user2_nom}'s post").format(**user2)
|
||||
if status["post_type"] == "post" or status["post_type"] == "copy":
|
||||
message += short_text(status)
|
||||
if "attachment" in status and len(status["attachment"]) > 0:
|
||||
message += extract_attachment(status["attachment"])
|
||||
if message == "":
|
||||
message = "no description available"
|
||||
return [user["user1_nom"], message, created_at]
|
||||
""" Render a wall post (shown in user's wall, not in newsfeed).
|
||||
Reference: https://vk.com/dev/post"""
|
||||
user = session.get_user(status["from_id"], key="user1")
|
||||
if "copy_history" in status:
|
||||
user2 = session.get_user(status["copy_history"][0]["owner_id"], key="user2")
|
||||
user2.update(user)
|
||||
user = dict(user1_nom=_("{user1_nom} has shared the {user2_nom}'s post").format(**user2))
|
||||
message = ""
|
||||
original_date = arrow.get(status["date"])
|
||||
created_at = original_date.humanize(locale=languageHandler.curLang[:2])
|
||||
if "copy_owner_id" in status:
|
||||
user2 = session.get_user(status["copy_owner_id"], key="user2")
|
||||
user2.update(user)
|
||||
user = _("{user1_nom} has shared the {user2_nom}'s post").format(**user2)
|
||||
if status["post_type"] == "post" or status["post_type"] == "copy":
|
||||
message += short_text(status)
|
||||
if "attachment" in status and len(status["attachment"]) > 0:
|
||||
message += extract_attachment(status["attachment"])
|
||||
if message == "":
|
||||
message = "no description available"
|
||||
return [user["user1_nom"], message, created_at]
|
||||
|
||||
def render_audio(audio, session=None):
|
||||
""" Render audio files added to VK.
|
||||
Example result:
|
||||
["Song title", "Artist", "03:15"]
|
||||
reference: https://vk.com/dev/audio_object"""
|
||||
if audio == False: return [_("Audio removed from library"), "", ""]
|
||||
return [audio["title"], audio["artist"], seconds_to_string(audio["duration"])]
|
||||
""" Render audio files added to VK.
|
||||
Example result:
|
||||
["Song title", "Artist", "03:15"]
|
||||
reference: https://vk.com/dev/audio_object"""
|
||||
if audio == False: return [_("Audio removed from library"), "", ""]
|
||||
return [audio["title"], audio["artist"], seconds_to_string(audio["duration"])]
|
||||
|
||||
def render_video(video, session=None):
|
||||
""" Render a video file from VK.
|
||||
Example result:
|
||||
["Video title", "Video description", "01:30:28"]
|
||||
Reference: https://vk.com/dev/video_object"""
|
||||
if video == False:
|
||||
return [_("Video not available"), "", ""]
|
||||
return [video["title"], video["description"], seconds_to_string(video["duration"])]
|
||||
""" Render a video file from VK.
|
||||
Example result:
|
||||
["Video title", "Video description", "01:30:28"]
|
||||
Reference: https://vk.com/dev/video_object"""
|
||||
if video == False:
|
||||
return [_("Video not available"), "", ""]
|
||||
return [video["title"], video["description"], seconds_to_string(video["duration"])]
|
||||
|
||||
def render_audio_message(audio_message, session=None):
|
||||
""" Render a voice message from VK
|
||||
Example result:
|
||||
["Voice message", "01:30:28"]"""
|
||||
if audio_message == False:
|
||||
return [_("Voice message not available"), "", ""]
|
||||
return [seconds_to_string(audio_message["duration"])]
|
||||
""" Render a voice message from VK
|
||||
Example result:
|
||||
["Voice message", "01:30:28"]"""
|
||||
if audio_message == False:
|
||||
return [_("Voice message not available"), "", ""]
|
||||
return [seconds_to_string(audio_message["duration"])]
|
||||
|
||||
def render_topic(topic, session):
|
||||
""" Render topics for a community.
|
||||
Reference: https://vk.com/dev/objects/topic"""
|
||||
user = session.get_user(topic["created_by"])
|
||||
title = topic["title"]
|
||||
comments = topic["comments"]
|
||||
last_commenter = session.get_user(topic["updated_by"])
|
||||
last_update = arrow.get(topic["updated"]).humanize(locale=languageHandler.curLang[:2])
|
||||
last_commenter.update(date=last_update)
|
||||
lastupdate = _("Last post by {user1_nom} {date}").format(**last_commenter)
|
||||
return [user["user1_nom"], title, str(comments), lastupdate]
|
||||
""" Render topics for a community.
|
||||
Reference: https://vk.com/dev/objects/topic"""
|
||||
user = session.get_user(topic["created_by"])
|
||||
title = topic["title"]
|
||||
comments = topic["comments"]
|
||||
last_commenter = session.get_user(topic["updated_by"])
|
||||
last_update = arrow.get(topic["updated"]).humanize(locale=languageHandler.curLang[:2])
|
||||
last_commenter.update(date=last_update)
|
||||
lastupdate = _("Last post by {user1_nom} {date}").format(**last_commenter)
|
||||
return [user["user1_nom"], title, str(comments), lastupdate]
|
||||
|
||||
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")}
|
||||
user = session.get_user(document["owner_id"])
|
||||
title = document["title"]
|
||||
size = convert_bytes(document["size"])
|
||||
date = arrow.get(document["date"]).humanize(locale=languageHandler.curLang[:2])
|
||||
doc_type = doc_types[document["type"]]
|
||||
return [user["user1_nom"], title, doc_type, size, date]
|
||||
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"])
|
||||
title = document["title"]
|
||||
size = convert_bytes(document["size"])
|
||||
date = arrow.get(document["date"]).humanize(locale=languageHandler.curLang[:2])
|
||||
doc_type = doc_types[document["type"]]
|
||||
return [user["user1_nom"], title, doc_type, size, date]
|
||||
|
||||
def render_notification(notification, session):
|
||||
notification.pop("hide_buttons")
|
||||
print(notification["icon_type"])
|
||||
# print(notification["header"])
|
||||
print(notification)
|
||||
date = arrow.get(notification["date"]).humanize(locale=languageHandler.curLang[:2])
|
||||
msg = notification["header"]
|
||||
# msg = notification["header"]
|
||||
# if notification["type"] == "follow":
|
||||
# if len(notification["feedback"]) == 1:
|
||||
# user = session.get_user(notification["feedback"][0])
|
||||
# msg = _("{user1_nom} subscribed to your account").format(**user)
|
||||
# else:
|
||||
# users = ["{first_name} {last_name},".format(first_name=user["first_name"], last_name=user["last_name"]) for user in notification["feedback"]]
|
||||
# msg = " ".join(users)
|
||||
# print(msg)
|
||||
return [msg, date]
|
||||
notification.pop("hide_buttons")
|
||||
print(notification["icon_type"])
|
||||
# print(notification["header"])
|
||||
print(notification)
|
||||
date = arrow.get(notification["date"]).humanize(locale=languageHandler.curLang[:2])
|
||||
msg = notification["header"]
|
||||
# msg = notification["header"]
|
||||
# if notification["type"] == "follow":
|
||||
# if len(notification["feedback"]) == 1:
|
||||
# user = session.get_user(notification["feedback"][0])
|
||||
# msg = _("{user1_nom} subscribed to your account").format(**user)
|
||||
# else:
|
||||
# users = ["{first_name} {last_name},".format(first_name=user["first_name"], last_name=user["last_name"]) for user in notification["feedback"]]
|
||||
# msg = " ".join(users)
|
||||
# print(msg)
|
||||
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")
|
||||
|
||||
def find_item(list, item):
|
||||
""" Find an item in a list by taking an identifier.
|
||||
@list list: A list of dict objects.
|
||||
@ item dict: A dictionary containing at least an identifier.
|
||||
"""
|
||||
# determine the kind of identifier that we are using
|
||||
global identifiers
|
||||
identifier = None
|
||||
for i in identifiers:
|
||||
if i in item:
|
||||
identifier = i
|
||||
break
|
||||
if identifier == None:
|
||||
# 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,))
|
||||
return False
|
||||
for i in list:
|
||||
if identifier in i and i[identifier] == item[identifier]:
|
||||
return True
|
||||
return False
|
||||
""" Find an item in a list by taking an identifier.
|
||||
@list list: A list of dict objects.
|
||||
@ item dict: A dictionary containing at least an identifier.
|
||||
"""
|
||||
# determine the kind of identifier that we are using
|
||||
global identifiers
|
||||
identifier = None
|
||||
for i in identifiers:
|
||||
if i in item:
|
||||
identifier = i
|
||||
break
|
||||
if identifier == None:
|
||||
# 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,))
|
||||
return False
|
||||
for i in list:
|
||||
if identifier in i and i[identifier] == item[identifier]:
|
||||
return True
|
||||
return False
|
||||
|
||||
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):
|
||||
""" Put new items on the local cache database.
|
||||
@name str: The name for the buffer stored in the dictionary.
|
||||
@data list: A list with items and some information about cursors.
|
||||
returns the number of items that have been added in this execution"""
|
||||
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.
|
||||
# ToDo: It would be nice to investigate whether reusing some existing objects would be a good idea, whenever possible.
|
||||
if name == "online_friends":
|
||||
newdata = self.vk.client.users.get(user_ids=",".join([str(z) for z in data]), fields="last_seen")
|
||||
data = newdata
|
||||
first_addition = False
|
||||
num = 0
|
||||
if (name in self.db) == False:
|
||||
self.db[name] = {}
|
||||
self.db[name]["items"] = []
|
||||
first_addition = True
|
||||
# Handles chat messages case, as the buffer is inverted
|
||||
if name.endswith("_messages") and show_nextpage == True:
|
||||
show_nextpage = False
|
||||
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):
|
||||
log.debug("Skipping unsupported item... %r" % (i,))
|
||||
continue
|
||||
# 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,
|
||||
# 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.
|
||||
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(i)
|
||||
continue
|
||||
if find_item(self.db[name]["items"], i) == False:
|
||||
# if i not in self.db[name]["items"]:
|
||||
if first_addition == True or show_nextpage == True:
|
||||
if self.settings["general"]["reverse_timelines"] == False: self.db[name]["items"].append(i)
|
||||
else: self.db[name]["items"].insert(0, i)
|
||||
else:
|
||||
if self.settings["general"]["reverse_timelines"] == False: self.db[name]["items"].insert(0, i)
|
||||
else: self.db[name]["items"].append(i)
|
||||
num = num+1
|
||||
log.debug("There are %d items in the %s buffer" % (len(self.db[name]["items"]), name))
|
||||
return num
|
||||
def order_buffer(self, name, data, show_nextpage):
|
||||
""" Put new items on the local cache database.
|
||||
@name str: The name for the buffer stored in the dictionary.
|
||||
@data list: A list with items and some information about cursors.
|
||||
returns the number of items that have been added in this execution"""
|
||||
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.
|
||||
# ToDo: It would be nice to investigate whether reusing some existing objects would be a good idea, whenever possible.
|
||||
if name == "online_friends":
|
||||
newdata = self.vk.client.users.get(user_ids=",".join([str(z) for z in data]), fields="last_seen")
|
||||
data = newdata
|
||||
first_addition = False
|
||||
num = 0
|
||||
if (name in self.db) == False:
|
||||
self.db[name] = {}
|
||||
self.db[name]["items"] = []
|
||||
first_addition = True
|
||||
# Handles chat messages case, as the buffer is inverted
|
||||
if name.endswith("_messages") and show_nextpage == True:
|
||||
show_nextpage = False
|
||||
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):
|
||||
log.debug("Skipping unsupported item... %r" % (i,))
|
||||
continue
|
||||
# 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,
|
||||
# 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.
|
||||
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(i)
|
||||
continue
|
||||
if find_item(self.db[name]["items"], i) == False:
|
||||
# if i not in self.db[name]["items"]:
|
||||
if first_addition == True or show_nextpage == True:
|
||||
if self.settings["general"]["reverse_timelines"] == False: self.db[name]["items"].append(i)
|
||||
else: self.db[name]["items"].insert(0, i)
|
||||
else:
|
||||
if self.settings["general"]["reverse_timelines"] == False: self.db[name]["items"].insert(0, i)
|
||||
else: self.db[name]["items"].append(i)
|
||||
num = num+1
|
||||
log.debug("There are %d items in the %s buffer" % (len(self.db[name]["items"]), name))
|
||||
return num
|
||||
|
||||
def __init__(self, session_id):
|
||||
self.session_id = session_id
|
||||
self.logged = False
|
||||
self.settings = None
|
||||
self.vk = vkSessionHandler.vkObject()
|
||||
self.db = {}
|
||||
self.db["users"] = {}
|
||||
self.db["groups"] = {}
|
||||
self.db["group_info"] = {}
|
||||
def __init__(self, session_id):
|
||||
self.session_id = session_id
|
||||
self.logged = False
|
||||
self.settings = None
|
||||
self.vk = vkSessionHandler.vkObject()
|
||||
self.db = {}
|
||||
self.db["users"] = {}
|
||||
self.db["groups"] = {}
|
||||
self.db["group_info"] = {}
|
||||
|
||||
@property
|
||||
def is_logged(self):
|
||||
return self.logged
|
||||
@property
|
||||
def is_logged(self):
|
||||
return self.logged
|
||||
|
||||
def get_configuration(self, nosound=False):
|
||||
def get_configuration(self, nosound=False):
|
||||
|
||||
""" Gets settings for a session."""
|
||||
|
||||
file_ = "%s/session.conf" % (self.session_id,)
|
||||
""" Gets settings for a session."""
|
||||
|
||||
file_ = "%s/session.conf" % (self.session_id,)
|
||||
# try:
|
||||
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"))
|
||||
if nosound == False:
|
||||
self.soundplayer = sound.soundSystem(config.app["sound"])
|
||||
pub.subscribe(self.play_sound, "play-sound")
|
||||
pub.subscribe(self.post, "post")
|
||||
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"))
|
||||
if nosound == False:
|
||||
self.soundplayer = sound.soundSystem(config.app["sound"])
|
||||
pub.subscribe(self.play_sound, "play-sound")
|
||||
pub.subscribe(self.post, "post")
|
||||
# except:
|
||||
# log.exception("The session configuration has failed.")
|
||||
|
||||
def play_sound(self, sound):
|
||||
self.soundplayer.play(sound)
|
||||
def play_sound(self, sound):
|
||||
self.soundplayer.play(sound)
|
||||
|
||||
def login(self):
|
||||
""" 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 self.logged == True:
|
||||
return
|
||||
try:
|
||||
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.settings["vk"]["token"] = self.vk.session_object.token["access_token"]
|
||||
self.settings.write()
|
||||
self.logged = True
|
||||
self.get_my_data()
|
||||
except VkApiError as error:
|
||||
print(error)
|
||||
if error.code == 5: # this means invalid access token.
|
||||
self.settings["vk"]["user"] = ""
|
||||
self.settings["vk"]["password"] = ""
|
||||
self.settings["vk"]["token"] = ""
|
||||
self.settings.write()
|
||||
pub.sendMessage("authorisation-failed")
|
||||
else: # print out error so we we will handle it in future versions.
|
||||
log.exception("Fatal error when authenticating the application.")
|
||||
log.exception(error.code)
|
||||
log.exception(error.message)
|
||||
except (ProxyError, ConnectionError):
|
||||
pub.sendMessage("connection_error")
|
||||
def login(self):
|
||||
""" 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 self.logged == True:
|
||||
return
|
||||
try:
|
||||
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.settings["vk"]["token"] = self.vk.session_object.token["access_token"]
|
||||
self.settings.write()
|
||||
self.logged = True
|
||||
self.get_my_data()
|
||||
except VkApiError as error:
|
||||
print(error)
|
||||
if error.code == 5: # this means invalid access token.
|
||||
self.settings["vk"]["user"] = ""
|
||||
self.settings["vk"]["password"] = ""
|
||||
self.settings["vk"]["token"] = ""
|
||||
self.settings.write()
|
||||
pub.sendMessage("authorisation-failed")
|
||||
else: # print out error so we we will handle it in future versions.
|
||||
log.exception("Fatal error when authenticating the application.")
|
||||
log.exception(error.code)
|
||||
log.exception(error.message)
|
||||
except (ProxyError, ConnectionError):
|
||||
pub.sendMessage("connection_error")
|
||||
|
||||
def post_wall_status(self, message, *args, **kwargs):
|
||||
""" 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,))
|
||||
response = self.vk.client.wall.post(message=message, *args, **kwargs)
|
||||
def post_wall_status(self, message, *args, **kwargs):
|
||||
""" 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,))
|
||||
response = self.vk.client.wall.post(message=message, *args, **kwargs)
|
||||
|
||||
def get_newsfeed(self, name="newsfeed", show_nextpage=False, endpoint="", *args, **kwargs):
|
||||
log.debug("Updating news feed...")
|
||||
if show_nextpage == True and "cursor" in self.db[name]:
|
||||
log.debug("user has requested previous items")
|
||||
kwargs["start_from"] = self.db[name]["cursor"]
|
||||
log.debug("Params for sending to vk: %r" % (kwargs,))
|
||||
data = getattr(self.vk.client.newsfeed, "get")(*args, **kwargs)
|
||||
if data != None:
|
||||
self.process_usernames(data)
|
||||
num = self.order_buffer(name, data["items"], show_nextpage)
|
||||
log.debug("Keys of the returned data for debug purposes: %r" % (list(data.keys()),))
|
||||
if "next_from" in data:
|
||||
self.db[name]["cursor"] = data["next_from"]
|
||||
log.debug("Next cursor saved for data: {cursor}".format(cursor=data["next_from"]))
|
||||
return num
|
||||
def get_newsfeed(self, name="newsfeed", show_nextpage=False, endpoint="", *args, **kwargs):
|
||||
log.debug("Updating news feed...")
|
||||
if show_nextpage == True and "cursor" in self.db[name]:
|
||||
log.debug("user has requested previous items")
|
||||
kwargs["start_from"] = self.db[name]["cursor"]
|
||||
log.debug("Params for sending to vk: %r" % (kwargs,))
|
||||
data = getattr(self.vk.client.newsfeed, "get")(*args, **kwargs)
|
||||
if data != None:
|
||||
self.process_usernames(data)
|
||||
num = self.order_buffer(name, data["items"], show_nextpage)
|
||||
log.debug("Keys of the returned data for debug purposes: %r" % (list(data.keys()),))
|
||||
if "next_from" in data:
|
||||
self.db[name]["cursor"] = data["next_from"]
|
||||
log.debug("Next cursor saved for data: {cursor}".format(cursor=data["next_from"]))
|
||||
return num
|
||||
|
||||
def get_page(self, name="", show_nextpage=False, endpoint="", *args, **kwargs):
|
||||
data = None
|
||||
if "audio" in endpoint and self.settings["vk"]["use_alternative_tokens"]:
|
||||
log.info("Using alternative audio methods.")
|
||||
c = self.vk.client_audio
|
||||
else:
|
||||
c = self.vk.client
|
||||
formatted_endpoint = ""
|
||||
if "parent_endpoint" in kwargs:
|
||||
p = kwargs["parent_endpoint"]
|
||||
formatted_endpoint = kwargs["parent_endpoint"]
|
||||
if "audio" in p and self.settings["vk"]["use_alternative_tokens"]:
|
||||
log.info("Using alternative audio methods.")
|
||||
c = self.vk.client_audio
|
||||
kwargs.pop("parent_endpoint")
|
||||
try:
|
||||
p = getattr(c, p)
|
||||
except AttributeError:
|
||||
p = c
|
||||
if name in self.db and "offset" in self.db[name] and show_nextpage == True:
|
||||
kwargs.update(offset=self.db[name]["offset"])
|
||||
else:
|
||||
kwargs.update(offset=0)
|
||||
formatted_endpoint = "{formatted_endpoint}.{new_path}".format(formatted_endpoint=formatted_endpoint, new_path=endpoint)
|
||||
offset_deprecated = ["notifications.get"]
|
||||
if formatted_endpoint in offset_deprecated:
|
||||
kwargs.update(offset=None)
|
||||
log.debug("Calling endpoint %s with params %r" % (formatted_endpoint, kwargs,))
|
||||
data = getattr(p, endpoint)(*args, **kwargs)
|
||||
if data != None:
|
||||
if "count" not in kwargs:
|
||||
kwargs["count"] = 100
|
||||
# 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.
|
||||
if type(data) == dict and "items" in data and endpoint == "getHistory" and kwargs["offset"] == 0:
|
||||
data["items"].reverse()
|
||||
if type(data) == dict:
|
||||
num = self.order_buffer(name, data["items"], show_nextpage)
|
||||
if formatted_endpoint not in offset_deprecated:
|
||||
self.db[name]["offset"] = kwargs["offset"]+kwargs["count"]
|
||||
if len(data["items"]) > 0 and "first_name" in data["items"][0]:
|
||||
data2 = {"profiles": [], "groups": []}
|
||||
for i in data["items"]:
|
||||
data2["profiles"].append(i)
|
||||
self.process_usernames(data2)
|
||||
if "profiles" in data and "groups" in data:
|
||||
self.process_usernames(data)
|
||||
else:
|
||||
num = self.order_buffer(name, data, show_nextpage)
|
||||
self.db[name]["offset"] = kwargs["offset"]+kwargs["count"]
|
||||
return num
|
||||
def get_page(self, name="", show_nextpage=False, endpoint="", *args, **kwargs):
|
||||
data = None
|
||||
if "audio" in endpoint and self.settings["vk"]["use_alternative_tokens"]:
|
||||
log.info("Using alternative audio methods.")
|
||||
c = self.vk.client_audio
|
||||
else:
|
||||
c = self.vk.client
|
||||
formatted_endpoint = ""
|
||||
if "parent_endpoint" in kwargs:
|
||||
p = kwargs["parent_endpoint"]
|
||||
formatted_endpoint = kwargs["parent_endpoint"]
|
||||
if "audio" in p and self.settings["vk"]["use_alternative_tokens"]:
|
||||
log.info("Using alternative audio methods.")
|
||||
c = self.vk.client_audio
|
||||
kwargs.pop("parent_endpoint")
|
||||
try:
|
||||
p = getattr(c, p)
|
||||
except AttributeError:
|
||||
p = c
|
||||
if name in self.db and "offset" in self.db[name] and show_nextpage == True:
|
||||
kwargs.update(offset=self.db[name]["offset"])
|
||||
else:
|
||||
kwargs.update(offset=0)
|
||||
formatted_endpoint = "{formatted_endpoint}.{new_path}".format(formatted_endpoint=formatted_endpoint, new_path=endpoint)
|
||||
offset_deprecated = ["notifications.get"]
|
||||
if formatted_endpoint in offset_deprecated:
|
||||
kwargs.update(offset=None)
|
||||
log.debug("Calling endpoint %s with params %r" % (formatted_endpoint, kwargs,))
|
||||
data = getattr(p, endpoint)(*args, **kwargs)
|
||||
if data != None:
|
||||
if "count" not in kwargs:
|
||||
kwargs["count"] = 100
|
||||
# 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.
|
||||
if type(data) == dict and "items" in data and endpoint == "getHistory" and kwargs["offset"] == 0:
|
||||
data["items"].reverse()
|
||||
if type(data) == dict:
|
||||
num = self.order_buffer(name, data["items"], show_nextpage)
|
||||
if formatted_endpoint not in offset_deprecated:
|
||||
self.db[name]["offset"] = kwargs["offset"]+kwargs["count"]
|
||||
if len(data["items"]) > 0 and "first_name" in data["items"][0]:
|
||||
data2 = {"profiles": [], "groups": []}
|
||||
for i in data["items"]:
|
||||
data2["profiles"].append(i)
|
||||
self.process_usernames(data2)
|
||||
if "profiles" in data and "groups" in data:
|
||||
self.process_usernames(data)
|
||||
else:
|
||||
num = self.order_buffer(name, data, show_nextpage)
|
||||
self.db[name]["offset"] = kwargs["offset"]+kwargs["count"]
|
||||
return num
|
||||
|
||||
def get_messages(self, name="", *args, **kwargs):
|
||||
data = self.vk.client.messages.getHistory(*args, **kwargs)
|
||||
data["items"].reverse()
|
||||
if data != None:
|
||||
num = self.order_buffer(name, data["items"], False)
|
||||
return num
|
||||
def get_messages(self, name="", *args, **kwargs):
|
||||
data = self.vk.client.messages.getHistory(*args, **kwargs)
|
||||
data["items"].reverse()
|
||||
if data != None:
|
||||
num = self.order_buffer(name, data["items"], False)
|
||||
return num
|
||||
|
||||
def get_users(self, user_ids=None, group_ids=None):
|
||||
log.debug("Getting user information from the VK servers")
|
||||
if user_ids != None:
|
||||
u = self.vk.client.users.get(user_ids=user_ids, fields="uid, first_name, last_name")
|
||||
for i in u:
|
||||
self.db["users"][i["id"]] = dict(nom="{0} {1}".format(i["first_name"], i["last_name"]))
|
||||
if group_ids != None:
|
||||
g = self.vk.client.groups.getById(group_ids=group_ids, fields="name")
|
||||
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"])
|
||||
def get_users(self, user_ids=None, group_ids=None):
|
||||
log.debug("Getting user information from the VK servers")
|
||||
if user_ids != None:
|
||||
u = self.vk.client.users.get(user_ids=user_ids, fields="uid, first_name, last_name")
|
||||
for i in u:
|
||||
self.db["users"][i["id"]] = dict(nom="{0} {1}".format(i["first_name"], i["last_name"]))
|
||||
if group_ids != None:
|
||||
g = self.vk.client.groups.getById(group_ids=group_ids, fields="name")
|
||||
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"])
|
||||
|
||||
def get_user(self, user_id, key="user1"):
|
||||
if user_id > 0:
|
||||
if user_id in self.db["users"]:
|
||||
user_data = {}
|
||||
user_fields = "nom, gen, ins, dat, abl, acc".split(", ")
|
||||
for i in user_fields:
|
||||
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])
|
||||
user_data[k] = v
|
||||
return user_data
|
||||
# if User_id is not present in db.
|
||||
else:
|
||||
user = dict(id=user_id)
|
||||
self.process_usernames(data=dict(profiles=[user], groups=[]))
|
||||
return self.get_user(user_id)
|
||||
else:
|
||||
if abs(user_id) in self.db["groups"]:
|
||||
user_data = {}
|
||||
user_fields = "nom, gen, ins, dat, abl, acc".split(", ")
|
||||
for i in user_fields:
|
||||
k = "{key}_{case}".format(key=key, case=i)
|
||||
v = self.db["groups"][abs(user_id)][i]
|
||||
user_data[k] = v
|
||||
else:
|
||||
group = self.vk.client.groups.getById(group_ids=-1*user_id)[0]
|
||||
self.process_usernames(data=dict(profiles=[], groups=[group]))
|
||||
return self.get_user(user_id=user_id, key=key)
|
||||
return user_data
|
||||
def get_user(self, user_id, key="user1"):
|
||||
if user_id > 0:
|
||||
if user_id in self.db["users"]:
|
||||
user_data = {}
|
||||
user_fields = "nom, gen, ins, dat, abl, acc".split(", ")
|
||||
for i in user_fields:
|
||||
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])
|
||||
user_data[k] = v
|
||||
return user_data
|
||||
# if User_id is not present in db.
|
||||
else:
|
||||
user = dict(id=user_id)
|
||||
self.process_usernames(data=dict(profiles=[user], groups=[]))
|
||||
return self.get_user(user_id)
|
||||
else:
|
||||
if abs(user_id) in self.db["groups"]:
|
||||
user_data = {}
|
||||
user_fields = "nom, gen, ins, dat, abl, acc".split(", ")
|
||||
for i in user_fields:
|
||||
k = "{key}_{case}".format(key=key, case=i)
|
||||
v = self.db["groups"][abs(user_id)][i]
|
||||
user_data[k] = v
|
||||
else:
|
||||
group = self.vk.client.groups.getById(group_ids=-1*user_id)[0]
|
||||
self.process_usernames(data=dict(profiles=[], groups=[group]))
|
||||
return self.get_user(user_id=user_id, key=key)
|
||||
return user_data
|
||||
|
||||
def process_usernames(self, data):
|
||||
""" 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 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."""
|
||||
log.debug("Adding usernames to the local database...")
|
||||
ids = ""
|
||||
for i in data["profiles"]:
|
||||
if (i["id"] in self.db["users"]) == False:
|
||||
ids = ids + "{0},".format(i["id"],)
|
||||
gids = ""
|
||||
for i in data["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"])
|
||||
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_list = user_fields.split(", ")
|
||||
if ids != "":
|
||||
users = self.vk.client.users.get(user_ids=ids, fields=user_fields)
|
||||
for i in users:
|
||||
if i["id"] not in self.db["users"]:
|
||||
userdata = {}
|
||||
for field in user_fields_list:
|
||||
if field in i:
|
||||
userdata[field] = i[field]
|
||||
self.db["users"][i["id"]] = userdata
|
||||
def process_usernames(self, data):
|
||||
""" 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 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."""
|
||||
log.debug("Adding usernames to the local database...")
|
||||
ids = ""
|
||||
for i in data["profiles"]:
|
||||
if (i["id"] in self.db["users"]) == False:
|
||||
ids = ids + "{0},".format(i["id"],)
|
||||
gids = ""
|
||||
for i in data["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"])
|
||||
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_list = user_fields.split(", ")
|
||||
if ids != "":
|
||||
users = self.vk.client.users.get(user_ids=ids, fields=user_fields)
|
||||
for i in users:
|
||||
if i["id"] not in self.db["users"]:
|
||||
userdata = {}
|
||||
for field in user_fields_list:
|
||||
if field in i:
|
||||
userdata[field] = i[field]
|
||||
self.db["users"][i["id"]] = userdata
|
||||
|
||||
def get_my_data(self):
|
||||
log.debug("Getting user identifier...")
|
||||
user = self.vk.client.users.get(fields="uid, first_name, last_name")
|
||||
self.user_id = user[0]["id"]
|
||||
def get_my_data(self):
|
||||
log.debug("Getting user identifier...")
|
||||
user = self.vk.client.users.get(fields="uid, first_name, last_name")
|
||||
self.user_id = user[0]["id"]
|
||||
|
||||
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.
|
||||
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."""
|
||||
# Define a list of error codes that are handled by the application.
|
||||
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.
|
||||
# We should see what can be done (reuploading everything vs using the already added attachments).
|
||||
attachments = ""
|
||||
# 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.
|
||||
if len(attachments_list) > 0:
|
||||
try:
|
||||
attachments = self.upload_attachments(attachments_list, post_arguments.get("peer_id"))
|
||||
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)))
|
||||
# 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)
|
||||
# After modifying everything, let's update the post arguments if needed.
|
||||
if len(attachments) > 0:
|
||||
if parent_endpoint == "messages":
|
||||
post_arguments.update(attachment=attachments)
|
||||
else:
|
||||
post_arguments.update(attachments=attachments)
|
||||
# Determines the correct functions to call here.
|
||||
endpoint = getattr(self.vk.client, parent_endpoint)
|
||||
endpoint = getattr(endpoint, child_endpoint)
|
||||
try:
|
||||
post = endpoint(**post_arguments)
|
||||
# Once the post has been send, let's report it to the interested objects.
|
||||
pub.sendMessage("posted", from_buffer=from_buffer)
|
||||
except Exception as 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.
|
||||
if error.code in handled_errors:
|
||||
wx.CallAfter(pub.sendMessage, "api-error", code=error.code)
|
||||
else:
|
||||
# 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)
|
||||
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.
|
||||
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."""
|
||||
# Define a list of error codes that are handled by the application.
|
||||
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.
|
||||
# We should see what can be done (reuploading everything vs using the already added attachments).
|
||||
attachments = ""
|
||||
# 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.
|
||||
if len(attachments_list) > 0:
|
||||
try:
|
||||
attachments = self.upload_attachments(attachments_list, post_arguments.get("peer_id"))
|
||||
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)))
|
||||
# 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)
|
||||
# After modifying everything, let's update the post arguments if needed.
|
||||
if len(attachments) > 0:
|
||||
if parent_endpoint == "messages":
|
||||
post_arguments.update(attachment=attachments)
|
||||
else:
|
||||
post_arguments.update(attachments=attachments)
|
||||
# Determines the correct functions to call here.
|
||||
endpoint = getattr(self.vk.client, parent_endpoint)
|
||||
endpoint = getattr(endpoint, child_endpoint)
|
||||
try:
|
||||
post = endpoint(**post_arguments)
|
||||
# Once the post has been send, let's report it to the interested objects.
|
||||
pub.sendMessage("posted", from_buffer=from_buffer)
|
||||
except Exception as 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.
|
||||
if error.code in handled_errors:
|
||||
wx.CallAfter(pub.sendMessage, "api-error", code=error.code)
|
||||
else:
|
||||
# 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)
|
||||
|
||||
def upload_attachments(self, attachments, peer_id=None):
|
||||
""" Upload attachments to VK before posting them.
|
||||
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.
|
||||
"""
|
||||
# To do: Check the caption and description fields for this kind of attachments.
|
||||
local_attachments = ""
|
||||
uploader = upload.VkUpload(self.vk.session_object)
|
||||
for i in attachments:
|
||||
if i["from"] == "online":
|
||||
local_attachments += "{0}{1}_{2},".format(i["type"], i["owner_id"], i["id"])
|
||||
elif i["from"] == "local" and i["type"] == "photo":
|
||||
photos = i["file"]
|
||||
description = i["description"]
|
||||
if peer_id == None:
|
||||
r = uploader.photo_wall(photos, caption=description)
|
||||
else:
|
||||
r = uploader.photo_messages(photos)
|
||||
id = r[0]["id"]
|
||||
owner_id = r[0]["owner_id"]
|
||||
local_attachments += "photo{0}_{1},".format(owner_id, id)
|
||||
elif i["from"] == "local" and i["type"] == "audio":
|
||||
audio = i["file"]
|
||||
title = "untitled"
|
||||
artist = "unnamed"
|
||||
if "artist" in i:
|
||||
artist = i["artist"]
|
||||
if "title" in i:
|
||||
title = i["title"]
|
||||
r = uploader.audio(audio, title=title, artist=artist)
|
||||
id = r["id"]
|
||||
owner_id = r["owner_id"]
|
||||
local_attachments += "audio{0}_{1},".format(owner_id, id)
|
||||
elif i["from"] == "local" and i["type"] == "voice_message":
|
||||
r = uploader.audio_message(i["file"], peer_id=peer_id)
|
||||
id = r["audio_message"]["id"]
|
||||
owner_id = r["audio_message"]["owner_id"]
|
||||
local_attachments += "audio_message{0}_{1},".format(owner_id, id)
|
||||
elif i["from"] == "local" and i["type"] == "document":
|
||||
document = i["file"]
|
||||
title = i["title"]
|
||||
if peer_id == None:
|
||||
r = uploader.document(document, title=title, to_wall=True)
|
||||
else:
|
||||
r = uploader.document(document, title=title, message_peer_id=peer_id)
|
||||
id = r["doc"]["id"]
|
||||
owner_id = r["doc"]["owner_id"]
|
||||
local_attachments += "doc{0}_{1},".format(owner_id, id)
|
||||
return local_attachments
|
||||
def upload_attachments(self, attachments, peer_id=None):
|
||||
""" Upload attachments to VK before posting them.
|
||||
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.
|
||||
"""
|
||||
# To do: Check the caption and description fields for this kind of attachments.
|
||||
local_attachments = ""
|
||||
uploader = upload.VkUpload(self.vk.session_object)
|
||||
for i in attachments:
|
||||
if i["from"] == "online":
|
||||
local_attachments += "{0}{1}_{2},".format(i["type"], i["owner_id"], i["id"])
|
||||
elif i["from"] == "local" and i["type"] == "photo":
|
||||
photos = i["file"]
|
||||
description = i["description"]
|
||||
if peer_id == None:
|
||||
r = uploader.photo_wall(photos, caption=description)
|
||||
else:
|
||||
r = uploader.photo_messages(photos)
|
||||
id = r[0]["id"]
|
||||
owner_id = r[0]["owner_id"]
|
||||
local_attachments += "photo{0}_{1},".format(owner_id, id)
|
||||
elif i["from"] == "local" and i["type"] == "audio":
|
||||
audio = i["file"]
|
||||
title = "untitled"
|
||||
artist = "unnamed"
|
||||
if "artist" in i:
|
||||
artist = i["artist"]
|
||||
if "title" in i:
|
||||
title = i["title"]
|
||||
r = uploader.audio(audio, title=title, artist=artist)
|
||||
id = r["id"]
|
||||
owner_id = r["owner_id"]
|
||||
local_attachments += "audio{0}_{1},".format(owner_id, id)
|
||||
elif i["from"] == "local" and i["type"] == "voice_message":
|
||||
r = uploader.audio_message(i["file"], peer_id=peer_id)
|
||||
id = r["audio_message"]["id"]
|
||||
owner_id = r["audio_message"]["owner_id"]
|
||||
local_attachments += "audio_message{0}_{1},".format(owner_id, id)
|
||||
elif i["from"] == "local" and i["type"] == "document":
|
||||
document = i["file"]
|
||||
title = i["title"]
|
||||
if peer_id == None:
|
||||
r = uploader.document(document, title=title, to_wall=True)
|
||||
else:
|
||||
r = uploader.document(document, title=title, message_peer_id=peer_id)
|
||||
id = r["doc"]["id"]
|
||||
owner_id = r["doc"]["owner_id"]
|
||||
local_attachments += "doc{0}_{1},".format(owner_id, id)
|
||||
return local_attachments
|
||||
|
@ -14,83 +14,83 @@ from .config_utils import Configuration
|
||||
log = logging.getLogger("sessionmanager.sessionManager")
|
||||
|
||||
class sessionManagerController(object):
|
||||
def __init__(self, starting=True):
|
||||
super(sessionManagerController, self).__init__()
|
||||
log.debug("Setting up the session manager.")
|
||||
if starting:
|
||||
title=_("Select an account")
|
||||
else:
|
||||
title = _("Manage accounts")
|
||||
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.remove, widgetUtils.BUTTON_PRESSED, self.remove)
|
||||
self.fill_list()
|
||||
if len(self.sessions) == 0:
|
||||
log.debug("the session list is empty, creating a new one...")
|
||||
self.manage_new_account()
|
||||
def __init__(self, starting=True):
|
||||
super(sessionManagerController, self).__init__()
|
||||
log.debug("Setting up the session manager.")
|
||||
if starting:
|
||||
title=_("Select an account")
|
||||
else:
|
||||
title = _("Manage accounts")
|
||||
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.remove, widgetUtils.BUTTON_PRESSED, self.remove)
|
||||
self.fill_list()
|
||||
if len(self.sessions) == 0:
|
||||
log.debug("the session list is empty, creating a new one...")
|
||||
self.manage_new_account()
|
||||
|
||||
def fill_list(self):
|
||||
self.sessions = []
|
||||
log.debug("Filling the session list...")
|
||||
for i in os.listdir(paths.config_path()):
|
||||
if i != "dicts" and os.path.isdir(os.path.join(paths.config_path(), i)):
|
||||
log.debug("Adding session %s" % (i,))
|
||||
config_test = Configuration(os.path.join(paths.config_path(), i, "session.conf"))
|
||||
name = config_test["vk"]["user"]
|
||||
if name != "" and config_test["vk"]["password"] != "":
|
||||
self.sessions.append((i, name))
|
||||
self.view.list.insert_item(False, *[name])
|
||||
def fill_list(self):
|
||||
self.sessions = []
|
||||
log.debug("Filling the session list...")
|
||||
for i in os.listdir(paths.config_path()):
|
||||
if i != "dicts" and os.path.isdir(os.path.join(paths.config_path(), i)):
|
||||
log.debug("Adding session %s" % (i,))
|
||||
config_test = Configuration(os.path.join(paths.config_path(), i, "session.conf"))
|
||||
name = config_test["vk"]["user"]
|
||||
if name != "" and config_test["vk"]["password"] != "":
|
||||
self.sessions.append((i, name))
|
||||
self.view.list.insert_item(False, *[name])
|
||||
|
||||
def manage_new_account(self, *args, **kwargs):
|
||||
if view.new_account_dialog() == widgetUtils.YES:
|
||||
location = (str(time.time())[-6:])
|
||||
log.debug("Creating session in the %s path" % (location,))
|
||||
s = session.vkSession(location)
|
||||
path = os.path.join(paths.config_path(), location)
|
||||
if not os.path.exists(path):
|
||||
os.mkdir(path)
|
||||
s.get_configuration(True)
|
||||
self.get_authorisation(s)
|
||||
name = s.settings["vk"]["user"]
|
||||
self.sessions.append((location, name))
|
||||
self.view.list.insert_item(False, *[name])
|
||||
self.modified = True
|
||||
def manage_new_account(self, *args, **kwargs):
|
||||
if view.new_account_dialog() == widgetUtils.YES:
|
||||
location = (str(time.time())[-6:])
|
||||
log.debug("Creating session in the %s path" % (location,))
|
||||
s = session.vkSession(location)
|
||||
path = os.path.join(paths.config_path(), location)
|
||||
if not os.path.exists(path):
|
||||
os.mkdir(path)
|
||||
s.get_configuration(True)
|
||||
self.get_authorisation(s)
|
||||
name = s.settings["vk"]["user"]
|
||||
self.sessions.append((location, name))
|
||||
self.view.list.insert_item(False, *[name])
|
||||
self.modified = True
|
||||
|
||||
def get_authorisation(self, c):
|
||||
log.debug("Starting the authorisation process...")
|
||||
dl = view.newSessionDialog()
|
||||
if dl.ShowModal() == widgetUtils.OK:
|
||||
c.settings["vk"]["user"] = dl.get_email()
|
||||
c.settings["vk"]["password"] = dl.get_password()
|
||||
try:
|
||||
c.login()
|
||||
except AuthenticationError:
|
||||
c.settings["vk"]["password"] = ""
|
||||
c.settings["vk"]["user"]
|
||||
return self.get_authorisation(c)
|
||||
def get_authorisation(self, c):
|
||||
log.debug("Starting the authorisation process...")
|
||||
dl = view.newSessionDialog()
|
||||
if dl.ShowModal() == widgetUtils.OK:
|
||||
c.settings["vk"]["user"] = dl.get_email()
|
||||
c.settings["vk"]["password"] = dl.get_password()
|
||||
try:
|
||||
c.login()
|
||||
except AuthenticationError:
|
||||
c.settings["vk"]["password"] = ""
|
||||
c.settings["vk"]["user"]
|
||||
return self.get_authorisation(c)
|
||||
|
||||
def do_ok(self):
|
||||
selected_session = self.sessions[self.view.list.get_selected()]
|
||||
self.session = selected_session[0]
|
||||
self.session = session.vkSession(self.session)
|
||||
self.session.get_configuration()
|
||||
session.sessions[selected_session[1]] = self.session
|
||||
def do_ok(self):
|
||||
selected_session = self.sessions[self.view.list.get_selected()]
|
||||
self.session = selected_session[0]
|
||||
self.session = session.vkSession(self.session)
|
||||
self.session.get_configuration()
|
||||
session.sessions[selected_session[1]] = self.session
|
||||
|
||||
def show(self):
|
||||
if len(self.sessions) > 1:
|
||||
answer = self.view.get_response()
|
||||
else:
|
||||
answer = widgetUtils.OK
|
||||
if answer == widgetUtils.OK:
|
||||
self.do_ok()
|
||||
else:
|
||||
sys.exit()
|
||||
self.view.destroy()
|
||||
def show(self):
|
||||
if len(self.sessions) > 1:
|
||||
answer = self.view.get_response()
|
||||
else:
|
||||
answer = widgetUtils.OK
|
||||
if answer == widgetUtils.OK:
|
||||
self.do_ok()
|
||||
else:
|
||||
sys.exit()
|
||||
self.view.destroy()
|
||||
|
||||
def remove(self, *args, **kwargs):
|
||||
if self.view.remove_account_dialog() == widgetUtils.YES:
|
||||
selected_session = self.sessions[self.view.list.get_selected()]
|
||||
shutil.rmtree(path=os.path.join(paths.config_path(), selected_session[0]), ignore_errors=True)
|
||||
self.sessions.remove(selected_session)
|
||||
self.view.list.remove_item(self.view.list.get_selected())
|
||||
self.modified = True
|
||||
def remove(self, *args, **kwargs):
|
||||
if self.view.remove_account_dialog() == widgetUtils.YES:
|
||||
selected_session = self.sessions[self.view.list.get_selected()]
|
||||
shutil.rmtree(path=os.path.join(paths.config_path(), selected_session[0]), ignore_errors=True)
|
||||
self.sessions.remove(selected_session)
|
||||
self.view.list.remove_item(self.view.list.get_selected())
|
||||
self.modified = True
|
||||
|
@ -12,93 +12,93 @@ url_re = re.compile("(?:\w+://|www\.)[^ ,.?!#%=+][^ ]*")
|
||||
bad_chars = '\'\\.,[](){}:;"'
|
||||
|
||||
def seconds_to_string(seconds, precision=0):
|
||||
""" convert a number of seconds in a string representation."""
|
||||
# ToDo: Improve it to handle properly Russian plurals.
|
||||
day = seconds // 86400
|
||||
hour = seconds // 3600
|
||||
min = (seconds // 60) % 60
|
||||
sec = seconds - (hour * 3600) - (min * 60)
|
||||
sec_spec = "." + str(precision) + "f"
|
||||
sec_string = sec.__format__(sec_spec)
|
||||
string = ""
|
||||
if day == 1:
|
||||
string += _("%d day, ") % day
|
||||
elif day >= 2:
|
||||
string += _("%d days, ") % day
|
||||
if (hour == 1):
|
||||
string += _("%d hour, ") % hour
|
||||
elif (hour >= 2):
|
||||
string += _("%d hours, ") % hour
|
||||
if (min == 1):
|
||||
string += _("%d minute, ") % min
|
||||
elif (min >= 2):
|
||||
string += _("%d minutes, ") % min
|
||||
if sec >= 0 and sec <= 2:
|
||||
string += _("%s second") % sec_string
|
||||
else:
|
||||
string += _("%s seconds") % sec_string
|
||||
return string
|
||||
""" convert a number of seconds in a string representation."""
|
||||
# ToDo: Improve it to handle properly Russian plurals.
|
||||
day = seconds // 86400
|
||||
hour = seconds // 3600
|
||||
min = (seconds // 60) % 60
|
||||
sec = seconds - (hour * 3600) - (min * 60)
|
||||
sec_spec = "." + str(precision) + "f"
|
||||
sec_string = sec.__format__(sec_spec)
|
||||
string = ""
|
||||
if day == 1:
|
||||
string += _("%d day, ") % day
|
||||
elif day >= 2:
|
||||
string += _("%d days, ") % day
|
||||
if (hour == 1):
|
||||
string += _("%d hour, ") % hour
|
||||
elif (hour >= 2):
|
||||
string += _("%d hours, ") % hour
|
||||
if (min == 1):
|
||||
string += _("%d minute, ") % min
|
||||
elif (min >= 2):
|
||||
string += _("%d minutes, ") % min
|
||||
if sec >= 0 and sec <= 2:
|
||||
string += _("%s second") % sec_string
|
||||
else:
|
||||
string += _("%s seconds") % sec_string
|
||||
return string
|
||||
|
||||
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):
|
||||
r = requests.get(url, stream=True)
|
||||
pub.sendMessage("change_status", status=_("Downloading {0}").format(local_filename,))
|
||||
total_length = r.headers.get("content-length")
|
||||
dl = 0
|
||||
total_length = int(total_length)
|
||||
with open(local_filename, 'wb') as f:
|
||||
for chunk in r.iter_content(chunk_size=512*1024):
|
||||
if chunk: # filter out keep-alive new chunks
|
||||
dl += len(chunk)
|
||||
f.write(chunk)
|
||||
done = int(100 * dl/total_length)
|
||||
msg = _("Downloading {0} ({1}%)").format(os.path.basename(local_filename), done)
|
||||
# print(msg)
|
||||
pub.sendMessage("change_status", status=msg)
|
||||
pub.sendMessage("change_status", status=_("Ready"))
|
||||
return local_filename
|
||||
r = requests.get(url, stream=True)
|
||||
pub.sendMessage("change_status", status=_("Downloading {0}").format(local_filename,))
|
||||
total_length = r.headers.get("content-length")
|
||||
dl = 0
|
||||
total_length = int(total_length)
|
||||
with open(local_filename, 'wb') as f:
|
||||
for chunk in r.iter_content(chunk_size=512*1024):
|
||||
if chunk: # filter out keep-alive new chunks
|
||||
dl += len(chunk)
|
||||
f.write(chunk)
|
||||
done = int(100 * dl/total_length)
|
||||
msg = _("Downloading {0} ({1}%)").format(os.path.basename(local_filename), done)
|
||||
# print(msg)
|
||||
pub.sendMessage("change_status", status=msg)
|
||||
pub.sendMessage("change_status", status=_("Ready"))
|
||||
return local_filename
|
||||
|
||||
def download_files(downloads):
|
||||
for download in downloads:
|
||||
download_file(download[0], download[1])
|
||||
for download in downloads:
|
||||
download_file(download[0], download[1])
|
||||
|
||||
def detect_users(text):
|
||||
""" Detect all users and communities mentionned in any text posted in VK."""
|
||||
# This regexp gets group and users mentionned in topic comments.
|
||||
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)
|
||||
# This is for users and communities just mentionned in wall comments or posts.
|
||||
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)
|
||||
return text
|
||||
""" Detect all users and communities mentionned in any text posted in VK."""
|
||||
# This regexp gets group and users mentionned in topic comments.
|
||||
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)
|
||||
# This is for users and communities just mentionned in wall comments or posts.
|
||||
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)
|
||||
return text
|
||||
|
||||
def clean_text(text):
|
||||
""" Clean text, removing all unneeded HTMl and converting HTML represented characters in their unicode counterparts."""
|
||||
text = detect_users(text)
|
||||
text = html.unescape(text)
|
||||
return text
|
||||
""" Clean text, removing all unneeded HTMl and converting HTML represented characters in their unicode counterparts."""
|
||||
text = detect_users(text)
|
||||
text = html.unescape(text)
|
||||
return text
|
||||
|
||||
def transform_audio_url(url):
|
||||
""" 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.
|
||||
Changelog:
|
||||
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.
|
||||
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:
|
||||
return url
|
||||
url = url.replace("/index.m3u8", ".mp3")
|
||||
parts = url.split("/")
|
||||
if "/audios" not in url:
|
||||
url = url.replace("/"+parts[-2], "")
|
||||
else:
|
||||
url = url.replace("/"+parts[-3], "")
|
||||
url = url.split(".mp3?")[0]+".mp3"
|
||||
return url
|
||||
""" 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.
|
||||
Changelog:
|
||||
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.
|
||||
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:
|
||||
return url
|
||||
url = url.replace("/index.m3u8", ".mp3")
|
||||
parts = url.split("/")
|
||||
if "/audios" not in url:
|
||||
url = url.replace("/"+parts[-2], "")
|
||||
else:
|
||||
url = url.replace("/"+parts[-3], "")
|
||||
url = url.split(".mp3?")[0]+".mp3"
|
||||
return url
|
||||
|
||||
def safe_filename(filename):
|
||||
allowed_symbols = ["_", ".", ",", "-", "(", ")"]
|
||||
return "".join([c for c in filename if c.isalpha() or c.isdigit() or c==' ' or c in allowed_symbols]).rstrip()
|
||||
allowed_symbols = ["_", ".", ",", "-", "(", ")"]
|
||||
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):
|
||||
|
||||
def __init__(self):
|
||||
self.api_key = keys.keyring.get_api_key()
|
||||
def __init__(self):
|
||||
self.api_key = keys.keyring.get_api_key()
|
||||
|
||||
def login(self, user, password, token, alt_token, filename):
|
||||
if alt_token == False:
|
||||
log.info("Using kate's token...")
|
||||
# Let's import the patched vk_api module for using a different user agent
|
||||
from . import vk_api_patched as vk_api
|
||||
if token == "" or token == None:
|
||||
log.info("Token is not valid. Generating one...")
|
||||
original_token = official.login(user, password)
|
||||
token = original_token
|
||||
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)
|
||||
else:
|
||||
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.auth()
|
||||
self.client = self.session_object.get_api()
|
||||
# print self.client.audio.get()
|
||||
log.debug("Getting tokens for 24 hours...")
|
||||
# info = self.client.account.getProfileInfo()
|
||||
# Add session data to the application statistics.
|
||||
self.client.stats.trackVisitor()
|
||||
self.client_audio = VkAudio(self.session_object)
|
||||
def login(self, user, password, token, alt_token, filename):
|
||||
if alt_token == False:
|
||||
log.info("Using kate's token...")
|
||||
# Let's import the patched vk_api module for using a different user agent
|
||||
from . import vk_api_patched as vk_api
|
||||
if token == "" or token == None:
|
||||
log.info("Token is not valid. Generating one...")
|
||||
original_token = official.login(user, password)
|
||||
token = original_token
|
||||
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)
|
||||
else:
|
||||
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.auth()
|
||||
self.client = self.session_object.get_api()
|
||||
# print self.client.audio.get()
|
||||
log.debug("Getting tokens for 24 hours...")
|
||||
# info = self.client.account.getProfileInfo()
|
||||
# Add session data to the application statistics.
|
||||
self.client.stats.trackVisitor()
|
||||
self.client_audio = VkAudio(self.session_object)
|
||||
|
@ -4,71 +4,71 @@ import wx
|
||||
import widgetUtils
|
||||
|
||||
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):
|
||||
def __init__(self):
|
||||
super(newSessionDialog, self).__init__(parent=None, id=wx.NewId(), title=_("Authorise VK"))
|
||||
panel = wx.Panel(self)
|
||||
lbl1 = wx.StaticText(panel, -1, _("&Email or phone number"))
|
||||
self.email = wx.TextCtrl(panel, -1)
|
||||
lbl2 = wx.StaticText(panel, -1, _("&Password"))
|
||||
self.passw = wx.TextCtrl(panel, -1, style=wx.TE_PASSWORD)
|
||||
sizer = wx.BoxSizer()
|
||||
b1 = wx.BoxSizer(wx.HORIZONTAL)
|
||||
b1.Add(lbl1, 0, wx.ALL, 5)
|
||||
b1.Add(self.email, 0, wx.ALL, 5)
|
||||
b2 = wx.BoxSizer(wx.HORIZONTAL)
|
||||
b2.Add(lbl2, 0, wx.ALL, 5)
|
||||
b2.Add(self.passw, 0, wx.ALL, 5)
|
||||
sizer.Add(b1, 0, wx.ALL, 5)
|
||||
sizer.Add(b2, 0, wx.ALL, 5)
|
||||
ok = wx.Button(panel, wx.ID_OK)
|
||||
ok.SetDefault()
|
||||
cancel = wx.Button(panel, wx.ID_CANCEL)
|
||||
btnb = wx.BoxSizer(wx.HORIZONTAL)
|
||||
btnb.Add(ok, 0, wx.ALL, 5)
|
||||
btnb.Add(cancel, 0, wx.ALL, 5)
|
||||
sizer.Add(btnb, 0, wx.ALL, 5)
|
||||
panel.SetSizer(sizer)
|
||||
def __init__(self):
|
||||
super(newSessionDialog, self).__init__(parent=None, id=wx.NewId(), title=_("Authorise VK"))
|
||||
panel = wx.Panel(self)
|
||||
lbl1 = wx.StaticText(panel, -1, _("&Email or phone number"))
|
||||
self.email = wx.TextCtrl(panel, -1)
|
||||
lbl2 = wx.StaticText(panel, -1, _("&Password"))
|
||||
self.passw = wx.TextCtrl(panel, -1, style=wx.TE_PASSWORD)
|
||||
sizer = wx.BoxSizer()
|
||||
b1 = wx.BoxSizer(wx.HORIZONTAL)
|
||||
b1.Add(lbl1, 0, wx.ALL, 5)
|
||||
b1.Add(self.email, 0, wx.ALL, 5)
|
||||
b2 = wx.BoxSizer(wx.HORIZONTAL)
|
||||
b2.Add(lbl2, 0, wx.ALL, 5)
|
||||
b2.Add(self.passw, 0, wx.ALL, 5)
|
||||
sizer.Add(b1, 0, wx.ALL, 5)
|
||||
sizer.Add(b2, 0, wx.ALL, 5)
|
||||
ok = wx.Button(panel, wx.ID_OK)
|
||||
ok.SetDefault()
|
||||
cancel = wx.Button(panel, wx.ID_CANCEL)
|
||||
btnb = wx.BoxSizer(wx.HORIZONTAL)
|
||||
btnb.Add(ok, 0, wx.ALL, 5)
|
||||
btnb.Add(cancel, 0, wx.ALL, 5)
|
||||
sizer.Add(btnb, 0, wx.ALL, 5)
|
||||
panel.SetSizer(sizer)
|
||||
|
||||
def get_email(self):
|
||||
return self.email.GetValue()
|
||||
def get_email(self):
|
||||
return self.email.GetValue()
|
||||
|
||||
def get_password(self):
|
||||
return self.passw.GetValue()
|
||||
def get_password(self):
|
||||
return self.passw.GetValue()
|
||||
|
||||
class sessionManagerWindow(widgetUtils.BaseDialog):
|
||||
def __init__(self, title, starting=True):
|
||||
super(sessionManagerWindow, self).__init__(parent=None, title=title, size=wx.DefaultSize)
|
||||
panel = wx.Panel(self)
|
||||
sizer = wx.BoxSizer(wx.VERTICAL)
|
||||
label = wx.StaticText(panel, -1, _(u"Accounts list"), size=wx.DefaultSize)
|
||||
listSizer = wx.BoxSizer(wx.HORIZONTAL)
|
||||
self.list = widgetUtils.list(panel, _("Account"), style=wx.LC_SINGLE_SEL|wx.LC_REPORT)
|
||||
listSizer.Add(label, 0, wx.ALL, 5)
|
||||
listSizer.Add(self.list.list, 0, wx.ALL, 5)
|
||||
sizer.Add(listSizer, 0, wx.ALL, 5)
|
||||
self.new = wx.Button(panel, -1, _("New account"), size=wx.DefaultSize)
|
||||
self.remove = wx.Button(panel, -1, _(u"Remove account"))
|
||||
if starting:
|
||||
id_ok = wx.ID_OK
|
||||
else:
|
||||
id_ok = wx.ID_CANCEL
|
||||
ok = wx.Button(panel, id_ok, size=wx.DefaultSize)
|
||||
ok.SetDefault()
|
||||
if starting:
|
||||
cancel = wx.Button(panel, wx.ID_CANCEL, size=wx.DefaultSize)
|
||||
self.SetAffirmativeId(id_ok)
|
||||
buttons = wx.BoxSizer(wx.HORIZONTAL)
|
||||
buttons.Add(self.new, 0, wx.ALL, 5)
|
||||
buttons.Add(ok, 0, wx.ALL, 5)
|
||||
if starting:
|
||||
buttons.Add(cancel, 0, wx.ALL, 5)
|
||||
sizer.Add(buttons, 0, wx.ALL, 5)
|
||||
panel.SetSizer(sizer)
|
||||
min = sizer.CalcMin()
|
||||
self.SetClientSize(min)
|
||||
def __init__(self, title, starting=True):
|
||||
super(sessionManagerWindow, self).__init__(parent=None, title=title, size=wx.DefaultSize)
|
||||
panel = wx.Panel(self)
|
||||
sizer = wx.BoxSizer(wx.VERTICAL)
|
||||
label = wx.StaticText(panel, -1, _(u"Accounts list"), size=wx.DefaultSize)
|
||||
listSizer = wx.BoxSizer(wx.HORIZONTAL)
|
||||
self.list = widgetUtils.list(panel, _("Account"), style=wx.LC_SINGLE_SEL|wx.LC_REPORT)
|
||||
listSizer.Add(label, 0, wx.ALL, 5)
|
||||
listSizer.Add(self.list.list, 0, wx.ALL, 5)
|
||||
sizer.Add(listSizer, 0, wx.ALL, 5)
|
||||
self.new = wx.Button(panel, -1, _("New account"), size=wx.DefaultSize)
|
||||
self.remove = wx.Button(panel, -1, _(u"Remove account"))
|
||||
if starting:
|
||||
id_ok = wx.ID_OK
|
||||
else:
|
||||
id_ok = wx.ID_CANCEL
|
||||
ok = wx.Button(panel, id_ok, size=wx.DefaultSize)
|
||||
ok.SetDefault()
|
||||
if starting:
|
||||
cancel = wx.Button(panel, wx.ID_CANCEL, size=wx.DefaultSize)
|
||||
self.SetAffirmativeId(id_ok)
|
||||
buttons = wx.BoxSizer(wx.HORIZONTAL)
|
||||
buttons.Add(self.new, 0, wx.ALL, 5)
|
||||
buttons.Add(ok, 0, wx.ALL, 5)
|
||||
if starting:
|
||||
buttons.Add(cancel, 0, wx.ALL, 5)
|
||||
sizer.Add(buttons, 0, wx.ALL, 5)
|
||||
panel.SetSizer(sizer)
|
||||
min = sizer.CalcMin()
|
||||
self.SetClientSize(min)
|
||||
|
||||
def remove_account_dialog(self):
|
||||
return wx.MessageDialog(self, _("Do you really want to delete this account?"), _("Remove account"), wx.YES_NO).ShowModal()
|
||||
def remove_account_dialog(self):
|
||||
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")
|
||||
|
||||
def find_sound_lib_datafiles():
|
||||
import os
|
||||
import platform
|
||||
import sound_lib
|
||||
path = os.path.join(sound_lib.__path__[0], 'lib')
|
||||
if platform.architecture()[0] == '32bit' or platform.system() == 'Darwin':
|
||||
arch = 'x86'
|
||||
else:
|
||||
arch = 'x64'
|
||||
dest_dir = os.path.join('sound_lib', 'lib', arch)
|
||||
source = os.path.join(path, arch)
|
||||
return (source, dest_dir)
|
||||
import os
|
||||
import platform
|
||||
import sound_lib
|
||||
path = os.path.join(sound_lib.__path__[0], 'lib')
|
||||
if platform.architecture()[0] == '32bit' or platform.system() == 'Darwin':
|
||||
arch = 'x86'
|
||||
else:
|
||||
arch = 'x64'
|
||||
dest_dir = os.path.join('sound_lib', 'lib', arch)
|
||||
source = os.path.join(path, arch)
|
||||
return (source, dest_dir)
|
||||
|
||||
def find_accessible_output2_datafiles():
|
||||
import os
|
||||
import accessible_output2
|
||||
path = os.path.join(accessible_output2.__path__[0], 'lib')
|
||||
dest_dir = os.path.join('accessible_output2', 'lib')
|
||||
return (path, dest_dir)
|
||||
import os
|
||||
import accessible_output2
|
||||
path = os.path.join(accessible_output2.__path__[0], 'lib')
|
||||
dest_dir = os.path.join('accessible_output2', 'lib')
|
||||
return (path, dest_dir)
|
||||
|
||||
base = None
|
||||
if sys.platform == 'win32':
|
||||
base = 'Win32GUI'
|
||||
|
||||
build_exe_options = dict(
|
||||
build_exe="dist",
|
||||
optimize=1,
|
||||
include_msvcr=True,
|
||||
zip_include_packages=["accessible_output2", "sound_lib", "arrow"],
|
||||
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")],
|
||||
packages=["interactors", "presenters", "views", "wxUI"],
|
||||
)
|
||||
build_exe="dist",
|
||||
optimize=1,
|
||||
include_msvcr=True,
|
||||
zip_include_packages=["accessible_output2", "sound_lib", "arrow"],
|
||||
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")],
|
||||
packages=["interactors", "presenters", "views", "wxUI"],
|
||||
)
|
||||
|
||||
executables = [
|
||||
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")
|
||||
|
||||
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):
|
||||
# try:
|
||||
val = recording.WaveRecording(filename=filename)
|
||||
val = recording.WaveRecording(filename=filename)
|
||||
# except sound_lib.main.BassError:
|
||||
# sound_lib.input.Input()
|
||||
# val = sound_lib.recording.WaveRecording(filename=filename)
|
||||
return val
|
||||
return val
|
||||
|
||||
class soundSystem(object):
|
||||
|
||||
def check_soundpack(self):
|
||||
""" Checks if the folder where live the current soundpack exists."""
|
||||
self.soundpack_OK = False
|
||||
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.soundpack_OK = True
|
||||
elif os.path.exists(os.path.join(paths.sound_path(), "default")):
|
||||
log.error("The soundpack does not exist, using default...")
|
||||
self.path = os.path.join(paths.sound_path(), "default")
|
||||
self.soundpack_OK = True
|
||||
else:
|
||||
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
|
||||
def check_soundpack(self):
|
||||
""" Checks if the folder where live the current soundpack exists."""
|
||||
self.soundpack_OK = False
|
||||
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.soundpack_OK = True
|
||||
elif os.path.exists(os.path.join(paths.sound_path(), "default")):
|
||||
log.error("The soundpack does not exist, using default...")
|
||||
self.path = os.path.join(paths.sound_path(), "default")
|
||||
self.soundpack_OK = True
|
||||
else:
|
||||
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
|
||||
|
||||
def __init__(self, soundConfig):
|
||||
""" Sound Player."""
|
||||
self.config = soundConfig
|
||||
# Set the output and input default devices.
|
||||
try:
|
||||
self.output = output.Output()
|
||||
self.input = input.Input()
|
||||
except:
|
||||
pass
|
||||
def __init__(self, soundConfig):
|
||||
""" Sound Player."""
|
||||
self.config = soundConfig
|
||||
# Set the output and input default devices.
|
||||
try:
|
||||
self.output = output.Output()
|
||||
self.input = input.Input()
|
||||
except:
|
||||
pass
|
||||
# Try to use the selected device from the configuration. It can fail if the machine does not has a mic.
|
||||
try:
|
||||
log.debug("Setting input and output devices...")
|
||||
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"]))
|
||||
except:
|
||||
log.error("Error in input or output devices, using defaults...")
|
||||
self.config["output_device"] = "Default"
|
||||
self.config["input_device"] = "Default"
|
||||
# Set proxy for audio.
|
||||
if config.app["app-settings"]["use_proxy"]:
|
||||
self.output.set_proxy(b"socializer:socializer@socializer.su:3128")
|
||||
self.files = []
|
||||
self.cleaner = RepeatingTimer(60, self.clear_list)
|
||||
self.cleaner.start()
|
||||
self.check_soundpack()
|
||||
try:
|
||||
log.debug("Setting input and output devices...")
|
||||
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"]))
|
||||
except:
|
||||
log.error("Error in input or output devices, using defaults...")
|
||||
self.config["output_device"] = "Default"
|
||||
self.config["input_device"] = "Default"
|
||||
# Set proxy for audio.
|
||||
if config.app["app-settings"]["use_proxy"]:
|
||||
self.output.set_proxy(b"socializer:socializer@socializer.su:3128")
|
||||
self.files = []
|
||||
self.cleaner = RepeatingTimer(60, self.clear_list)
|
||||
self.cleaner.start()
|
||||
self.check_soundpack()
|
||||
|
||||
def clear_list(self):
|
||||
if len(self.files) == 0: return
|
||||
try:
|
||||
for i in range(0, len(self.files)):
|
||||
if self.files[i].is_playing == False:
|
||||
self.files[i].free()
|
||||
self.files.pop(i)
|
||||
except IndexError:
|
||||
pass
|
||||
def clear_list(self):
|
||||
if len(self.files) == 0: return
|
||||
try:
|
||||
for i in range(0, len(self.files)):
|
||||
if self.files[i].is_playing == False:
|
||||
self.files[i].free()
|
||||
self.files.pop(i)
|
||||
except IndexError:
|
||||
pass
|
||||
|
||||
def play(self, sound, argument=False):
|
||||
if self.soundpack_OK == False: return
|
||||
if self.config["session_mute"] == True: return
|
||||
sound_object = sound_lib.stream.FileStream(file="%s/%s" % (self.path, sound))
|
||||
# sound_object.volume = self.config["volume"]/100
|
||||
self.files.append(sound_object)
|
||||
sound_object.play()
|
||||
def play(self, sound, argument=False):
|
||||
if self.soundpack_OK == False: return
|
||||
if self.config["session_mute"] == True: return
|
||||
sound_object = sound_lib.stream.FileStream(file="%s/%s" % (self.path, sound))
|
||||
# sound_object.volume = self.config["volume"]/100
|
||||
self.files.append(sound_object)
|
||||
sound_object.play()
|
||||
|
@ -7,64 +7,64 @@ from interactors import audioRecorder as interactor
|
||||
|
||||
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.base.pub", esp_set=True)
|
||||
@mock.patch("presenters.audioRecorder.tempfile", esp_set=True)
|
||||
@mock.patch("presenters.audioRecorder.sound", esp_set=True)
|
||||
@mock.patch("presenters.audioRecorder.output", 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):
|
||||
""" Test methods for audio recorder presenter. """
|
||||
tempfile_mock.mktemp.return_value = "somefile.wav"
|
||||
sound_mock.get_recording.return_value = mock.MagicMock()
|
||||
soundlib_mock.stream.fileStream.return_value = mock.MagicMock()
|
||||
view=mock.MagicMock(name="view")
|
||||
interactor_ = mock.MagicMock(name="interactor", esp_set=interactor.audioRecorderInteractor)
|
||||
presenter_ = presenter.audioRecorderPresenter(view=view, interactor=interactor_)
|
||||
# Start sending events to the presenter and see its reactions.
|
||||
presenter_.start_recording()
|
||||
tempfile_mock.mktemp.assert_any_call(suffix=".wav")
|
||||
sound_mock.get_recording.assert_any_call(presenter_.file)
|
||||
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_disable_control", control="ok")
|
||||
presenter_.stop_recording()
|
||||
presenter_.recording.stop.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_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="discard")
|
||||
pub_mock.sendMessage.assert_any_call("audiorecorder_enable_control", control="ok")
|
||||
pub_mock.sendMessage.assert_any_call("audiorecorder_focus_control", control="play")
|
||||
presenter_.discard_recording()
|
||||
self.assertTrue(presenter_.playing==None)
|
||||
@mock.patch("presenters.audioRecorder.sound_lib", esp_set=True)
|
||||
@mock.patch("presenters.base.pub", esp_set=True)
|
||||
@mock.patch("presenters.audioRecorder.tempfile", esp_set=True)
|
||||
@mock.patch("presenters.audioRecorder.sound", esp_set=True)
|
||||
@mock.patch("presenters.audioRecorder.output", 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):
|
||||
""" Test methods for audio recorder presenter. """
|
||||
tempfile_mock.mktemp.return_value = "somefile.wav"
|
||||
sound_mock.get_recording.return_value = mock.MagicMock()
|
||||
soundlib_mock.stream.fileStream.return_value = mock.MagicMock()
|
||||
view=mock.MagicMock(name="view")
|
||||
interactor_ = mock.MagicMock(name="interactor", esp_set=interactor.audioRecorderInteractor)
|
||||
presenter_ = presenter.audioRecorderPresenter(view=view, interactor=interactor_)
|
||||
# Start sending events to the presenter and see its reactions.
|
||||
presenter_.start_recording()
|
||||
tempfile_mock.mktemp.assert_any_call(suffix=".wav")
|
||||
sound_mock.get_recording.assert_any_call(presenter_.file)
|
||||
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_disable_control", control="ok")
|
||||
presenter_.stop_recording()
|
||||
presenter_.recording.stop.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_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="discard")
|
||||
pub_mock.sendMessage.assert_any_call("audiorecorder_enable_control", control="ok")
|
||||
pub_mock.sendMessage.assert_any_call("audiorecorder_focus_control", control="play")
|
||||
presenter_.discard_recording()
|
||||
self.assertTrue(presenter_.playing==None)
|
||||
|
||||
@mock.patch("interactors.audioRecorder.widgetUtils", esp_set=True)
|
||||
def test_audiorecorder_interactor(self, widgetUtils_mock):
|
||||
view=mock.MagicMock(name="view")
|
||||
interactor_ = interactor.audioRecorderInteractor()
|
||||
presenter_ = mock.MagicMock(name="Presenter", esp_set=presenter.audioRecorderPresenter)
|
||||
interactor_.install(view=view, presenter=presenter_)
|
||||
# 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.record, widgetUtils_mock.BUTTON_PRESSED, interactor_.on_record)
|
||||
widgetUtils_mock.connect_event.assert_any_call(view.discard, widgetUtils_mock.BUTTON_PRESSED, interactor_.on_discard)
|
||||
# Let's call some methods simulating user interaction.
|
||||
interactor_.on_record()
|
||||
presenter_.toggle_recording.assert_called_with()
|
||||
interactor_.on_play()
|
||||
presenter_.play.assert_called_with()
|
||||
# Let's simulate user response here
|
||||
view.get_response.return_value = widgetUtils_mock.OK
|
||||
interactor_.start()
|
||||
# this should call on_postprocess after receiving the OK signal.
|
||||
presenter_.postprocess.assert_called_with()
|
||||
@mock.patch("interactors.audioRecorder.widgetUtils", esp_set=True)
|
||||
def test_audiorecorder_interactor(self, widgetUtils_mock):
|
||||
view=mock.MagicMock(name="view")
|
||||
interactor_ = interactor.audioRecorderInteractor()
|
||||
presenter_ = mock.MagicMock(name="Presenter", esp_set=presenter.audioRecorderPresenter)
|
||||
interactor_.install(view=view, presenter=presenter_)
|
||||
# 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.record, widgetUtils_mock.BUTTON_PRESSED, interactor_.on_record)
|
||||
widgetUtils_mock.connect_event.assert_any_call(view.discard, widgetUtils_mock.BUTTON_PRESSED, interactor_.on_discard)
|
||||
# Let's call some methods simulating user interaction.
|
||||
interactor_.on_record()
|
||||
presenter_.toggle_recording.assert_called_with()
|
||||
interactor_.on_play()
|
||||
presenter_.play.assert_called_with()
|
||||
# Let's simulate user response here
|
||||
view.get_response.return_value = widgetUtils_mock.OK
|
||||
interactor_.start()
|
||||
# this should call on_postprocess after receiving the OK signal.
|
||||
presenter_.postprocess.assert_called_with()
|
||||
|
||||
def setUp(self):
|
||||
languageHandler.setLanguage("en")
|
||||
def setUp(self):
|
||||
languageHandler.setLanguage("en")
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
unittest.main()
|
||||
|
@ -4,34 +4,34 @@ import mock
|
||||
from interactors import base
|
||||
|
||||
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)
|
||||
def test_base_interactor(self, pub_mock):
|
||||
""" Test the base interactor class. """
|
||||
view=mock.MagicMock(name="view")
|
||||
interactor_ = base.baseInteractor()
|
||||
presenter_ = mock.MagicMock(name="Presenter")
|
||||
interactor_.install(view=view, presenter=presenter_, modulename="base")
|
||||
# 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_.enable_control, "base_enable_control"),
|
||||
pub_mock.subscribe.assert_any_call(interactor_.set_label, "base_set_label"),
|
||||
pub_mock.subscribe.assert_any_call(interactor_.focus_control, "base_focus_control")
|
||||
# Now, simulate some event calls.
|
||||
interactor_.disable_control(control="some_control")
|
||||
view.disable.assert_called_with("some_control")
|
||||
interactor_.enable_control(control="some_control")
|
||||
view.enable.assert_called_with("some_control")
|
||||
interactor_.set_label(control="some_control", label="label")
|
||||
view.set.assert_called_with("some_control", "label")
|
||||
interactor_.focus_control(control="some_control")
|
||||
view.some_control.SetFocus.assert_called_with()
|
||||
interactor_.uninstall()
|
||||
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_.set_label, "base_set_label"),
|
||||
pub_mock.unsubscribe.assert_any_call(interactor_.focus_control, "base_focus_control")
|
||||
@mock.patch("interactors.base.pub", esp_set=True)
|
||||
def test_base_interactor(self, pub_mock):
|
||||
""" Test the base interactor class. """
|
||||
view=mock.MagicMock(name="view")
|
||||
interactor_ = base.baseInteractor()
|
||||
presenter_ = mock.MagicMock(name="Presenter")
|
||||
interactor_.install(view=view, presenter=presenter_, modulename="base")
|
||||
# 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_.enable_control, "base_enable_control"),
|
||||
pub_mock.subscribe.assert_any_call(interactor_.set_label, "base_set_label"),
|
||||
pub_mock.subscribe.assert_any_call(interactor_.focus_control, "base_focus_control")
|
||||
# Now, simulate some event calls.
|
||||
interactor_.disable_control(control="some_control")
|
||||
view.disable.assert_called_with("some_control")
|
||||
interactor_.enable_control(control="some_control")
|
||||
view.enable.assert_called_with("some_control")
|
||||
interactor_.set_label(control="some_control", label="label")
|
||||
view.set.assert_called_with("some_control", "label")
|
||||
interactor_.focus_control(control="some_control")
|
||||
view.some_control.SetFocus.assert_called_with()
|
||||
interactor_.uninstall()
|
||||
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_.set_label, "base_set_label"),
|
||||
pub_mock.unsubscribe.assert_any_call(interactor_.focus_control, "base_focus_control")
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
unittest.main()
|
||||
|
@ -7,22 +7,22 @@ from sessionmanager import renderers
|
||||
|
||||
class renderersTestCase(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
languageHandler.setLanguage("en")
|
||||
vk = testconfig.get_vk()
|
||||
self.vk = vk.get_api()
|
||||
def setUp(self):
|
||||
languageHandler.setLanguage("en")
|
||||
vk = testconfig.get_vk()
|
||||
self.vk = vk.get_api()
|
||||
|
||||
def test_render_person(self):
|
||||
""" Test the person renderer function."""
|
||||
user = self.vk.users.get(user_ids=1, fields="first_name, last_name, last_seen")
|
||||
self.assertIsInstance(user, list)
|
||||
self.assertEquals(len(user), 1)
|
||||
user = user[0]
|
||||
rendered_object = renderers.render_person(user, user["last_seen"])
|
||||
self.assertIsInstance(rendered_object, list)
|
||||
self.assertEquals(len(rendered_object), 2)
|
||||
self.assertIsInstance(rendered_object[0], str)
|
||||
self.assertIsInstance(rendered_object[1], str)
|
||||
def test_render_person(self):
|
||||
""" Test the person renderer function."""
|
||||
user = self.vk.users.get(user_ids=1, fields="first_name, last_name, last_seen")
|
||||
self.assertIsInstance(user, list)
|
||||
self.assertEquals(len(user), 1)
|
||||
user = user[0]
|
||||
rendered_object = renderers.render_person(user, user["last_seen"])
|
||||
self.assertIsInstance(rendered_object, list)
|
||||
self.assertEquals(len(rendered_object), 2)
|
||||
self.assertIsInstance(rendered_object[0], str)
|
||||
self.assertIsInstance(rendered_object[1], str)
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
unittest.main()
|
||||
|
@ -4,14 +4,14 @@ import application
|
||||
|
||||
class py2exeTestCase(unittest.TestCase):
|
||||
|
||||
@unittest.skipUnless(sys.version[0] == "2", "this only fails under Python 2")
|
||||
def test_application_not_unicode(self):
|
||||
""" Testing if some strings present in application have not changed to unicode. """
|
||||
self.assertIsInstance(application.name, str)
|
||||
self.assertIsInstance(application.author, str)
|
||||
self.assertIsInstance(application.authorEmail, str)
|
||||
self.assertIsInstance(application.version, str)
|
||||
self.assertIsInstance(application.url, str)
|
||||
@unittest.skipUnless(sys.version[0] == "2", "this only fails under Python 2")
|
||||
def test_application_not_unicode(self):
|
||||
""" Testing if some strings present in application have not changed to unicode. """
|
||||
self.assertIsInstance(application.name, str)
|
||||
self.assertIsInstance(application.author, str)
|
||||
self.assertIsInstance(application.authorEmail, str)
|
||||
self.assertIsInstance(application.version, str)
|
||||
self.assertIsInstance(application.url, str)
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
unittest.main()
|
||||
|
@ -3,8 +3,8 @@ import os
|
||||
from vk_api import VkApi
|
||||
|
||||
def get_vk():
|
||||
login = os.environ['LOGIN']
|
||||
password = os.environ['PASSWORD']
|
||||
vk = VkApi(login, password)
|
||||
vk.auth(token_only=True)
|
||||
return vk
|
||||
login = os.environ['LOGIN']
|
||||
password = os.environ['PASSWORD']
|
||||
vk = VkApi(login, password)
|
||||
vk.auth(token_only=True)
|
||||
return vk
|
||||
|
@ -3,10 +3,10 @@ import os.path
|
||||
import platform
|
||||
|
||||
def find_datafiles():
|
||||
system = platform.system()
|
||||
if system == 'Windows':
|
||||
file_ext = '*.exe'
|
||||
else:
|
||||
file_ext = '*.sh'
|
||||
path = os.path.abspath(os.path.join(__path__[0], 'bootstrappers', file_ext))
|
||||
return [('', glob.glob(path))]
|
||||
system = platform.system()
|
||||
if system == 'Windows':
|
||||
file_ext = '*.exe'
|
||||
else:
|
||||
file_ext = '*.sh'
|
||||
path = os.path.abspath(os.path.join(__path__[0], 'bootstrappers', file_ext))
|
||||
return [('', glob.glob(path))]
|
||||
|
@ -11,123 +11,123 @@ import tempfile
|
||||
import widgetUtils
|
||||
import webbrowser
|
||||
try:
|
||||
import czipfile as zipfile
|
||||
import czipfile as zipfile
|
||||
except ImportError:
|
||||
import zipfile
|
||||
import zipfile
|
||||
|
||||
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):
|
||||
requests_session = create_requests_session(app_name=app_name, version=current_version)
|
||||
available_update = find_update(endpoint, requests_session=requests_session)
|
||||
if not available_update:
|
||||
logger.debug("No update available")
|
||||
return False
|
||||
available_version, available_description, update_url = find_version_data(update_type, current_version, available_update)
|
||||
if available_version == False:
|
||||
return False
|
||||
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
|
||||
logger.info("User canceled update.")
|
||||
return
|
||||
base_path = tempfile.mkdtemp()
|
||||
download_path = os.path.join(base_path, 'update.zip')
|
||||
update_path = os.path.join(base_path, 'update')
|
||||
downloaded = download_update(update_url, download_path, requests_session=requests_session, progress_callback=progress_callback)
|
||||
extracted = extract_update(downloaded, update_path, password=password)
|
||||
bootstrap_path = move_bootstrap(extracted)
|
||||
execute_bootstrap(bootstrap_path, extracted)
|
||||
logger.info("Update prepared for installation.")
|
||||
if callable(update_complete_callback):
|
||||
update_complete_callback()
|
||||
requests_session = create_requests_session(app_name=app_name, version=current_version)
|
||||
available_update = find_update(endpoint, requests_session=requests_session)
|
||||
if not available_update:
|
||||
logger.debug("No update available")
|
||||
return False
|
||||
available_version, available_description, update_url = find_version_data(update_type, current_version, available_update)
|
||||
if available_version == False:
|
||||
return False
|
||||
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
|
||||
logger.info("User canceled update.")
|
||||
return
|
||||
base_path = tempfile.mkdtemp()
|
||||
download_path = os.path.join(base_path, 'update.zip')
|
||||
update_path = os.path.join(base_path, 'update')
|
||||
downloaded = download_update(update_url, download_path, requests_session=requests_session, progress_callback=progress_callback)
|
||||
extracted = extract_update(downloaded, update_path, password=password)
|
||||
bootstrap_path = move_bootstrap(extracted)
|
||||
execute_bootstrap(bootstrap_path, extracted)
|
||||
logger.info("Update prepared for installation.")
|
||||
if callable(update_complete_callback):
|
||||
update_complete_callback()
|
||||
|
||||
def create_requests_session(app_name=None, version=None):
|
||||
user_agent = ''
|
||||
session = requests.session()
|
||||
if app_name:
|
||||
user_agent = ' %s/%r' % (app_name, version)
|
||||
session.headers['User-Agent'] = session.headers['User-Agent'] + user_agent
|
||||
return session
|
||||
user_agent = ''
|
||||
session = requests.session()
|
||||
if app_name:
|
||||
user_agent = ' %s/%r' % (app_name, version)
|
||||
session.headers['User-Agent'] = session.headers['User-Agent'] + user_agent
|
||||
return session
|
||||
|
||||
def find_update(endpoint, requests_session):
|
||||
response = requests_session.get(endpoint)
|
||||
response.raise_for_status()
|
||||
content = response.json()
|
||||
return content
|
||||
response = requests_session.get(endpoint)
|
||||
response.raise_for_status()
|
||||
content = response.json()
|
||||
return content
|
||||
|
||||
def find_version_data(update_type, current_version, available_update):
|
||||
if update_type == "stable":
|
||||
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']:
|
||||
logger.debug("No update for this architecture")
|
||||
return (False, False, False)
|
||||
available_description = available_update.get('description', None)
|
||||
update_url = available_update ['downloads'][platform.system()+platform.architecture()[0][:2]]
|
||||
return (available_version, available_description, update_url)
|
||||
else: # Unstable versions, based in commits instead of version numbers.
|
||||
available_version = available_update["current_version"]
|
||||
if available_version == current_version:
|
||||
return (False, False, False)
|
||||
available_description = available_update["description"]
|
||||
update_url = available_update ['downloads'][platform.system()+platform.architecture()[0][:2]]
|
||||
return (available_version, available_description, update_url)
|
||||
if update_type == "stable":
|
||||
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']:
|
||||
logger.debug("No update for this architecture")
|
||||
return (False, False, False)
|
||||
available_description = available_update.get('description', None)
|
||||
update_url = available_update ['downloads'][platform.system()+platform.architecture()[0][:2]]
|
||||
return (available_version, available_description, update_url)
|
||||
else: # Unstable versions, based in commits instead of version numbers.
|
||||
available_version = available_update["current_version"]
|
||||
if available_version == current_version:
|
||||
return (False, False, False)
|
||||
available_description = available_update["description"]
|
||||
update_url = available_update ['downloads'][platform.system()+platform.architecture()[0][:2]]
|
||||
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):
|
||||
total_downloaded = total_size = 0
|
||||
with io.open(update_destination, 'w+b') as outfile:
|
||||
download = requests_session.get(update_url, stream=True)
|
||||
total_size = int(download.headers.get('content-length', 0))
|
||||
logger.debug("Total update size: %d" % total_size)
|
||||
download.raise_for_status()
|
||||
for chunk in download.iter_content(chunk_size):
|
||||
outfile.write(chunk)
|
||||
total_downloaded += len(chunk)
|
||||
if callable(progress_callback):
|
||||
call_callback(progress_callback, total_downloaded, total_size)
|
||||
logger.debug("Update downloaded")
|
||||
return update_destination
|
||||
total_downloaded = total_size = 0
|
||||
with io.open(update_destination, 'w+b') as outfile:
|
||||
download = requests_session.get(update_url, stream=True)
|
||||
total_size = int(download.headers.get('content-length', 0))
|
||||
logger.debug("Total update size: %d" % total_size)
|
||||
download.raise_for_status()
|
||||
for chunk in download.iter_content(chunk_size):
|
||||
outfile.write(chunk)
|
||||
total_downloaded += len(chunk)
|
||||
if callable(progress_callback):
|
||||
call_callback(progress_callback, total_downloaded, total_size)
|
||||
logger.debug("Update downloaded")
|
||||
return update_destination
|
||||
|
||||
def extract_update(update_archive, destination, password=None):
|
||||
"""Given an update archive, extracts it. Returns the directory to which it has been extracted"""
|
||||
with contextlib.closing(zipfile.ZipFile(update_archive)) as archive:
|
||||
if password:
|
||||
archive.setpassword(password)
|
||||
archive.extractall(path=destination)
|
||||
logger.debug("Update extracted")
|
||||
return destination
|
||||
"""Given an update archive, extracts it. Returns the directory to which it has been extracted"""
|
||||
with contextlib.closing(zipfile.ZipFile(update_archive)) as archive:
|
||||
if password:
|
||||
archive.setpassword(password)
|
||||
archive.extractall(path=destination)
|
||||
logger.debug("Update extracted")
|
||||
return destination
|
||||
|
||||
def move_bootstrap(extracted_path):
|
||||
working_path = os.path.abspath(os.path.join(extracted_path, '..'))
|
||||
if platform.system() == 'Darwin':
|
||||
extracted_path = os.path.join(extracted_path, 'Contents', 'Resources')
|
||||
downloaded_bootstrap = os.path.join(extracted_path, bootstrap_name())
|
||||
new_bootstrap_path = os.path.join(working_path, bootstrap_name())
|
||||
os.rename(downloaded_bootstrap, new_bootstrap_path)
|
||||
return new_bootstrap_path
|
||||
working_path = os.path.abspath(os.path.join(extracted_path, '..'))
|
||||
if platform.system() == 'Darwin':
|
||||
extracted_path = os.path.join(extracted_path, 'Contents', 'Resources')
|
||||
downloaded_bootstrap = os.path.join(extracted_path, bootstrap_name())
|
||||
new_bootstrap_path = os.path.join(working_path, bootstrap_name())
|
||||
os.rename(downloaded_bootstrap, new_bootstrap_path)
|
||||
return new_bootstrap_path
|
||||
|
||||
def execute_bootstrap(bootstrap_path, source_path):
|
||||
arguments = r'"%s" "%s" "%s" "%s"' % (os.getpid(), source_path, paths.app_path(), paths.get_executable())
|
||||
if platform.system() == 'Windows':
|
||||
import win32api
|
||||
win32api.ShellExecute(0, 'open', bootstrap_path, arguments, '', 5)
|
||||
else:
|
||||
import subprocess
|
||||
make_executable(bootstrap_path)
|
||||
subprocess.Popen(['%s %s' % (bootstrap_path, arguments)], shell=True)
|
||||
logger.info("Bootstrap executed")
|
||||
arguments = r'"%s" "%s" "%s" "%s"' % (os.getpid(), source_path, paths.app_path(), paths.get_executable())
|
||||
if platform.system() == 'Windows':
|
||||
import win32api
|
||||
win32api.ShellExecute(0, 'open', bootstrap_path, arguments, '', 5)
|
||||
else:
|
||||
import subprocess
|
||||
make_executable(bootstrap_path)
|
||||
subprocess.Popen(['%s %s' % (bootstrap_path, arguments)], shell=True)
|
||||
logger.info("Bootstrap executed")
|
||||
|
||||
def bootstrap_name():
|
||||
if platform.system() == 'Windows': return 'bootstrap.exe'
|
||||
if platform.system() == 'Darwin': return 'bootstrap-mac.sh'
|
||||
return 'bootstrap-lin.sh'
|
||||
if platform.system() == 'Windows': return 'bootstrap.exe'
|
||||
if platform.system() == 'Darwin': return 'bootstrap-mac.sh'
|
||||
return 'bootstrap-lin.sh'
|
||||
|
||||
def make_executable(path):
|
||||
import stat
|
||||
st = os.stat(path)
|
||||
os.chmod(path, st.st_mode | stat.S_IEXEC)
|
||||
import stat
|
||||
st = os.stat(path)
|
||||
os.chmod(path, st.st_mode | stat.S_IEXEC)
|
||||
|
||||
def call_callback(callback, *args, **kwargs):
|
||||
# try:
|
||||
callback(*args, **kwargs)
|
||||
callback(*args, **kwargs)
|
||||
# except:
|
||||
# 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")
|
||||
|
||||
def do_update(update_type="stable"):
|
||||
# Updates cannot be performed in the source code version of Socializer.
|
||||
if hasattr(sys, "frozen") == False:
|
||||
return
|
||||
if update_type == "stable":
|
||||
endpoint = application.update_stable_url
|
||||
version = application.version
|
||||
else:
|
||||
endpoint = application.update_next_url
|
||||
version = application.update_next_version
|
||||
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)
|
||||
except ConnectionError:
|
||||
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)
|
||||
# Updates cannot be performed in the source code version of Socializer.
|
||||
if hasattr(sys, "frozen") == False:
|
||||
return
|
||||
if update_type == "stable":
|
||||
endpoint = application.update_stable_url
|
||||
version = application.version
|
||||
else:
|
||||
endpoint = application.update_next_url
|
||||
version = application.update_next_version
|
||||
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)
|
||||
except ConnectionError:
|
||||
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)
|
||||
|
@ -2,42 +2,42 @@
|
||||
from __future__ import unicode_literals
|
||||
|
||||
def convert_bytes(n):
|
||||
K, M, G, T, P = 1 << 10, 1 << 20, 1 << 30, 1 << 40, 1 << 50
|
||||
if n >= P:
|
||||
return '%.2fPb' % (float(n) / T)
|
||||
elif n >= T:
|
||||
return '%.2fTb' % (float(n) / T)
|
||||
elif n >= G:
|
||||
return '%.2fGb' % (float(n) / G)
|
||||
elif n >= M:
|
||||
return '%.2fMb' % (float(n) / M)
|
||||
elif n >= K:
|
||||
return '%.2fKb' % (float(n) / K)
|
||||
else:
|
||||
return '%d' % n
|
||||
K, M, G, T, P = 1 << 10, 1 << 20, 1 << 30, 1 << 40, 1 << 50
|
||||
if n >= P:
|
||||
return '%.2fPb' % (float(n) / T)
|
||||
elif n >= T:
|
||||
return '%.2fTb' % (float(n) / T)
|
||||
elif n >= G:
|
||||
return '%.2fGb' % (float(n) / G)
|
||||
elif n >= M:
|
||||
return '%.2fMb' % (float(n) / M)
|
||||
elif n >= K:
|
||||
return '%.2fKb' % (float(n) / K)
|
||||
else:
|
||||
return '%d' % n
|
||||
|
||||
def seconds_to_string(seconds, precision=0):
|
||||
day = seconds // 86400
|
||||
hour = seconds // 3600
|
||||
min = (seconds // 60) % 60
|
||||
sec = seconds - (hour * 3600) - (min * 60)
|
||||
sec_spec = "." + str(precision) + "f"
|
||||
sec_string = sec.__format__(sec_spec)
|
||||
string = ""
|
||||
if day == 1:
|
||||
string += _("%d day, ") % day
|
||||
elif day >= 2:
|
||||
string += _("%d days, ") % day
|
||||
if (hour == 1):
|
||||
string += _("%d hour, ") % hour
|
||||
elif (hour >= 2):
|
||||
string += _("%d hours, ") % hour
|
||||
if (min == 1):
|
||||
string += _("%d minute, ") % min
|
||||
elif (min >= 2):
|
||||
string += _("%d minutes, ") % min
|
||||
if sec >= 0 and sec <= 2:
|
||||
string += _("%s second") % sec_string
|
||||
else:
|
||||
string += _("%s seconds") % sec_string
|
||||
return string
|
||||
day = seconds // 86400
|
||||
hour = seconds // 3600
|
||||
min = (seconds // 60) % 60
|
||||
sec = seconds - (hour * 3600) - (min * 60)
|
||||
sec_spec = "." + str(precision) + "f"
|
||||
sec_string = sec.__format__(sec_spec)
|
||||
string = ""
|
||||
if day == 1:
|
||||
string += _("%d day, ") % day
|
||||
elif day >= 2:
|
||||
string += _("%d days, ") % day
|
||||
if (hour == 1):
|
||||
string += _("%d hour, ") % hour
|
||||
elif (hour >= 2):
|
||||
string += _("%d hours, ") % hour
|
||||
if (min == 1):
|
||||
string += _("%d minute, ") % min
|
||||
elif (min >= 2):
|
||||
string += _("%d minutes, ") % min
|
||||
if sec >= 0 and sec <= 2:
|
||||
string += _("%s second") % sec_string
|
||||
else:
|
||||
string += _("%s seconds") % sec_string
|
||||
return string
|
||||
|
@ -8,27 +8,27 @@ from . import utils
|
||||
progress_dialog = None
|
||||
|
||||
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)
|
||||
if dialog.ShowModal() == wx.ID_YES:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
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:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
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):
|
||||
wx.CallAfter(_progress_callback, total_downloaded, total_size)
|
||||
wx.CallAfter(_progress_callback, total_downloaded, total_size)
|
||||
|
||||
def _progress_callback(total_downloaded, total_size):
|
||||
global progress_dialog
|
||||
if progress_dialog == None:
|
||||
progress_dialog = create_progress_dialog()
|
||||
progress_dialog.Show()
|
||||
if total_downloaded == total_size:
|
||||
progress_dialog.Destroy()
|
||||
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)))
|
||||
global progress_dialog
|
||||
if progress_dialog == None:
|
||||
progress_dialog = create_progress_dialog()
|
||||
progress_dialog.Show()
|
||||
if total_downloaded == total_size:
|
||||
progress_dialog.Destroy()
|
||||
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)))
|
||||
|
||||
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.
|
||||
No other functionality is assumed in this 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.
|
||||
No other functionality is assumed in this 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.
|
||||
"""
|
||||
from .dialogs.attach import *
|
||||
from .dialogs.audioRecorder import *
|
||||
@ -9,4 +9,4 @@ from .dialogs.blacklist import *
|
||||
from .dialogs.postCreation import *
|
||||
from .dialogs.postDisplay import *
|
||||
from .dialogs.configuration import *
|
||||
from .dialogs.profiles import *
|
||||
from .dialogs.profiles import *
|
||||
|
@ -4,65 +4,65 @@ import wx
|
||||
import widgetUtils
|
||||
|
||||
class attachDialog(widgetUtils.BaseDialog):
|
||||
def __init__(self, voice_messages=False):
|
||||
super(attachDialog, self).__init__(None, title=_("Add an attachment"))
|
||||
panel = wx.Panel(self)
|
||||
sizer = wx.BoxSizer(wx.VERTICAL)
|
||||
lbl1 = wx.StaticText(panel, wx.NewId(), _("Attachments"))
|
||||
self.attachments = widgetUtils.list(panel, _("Type"), _("Title"), style=wx.LC_REPORT)
|
||||
box = wx.BoxSizer(wx.HORIZONTAL)
|
||||
box.Add(lbl1, 0, wx.ALL, 5)
|
||||
box.Add(self.attachments.list, 0, wx.ALL, 5)
|
||||
sizer.Add(box, 0, wx.ALL, 5)
|
||||
static = wx.StaticBoxSizer(parent=panel, orient=wx.HORIZONTAL, label=_("Add attachments"))
|
||||
self.photo = wx.Button(static.GetStaticBox(), wx.NewId(), _("&Photo"))
|
||||
self.audio = wx.Button(static.GetStaticBox(), wx.NewId(), _("Audio file"))
|
||||
self.document = wx.Button(static.GetStaticBox(), wx.NewId(), _("Document"))
|
||||
if voice_messages:
|
||||
self.voice_message = wx.Button(static.GetStaticBox(), wx.NewId(), _("Voice message"))
|
||||
self.remove = wx.Button(static.GetStaticBox(), wx.NewId(), _("Remove attachment"))
|
||||
self.remove.Enable(False)
|
||||
static.Add(self.photo, 0, wx.ALL, 5)
|
||||
static.Add(self.audio, 0, wx.ALL, 5)
|
||||
static.Add(self.document, 0, wx.ALL, 5)
|
||||
if voice_messages:
|
||||
static.Add(self.voice_message, 0, wx.ALL, 5)
|
||||
sizer.Add(static, 0, wx.ALL, 5)
|
||||
ok = wx.Button(panel, wx.ID_OK)
|
||||
ok.SetDefault()
|
||||
cancelBtn = wx.Button(panel, wx.ID_CANCEL)
|
||||
btnSizer = wx.BoxSizer()
|
||||
btnSizer.Add(ok, 0, wx.ALL, 5)
|
||||
btnSizer.Add(cancelBtn, 0, wx.ALL, 5)
|
||||
sizer.Add(btnSizer, 0, wx.ALL, 5)
|
||||
panel.SetSizer(sizer)
|
||||
self.SetClientSize(sizer.CalcMin())
|
||||
def __init__(self, voice_messages=False):
|
||||
super(attachDialog, self).__init__(None, title=_("Add an attachment"))
|
||||
panel = wx.Panel(self)
|
||||
sizer = wx.BoxSizer(wx.VERTICAL)
|
||||
lbl1 = wx.StaticText(panel, wx.NewId(), _("Attachments"))
|
||||
self.attachments = widgetUtils.list(panel, _("Type"), _("Title"), style=wx.LC_REPORT)
|
||||
box = wx.BoxSizer(wx.HORIZONTAL)
|
||||
box.Add(lbl1, 0, wx.ALL, 5)
|
||||
box.Add(self.attachments.list, 0, wx.ALL, 5)
|
||||
sizer.Add(box, 0, wx.ALL, 5)
|
||||
static = wx.StaticBoxSizer(parent=panel, orient=wx.HORIZONTAL, label=_("Add attachments"))
|
||||
self.photo = wx.Button(static.GetStaticBox(), wx.NewId(), _("&Photo"))
|
||||
self.audio = wx.Button(static.GetStaticBox(), wx.NewId(), _("Audio file"))
|
||||
self.document = wx.Button(static.GetStaticBox(), wx.NewId(), _("Document"))
|
||||
if voice_messages:
|
||||
self.voice_message = wx.Button(static.GetStaticBox(), wx.NewId(), _("Voice message"))
|
||||
self.remove = wx.Button(static.GetStaticBox(), wx.NewId(), _("Remove attachment"))
|
||||
self.remove.Enable(False)
|
||||
static.Add(self.photo, 0, wx.ALL, 5)
|
||||
static.Add(self.audio, 0, wx.ALL, 5)
|
||||
static.Add(self.document, 0, wx.ALL, 5)
|
||||
if voice_messages:
|
||||
static.Add(self.voice_message, 0, wx.ALL, 5)
|
||||
sizer.Add(static, 0, wx.ALL, 5)
|
||||
ok = wx.Button(panel, wx.ID_OK)
|
||||
ok.SetDefault()
|
||||
cancelBtn = wx.Button(panel, wx.ID_CANCEL)
|
||||
btnSizer = wx.BoxSizer()
|
||||
btnSizer.Add(ok, 0, wx.ALL, 5)
|
||||
btnSizer.Add(cancelBtn, 0, wx.ALL, 5)
|
||||
sizer.Add(btnSizer, 0, wx.ALL, 5)
|
||||
panel.SetSizer(sizer)
|
||||
self.SetClientSize(sizer.CalcMin())
|
||||
|
||||
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)
|
||||
if openFileDialog.ShowModal() == wx.ID_CANCEL:
|
||||
return (None, None)
|
||||
dsc = self.ask_description()
|
||||
return (openFileDialog.GetPath(), dsc)
|
||||
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)
|
||||
if openFileDialog.ShowModal() == wx.ID_CANCEL:
|
||||
return (None, None)
|
||||
dsc = self.ask_description()
|
||||
return (openFileDialog.GetPath(), dsc)
|
||||
|
||||
def ask_description(self):
|
||||
dlg = wx.TextEntryDialog(self, _("please provide a description"), _("Description"))
|
||||
dlg.ShowModal()
|
||||
result = dlg.GetValue()
|
||||
dlg.Destroy()
|
||||
return result
|
||||
def ask_description(self):
|
||||
dlg = wx.TextEntryDialog(self, _("please provide a description"), _("Description"))
|
||||
dlg.ShowModal()
|
||||
result = dlg.GetValue()
|
||||
dlg.Destroy()
|
||||
return result
|
||||
|
||||
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)
|
||||
if openFileDialog.ShowModal() == wx.ID_CANCEL:
|
||||
return None
|
||||
return openFileDialog.GetPath()
|
||||
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)
|
||||
if openFileDialog.ShowModal() == wx.ID_CANCEL:
|
||||
return None
|
||||
return openFileDialog.GetPath()
|
||||
|
||||
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)
|
||||
if openFileDialog.ShowModal() == wx.ID_CANCEL:
|
||||
return None
|
||||
return openFileDialog.GetPath()
|
||||
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)
|
||||
if openFileDialog.ShowModal() == wx.ID_CANCEL:
|
||||
return None
|
||||
return openFileDialog.GetPath()
|
||||
|
||||
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()
|
||||
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()
|
||||
|
@ -4,33 +4,33 @@ import wx
|
||||
import widgetUtils
|
||||
|
||||
class audioRecorderDialog(widgetUtils.BaseDialog):
|
||||
def __init__(self):
|
||||
super(audioRecorderDialog, self).__init__(None, title=_("Record voice message"))
|
||||
panel = wx.Panel(self)
|
||||
sizer = wx.BoxSizer(wx.VERTICAL)
|
||||
self.play = wx.Button(panel, -1, _("&Play"))
|
||||
self.play.Disable()
|
||||
self.record = wx.Button(panel, -1, _("&Record"))
|
||||
self.record.SetFocus()
|
||||
self.discard = wx.Button(panel, -1, _("&Discard"))
|
||||
self.discard.Disable()
|
||||
self.ok = wx.Button(panel, wx.ID_OK, _("&Add"))
|
||||
cancel = wx.Button(panel, wx.ID_CANCEL, _("&Cancel"))
|
||||
btnSizer = wx.BoxSizer(wx.HORIZONTAL)
|
||||
btnSizer2 = wx.BoxSizer(wx.HORIZONTAL)
|
||||
btnSizer.Add(self.play, 0, wx.ALL, 5)
|
||||
btnSizer.Add(self.record, 0, wx.ALL, 5)
|
||||
btnSizer2.Add(self.ok, 0, wx.ALL, 5)
|
||||
btnSizer2.Add(cancel, 0, wx.ALL, 5)
|
||||
sizer.Add(btnSizer, 0, wx.ALL, 5)
|
||||
sizer.Add(btnSizer2, 0, wx.ALL, 5)
|
||||
panel.SetSizer(sizer)
|
||||
self.SetClientSize(sizer.CalcMin())
|
||||
def __init__(self):
|
||||
super(audioRecorderDialog, self).__init__(None, title=_("Record voice message"))
|
||||
panel = wx.Panel(self)
|
||||
sizer = wx.BoxSizer(wx.VERTICAL)
|
||||
self.play = wx.Button(panel, -1, _("&Play"))
|
||||
self.play.Disable()
|
||||
self.record = wx.Button(panel, -1, _("&Record"))
|
||||
self.record.SetFocus()
|
||||
self.discard = wx.Button(panel, -1, _("&Discard"))
|
||||
self.discard.Disable()
|
||||
self.ok = wx.Button(panel, wx.ID_OK, _("&Add"))
|
||||
cancel = wx.Button(panel, wx.ID_CANCEL, _("&Cancel"))
|
||||
btnSizer = wx.BoxSizer(wx.HORIZONTAL)
|
||||
btnSizer2 = wx.BoxSizer(wx.HORIZONTAL)
|
||||
btnSizer.Add(self.play, 0, wx.ALL, 5)
|
||||
btnSizer.Add(self.record, 0, wx.ALL, 5)
|
||||
btnSizer2.Add(self.ok, 0, wx.ALL, 5)
|
||||
btnSizer2.Add(cancel, 0, wx.ALL, 5)
|
||||
sizer.Add(btnSizer, 0, wx.ALL, 5)
|
||||
sizer.Add(btnSizer2, 0, wx.ALL, 5)
|
||||
panel.SetSizer(sizer)
|
||||
self.SetClientSize(sizer.CalcMin())
|
||||
|
||||
def enable_control(self, control):
|
||||
if hasattr(self, control):
|
||||
getattr(self, control).Enable()
|
||||
def enable_control(self, control):
|
||||
if hasattr(self, control):
|
||||
getattr(self, control).Enable()
|
||||
|
||||
def disable_control(self, control):
|
||||
if hasattr(self, control):
|
||||
getattr(self, control).Disable()
|
||||
def disable_control(self, control):
|
||||
if hasattr(self, control):
|
||||
getattr(self, control).Disable()
|
||||
|
@ -3,17 +3,17 @@ import wx
|
||||
import widgetUtils
|
||||
|
||||
class blacklistDialog(widgetUtils.BaseDialog):
|
||||
def __init__(self):
|
||||
super(blacklistDialog, self).__init__(parent=None, title=_("blacklist"))
|
||||
panel = wx.Panel(self)
|
||||
sizer = wx.BoxSizer(wx.VERTICAL)
|
||||
box1 = wx.StaticBoxSizer(parent=panel, orient=wx.HORIZONTAL, label=_("blocked users"))
|
||||
self.persons = widgetUtils.list(panel, _("User"), style=wx.LC_REPORT)
|
||||
box1.Add(self.persons.list, 0, wx.ALL, 5)
|
||||
sizer.Add(box1, 0, wx.ALL, 5)
|
||||
self.unblock = wx.Button(panel, wx.NewId(), _("Unblock"))
|
||||
sizer.Add(self.unblock, 0, wx.ALL, 5)
|
||||
close = wx.Button(panel, wx.ID_CANCEL, _("Close"))
|
||||
sizer.Add(close, 0, wx.ALL, 5)
|
||||
panel.SetSizer(sizer)
|
||||
self.SetClientSize(sizer.CalcMin())
|
||||
def __init__(self):
|
||||
super(blacklistDialog, self).__init__(parent=None, title=_("blacklist"))
|
||||
panel = wx.Panel(self)
|
||||
sizer = wx.BoxSizer(wx.VERTICAL)
|
||||
box1 = wx.StaticBoxSizer(parent=panel, orient=wx.HORIZONTAL, label=_("blocked users"))
|
||||
self.persons = widgetUtils.list(panel, _("User"), style=wx.LC_REPORT)
|
||||
box1.Add(self.persons.list, 0, wx.ALL, 5)
|
||||
sizer.Add(box1, 0, wx.ALL, 5)
|
||||
self.unblock = wx.Button(panel, wx.NewId(), _("Unblock"))
|
||||
sizer.Add(self.unblock, 0, wx.ALL, 5)
|
||||
close = wx.Button(panel, wx.ID_CANCEL, _("Close"))
|
||||
sizer.Add(close, 0, wx.ALL, 5)
|
||||
panel.SetSizer(sizer)
|
||||
self.SetClientSize(sizer.CalcMin())
|
||||
|
@ -4,179 +4,179 @@ import wx
|
||||
import widgetUtils
|
||||
|
||||
class general(wx.Panel, widgetUtils.BaseDialog):
|
||||
def __init__(self, panel, languages):
|
||||
super(general, self).__init__(panel)
|
||||
sizer = wx.BoxSizer(wx.VERTICAL)
|
||||
langBox = wx.StaticBoxSizer(parent=self, orient=wx.HORIZONTAL, label=_("Language"))
|
||||
self.language = wx.ListBox(langBox.GetStaticBox(), wx.NewId(), choices=languages)
|
||||
self.language.SetSize(self.language.GetBestSize())
|
||||
langBox.Add(self.language, 0, wx.ALL, 5)
|
||||
sizer.Add(langBox, 0, wx.ALL, 5)
|
||||
self.load_images = wx.CheckBox(self, wx.NewId(), _("Load images in posts"))
|
||||
sizer.Add(self.load_images, 0, wx.ALL, 5)
|
||||
self.use_proxy = wx.CheckBox(self, wx.NewId(), _("Use proxy"))
|
||||
sizer.Add(self.use_proxy, 0, wx.ALL, 5)
|
||||
self.debug_logging = wx.CheckBox(self, wx.NewId(), _("Enable debug logging (useful for reporting errors)"))
|
||||
sizer.Add(self.debug_logging, 0, wx.ALL, 5)
|
||||
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)
|
||||
box4 = wx.BoxSizer(wx.HORIZONTAL)
|
||||
box4.Add(lbl4, 0, wx.ALL, 5)
|
||||
box4.Add(self.update_channel, 0, wx.ALL, 5)
|
||||
sizer.Add(box4, 0, wx.ALL, 5)
|
||||
self.SetSizer(sizer)
|
||||
def __init__(self, panel, languages):
|
||||
super(general, self).__init__(panel)
|
||||
sizer = wx.BoxSizer(wx.VERTICAL)
|
||||
langBox = wx.StaticBoxSizer(parent=self, orient=wx.HORIZONTAL, label=_("Language"))
|
||||
self.language = wx.ListBox(langBox.GetStaticBox(), wx.NewId(), choices=languages)
|
||||
self.language.SetSize(self.language.GetBestSize())
|
||||
langBox.Add(self.language, 0, wx.ALL, 5)
|
||||
sizer.Add(langBox, 0, wx.ALL, 5)
|
||||
self.load_images = wx.CheckBox(self, wx.NewId(), _("Load images in posts"))
|
||||
sizer.Add(self.load_images, 0, wx.ALL, 5)
|
||||
self.use_proxy = wx.CheckBox(self, wx.NewId(), _("Use proxy"))
|
||||
sizer.Add(self.use_proxy, 0, wx.ALL, 5)
|
||||
self.debug_logging = wx.CheckBox(self, wx.NewId(), _("Enable debug logging (useful for reporting errors)"))
|
||||
sizer.Add(self.debug_logging, 0, wx.ALL, 5)
|
||||
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)
|
||||
box4 = wx.BoxSizer(wx.HORIZONTAL)
|
||||
box4.Add(lbl4, 0, wx.ALL, 5)
|
||||
box4.Add(self.update_channel, 0, wx.ALL, 5)
|
||||
sizer.Add(box4, 0, wx.ALL, 5)
|
||||
self.SetSizer(sizer)
|
||||
|
||||
class buffers(wx.Panel, widgetUtils.BaseDialog):
|
||||
|
||||
def __init__(self, panel):
|
||||
super(buffers, self).__init__(panel)
|
||||
sizer = wx.BoxSizer(wx.VERTICAL)
|
||||
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.SetRange(1, 100)
|
||||
box1 = wx.BoxSizer(wx.HORIZONTAL)
|
||||
box1.Add(lbl1, 0, wx.ALL, 5)
|
||||
box1.Add(self.wall_buffer_count, 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)"))
|
||||
self.video_buffers_count = wx.SpinCtrl(self, wx.NewId())
|
||||
self.video_buffers_count.SetRange(1, 200)
|
||||
box3 = wx.BoxSizer(wx.HORIZONTAL)
|
||||
box3.Add(lbl3, 0, wx.ALL, 5)
|
||||
box3.Add(self.video_buffers_count, 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)"))
|
||||
self.chat_buffers_count = wx.SpinCtrl(self, wx.NewId())
|
||||
self.chat_buffers_count.SetRange(1, 200)
|
||||
box4 = wx.BoxSizer(wx.HORIZONTAL)
|
||||
box4.Add(lbl4, 0, wx.ALL, 5)
|
||||
box4.Add(self.chat_buffers_count, 0, wx.ALL, 5)
|
||||
sizer.Add(box4, 0, wx.ALL, 5)
|
||||
self.SetSizer(sizer)
|
||||
def __init__(self, panel):
|
||||
super(buffers, self).__init__(panel)
|
||||
sizer = wx.BoxSizer(wx.VERTICAL)
|
||||
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.SetRange(1, 100)
|
||||
box1 = wx.BoxSizer(wx.HORIZONTAL)
|
||||
box1.Add(lbl1, 0, wx.ALL, 5)
|
||||
box1.Add(self.wall_buffer_count, 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)"))
|
||||
self.video_buffers_count = wx.SpinCtrl(self, wx.NewId())
|
||||
self.video_buffers_count.SetRange(1, 200)
|
||||
box3 = wx.BoxSizer(wx.HORIZONTAL)
|
||||
box3.Add(lbl3, 0, wx.ALL, 5)
|
||||
box3.Add(self.video_buffers_count, 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)"))
|
||||
self.chat_buffers_count = wx.SpinCtrl(self, wx.NewId())
|
||||
self.chat_buffers_count.SetRange(1, 200)
|
||||
box4 = wx.BoxSizer(wx.HORIZONTAL)
|
||||
box4.Add(lbl4, 0, wx.ALL, 5)
|
||||
box4.Add(self.chat_buffers_count, 0, wx.ALL, 5)
|
||||
sizer.Add(box4, 0, wx.ALL, 5)
|
||||
self.SetSizer(sizer)
|
||||
|
||||
class chat(wx.Panel, widgetUtils.BaseDialog):
|
||||
def __init__(self, panel):
|
||||
super(chat, self).__init__(panel)
|
||||
sizer = wx.BoxSizer(wx.VERTICAL)
|
||||
self.notify_online = wx.CheckBox(self, wx.NewId(), _("Show notifications when users are online"))
|
||||
sizer.Add(self.notify_online, 0, wx.ALL, 5)
|
||||
self.notify_offline = wx.CheckBox(self, wx.NewId(), _("Show notifications when users are offline"))
|
||||
sizer.Add(self.notify_offline, 0, wx.ALL, 5)
|
||||
lbl = wx.StaticText(self, wx.NewId(), _("Notification type"))
|
||||
self.notifications = wx.ComboBox(self, wx.NewId(), choices=[_("Native"), _("Custom"),], value=_("Native"), style=wx.CB_READONLY)
|
||||
nbox = wx.BoxSizer(wx.HORIZONTAL)
|
||||
nbox.Add(lbl, 0, wx.ALL, 5)
|
||||
nbox.Add(self.notifications, 0, wx.ALL, 5)
|
||||
sizer.Add(nbox, 0, wx.ALL, 5)
|
||||
self.SetSizer(sizer)
|
||||
def __init__(self, panel):
|
||||
super(chat, self).__init__(panel)
|
||||
sizer = wx.BoxSizer(wx.VERTICAL)
|
||||
self.notify_online = wx.CheckBox(self, wx.NewId(), _("Show notifications when users are online"))
|
||||
sizer.Add(self.notify_online, 0, wx.ALL, 5)
|
||||
self.notify_offline = wx.CheckBox(self, wx.NewId(), _("Show notifications when users are offline"))
|
||||
sizer.Add(self.notify_offline, 0, wx.ALL, 5)
|
||||
lbl = wx.StaticText(self, wx.NewId(), _("Notification type"))
|
||||
self.notifications = wx.ComboBox(self, wx.NewId(), choices=[_("Native"), _("Custom"),], value=_("Native"), style=wx.CB_READONLY)
|
||||
nbox = wx.BoxSizer(wx.HORIZONTAL)
|
||||
nbox.Add(lbl, 0, wx.ALL, 5)
|
||||
nbox.Add(self.notifications, 0, wx.ALL, 5)
|
||||
sizer.Add(nbox, 0, wx.ALL, 5)
|
||||
self.SetSizer(sizer)
|
||||
|
||||
class loadAtStartup(wx.Panel, widgetUtils.BaseDialog):
|
||||
def __init__(self, panel):
|
||||
super(loadAtStartup, self).__init__(panel)
|
||||
sizer = wx.BoxSizer(wx.VERTICAL)
|
||||
self.audio_albums = wx.CheckBox(self, wx.NewId(), _("Create buffers for audio albums at startup"))
|
||||
sizer.Add(self.audio_albums, 0, wx.ALL, 5)
|
||||
self.video_albums = wx.CheckBox(self, wx.NewId(), _("Create buffers for video albums at startup"))
|
||||
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"))
|
||||
sizer.Add(self.communities, 0, wx.ALL, 5)
|
||||
self.SetSizer(sizer)
|
||||
def __init__(self, panel):
|
||||
super(loadAtStartup, self).__init__(panel)
|
||||
sizer = wx.BoxSizer(wx.VERTICAL)
|
||||
self.audio_albums = wx.CheckBox(self, wx.NewId(), _("Create buffers for audio albums at startup"))
|
||||
sizer.Add(self.audio_albums, 0, wx.ALL, 5)
|
||||
self.video_albums = wx.CheckBox(self, wx.NewId(), _("Create buffers for video albums at startup"))
|
||||
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"))
|
||||
sizer.Add(self.communities, 0, wx.ALL, 5)
|
||||
self.SetSizer(sizer)
|
||||
|
||||
class sound(wx.Panel, widgetUtils.BaseDialog):
|
||||
def __init__(self, panel, input_devices, output_devices, soundpacks):
|
||||
super(sound, self).__init__(panel)
|
||||
sizer = wx.BoxSizer(wx.VERTICAL)
|
||||
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.SetSize(self.output.GetBestSize())
|
||||
outputBox = wx.BoxSizer(wx.HORIZONTAL)
|
||||
outputBox.Add(output_label, 0, wx.ALL, 5)
|
||||
outputBox.Add(self.output, 0, wx.ALL, 5)
|
||||
sizer.Add(outputBox, 0, wx.ALL, 5)
|
||||
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.SetSize(self.input.GetBestSize())
|
||||
inputBox = wx.BoxSizer(wx.HORIZONTAL)
|
||||
inputBox.Add(input_label, 0, wx.ALL, 5)
|
||||
inputBox.Add(self.input, 0, wx.ALL, 5)
|
||||
sizer.Add(inputBox, 0, wx.ALL, 5)
|
||||
# soundBox = wx.BoxSizer(wx.VERTICAL)
|
||||
# soundpack_label = wx.StaticText(self, wx.NewId(), _(u"Sound pack"))
|
||||
# self.soundpack = wx.ComboBox(self, -1, choices=soundpacks, style=wx.CB_READONLY)
|
||||
# self.soundpack.SetSize(self.soundpack.GetBestSize())
|
||||
# soundBox.Add(soundpack_label, 0, wx.ALL, 5)
|
||||
# soundBox.Add(self.soundpack, 0, wx.ALL, 5)
|
||||
# sizer.Add(soundBox, 0, wx.ALL, 5)
|
||||
self.SetSizer(sizer)
|
||||
def __init__(self, panel, input_devices, output_devices, soundpacks):
|
||||
super(sound, self).__init__(panel)
|
||||
sizer = wx.BoxSizer(wx.VERTICAL)
|
||||
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.SetSize(self.output.GetBestSize())
|
||||
outputBox = wx.BoxSizer(wx.HORIZONTAL)
|
||||
outputBox.Add(output_label, 0, wx.ALL, 5)
|
||||
outputBox.Add(self.output, 0, wx.ALL, 5)
|
||||
sizer.Add(outputBox, 0, wx.ALL, 5)
|
||||
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.SetSize(self.input.GetBestSize())
|
||||
inputBox = wx.BoxSizer(wx.HORIZONTAL)
|
||||
inputBox.Add(input_label, 0, wx.ALL, 5)
|
||||
inputBox.Add(self.input, 0, wx.ALL, 5)
|
||||
sizer.Add(inputBox, 0, wx.ALL, 5)
|
||||
# soundBox = wx.BoxSizer(wx.VERTICAL)
|
||||
# soundpack_label = wx.StaticText(self, wx.NewId(), _(u"Sound pack"))
|
||||
# self.soundpack = wx.ComboBox(self, -1, choices=soundpacks, style=wx.CB_READONLY)
|
||||
# self.soundpack.SetSize(self.soundpack.GetBestSize())
|
||||
# soundBox.Add(soundpack_label, 0, wx.ALL, 5)
|
||||
# soundBox.Add(self.soundpack, 0, wx.ALL, 5)
|
||||
# sizer.Add(soundBox, 0, wx.ALL, 5)
|
||||
self.SetSizer(sizer)
|
||||
|
||||
def on_keypress(self, event, *args, **kwargs):
|
||||
""" Invert movement of up and down arrow keys when dealing with a wX Slider.
|
||||
See https://github.com/manuelcortez/TWBlue/issues/261
|
||||
and http://trac.wxwidgets.org/ticket/2068
|
||||
"""
|
||||
keycode = event.GetKeyCode()
|
||||
if keycode == wx.WXK_UP:
|
||||
return self.volumeCtrl.SetValue(self.volumeCtrl.GetValue()+1)
|
||||
elif keycode == wx.WXK_DOWN:
|
||||
return self.volumeCtrl.SetValue(self.volumeCtrl.GetValue()-1)
|
||||
event.Skip()
|
||||
def on_keypress(self, event, *args, **kwargs):
|
||||
""" Invert movement of up and down arrow keys when dealing with a wX Slider.
|
||||
See https://github.com/manuelcortez/TWBlue/issues/261
|
||||
and http://trac.wxwidgets.org/ticket/2068
|
||||
"""
|
||||
keycode = event.GetKeyCode()
|
||||
if keycode == wx.WXK_UP:
|
||||
return self.volumeCtrl.SetValue(self.volumeCtrl.GetValue()+1)
|
||||
elif keycode == wx.WXK_DOWN:
|
||||
return self.volumeCtrl.SetValue(self.volumeCtrl.GetValue()-1)
|
||||
event.Skip()
|
||||
|
||||
def get(self, control):
|
||||
return getattr(self, control).GetStringSelection()
|
||||
def get(self, control):
|
||||
return getattr(self, control).GetStringSelection()
|
||||
|
||||
class configurationDialog(widgetUtils.BaseDialog):
|
||||
|
||||
def __init__(self, title):
|
||||
super(configurationDialog, self).__init__(None, -1, title=title)
|
||||
self.panel = wx.Panel(self)
|
||||
self.sizer = wx.BoxSizer(wx.VERTICAL)
|
||||
self.notebook = wx.Notebook(self.panel)
|
||||
def __init__(self, title):
|
||||
super(configurationDialog, self).__init__(None, -1, title=title)
|
||||
self.panel = wx.Panel(self)
|
||||
self.sizer = wx.BoxSizer(wx.VERTICAL)
|
||||
self.notebook = wx.Notebook(self.panel)
|
||||
|
||||
def create_general(self, languages):
|
||||
self.general = general(self.notebook, languages)
|
||||
self.notebook.AddPage(self.general, _("General"))
|
||||
self.general.SetFocus()
|
||||
def create_general(self, languages):
|
||||
self.general = general(self.notebook, languages)
|
||||
self.notebook.AddPage(self.general, _("General"))
|
||||
self.general.SetFocus()
|
||||
|
||||
def create_buffers(self):
|
||||
self.buffers = buffers(self.notebook)
|
||||
self.notebook.AddPage(self.buffers, _("Buffer settings"))
|
||||
def create_buffers(self):
|
||||
self.buffers = buffers(self.notebook)
|
||||
self.notebook.AddPage(self.buffers, _("Buffer settings"))
|
||||
|
||||
def create_chat(self):
|
||||
self.chat = chat(self.notebook)
|
||||
self.notebook.AddPage(self.chat, _("Chat settings"))
|
||||
def create_chat(self):
|
||||
self.chat = chat(self.notebook)
|
||||
self.notebook.AddPage(self.chat, _("Chat settings"))
|
||||
|
||||
def create_startup_options(self):
|
||||
self.startup = loadAtStartup(self.notebook)
|
||||
self.notebook.AddPage(self.startup, _("Optional buffers"))
|
||||
def create_startup_options(self):
|
||||
self.startup = loadAtStartup(self.notebook)
|
||||
self.notebook.AddPage(self.startup, _("Optional buffers"))
|
||||
|
||||
def create_sound(self, input_devices, output_devices, soundpacks):
|
||||
self.sound = sound(self.notebook, input_devices, output_devices, soundpacks)
|
||||
self.notebook.AddPage(self.sound, _("Sound settings"))
|
||||
def create_sound(self, input_devices, output_devices, soundpacks):
|
||||
self.sound = sound(self.notebook, input_devices, output_devices, soundpacks)
|
||||
self.notebook.AddPage(self.sound, _("Sound settings"))
|
||||
|
||||
def realize(self):
|
||||
self.sizer.Add(self.notebook, 0, wx.ALL, 5)
|
||||
ok_cancel_box = wx.BoxSizer(wx.HORIZONTAL)
|
||||
ok = wx.Button(self.panel, wx.ID_OK, _("Save"))
|
||||
ok.SetDefault()
|
||||
cancel = wx.Button(self.panel, wx.ID_CANCEL, _("Close"))
|
||||
self.SetEscapeId(cancel.GetId())
|
||||
ok_cancel_box.Add(ok, 0, wx.ALL, 5)
|
||||
ok_cancel_box.Add(cancel, 0, wx.ALL, 5)
|
||||
self.sizer.Add(ok_cancel_box, 0, wx.ALL, 5)
|
||||
self.panel.SetSizer(self.sizer)
|
||||
self.SetClientSize(self.sizer.CalcMin())
|
||||
def realize(self):
|
||||
self.sizer.Add(self.notebook, 0, wx.ALL, 5)
|
||||
ok_cancel_box = wx.BoxSizer(wx.HORIZONTAL)
|
||||
ok = wx.Button(self.panel, wx.ID_OK, _("Save"))
|
||||
ok.SetDefault()
|
||||
cancel = wx.Button(self.panel, wx.ID_CANCEL, _("Close"))
|
||||
self.SetEscapeId(cancel.GetId())
|
||||
ok_cancel_box.Add(ok, 0, wx.ALL, 5)
|
||||
ok_cancel_box.Add(cancel, 0, wx.ALL, 5)
|
||||
self.sizer.Add(ok_cancel_box, 0, wx.ALL, 5)
|
||||
self.panel.SetSizer(self.sizer)
|
||||
self.SetClientSize(self.sizer.CalcMin())
|
||||
|
||||
def get_value(self, panel, key):
|
||||
p = getattr(self, panel)
|
||||
return getattr(p, key).GetValue()
|
||||
def get_value(self, panel, key):
|
||||
p = getattr(self, panel)
|
||||
return getattr(p, key).GetValue()
|
||||
|
||||
def set_value(self, panel, key, value):
|
||||
p = getattr(self, panel)
|
||||
control = getattr(p, key)
|
||||
getattr(control, "SetValue")(value)
|
||||
def set_value(self, panel, key, value):
|
||||
p = getattr(self, panel)
|
||||
control = getattr(p, key)
|
||||
getattr(control, "SetValue")(value)
|
||||
|
||||
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()
|
||||
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()
|
||||
|
||||
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()
|
||||
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()
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user