Port socializer to Python 3. #16

This commit is contained in:
2019-01-02 04:42:53 +03:00
parent 1aeab0aef5
commit 4442931dd4
68 changed files with 967 additions and 1006 deletions

View File

@@ -2,10 +2,11 @@
""" Attachment controller for different kind of posts in VK.
this controller will take care of preparing data structures to be uploaded later, when the user decides to start the upload process by sending the post.
"""
from __future__ import unicode_literals
import os
import logging
import widgetUtils
import audioRecorder
from . import audioRecorder
from mutagen.id3 import ID3
from sessionmanager.utils import seconds_to_string
from wxUI.dialogs import attach as gui
@@ -63,7 +64,7 @@ class attach(object):
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 = [_(u"Photo"), description]
info = [_("Photo"), description]
self.dialog.attachments.insert_item(False, *info)
self.dialog.remove.Enable(True)
@@ -77,15 +78,15 @@ class attach(object):
if "TIT2" in audio_tags:
title = audio_tags["TIT2"].text[0]
else:
title = _(u"Untitled")
title = _("Untitled")
if "TPE1" in audio_tags:
artist = audio_tags["TPE1"].text[0]
else:
artist = _(u"Unknown artist")
artist = _("Unknown artist")
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 = [_(u"Audio file"), u"{title} - {artist}".format(title=title, artist=artist)]
info = [_("Audio file"), "{title} - {artist}".format(title=title, artist=artist)]
self.dialog.attachments.insert_item(False, *info)
self.dialog.remove.Enable(True)
@@ -95,7 +96,7 @@ class attach(object):
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 = [_(u"Voice message"), seconds_to_string(a.duration,)]
info = [_("Voice message"), seconds_to_string(a.duration,)]
self.dialog.attachments.insert_item(False, *info)
self.dialog.remove.Enable(True)
@@ -105,8 +106,8 @@ class attach(object):
list_of_audios = self.session.db["me_audio"]["items"]
audios = []
for i in list_of_audios:
audios.append(u"{0}, {1}".format(i["title"], i["artist"]))
select = selector.selectAttachment(_(u"Select the audio files you want to send"), audios)
audios.append("{0}, {1}".format(i["title"], i["artist"]))
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()
for i in attachments:
@@ -114,7 +115,7 @@ class attach(object):
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 = [_(u"Audio file"), u"{0} - {1}".format(list_of_audios[i]["title"], list_of_audios[i]["artist"])]
info2 = [_("Audio file"), "{0} - {1}".format(list_of_audios[i]["title"], list_of_audios[i]["artist"])]
self.dialog.attachments.insert_item(False, *info2)
self.check_remove_status()

View File

@@ -1,4 +1,5 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
import time
import os
import tempfile
@@ -24,12 +25,12 @@ class audioRecorder(object):
self.postprocess()
def on_pause(self, *args, **kwargs):
if self.dialog.get("pause") == _(u"Pause"):
if self.dialog.get("pause") == _("Pause"):
self.recording.pause()
self.dialog.set("pause", _(u"&Resume"))
elif self.dialog.get("pause") == _(u"Resume"):
self.dialog.set("pause", _("&Resume"))
elif self.dialog.get("pause") == _("Resume"):
self.recording.play()
self.dialog.set("pause", _(U"&Pause"))
self.dialog.set("pause", _("&Pause"))
def on_record(self, *args, **kwargs):
if self.recording != None:
@@ -45,20 +46,20 @@ class audioRecorder(object):
self.recording = sound.get_recording(self.file)
self.duration = time.time()
self.recording.play()
self.dialog.set("record", _(u"&Stop"))
output.speak(_(u"Recording"))
self.dialog.set("record", _("&Stop"))
output.speak(_("Recording"))
def stop_recording(self):
self.recording.stop()
self.duration = int(time.time()-self.duration)
self.recording.free()
output.speak(_(u"Stopped"))
output.speak(_("Stopped"))
self.recorded = True
self.dialog.set("record", _(u"&Record"))
self.dialog.set("record", _("&Record"))
self.file_attached()
def file_attached(self):
self.dialog.set("pause", _(u"&Pause"))
self.dialog.set("pause", _("&Pause"))
self.dialog.disable_control("record")
self.dialog.enable_control("play")
self.dialog.enable_control("discard")
@@ -79,7 +80,7 @@ class audioRecorder(object):
self.dialog.record.SetFocus()
self.dialog.disable_control("discard")
self.recording = None
output.speak(_(u"Discarded"))
output.speak(_("Discarded"))
def on_play(self, *args, **kwargs):
if not self.playing:
@@ -88,30 +89,30 @@ class audioRecorder(object):
self._stop()
def _play(self):
output.speak(_(u"Playing..."))
output.speak(_("Playing..."))
# try:
self.playing = sound_lib.stream.FileStream(file=unicode(self.file), flags=sound_lib.stream.BASS_UNICODE)
self.playing = sound_lib.stream.FileStream(file=str(self.file), flags=sound_lib.stream.BASS_UNICODE)
self.playing.play()
self.dialog.set("play", _(u"&Stop"))
self.dialog.set("play", _("&Stop"))
try:
while self.playing.is_playing:
pass
self.dialog.set("play", _(u"&Play"))
self.dialog.set("play", _("&Play"))
self.playing.free()
self.playing = None
except:
pass
def _stop(self):
output.speak(_(u"Stopped"))
output.speak(_("Stopped"))
self.playing.stop()
self.playing.free()
self.dialog.set("play", _(u"&Play"))
self.dialog.set("play", _("&Play"))
self.playing = None
def postprocess(self):
if self.file.lower().endswith('.wav'):
output.speak(_(u"Recoding audio..."))
output.speak(_("Recoding audio..."))
sound.recode_audio(self.file)
self.wav_file = self.file
self.file = '%s.ogg' % self.file[:-4]

View File

@@ -1,5 +1,6 @@
# -*- coding: utf-8 -*-
""" A buffer is a (virtual) list of items. All items belong to a category (wall posts, messages, persons...)"""
from __future__ import unicode_literals
import random
import logging
import webbrowser
@@ -7,12 +8,12 @@ import arrow
import wx
import languageHandler
import widgetUtils
import messages
import player
from . import messages
from . import player
import output
import selector
import posts
import attach
from . import selector
from . import posts
from . import attach
from pubsub import pub
from vk_api.exceptions import VkApiError
from vk_api import upload
@@ -21,7 +22,7 @@ from wxUI.tabs import home
from sessionmanager import session, renderers, utils
from mysc.thread_utils import call_threaded
from wxUI import commonMessages, menus
from sessionmanager.utils import add_attachment
from sessionmanager.renderers import add_attachment
log = logging.getLogger("controller.buffers")
@@ -85,10 +86,10 @@ class baseBuffer(object):
try:
num = getattr(self.session, "get_newsfeed")(show_nextpage=show_nextpage, name=self.name, *self.args, **self.kwargs)
except VkApiError as err:
log.error(u"Error {0}: {1}".format(err.code, err.message))
log.error("Error {0}: {1}".format(err.code, err.message))
retrieved = err.code
return retrieved
except ReadTimeout, ConnectionError:
except ReadTimeout as ConnectionError:
log.exception("Connection error when updating buffer %s. Will try again in 2 minutes" % (self.name,))
return False
if show_nextpage == False:
@@ -111,7 +112,7 @@ class baseBuffer(object):
""" 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 = messages.post(session=self.session, title=_(u"Write your post"), caption="", text="")
p = messages.post(session=self.session, title=_("Write your post"), caption="", text="")
if p.message.get_response() == widgetUtils.OK:
call_threaded(self.do_last, p=p)
@@ -192,12 +193,12 @@ class baseBuffer(object):
p = self.get_post()
if p == None:
return
if p.has_key("likes") == False:
if ("likes" in p) == False:
m.like.Enable(False)
elif p["likes"]["user_likes"] == 1:
m.like.Enable(False)
m.dislike.Enable(True)
if p.has_key("comments") == False:
if ("comments" in p) == False:
m.comment.Enable(False)
widgetUtils.connect_event(m, widgetUtils.MENU, self.open_post, menuitem=m.open)
widgetUtils.connect_event(m, widgetUtils.MENU, self.do_like, menuitem=m.like)
@@ -213,7 +214,7 @@ class baseBuffer(object):
return
user = post[self.user_key]
id = post[self.post_key]
if post.has_key("type"):
if "type" in post:
type_ = post["type"]
else:
type_ = "post"
@@ -221,7 +222,7 @@ class baseBuffer(object):
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(_(u"You liked this"))
output.speak(_("You liked this"))
def do_dislike(self, *args, **kwargs):
""" Set dislike (undo like) in the currently focused post."""
@@ -230,7 +231,7 @@ class baseBuffer(object):
return
user = post[self.user_key]
id = post[self.post_key]
if post.has_key("type"):
if "type" in post:
type_ = post["type"]
else:
type_ = "post"
@@ -238,21 +239,21 @@ class baseBuffer(object):
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(_(u"You don't like this"))
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 = messages.comment(title=_(u"Add a comment"), caption="", text="")
comment = messages.comment(title=_("Add a comment"), caption="", text="")
if comment.message.get_response() == widgetUtils.OK:
msg = comment.message.get_text().encode("utf-8")
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(_(u"You've posted a comment"))
output.speak(_("You've posted a comment"))
except Exception as msg:
log.error(msg)
@@ -285,7 +286,7 @@ class baseBuffer(object):
post = self.get_post()
if post == None:
return
if post.has_key("type") and post["type"] == "audio":
if "type" in post and post["type"] == "audio":
pub.sendMessage("play-audio", audio_object=post["audio"]["items"][0])
return True
@@ -297,7 +298,7 @@ class baseBuffer(object):
# Check all possible keys for an user object in VK API.
keys = ["from_id", "source_id", "id"]
for i in keys:
if selected.has_key(i):
if i in selected:
pub.sendMessage("user-profile", person=selected[i])
def open_post(self, *args, **kwargs):
@@ -305,11 +306,11 @@ class baseBuffer(object):
post = self.get_post()
if post == None:
return
if post.has_key("type") and post["type"] == "audio":
if "type" in post and post["type"] == "audio":
a = posts.audio(self.session, post["audio"]["items"])
a.dialog.get_response()
a.dialog.Destroy()
elif post.has_key("type") and post["type"] == "friend":
elif "type" in post and post["type"] == "friend":
pub.sendMessage("open-post", post_object=post, controller_="friendship")
else:
pub.sendMessage("open-post", post_object=post, controller_="postController")
@@ -327,7 +328,7 @@ class baseBuffer(object):
post = self.get_post()
if post == None:
return
if post.has_key("type") == False:
if ("type" in post) == False:
return [post["from_id"]]
else:
return [post["source_id"]]
@@ -352,10 +353,10 @@ class feedBuffer(baseBuffer):
try:
num = getattr(self.session, "get_page")(show_nextpage=show_nextpage, name=self.name, *self.args, **self.kwargs)
except VkApiError as err:
log.error(u"Error {0}: {1}".format(err.code, err.message))
log.error("Error {0}: {1}".format(err.code, err.message))
retrieved = err.code
return retrieved
except ReadTimeout, ConnectionError:
except ReadTimeout as ConnectionError:
log.exception("Connection error when updating buffer %s. Will try again in 2 minutes" % (self.name,))
return False
if show_nextpage == False:
@@ -370,7 +371,7 @@ class feedBuffer(baseBuffer):
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(_(u"This buffer can't be deleted"))
output.speak(_("This buffer can't be deleted"))
return False
else:
if mandatory == False:
@@ -398,7 +399,7 @@ class communityBuffer(feedBuffer):
widgetUtils.connect_event(self.tab.load, widgetUtils.BUTTON_PRESSED, self.load_community)
def load_community(self, *args, **kwargs):
output.speak(_(u"Loading community..."))
output.speak(_("Loading community..."))
self.can_get_items = True
self.tab.load.Enable(False)
wx.CallAfter(self.get_items)
@@ -462,7 +463,7 @@ class audioBuffer(feedBuffer):
def remove_buffer(self, mandatory=False):
if "me_audio" == self.name or "popular_audio" == self.name or "recommended_audio" == self.name:
output.speak(_(u"This buffer can't be deleted"))
output.speak(_("This buffer can't be deleted"))
return False
else:
if mandatory == False:
@@ -477,7 +478,7 @@ class audioBuffer(feedBuffer):
def get_more_items(self, *args, **kwargs):
# Translators: Some buffers can't use the get previous item feature due to API limitations.
output.speak(_(u"This buffer doesn't support getting more items."))
output.speak(_("This buffer doesn't support getting more items."))
def onFocus(self, *args, **kwargs):
pass
@@ -488,12 +489,12 @@ class audioBuffer(feedBuffer):
return
args = {}
args["audio_id"] = post["id"]
if post.has_key("album_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:
output.speak(_(u"Audio added to your library"))
output.speak(_("Audio added to your library"))
def remove_from_library(self, *args, **kwargs):
post = self.get_post()
@@ -504,7 +505,7 @@ class audioBuffer(feedBuffer):
args["owner_id"] = self.session.user_id
result = self.session.vk.client.audio.delete(**args)
if int(result) == 1:
output.speak(_(u"Removed audio from library"))
output.speak(_("Removed audio from library"))
self.tab.list.remove_item(self.tab.list.get_selected())
def move_to_album(self, *args, **kwargs):
@@ -513,13 +514,13 @@ class audioBuffer(feedBuffer):
post = self.get_post()
if post == None:
return
album = selector.album(_(u"Select the album where you want to move this song"), self.session)
album = selector.album(_("Select the album where you want to move this song"), self.session)
if album.item == None: return
id = post["id"]
response = self.session.vk.client.audio.moveToAlbum(album_id=album.item, audio_ids=id)
if response == 1:
# Translators: Used when the user has moved an audio to an album.
output.speak(_(u"Moved"))
output.speak(_("Moved"))
def get_menu(self):
p = self.get_post()
@@ -531,7 +532,7 @@ class audioBuffer(feedBuffer):
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(_(u"&Remove from library"))
m.library.SetItemLabel(_("&Remove from library"))
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)
@@ -551,7 +552,7 @@ class audioAlbum(audioBuffer):
widgetUtils.connect_event(self.tab.load, widgetUtils.BUTTON_PRESSED, self.load_album)
def load_album(self, *args, **kwargs):
output.speak(_(u"Loading album..."))
output.speak(_("Loading album..."))
self.can_get_items = True
self.tab.load.Enable(False)
wx.CallAfter(self.get_items)
@@ -576,7 +577,7 @@ class videoBuffer(feedBuffer):
return
if selected == -1:
selected = 0
output.speak(_(u"Opening video in webbrowser..."))
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
@@ -586,7 +587,7 @@ class videoBuffer(feedBuffer):
def remove_buffer(self, mandatory=False):
if "me_video" == self.name:
output.speak(_(u"This buffer can't be deleted"))
output.speak(_("This buffer can't be deleted"))
return False
else:
if mandatory == False:
@@ -601,7 +602,7 @@ class videoBuffer(feedBuffer):
def get_more_items(self, *args, **kwargs):
# Translators: Some buffers can't use the get previous item feature due to API limitations.
output.speak(_(u"This buffer doesn't support getting more items."))
output.speak(_("This buffer doesn't support getting more items."))
def onFocus(self, *args, **kwargs):
pass
@@ -612,12 +613,12 @@ class videoBuffer(feedBuffer):
return
args = {}
args["video_id"] = post["id"]
if post.has_key("album_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(_(u"Video added to your library"))
output.speak(_("Video added to your library"))
def remove_from_library(self, *args, **kwargs):
post = self.get_post()
@@ -628,7 +629,7 @@ class videoBuffer(feedBuffer):
args["owner_id"] = self.session.user_id
result = self.session.vk.client.video.delete(**args)
if int(result) == 1:
output.speak(_(u"Removed video from library"))
output.speak(_("Removed video from library"))
self.tab.list.remove_item(self.tab.list.get_selected())
def move_to_album(self, *args, **kwargs):
@@ -637,13 +638,13 @@ class videoBuffer(feedBuffer):
post= self.get_post()
if post == None:
return
album = selector.album(_(u"Select the album where you want to move this video"), self.session, "video_albums")
album = selector.album(_("Select the album where you want to move this video"), self.session, "video_albums")
if album.item == None: return
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(_(u"Moved"))
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"""
@@ -656,7 +657,7 @@ class videoBuffer(feedBuffer):
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(_(u"&Remove from library"))
m.library.SetItemLabel(_("&Remove from library"))
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)
@@ -673,7 +674,7 @@ class videoAlbum(videoBuffer):
widgetUtils.connect_event(self.tab.load, widgetUtils.BUTTON_PRESSED, self.load_album)
def load_album(self, *args, **kwargs):
output.speak(_(u"Loading album..."))
output.speak(_("Loading album..."))
self.can_get_items = True
self.tab.load.Enable(False)
wx.CallAfter(self.get_items)
@@ -689,7 +690,7 @@ class empty(object):
pass
def get_more_items(self, *args, **kwargs):
output.speak(_(u"This buffer doesn't support getting more items."))
output.speak(_("This buffer doesn't support getting more items."))
def remove_buffer(self, mandatory=False): return False
@@ -710,7 +711,7 @@ class chatBuffer(baseBuffer):
# Get text position here.
position = self.tab.history.PositionToXY(self.tab.history.GetInsertionPoint())
id_ = None
for i in self.chats.keys():
for i in 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.GetNumberLines() that is not possible.
@@ -733,12 +734,12 @@ class chatBuffer(baseBuffer):
msg = self.get_focused_post()
if msg == False: # Handle the case where the last line of the control cannot be matched to anything.
return
if msg.has_key("read_state") and msg["read_state"] == 0 and msg["id"] not in self.reads and msg.has_key("out") and msg["out"] == 0:
if "read_state" in msg and msg["read_state"] == 0 and msg["id"] not in self.reads and "out" in msg and msg["out"] == 0:
self.session.soundplayer.play("message_unread.ogg")
self.reads.append(msg["id"])
self.session.db[self.name]["items"][-1]["read_state"] = 1
# print msg
if msg.has_key("attachments") and len(msg["attachments"]) > 0:
if "attachments" in msg and len(msg["attachments"]) > 0:
self.tab.attachments.list.Enable(True)
self.attachments = list()
self.tab.attachments.clear()
@@ -770,10 +771,10 @@ class chatBuffer(baseBuffer):
try:
num = getattr(self.session, "get_messages")(name=self.name, *self.args, **self.kwargs)
except VkApiError as err:
log.error(u"Error {0}: {1}".format(err.code, err.message))
log.error("Error {0}: {1}".format(err.code, err.message))
retrieved = err.code
return retrieved
except ReadTimeout, ConnectionError:
except ReadTimeout as ConnectionError:
log.exception("Connection error when updating buffer %s. Will try again in 2 minutes" % (self.name,))
return False
if show_nextpage == False:
@@ -853,7 +854,7 @@ class chatBuffer(baseBuffer):
response = self.session.vk.client.messages.send(user_id=self.kwargs["user_id"], message=text, random_id=random_id)
except ValueError as ex:
if ex.code == 9:
output.speak(_(u"You have been sending a message that is already sent. Try to update the buffer if you can't see the new message in the history."))
output.speak(_("You have been sending a message that is already sent. Try to update the buffer if you can't see the new message in the history."))
def __init__(self, *args, **kwargs):
super(chatBuffer, self).__init__(*args, **kwargs)
@@ -863,7 +864,7 @@ class chatBuffer(baseBuffer):
def parse_attachments(self, post):
attachments = []
if post.has_key("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":
@@ -882,13 +883,13 @@ class chatBuffer(baseBuffer):
a.dialog.Destroy()
elif attachment["type"] == "audio_message":
link = attachment["audio_message"]["link_mp3"]
output.speak(_(u"Playing..."))
output.speak(_("Playing..."))
player.player.play(url=dict(url=link), set_info=False)
elif attachment["type"] == "link":
output.speak(_(u"Opening URL..."), True)
output.speak(_("Opening URL..."), True)
webbrowser.open_new_tab(attachment["link"]["url"])
elif attachment["type"] == "doc":
output.speak(_(u"Opening document in web browser..."))
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
@@ -900,15 +901,15 @@ class chatBuffer(baseBuffer):
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(_(u"Opening video in web browser..."), True)
output.speak(_("Opening video in web browser..."), True)
webbrowser.open_new_tab(video_object["player"])
elif attachment["type"] == "photo":
output.speak(_(u"Opening photo in web browser..."), True)
output.speak(_("Opening photo in web browser..."), True)
# Possible photo sizes for looking in the attachment information. Try to use the biggest photo available.
possible_sizes = [1280, 604, 130, 75]
url = ""
for i in possible_sizes:
if attachment["photo"].has_key("photo_{0}".format(i,)):
if "photo_{0}".format(i,) in attachment["photo"]:
url = attachment["photo"]["photo_{0}".format(i,)]
break
if url != "":
@@ -941,7 +942,7 @@ class peopleBuffer(feedBuffer):
post = self.get_post()
if post == None:
return
if post.has_key("last_seen") == False: return
if ("last_seen" in post) == False: return
original_date = arrow.get(post["last_seen"]["time"])
created_at = original_date.humanize(locale=languageHandler.curLang[:2])
self.tab.list.list.SetItem(self.tab.list.get_selected(), 1, created_at)
@@ -992,10 +993,10 @@ class requestsBuffer(peopleBuffer):
try:
ids = self.session.vk.client.friends.getRequests(*self.args, **self.kwargs)
except VkApiError as err:
log.error(u"Error {0}: {1}".format(err.code, err.message))
log.error("Error {0}: {1}".format(err.code, err.message))
retrieved = err.code
return retrieved
except ReadTimeout, ConnectionError:
except ReadTimeout as ConnectionError:
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")
@@ -1017,7 +1018,7 @@ class requestsBuffer(peopleBuffer):
return
result = self.session.vk.client.friends.add(user_id=person["id"])
if result == 2:
msg = _(u"{0} {1} now is your friend.").format(person["first_name"], person["last_name"])
msg = _("{0} {1} now is your friend.").format(person["first_name"], person["last_name"])
pub.sendMessage("notify", message=msg)
self.session.db[self.name]["items"].pop(self.tab.list.get_selected())
self.tab.list.remove_item(self.tab.list.get_selected())
@@ -1031,9 +1032,9 @@ class requestsBuffer(peopleBuffer):
return
result = self.session.vk.client.friends.delete(user_id=person["id"])
if "out_request_deleted" in result:
msg = _(u"You've deleted the friends request to {0} {1}.").format(person["first_name"], person["last_name"])
msg = _("You've deleted the friends request to {0} {1}.").format(person["first_name"], person["last_name"])
elif "in_request_deleted" in result:
msg = _(u"You've declined the friend request of {0} {1}.").format(person["first_name"], person["last_name"])
msg = _("You've declined the friend request of {0} {1}.").format(person["first_name"], person["last_name"])
pub.sendMessage("notify", message=msg)
self.session.db[self.name]["items"].pop(self.tab.list.get_selected())
self.tab.list.remove_item(self.tab.list.get_selected())
@@ -1047,7 +1048,7 @@ class requestsBuffer(peopleBuffer):
return
result = self.session.vk.client.friends.add(user_id=person["id"], follow=1)
if result == 2:
msg = _(u"{0} {1} is following you.").format(person["first_name"], person["last_name"])
msg = _("{0} {1} is following you.").format(person["first_name"], person["last_name"])
pub.sendMessage("notify", message=msg)
self.session.db[self.name]["items"].pop(self.tab.list.get_selected())
self.tab.list.remove_item(self.tab.list.get_selected())

View File

@@ -1,40 +1,41 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
import widgetUtils
from wxUI.dialogs import configuration as configurationUI
class configuration(object):
def get_notification_type(self, value):
if value == _(u"Native"):
if value == _("Native"):
return "native"
else:
return "custom"
def get_notification_label(self, value):
if value == "native":
return _(u"Native")
return _("Native")
else:
return _(u"Custom")
return _("Custom")
def get_update_channel_type(self, value):
if value == _(u"Stable"):
if value == _("Stable"):
return "stable"
elif value == _(u"Weekly"):
elif value == _("Weekly"):
return "weekly"
else:
return "alpha"
def get_update_channel_label(self, value):
if value == "stable":
return _(u"Stable")
return _("Stable")
elif value == "weekly":
return _(u"Weekly")
return _("Weekly")
else:
return _(u"Alpha")
return _("Alpha")
def __init__(self, session):
self.session = session
self.dialog = configurationUI.configurationDialog(_(u"Preferences"))
self.dialog = configurationUI.configurationDialog(_("Preferences"))
self.create_config()
def create_config(self):

View File

@@ -1,19 +1,21 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from builtins import range
import time
import os
import wx
import widgetUtils
import messages
import buffers
import configuration
import player
import posts
import profiles
from . import messages
from . import buffers
from . import configuration
from . import player
from . import posts
from . import profiles
import webbrowser
import logging
import output
import longpollthread
import selector
from . import longpollthread
from . import selector
from vk_api.exceptions import LoginRequired, VkApiError
from requests.exceptions import ConnectionError
from pubsub import pub
@@ -32,7 +34,7 @@ log = logging.getLogger("controller.main")
class Controller(object):
def search(self, tab_name):
for i in xrange(0, len(self.buffers)):
for i in range(0, len(self.buffers)):
if self.buffers[i].name == tab_name:
return self.buffers[i]
return False
@@ -51,8 +53,8 @@ class Controller(object):
player.setup()
self.window = mainWindow.mainWindow()
log.debug("Main window created")
self.window.change_status(_(u"Ready"))
self.session = session.sessions[session.sessions.keys()[0]]
self.window.change_status(_("Ready"))
self.session = session.sessions[list(session.sessions.keys())[0]]
self.create_controls()
self.window.Show()
self.connect_events()
@@ -63,11 +65,11 @@ class Controller(object):
posts_ = buffers.empty(parent=self.window.tb, name="posts")
self.buffers.append(posts_)
# Translators: Name for the posts tab in the tree view.
self.window.add_buffer(posts_.tab, _(u"Posts"))
self.window.add_buffer(posts_.tab, _("Posts"))
home = buffers.baseBuffer(parent=self.window.tb, name="home_timeline", session=self.session, composefunc="render_newsfeed_item", endpoint="newsfeed", count=self.session.settings["buffers"]["count_for_wall_buffers"])
self.buffers.append(home)
# Translators: Newsfeed's name in the tree view.
self.window.insert_buffer(home.tab, _(u"Home"), self.window.search("posts"))
self.window.insert_buffer(home.tab, _("Home"), self.window.search("posts"))
self.repeatedUpdate = RepeatingTimer(120, self.update_all_buffers)
self.repeatedUpdate.start()
self.readMarker = RepeatingTimer(60, self.mark_as_read)
@@ -75,60 +77,60 @@ class Controller(object):
feed = buffers.feedBuffer(parent=self.window.tb, name="me_feed", composefunc="render_status", session=self.session, endpoint="get", parent_endpoint="wall", extended=1, count=self.session.settings["buffers"]["count_for_wall_buffers"])
self.buffers.append(feed)
# Translators: Own user's wall name in the tree view.
self.window.insert_buffer(feed.tab, _(u"My wall"), self.window.search("posts"))
self.window.insert_buffer(feed.tab, _("My wall"), self.window.search("posts"))
audios = buffers.empty(parent=self.window.tb, name="audios")
self.buffers.append(audios)
# Translators: name for the music category in the tree view.
self.window.add_buffer(audios.tab, _(u"Music"))
self.window.add_buffer(audios.tab, _("Music"))
audio = buffers.audioBuffer(parent=self.window.tb, name="me_audio", composefunc="render_audio", session=self.session, endpoint="get", parent_endpoint="audio")
self.buffers.append(audio)
self.window.insert_buffer(audio.tab, _(u"My audios"), self.window.search("audios"))
self.window.insert_buffer(audio.tab, _("My audios"), self.window.search("audios"))
if self.session.settings["vk"]["use_alternative_tokens"] == False:
p_audio = buffers.audioBuffer(parent=self.window.tb, name="popular_audio", composefunc="render_audio", session=self.session, endpoint="getPopular", parent_endpoint="audio", full_list=True, count=self.session.settings["buffers"]["count_for_audio_buffers"])
self.buffers.append(p_audio)
self.window.insert_buffer(p_audio.tab, _(u"Populars"), self.window.search("audios"))
self.window.insert_buffer(p_audio.tab, _("Populars"), self.window.search("audios"))
r_audio = buffers.audioBuffer(parent=self.window.tb, name="recommended_audio", composefunc="render_audio", session=self.session, endpoint="getRecommendations", parent_endpoint="audio", full_list=True, count=self.session.settings["buffers"]["count_for_audio_buffers"])
self.buffers.append(r_audio)
self.window.insert_buffer(r_audio.tab, _(u"Recommendations"), self.window.search("audios"))
self.window.insert_buffer(r_audio.tab, _("Recommendations"), self.window.search("audios"))
albums = buffers.empty(parent=self.window.tb, name="albums")
self.buffers.append(albums)
self.window.insert_buffer(albums.tab, _(u"Albums"), self.window.search("audios"))
self.window.insert_buffer(albums.tab, _("Albums"), self.window.search("audios"))
videos = buffers.empty(parent=self.window.tb, name="videos")
self.buffers.append(videos)
# Translators: name for the videos category in the tree view.
self.window.add_buffer(videos.tab, _(u"Video"))
self.window.add_buffer(videos.tab, _("Video"))
my_videos = buffers.videoBuffer(parent=self.window.tb, name="me_video", composefunc="render_video", session=self.session, endpoint="get", parent_endpoint="video", count=self.session.settings["buffers"]["count_for_video_buffers"])
self.buffers.append(my_videos)
self.window.insert_buffer(my_videos.tab, _(u"My videos"), self.window.search("videos"))
self.window.insert_buffer(my_videos.tab, _("My videos"), self.window.search("videos"))
video_albums = buffers.empty(parent=self.window.tb, name="video_albums")
self.buffers.append(video_albums)
self.window.insert_buffer(video_albums.tab, _(u"Albums"), self.window.search("videos"))
self.window.insert_buffer(video_albums.tab, _("Albums"), self.window.search("videos"))
people = buffers.empty(parent=self.window.tb, name="people")
self.buffers.append(people)
self.window.add_buffer(people.tab, _(u"People"))
self.window.add_buffer(people.tab, _("People"))
friends = buffers.peopleBuffer(parent=self.window.tb, name="friends_", composefunc="render_person", session=self.session, endpoint="get", parent_endpoint="friends", count=5000, fields="uid, first_name, last_name, last_seen")
self.buffers.append(friends)
self.window.insert_buffer(friends.tab, _(u"Friends"), self.window.search("people"))
self.window.insert_buffer(friends.tab, _("Friends"), self.window.search("people"))
requests_ = buffers.empty(parent=self.window.tb, name="requests")
self.buffers.append(requests_)
self.window.insert_buffer(requests_.tab, _(u"Friendship requests"), self.window.search("people"))
self.window.insert_buffer(requests_.tab, _("Friendship requests"), self.window.search("people"))
incoming_requests = buffers.requestsBuffer(parent=self.window.tb, name="friend_requests", composefunc="render_person", session=self.session, count=1000)
self.buffers.append(incoming_requests)
self.window.insert_buffer(incoming_requests.tab, _(u"Pending requests"), self.window.search("requests"))
self.window.insert_buffer(incoming_requests.tab, _("Pending requests"), self.window.search("requests"))
outgoing_requests = buffers.requestsBuffer(parent=self.window.tb, name="friend_requests_sent", composefunc="render_person", session=self.session, count=1000, out=1)
self.buffers.append(outgoing_requests)
self.window.insert_buffer(outgoing_requests.tab, _(u"I follow"), self.window.search("requests"))
# communities= buffers.empty(parent=self.window.tb, name="communities")
# self.buffers.append(communities)
self.window.insert_buffer(outgoing_requests.tab, _("I follow"), self.window.search("requests"))
communities= buffers.empty(parent=self.window.tb, name="communities")
self.buffers.append(communities)
# Translators: name for the videos category in the tree view.
# self.window.add_buffer(communities.tab, _(u"Communities"))
self.window.add_buffer(communities.tab, _("Communities"))
chats = buffers.empty(parent=self.window.tb, name="chats")
self.buffers.append(chats)
self.window.add_buffer(chats.tab, _(u"Chats"))
self.window.add_buffer(chats.tab, _("Chats"))
timelines = buffers.empty(parent=self.window.tb, name="timelines")
self.buffers.append(timelines)
self.window.add_buffer(timelines.tab, _(u"Timelines"))
self.window.add_buffer(timelines.tab, _("Timelines"))
self.window.realize()
def connect_events(self):
@@ -193,15 +195,15 @@ class Controller(object):
commonMessages.bad_authorisation()
def login(self):
self.window.change_status(_(u"Logging in VK"))
self.window.change_status(_("Logging in VK"))
self.session.login()
self.window.change_status(_(u"Ready"))
self.window.change_status(_("Ready"))
for i in self.buffers:
if hasattr(i, "get_items"):
# Translators: {0} will be replaced with the name of a buffer.
self.window.change_status(_(u"Loading items for {0}").format(i.name,))
self.window.change_status(_("Loading items for {0}").format(i.name,))
i.get_items()
self.window.change_status(_(u"Ready"))
self.window.change_status(_("Ready"))
self.create_longpoll_thread()
self.status_setter = RepeatingTimer(280, self.set_online)
self.status_setter.start()
@@ -216,7 +218,7 @@ class Controller(object):
self.longpoll = longpollthread.worker(self.session)
self.longpoll.start()
if notify:
self.notify(message=_(u"Chat server reconnected"))
self.notify(message=_("Chat server reconnected"))
except ConnectionError:
pub.sendMessage("longpoll-read-timeout")
@@ -233,17 +235,17 @@ class Controller(object):
for i in self.buffers:
if hasattr(i, "get_items"):
i.get_items()
log.debug(u"Updated %s" % (i.name))
log.debug("Updated %s" % (i.name))
def download(self, url, filename):
log.debug(u"downloading %s URL to %s filename" % (url, filename,))
log.debug("downloading %s URL to %s filename" % (url, filename,))
call_threaded(utils.download_file, url, filename, self.window)
def play_audio(self, audio_object):
# Restricted audios does not include an URL paramether.
# Restriction can be due to licensed content to unauthorized countries.
if "url" in audio_object and audio_object["url"] =="":
self.notify(message=_(u"This file could not be played because it is not allowed in your country"))
self.notify(message=_("This file could not be played because it is not allowed in your country"))
return
call_threaded(player.player.play, audio_object)
@@ -279,11 +281,11 @@ class Controller(object):
dlg = searchDialogs.searchAudioDialog()
if dlg.get_response() == widgetUtils.OK:
q = dlg.get("term").encode("utf-8")
newbuff = buffers.audioBuffer(parent=self.window.tb, name=u"{0}_audiosearch".format(q.decode("utf-8"),), session=self.session, composefunc="render_audio", parent_endpoint="audio", endpoint="search", q=q)
newbuff = buffers.audioBuffer(parent=self.window.tb, name="{0}_audiosearch".format(q,), session=self.session, composefunc="render_audio", parent_endpoint="audio", endpoint="search", q=q)
self.buffers.append(newbuff)
call_threaded(newbuff.get_items)
# Translators: {0} will be replaced with the search term.
self.window.insert_buffer(newbuff.tab, _(u"Search for {0}").format(q.decode("utf-8"),), self.window.search("audios"))
self.window.insert_buffer(newbuff.tab, _("Search for {0}").format(q,), self.window.search("audios"))
def search_videos(self, *args, **kwargs):
dlg = searchDialogs.searchVideoDialog()
@@ -297,11 +299,11 @@ class Controller(object):
params["adult"] = dlg.get_checkable("safe_search")
params["sort"] = dlg.get_sort_order()
params["filters"] = "youtube, vimeo, short, long"
newbuff = buffers.videoBuffer(parent=self.window.tb, name=u"{0}_videosearch".format(params["q"].decode("utf-8"),), session=self.session, composefunc="render_video", parent_endpoint="video", endpoint="search", **params)
newbuff = buffers.videoBuffer(parent=self.window.tb, name="{0}_videosearch".format(params["q"],), session=self.session, composefunc="render_video", parent_endpoint="video", endpoint="search", **params)
self.buffers.append(newbuff)
call_threaded(newbuff.get_items)
# Translators: {0} will be replaced with the search term.
self.window.insert_buffer(newbuff.tab, _(u"Search for {0}").format(params["q"].decode("utf-8"),), self.window.search("videos"))
self.window.insert_buffer(newbuff.tab, _("Search for {0}").format(params["q"],), self.window.search("videos"))
def update_status_bar(self, status):
self.window.change_status(status)
@@ -350,15 +352,15 @@ class Controller(object):
if buffertype == "audio":
buffer = buffers.audioBuffer(parent=self.window.tb, name="{0}_audio".format(user_id,), composefunc="render_audio", session=self.session, endpoint="get", parent_endpoint="audio", owner_id=user_id)
# Translators: {0} will be replaced with an user.
name_ = _(u"{0}'s audios").format(self.session.get_user_name(user_id, "gen"),)
name_ = _("{0}'s audios").format(self.session.get_user_name(user_id, "gen"),)
elif buffertype == "wall":
buffer = buffers.feedBuffer(parent=self.window.tb, name="{0}_feed".format(user_id,), composefunc="render_status", session=self.session, endpoint="get", parent_endpoint="wall", extended=1, count=self.session.settings["buffers"]["count_for_wall_buffers"], owner_id=user_id)
# Translators: {0} will be replaced with an user.
name_ = _(u"{0}'s wall posts").format(self.session.get_user_name(user_id, "gen"),)
name_ = _("{0}'s wall posts").format(self.session.get_user_name(user_id, "gen"),)
elif buffertype == "friends":
buffer = buffers.peopleBuffer(parent=self.window.tb, name="friends_{0}".format(user_id,), composefunc="render_person", session=self.session, endpoint="get", parent_endpoint="friends", count=5000, fields="uid, first_name, last_name, last_seen", user_id=user_id)
# Translators: {0} will be replaced with an user.
name_ = _(u"{0}'s friends").format(self.session.get_user_name(user_id, "friends"),)
name_ = _("{0}'s friends").format(self.session.get_user_name(user_id, "friends"),)
self.buffers.append(buffer)
call_threaded(self.complete_buffer_creation, buffer=buffer, name_=name_, position=self.window.search("timelines"))
@@ -374,7 +376,7 @@ class Controller(object):
def search_chat_buffer(self, user_id):
for i in self.buffers:
if "_messages" in i.name:
if i.kwargs.has_key("user_id") and i.kwargs["user_id"] == user_id: return i
if "user_id" in i.kwargs and i.kwargs["user_id"] == user_id: return i
return None
def chat_from_id(self, user_id, setfocus=True, unread=False):
@@ -388,7 +390,7 @@ class Controller(object):
buffer = buffers.chatBuffer(parent=self.window.tb, name="{0}_messages".format(user_id,), composefunc="render_message", session=self.session, count=200, user_id=user_id, rev=0, extended=True, fields="id, user_id, date, read_state, out, body, attachments, deleted")
self.buffers.append(buffer)
# Translators: {0} will be replaced with an user.
self.window.insert_buffer(buffer.tab, _(u"Chat with {0}").format(self.session.get_user_name(user_id, "ins")), self.window.search("chats"))
self.window.insert_buffer(buffer.tab, _("Chat with {0}").format(self.session.get_user_name(user_id, "ins")), self.window.search("chats"))
if setfocus:
pos = self.window.search(buffer.name)
self.window.change_buffer(pos)
@@ -400,7 +402,7 @@ class Controller(object):
if self.session.settings["chat"]["notify_online"] == False:
return
user_name = self.session.get_user_name(event.user_id, "nom")
msg = _(u"{0} is online.").format(user_name,)
msg = _("{0} is online.").format(user_name,)
sound = "friend_online.ogg"
self.notify(msg, sound, self.session.settings["chat"]["notifications"])
@@ -408,7 +410,7 @@ class Controller(object):
if self.session.settings["chat"]["notify_offline"] == False:
return
user_name = self.session.get_user_name(event.user_id, "nom")
msg = _(u"{0} is offline.").format(user_name,)
msg = _("{0} is offline.").format(user_name,)
sound = "friend_offline.ogg"
self.notify(msg, sound, self.session.settings["chat"]["notifications"])
@@ -503,7 +505,7 @@ class Controller(object):
buffer = buffers.audioAlbum(parent=self.window.tb, name="{0}_audio_album".format(i["id"],), composefunc="render_audio", session=self.session, endpoint="get", parent_endpoint="audio", owner_id=user_id, album_id=i["id"])
buffer.can_get_items = False
# Translators: {0} Will be replaced with an audio album's title.
name_ = _(u"Album: {0}").format(i["title"],)
name_ = _("Album: {0}").format(i["title"],)
self.buffers.append(buffer)
self.window.insert_buffer(buffer.tab, name_, self.window.search("albums"))
# buffer.get_items()
@@ -519,7 +521,7 @@ class Controller(object):
buffer = buffers.videoAlbum(parent=self.window.tb, name="{0}_video_album".format(i["id"],), composefunc="render_video", session=self.session, endpoint="get", parent_endpoint="video", count=self.session.settings["buffers"]["count_for_video_buffers"], user_id=user_id, album_id=i["id"])
buffer.can_get_items = False
# Translators: {0} Will be replaced with a video album's title.
name_ = _(u"Album: {0}").format(i["title"],)
name_ = _("Album: {0}").format(i["title"],)
self.buffers.append(buffer)
self.window.insert_buffer(buffer.tab, name_, self.window.search("video_albums"))
# buffer.get_items()
@@ -529,14 +531,14 @@ class Controller(object):
def get_communities(self, user_id=None, create_buffers=True):
log.debug("Create community buffers...")
groups= self.session.vk.client.groups.get(user_id=user_id, extended=1, fields="city, country, place, description, wiki_page, members_count, counters, start_date, finish_date, can_post, can_see_all_posts, activity, status, contacts, links, fixed_post, verified, site, can_create_topic")
print groups.keys()
# print(list(groups.keys()))
self.session.groups=groups["items"]
# Let's feed the local database cache with new groups coming from here.
data= dict(profiles=[], groups=groups["items"])
self.session.process_usernames(data)
if create_buffers:
for i in groups["items"]:
print i.keys()
# print(list(i.keys()))
buffer = buffers.communityBuffer(parent=self.window.tb, name="{0}_community".format(i["id"],), composefunc="render_status", session=self.session, endpoint="get", parent_endpoint="wall", count=self.session.settings["buffers"]["count_for_wall_buffers"], owner_id=-1*i["id"])
buffer.can_get_items = False
# Translators: {0} Will be replaced with a video album's title.
@@ -551,19 +553,19 @@ class Controller(object):
d = creation.audio_album()
if d.get_response() == widgetUtils.OK and d.get("title") != "":
response = self.session.vk.client.audio.addAlbum(title=d.get("title"))
if response.has_key("album_id") == False: return
if ("album_id" in response) == False: return
album_id = response["album_id"]
buffer = buffers.audioAlbum(parent=self.window.tb, name="{0}_audio_album".format(album_id,), composefunc="render_audio", session=self.session, endpoint="get", parent_endpoint="audio", full_list=True, count=self.session.settings["buffers"]["count_for_audio_buffers"], user_id=self.session.user_id, album_id=album_id)
buffer.can_get_items = False
# Translators: {0} will be replaced with an audio album's title.
name_ = _(u"Album: {0}").format(d.get("title"),)
name_ = _("Album: {0}").format(d.get("title"),)
self.buffers.append(buffer)
self.window.insert_buffer(buffer.tab, name_, self.window.search("albums"))
buffer.get_items()
self.session.audio_albums = self.session.vk.client.audio.getAlbums(owner_id=self.session.user_id)["items"]
def delete_audio_album(self, *args, **kwargs):
answer = selector.album(_(u"Select the album you want to delete"), self.session)
answer = selector.album(_("Select the album you want to delete"), self.session)
if answer.item == None:
return
response = commonMessages.delete_audio_album()
@@ -580,19 +582,19 @@ class Controller(object):
d = creation.audio_album()
if d.get_response() == widgetUtils.OK and d.get("title") != "":
response = self.session.vk.client.video.addAlbum(title=d.get("title"))
if response.has_key("album_id") == False: return
if ("album_id" in response) == False: return
album_id = response["album_id"]
buffer = buffers.videoAlbum(parent=self.window.tb, name="{0}_video_album".format(album_id,), composefunc="render_video", session=self.session, endpoint="get", parent_endpoint="video", count=self.session.settings["buffers"]["count_for_video_buffers"], user_id=self.session.user_id, album_id=album_id)
buffer.can_get_items = False
# Translators: {0} will be replaced with a video album's title.
name_ = _(u"Album: {0}").format(d.get("title"),)
name_ = _("Album: {0}").format(d.get("title"),)
self.buffers.append(buffer)
self.window.insert_buffer(buffer.tab, name_, self.window.search("video_albums"))
buffer.get_items()
self.session.video_albums = self.session.vk.client.video.getAlbums(owner_id=self.session.user_id)["items"]
def delete_video_album(self, *args, **kwargs):
answer = selector.album(_(u"Select the album you want to delete"), self.session, "video_albums")
answer = selector.album(_("Select the album you want to delete"), self.session, "video_albums")
if answer.item == None:
return
response = commonMessages.delete_audio_album()
@@ -674,14 +676,14 @@ class Controller(object):
def handle_longpoll_read_timeout(self):
if hasattr(self, "longpoll"):
self.notify(message=_(u"Chat disconnected. Trying to connect in 60 seconds"))
self.notify(message=_("Chat disconnected. Trying to connect in 60 seconds"))
time.sleep(60)
if hasattr(self, "longpoll"):
del self.longpoll
self.create_longpoll_thread(notify=True)
def set_status(self, *args, **kwargs):
dlg = wx.TextEntryDialog(self.window, _(u"Write your status message"), _(u"Set status"))
dlg = wx.TextEntryDialog(self.window, _("Write your status message"), _("Set status"))
if dlg.ShowModal() == widgetUtils.OK:
result = dlg.GetValue()
info = self.session.vk.client.account.saveProfileInfo(status=result)

View File

@@ -1,9 +1,10 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
import time
import widgetUtils
import output
from pubsub import pub
import attach
from . import attach
from wxUI.dialogs import message, selector
from extra import SpellChecker, translator
from logging import getLogger
@@ -26,9 +27,9 @@ class post(object):
def get_privacy_options(self):
p = self.message.get("privacy")
if p == _(u"Friends of friends"):
if p == _("Friends of friends"):
privacy = 0
elif p == _(u"All users"):
elif p == _("All users"):
privacy = 1
return privacy
@@ -42,14 +43,14 @@ class post(object):
return self.mention(*args, **kwargs)
users = []
for i in friends["items"]:
users.append(u"{0} {1}".format(i["first_name"], i["last_name"]))
users.append("{0} {1}".format(i["first_name"], i["last_name"]))
select = selector.selectPeople(users)
if select.get_response() == widgetUtils.OK and select.users.GetCount() > 0:
self.tagged_people = []
tagged_users = select.get_all_users()
for i in tagged_users:
self.tagged_people.append(u"[id%s|%s]" % (str(friends["items"][i]["id"]), friends["items"][i]["first_name"]))
self.message.text.SetValue(self.message.text.GetValue()+ u", ".join(self.tagged_people))
self.tagged_people.append("[id%s|%s]" % (str(friends["items"][i]["id"]), friends["items"][i]["first_name"]))
self.message.text.SetValue(self.message.text.GetValue()+ ", ".join(self.tagged_people))
def translate(self, *args, **kwargs):
dlg = translator.gui.translateDialog()
@@ -59,7 +60,7 @@ class post(object):
msg = translator.translator.translate(text_to_translate, dest)
self.message.set_text(msg)
self.message.text_focus()
output.speak(_(u"Translated"))
output.speak(_("Translated"))
dlg.Destroy()
def spellcheck(self, event=None):
@@ -77,4 +78,4 @@ class post(object):
class comment(post):
def __init__(self, session, title, caption, text):
super(comment, self).__init__(session, title, caption, text, "comment")
self.message.set_title(_(u"New comment"))
self.message.set_title(_("New comment"))

View File

@@ -1,4 +1,5 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
import random
import output
import sound_lib
@@ -43,13 +44,13 @@ class audioPlayer(object):
if self.is_working == False:
self.is_working = True
try:
self.stream = URLStream(url=url["url"])
self.stream = URLStream(url=bytes(url["url"], "utf-8"))
except BassError:
log.debug("Error when playing the file %r") % (url,)
return
# Translators: {0} will be replaced with a song's title and {1} with the artist.
if set_info:
msg = _(u"Playing {0} by {1}").format(url["title"], url["artist"])
msg = _("Playing {0} by {1}").format(url["title"], url["artist"])
pub.sendMessage("update-status-bar", status=msg)
self.stream.volume = self.vol/100.0
self.stream.play()

View File

@@ -1,10 +1,13 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from future import standard_library
standard_library.install_aliases()
import re
import os
import cStringIO
import io
import threading
import arrow
import messages
from . import messages
import requests
import languageHandler
import widgetUtils
@@ -12,8 +15,7 @@ import output
import wx
import webbrowser
import logging
from sessionmanager import session # We'll use some functions from there
from sessionmanager import utils
from sessionmanager import session, renderers, utils # We'll use some functions from there
from pubsub import pub
from wxUI.dialogs import postDialogs, urlList, profiles
from extra import SpellChecker, translator
@@ -26,14 +28,14 @@ def get_user(id, profiles):
""" Returns an user name and last name based in the id receibed."""
for i in profiles:
if i["id"] == id:
return u"{0} {1}".format(i["first_name"], i["last_name"])
return "{0} {1}".format(i["first_name"], i["last_name"])
# Translators: This string is used when socializer can't find the right user information.
return _(u"Unknown username")
return _("Unknown username")
def get_message(status):
message = ""
if status.has_key("text"):
message = utils.clean_text(status["text"])
if "text" in status:
message = renderers.clean_text(status["text"])
return message
class postController(object):
@@ -44,13 +46,13 @@ class postController(object):
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 self.post.has_key("source_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 not self.post.has_key("owner_id"):
if "owner_id" not in self.post:
self.user_identifier = "from_id"
else:
self.user_identifier = "owner_id"
@@ -83,9 +85,9 @@ class postController(object):
if "deleted" in i:
continue
from_ = get_user(i["from_id"], self.comments["profiles"])
if i.has_key("reply_to_user"):
if "reply_to_user" in i:
extra_info = get_user(i["reply_to_user"], self.comments["profiles"])
from_ = _(u"{0} > {1}").format(from_, extra_info)
from_ = _("{0} > {1}").format(from_, extra_info)
# As we set the comment reply properly in the from_ field, let's remove the first username from here if it exists.
fixed_text = re.sub("^\[id\d+\|\D+\], ", "", i["text"])
if len(fixed_text) > 140:
@@ -103,22 +105,22 @@ class postController(object):
def get_post_information(self):
from_ = self.session.get_user_name(self.post[self.user_identifier])
if self.post.has_key("copy_history"):
if "copy_history" in self.post:
# Translators: {0} will be replaced with an user.
title = _(u"repost from {0}").format(from_,)
title = _("repost from {0}").format(from_,)
else:
if self.post.has_key("from_id") and self.post.has_key("owner_id"):
if "from_id" in self.post and "owner_id" in self.post:
# Translators: {0} will be replaced with the user who is posting, and {1} with the wall owner.
title = _(u"Post from {0} in the {1}'s wall").format(self.session.get_user_name(self.post["from_id"]), self.session.get_user_name(self.post["owner_id"]))
title = _("Post from {0} in the {1}'s wall").format(self.session.get_user_name(self.post["from_id"]), self.session.get_user_name(self.post["owner_id"]))
else:
title = _(u"Post from {0}").format(from_,)
title = _("Post from {0}").format(from_,)
self.dialog.set_title(title)
message = u""
message = ""
message = get_message(self.post)
if self.post.has_key("copy_history"):
nm = u"\n"
if "copy_history" in self.post:
nm = "\n"
for i in self.post["copy_history"]:
nm += u"{0}: {1}\n\n".format(self.session.get_user_name(i["from_id"]), get_message(i))
nm += "{0}: {1}\n\n".format(self.session.get_user_name(i["from_id"]), get_message(i))
self.get_attachments(i)
message += nm
self.dialog.set_post(message)
@@ -127,7 +129,7 @@ class postController(object):
def get_attachments(self, post):
attachments = []
if post.has_key("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":
@@ -135,7 +137,7 @@ class postController(object):
if i["type"] == "photo":
if self.load_images == False: self.load_images = True
self.images.append(i)
attachments.append(utils.add_attachment(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.
@@ -143,9 +145,9 @@ class postController(object):
if len(urls) > 0:
links = []
for i in urls:
links.append({"link": {"title": _(U"Untitled link"), "url": i}, "type": "link"})
links.append({"link": {"title": _("Untitled link"), "url": i}, "type": "link"})
for i in links:
attachments.append(utils.add_attachment(i))
attachments.append(renderers.add_attachment(i))
self.attachments.append(i)
if len(self.attachments) > 0:
self.dialog.attachments.list.Enable(True)
@@ -186,14 +188,14 @@ class postController(object):
url = self.get_photo_url(self.images[index]["photo"], "x")
if url != "":
img = requests.get(url)
image = wx.Image(stream=cStringIO.StringIO(requests.get(url).content))
image = wx.Image(stream=io.StringIO(requests.get(url).content))
try:
self.dialog.image.SetBitmap(wx.Bitmap(image))
except NameError:
return
self.dialog.SetClientSize(self.dialog.sizer.CalcMin())
# Translators: {0} is the number of the current photo and {1} is the total number of photos.
output.speak(_(u"Loaded photo {0} of {1}").format(index+1, len(self.images)))
output.speak(_("Loaded photo {0} of {1}").format(index+1, len(self.images)))
return
def get_photo_url(self, photo, size="x"):
@@ -214,38 +216,38 @@ class postController(object):
if self.post["likes"]["can_like"] == 0 and self.post["likes"]["user_likes"] == 0:
self.dialog.disable("like")
elif self.post["likes"]["user_likes"] == 1:
self.dialog.set("like", _(u"&Dislike"))
self.dialog.set("like", _("&Dislike"))
if self.post["likes"]["can_publish"] == 0:
self.dialog.disable("repost")
def post_like(self, *args, **kwargs):
if self.post.has_key("owner_id") == False:
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 self.post.has_key("type"):
if "type" in self.post:
type_ = self.post["type"]
else:
type_ = "post"
if self.dialog.get("like") == _(u"&Dislike"):
if self.dialog.get("like") == _("&Dislike"):
l = self.session.vk.client.likes.delete(owner_id=user, item_id=id, type=type_)
output.speak(_(u"You don't like this"))
output.speak(_("You don't like this"))
self.post["likes"]["count"] = l["likes"]
self.post["likes"]["user_likes"] = 2
self.get_likes()
self.dialog.set("like", _(u"&Like"))
self.dialog.set("like", _("&Like"))
else:
l = self.session.vk.client.likes.add(owner_id=user, item_id=id, type=type_)
output.speak(_(u"You liked this"))
self.dialog.set("like", _(u"&Dislike"))
output.speak(_("You liked this"))
self.dialog.set("like", _("&Dislike"))
self.post["likes"]["count"] = l["likes"]
self.post["likes"]["user_likes"] = 1
self.get_likes()
def post_repost(self, *args, **kwargs):
object_id = "wall{0}_{1}".format(self.post[self.user_identifier], self.post[self.post_identifier])
p = messages.post(session=self.session, title=_(u"Repost"), caption=_(u"Add your comment here"), text="")
p = messages.post(session=self.session, title=_("Repost"), caption=_("Add your comment here"), text="")
if p.message.get_response() == widgetUtils.OK:
msg = p.message.get_text().encode("utf-8")
self.session.vk.client.wall.repost(object=object_id, message=msg)
@@ -263,14 +265,14 @@ class postController(object):
pass
def add_comment(self, *args, **kwargs):
comment = messages.comment(session=self.session, title=_(u"Add a comment"), caption="", text="")
comment = messages.comment(session=self.session, title=_("Add a comment"), caption="", text="")
if comment.message.get_response() == widgetUtils.OK:
msg = comment.message.get_text().encode("utf-8")
try:
user = self.post[self.user_identifier]
id = self.post[self.post_identifier]
self.session.vk.client.wall.addComment(owner_id=user, post_id=id, text=msg)
output.speak(_(u"You've posted a comment"))
output.speak(_("You've posted a comment"))
if self.comments["count"] < 100:
self.clear_comments_list()
self.get_comments()
@@ -306,12 +308,12 @@ class postController(object):
def comment_like(self, *args, **kwargs):
comment_id = self.comments["data"][self.dialog.comments.get_selected()]["id"]
self.session.like(comment_id)
output.speak(_(u"You do like this comment"))
output.speak(_("You do like this comment"))
def comment_unlike(self, *args, **kwargs):
comment_id = self.comments["data"][self.dialog.comments.get_selected()]["id"]
self.session.unlike(comment_id)
output.speak(_(u"You don't like this comment"))
output.speak(_("You don't like this comment"))
def translate(self, *args, **kwargs):
dlg = translator.gui.translateDialog()
@@ -320,7 +322,7 @@ class postController(object):
dest = [x[0] for x in translator.translator.available_languages()][dlg.get("dest_lang")]
msg = translator.translator.translate(text_to_translate, target=dest)
self.dialog.post_view.ChangeValue(msg)
output.speak(_(u"Translated"))
output.speak(_("Translated"))
else:
return
@@ -338,10 +340,10 @@ class postController(object):
a.dialog.get_response()
a.dialog.Destroy()
if attachment["type"] == "link":
output.speak(_(u"Opening URL..."), True)
output.speak(_("Opening URL..."), True)
webbrowser.open_new_tab(attachment["link"]["url"])
elif attachment["type"] == "doc":
output.speak(_(u"Opening document in web browser..."))
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
@@ -353,15 +355,15 @@ class postController(object):
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(_(u"Opening video in web browser..."), True)
output.speak(_("Opening video in web browser..."), True)
webbrowser.open_new_tab(video_object["player"])
elif attachment["type"] == "photo":
output.speak(_(u"Opening photo in web browser..."), True)
output.speak(_("Opening photo in web browser..."), True)
# Possible photo sizes for looking in the attachment information. Try to use the biggest photo available.
possible_sizes = [1280, 604, 130, 75]
url = ""
for i in possible_sizes:
if attachment["photo"].has_key("photo_{0}".format(i,)):
if "photo_{0}".format(i,) in attachment["photo"]:
url = attachment["photo"]["photo_{0}".format(i,)]
break
if url != "":
@@ -384,7 +386,7 @@ class comment(object):
original_date = arrow.get(self.comment["created_time"], "YYYY-MM-DTHH:m:sZ", locale="en")
created_at = original_date.humanize(locale=languageHandler.getLanguage())
self.dialog.set_post(message)
self.dialog.set_title(_(u"Comment from {0}").format(from_,))
self.dialog.set_title(_("Comment from {0}").format(from_,))
widgetUtils.connect_event(self.dialog.like, widgetUtils.BUTTON_PRESSED, self.post_like)
call_threaded(self.get_likes)
@@ -414,7 +416,7 @@ class audio(postController):
post = self.post[self.dialog.get_audio()]
args = {}
args["audio_id"] = post["id"]
if post.has_key("album_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)
@@ -426,7 +428,7 @@ class audio(postController):
def remove_from_library(self, *args, **kwargs):
post = self.post[self.dialog.get_audio()]
args = {}
if self.added_audios.has_key(post["id"]):
if post["id"] in self.added_audios:
args["audio_id"] = self.added_audios[post["id"]]
args["owner_id"] = self.session.user_id
else:
@@ -436,20 +438,20 @@ class audio(postController):
if int(result) == 1:
self.dialog.change_state("add", True)
self.dialog.change_state("remove", False)
if self.added_audios.has_key(post["id"]):
if post["id"] in self.added_audios:
self.added_audios.pop(post["id"])
def fill_information(self, index):
post = self.post[index]
if post.has_key("artist"):
if "artist" in post:
self.dialog.set("artist", post["artist"])
if post.has_key("title"):
if "title" in post:
self.dialog.set("title", post["title"])
if post.has_key("duration"):
if "duration" in post:
self.dialog.set("duration", utils.seconds_to_string(post["duration"]))
self.dialog.set_title(u"{0} - {1}".format(post["title"], post["artist"]))
self.dialog.set_title("{0} - {1}".format(post["title"], post["artist"]))
call_threaded(self.get_lyrics)
if post["owner_id"] == self.session.user_id or self.added_audios.has_key(post["id"]) == True:
if post["owner_id"] == self.session.user_id or (post["id"] in self.added_audios) == True:
self.dialog.change_state("remove", True)
self.dialog.change_state("add", False)
else:
@@ -458,7 +460,7 @@ class audio(postController):
def get_lyrics(self):
post = self.post[self.dialog.get_audio()]
if post.has_key("lyrics_id"):
if "lyrics_id" in post:
l = self.session.vk.client.audio.getLyrics(lyrics_id=int(post["lyrics_id"]))
self.dialog.set("lyric", l["text"])
else:
@@ -466,7 +468,7 @@ class audio(postController):
def download(self, *args, **kwargs):
post = self.post[self.dialog.get_audio()]
f = u"{0} - {1}.mp3".format(post["title"], post["artist"])
f = "{0} - {1}.mp3".format(post["title"], post["artist"])
path = self.dialog.get_destination_path(f)
if path != None:
pub.sendMessage("download-file", url=post["url"], filename=path)
@@ -477,7 +479,7 @@ class audio(postController):
def load_audios(self):
for i in self.post:
s = u"{0} - {1}. {2}".format(i["title"], i["artist"], utils.seconds_to_string(i["duration"]))
s = "{0} - {1}. {2}".format(i["title"], i["artist"], utils.seconds_to_string(i["duration"]))
self.dialog.insert_audio(s)
self.dialog.list.SetSelection(0)
if len(self.post) == 1:
@@ -496,7 +498,7 @@ class friendship(object):
self.dialog = postDialogs.friendship()
list_of_friends = self.get_friend_names()
from_ = self.session.get_user_name(self.post["source_id"])
title = _(u"{0} added the following friends").format(from_,)
title = _("{0} added the following friends").format(from_,)
self.dialog.set_title(title)
self.set_friends_list(list_of_friends)
@@ -514,7 +516,7 @@ class userProfile(object):
self.person = None
self.session = session
self.user_id = user_id
self.dialog = profiles.userProfile(title=_(u"Profile"))
self.dialog = profiles.userProfile(title=_("Profile"))
self.dialog.create_controls("main_info")
self.dialog.realice()
self.get_basic_information()
@@ -527,81 +529,81 @@ class userProfile(object):
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"
person = self.session.vk.client.users.get(user_ids=self.user_id, fields=fields)
if len(person) == 0:
return output.speak(_(u"Information for groups is not supported, yet."))
return output.speak(_("Information for groups is not supported, yet."))
person = person[0]
print person
print(person)
# Gets full name.
n = u"{0} {1}".format(person["first_name"], person["last_name"])
n = "{0} {1}".format(person["first_name"], person["last_name"])
# Gets birthdate.
if person.has_key("bdate") and person["bdate"] != "":
if "bdate" in person and person["bdate"] != "":
self.dialog.main_info.enable("bdate")
if len(person["bdate"]) <= 5:
d = arrow.get(person["bdate"], "D.m")
self.dialog.main_info.set("bdate", d.format(_(u"MMMM D"), locale=languageHandler.getLanguage()))
self.dialog.main_info.set("bdate", d.format(_("MMMM D"), locale=languageHandler.getLanguage()))
else:
d = arrow.get(person["bdate"], "D.M.YYYY")
self.dialog.main_info.set("bdate", d.format(_(u"MMMM D, YYYY"), locale=languageHandler.getLanguage()))
self.dialog.main_info.set("bdate", d.format(_("MMMM D, YYYY"), locale=languageHandler.getLanguage()))
# Gets current city and home town
city = ""
if person.has_key("home_town") and person["home_town"] != "":
if "home_town" in person and person["home_town"] != "":
home_town = person["home_town"]
self.dialog.main_info.enable("home_town")
self.dialog.main_info.set("home_town", home_town)
if person.has_key("city") and len(person["city"]) > 0:
if "city" in person and len(person["city"]) > 0:
city = person["city"]["title"]
if person.has_key("country") and person["country"] != "":
if "country" in person and person["country"] != "":
if city != "":
city = city+u", {0}".format(person["country"]["title"])
city = city+", {0}".format(person["country"]["title"])
else:
city = person["country"]["title"]
self.dialog.main_info.enable("city")
self.dialog.main_info.set("city", city)
self.dialog.main_info.set("name", n)
self.dialog.SetTitle(_(u"{name}'s profile").format(name=n,))
self.dialog.SetTitle(_("{name}'s profile").format(name=n,))
# Gets website
if person.has_key("site") and person["site"] != "":
if "site" in person and person["site"] != "":
self.dialog.main_info.enable("website")
self.dialog.main_info.set("website", person["site"])
self.dialog.main_info.enable("go_site")
widgetUtils.connect_event(self.dialog.main_info.go_site, widgetUtils.BUTTON_PRESSED, self.visit_website)
if person.has_key("status") and person["status"] != "":
if "status" in person and person["status"] != "":
self.dialog.main_info.enable("status")
self.dialog.main_info.set("status", person["status"])
if person.has_key("occupation") and person["occupation"] != None:
if person["occupation"]["type"] == "work": c1 = _(u"Work ")
elif person["occupation"]["type"] == "school": c1 = _(u"Student ")
elif person["occupation"]["type"] == "university": c1 = _(u"Student ")
if person["occupation"].has_key("name") and person["occupation"]["name"] != "":
c2 = _(u"In {0}").format(person["occupation"]["name"],)
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.dialog.main_info.enable("occupation")
self.dialog.main_info.set("occupation", c1+c2)
if person.has_key("relation") and person["relation"] != 0:
print person["relation"]
if "relation" in person and person["relation"] != 0:
print(person["relation"])
if person["relation"] == 1:
r = _(u"Single")
r = _("Single")
elif person["relation"] == 2:
if person.has_key("relation_partner"):
r = _(u"Dating with {0} {1}").format(person["relation_partner"]["first_name"], person["relation_partner"]["last_name"])
if "relation_partner" in person:
r = _("Dating with {0} {1}").format(person["relation_partner"]["first_name"], person["relation_partner"]["last_name"])
else:
r = _(u"Dating")
r = _("Dating")
elif person["relation"] == 3:
r = _(u"Engaged with {0} {1}").format(person["relation_partner"]["first_name"], person["relation_partner"]["last_name"])
r = _("Engaged with {0} {1}").format(person["relation_partner"]["first_name"], person["relation_partner"]["last_name"])
elif person["relation"] == 4:
r = _(u"Married with {0} {1}").format(person["relation_partner"]["first_name"], person["relation_partner"]["last_name"])
r = _("Married with {0} {1}").format(person["relation_partner"]["first_name"], person["relation_partner"]["last_name"])
elif person["relation"] == 5:
r = _(u"It's complicated")
r = _("It's complicated")
elif person["relation"] == 6:
r = _(u"Actively searching")
r = _("Actively searching")
elif person["relation"] == 7:
r = _(u"In love")
r = _("In love")
self.dialog.main_info.enable("relation")
self.dialog.main_info.relation.SetLabel(_(u"Relationship: ")+r)
if person.has_key("last_seen") and person["last_seen"] != False:
self.dialog.main_info.relation.SetLabel(_("Relationship: ")+r)
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 = _(u"{0}").format(original_date.humanize(locale=languageHandler.getLanguage()),)
last_seen = _("{0}").format(original_date.humanize(locale=languageHandler.getLanguage()),)
self.dialog.main_info.enable("last_seen")
self.dialog.main_info.set("last_seen", last_seen)
log.info("getting info...")
@@ -609,5 +611,5 @@ class userProfile(object):
self.dialog.SetClientSize(self.dialog.sizer.CalcMin())
def visit_website(self, *args, **kwargs):
output.speak(_(u"Opening website..."))
output.speak(_("Opening website..."))
webbrowser.open_new_tab(self.person["site"])

View File

@@ -1,6 +1,9 @@
# -*- coding: utf-8 -*-
""" A profile viewer and editor for VK user objects."""
import cStringIO
from __future__ import unicode_literals
from future import standard_library
standard_library.install_aliases()
import io
import webbrowser
import logging
import arrow
@@ -27,7 +30,7 @@ class userProfile(object):
self.person = None
self.session = session
self.user_id = user_id
self.dialog = profiles.userProfile(title=_(u"Profile"))
self.dialog = profiles.userProfile(title=_("Profile"))
self.dialog.create_controls("main_info")
self.dialog.realice()
self.get_basic_information()
@@ -44,97 +47,97 @@ class userProfile(object):
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(_(u"Information for groups is not supported, yet."))
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 = u"{0} {1}".format(person["first_name"], person["last_name"])
n = "{0} {1}".format(person["first_name"], person["last_name"])
# Format birthdate.
if person.has_key("bdate") and person["bdate"] != "":
if "bdate" in person and person["bdate"] != "":
self.dialog.main_info.enable("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.dialog.main_info.set("bdate", d.format(_(u"MMMM D"), locale=languageHandler.curLang[:2]))
self.dialog.main_info.set("bdate", d.format(_("MMMM D"), locale=languageHandler.curLang[:2]))
else: # mm.dd.yyyy
d = arrow.get(person["bdate"], "D.M.YYYY")
self.dialog.main_info.set("bdate", d.format(_(u"MMMM D, YYYY"), locale=languageHandler.curLang[:2]))
self.dialog.main_info.set("bdate", d.format(_("MMMM D, YYYY"), locale=languageHandler.curLang[:2]))
# Format current city and home town
city = ""
if person.has_key("home_town") and person["home_town"] != "":
if "home_town" in person and person["home_town"] != "":
home_town = person["home_town"]
self.dialog.main_info.enable("home_town")
self.dialog.main_info.set("home_town", home_town)
if person.has_key("city") and len(person["city"]) > 0:
if "city" in person and len(person["city"]) > 0:
city = person["city"]["title"]
if person.has_key("country") and person["country"] != "":
if "country" in person and person["country"] != "":
if city != "":
city = city+u", {0}".format(person["country"]["title"])
city = city+", {0}".format(person["country"]["title"])
else:
city = person["country"]["title"]
self.dialog.main_info.enable("city")
self.dialog.main_info.set("city", city)
self.dialog.main_info.set("name", n)
self.dialog.SetTitle(_(u"{name}'s profile").format(name=n,))
self.dialog.SetTitle(_("{name}'s profile").format(name=n,))
# Format website (or websites, if there are multiple of them).
if person.has_key("site") and person["site"] != "":
if "site" in person and person["site"] != "":
self.dialog.main_info.enable("website")
self.dialog.main_info.set("website", person["site"])
self.dialog.main_info.enable("go_site")
widgetUtils.connect_event(self.dialog.main_info.go_site, widgetUtils.BUTTON_PRESSED, self.visit_website)
# Format status message.
if person.has_key("status") and person["status"] != "":
if "status" in person and person["status"] != "":
self.dialog.main_info.enable("status")
self.dialog.main_info.set("status", person["status"])
# Format occupation.
# toDo: Research in this field is needed. Sometimes it returns university information even if users have active work places.
if person.has_key("occupation") and person["occupation"] != None:
if person["occupation"]["type"] == "work": c1 = _(u"Work ")
elif person["occupation"]["type"] == "school": c1 = _(u"Student ")
elif person["occupation"]["type"] == "university": c1 = _(u"Student ")
if person["occupation"].has_key("name") and person["occupation"]["name"] != "":
c2 = _(u"In {0}").format(person["occupation"]["name"],)
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.dialog.main_info.enable("occupation")
self.dialog.main_info.set("occupation", c1+c2)
# format relationship status.
# ToDo: When dating someone, the button associated to the information should point to the profile of the user.
if person.has_key("relation") and person["relation"] != 0:
if "relation" in person and person["relation"] != 0:
if person["relation"] == 1:
r = _(u"Single")
r = _("Single")
elif person["relation"] == 2:
if person.has_key("relation_partner"):
r = _(u"Dating with {0} {1}").format(person["relation_partner"]["first_name"], person["relation_partner"]["last_name"])
if "relation_partner" in person:
r = _("Dating with {0} {1}").format(person["relation_partner"]["first_name"], person["relation_partner"]["last_name"])
else:
r = _(u"Dating")
r = _("Dating")
elif person["relation"] == 3:
r = _(u"Engaged with {0} {1}").format(person["relation_partner"]["first_name"], person["relation_partner"]["last_name"])
r = _("Engaged with {0} {1}").format(person["relation_partner"]["first_name"], person["relation_partner"]["last_name"])
elif person["relation"] == 4:
r = _(u"Married with {0} {1}").format(person["relation_partner"]["first_name"], person["relation_partner"]["last_name"])
r = _("Married with {0} {1}").format(person["relation_partner"]["first_name"], person["relation_partner"]["last_name"])
elif person["relation"] == 5:
r = _(u"It's complicated")
r = _("It's complicated")
elif person["relation"] == 6:
r = _(u"Actively searching")
r = _("Actively searching")
elif person["relation"] == 7:
r = _(u"In love")
r = _("In love")
self.dialog.main_info.enable("relation")
self.dialog.main_info.relation.SetLabel(_(u"Relationship: ")+r)
self.dialog.main_info.relation.SetLabel(_("Relationship: ")+r)
# format last seen.
if person.has_key("last_seen") and person["last_seen"] != False:
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 = _(u"{0}").format(original_date.humanize(locale=languageHandler.curLang[:2]),)
last_seen = _("{0}").format(original_date.humanize(locale=languageHandler.curLang[:2]),)
self.dialog.main_info.enable("last_seen")
self.dialog.main_info.set("last_seen", last_seen)
self.person = person
# Adds photo to the dialog.
# ToDo: Need to ask if this has a visible effect in the dialog.
if person.has_key("photo_200_orig"):
if "photo_200_orig" in person:
img = requests.get(person["photo_200_orig"])
image = wx.Image(stream=cStringIO.StringIO(requests.get(person["photo_200_orig"]).content))
image = wx.Image(stream=io.StringIO(requests.get(person["photo_200_orig"]).content))
try:
self.dialog.image.SetBitmap(wx.Bitmap(image))
except ValueError:
@@ -147,7 +150,7 @@ class userProfile(object):
# 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(_(u"No URL addresses were detected."))
output.speak(_("No URL addresses were detected."))
return
elif len(urls) == 1:
selected_url = urls[0]
@@ -157,5 +160,5 @@ class userProfile(object):
if dialog.get_response() != widgetUtils.OK:
return
selected_url = urls[dialog.get_item()]
output.speak(_(u"Opening URL..."))
output.speak(_("Opening URL..."))
webbrowser.open_new_tab(selected_url)