Merge branch 'py3' into 'master'

Port socializer to Python 3. #16

See merge request manuelcortez/socializer!2
This commit is contained in:
Manuel Cortez 2019-01-02 04:42:53 +03:00
commit acdfae1608
68 changed files with 967 additions and 1006 deletions

1
.gitignore vendored
View File

@ -1,3 +1,4 @@
*.py.bak
*.pyc *.pyc
*~ *~
src/config/ src/config/

View File

@ -1,14 +1,16 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from __future__ import unicode_literals
name = "Socializer" name = "Socializer"
version = "0.17" version = "0.17"
author = u"Manuel Cortez" author = "Manuel Cortez"
authorEmail = "manuel@manuelcortez.net" authorEmail = "manuel@manuelcortez.net"
copyright = u"Copyright (C) 2016-2018, Manuel Cortez" copyright = "Copyright (C) 2016-2018, Manuel Cortez"
description = unicode(name+" Is an accessible VK client for Windows.") description = name+" Is an accessible VK client for Windows."
url = "https://manuelcortez.net/socializer" url = "https://manuelcortez.net/socializer"
# The short name will be used for detecting translation files. See languageHandler for more details. # The short name will be used for detecting translation files. See languageHandler for more details.
short_name = "socializer" short_name = "socializer"
translators = [u"Darya Ratnikova (Russian)", u"Manuel Cortez (Spanish)"] translators = ["Darya Ratnikova (Russian)", "Manuel Cortez (Spanish)"]
bts_name = "socializer" bts_name = "socializer"
bts_access_token = "U29jaWFsaXplcg" bts_access_token = "U29jaWFsaXplcg"
bts_url = "https://issues.manuelcortez.net" bts_url = "https://issues.manuelcortez.net"

View File

@ -45,7 +45,7 @@ def hist(keys):
def find_problems(hist): def find_problems(hist):
"Takes a histogram and returns a list of items occurring more than once." "Takes a histogram and returns a list of items occurring more than once."
res=[] res=[]
for k,v in hist.items(): for k,v in list(hist.items()):
if v>1: if v>1:
res.append(k) res.append(k)
return res return res

View File

@ -2,10 +2,11 @@
""" Attachment controller for different kind of posts in VK. """ 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. 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 os
import logging import logging
import widgetUtils import widgetUtils
import audioRecorder from . import audioRecorder
from mutagen.id3 import ID3 from mutagen.id3 import ID3
from sessionmanager.utils import seconds_to_string from sessionmanager.utils import seconds_to_string
from wxUI.dialogs import attach as gui from wxUI.dialogs import attach as gui
@ -63,7 +64,7 @@ class attach(object):
imageInfo = {"type": "photo", "file": image, "description": description, "from": "local"} imageInfo = {"type": "photo", "file": image, "description": description, "from": "local"}
self.attachments.append(imageInfo) self.attachments.append(imageInfo)
# Translators: This is the text displayed in the attachments dialog, when the user adds a photo. # Translators: This is the text displayed in the attachments dialog, when the user adds a photo.
info = [_(u"Photo"), description] info = [_("Photo"), description]
self.dialog.attachments.insert_item(False, *info) self.dialog.attachments.insert_item(False, *info)
self.dialog.remove.Enable(True) self.dialog.remove.Enable(True)
@ -77,15 +78,15 @@ class attach(object):
if "TIT2" in audio_tags: if "TIT2" in audio_tags:
title = audio_tags["TIT2"].text[0] title = audio_tags["TIT2"].text[0]
else: else:
title = _(u"Untitled") title = _("Untitled")
if "TPE1" in audio_tags: if "TPE1" in audio_tags:
artist = audio_tags["TPE1"].text[0] artist = audio_tags["TPE1"].text[0]
else: else:
artist = _(u"Unknown artist") artist = _("Unknown artist")
audioInfo = {"type": "audio", "file": audio, "from": "local", "title": title, "artist": artist} audioInfo = {"type": "audio", "file": audio, "from": "local", "title": title, "artist": artist}
self.attachments.append(audioInfo) self.attachments.append(audioInfo)
# Translators: This is the text displayed in the attachments dialog, when the user adds an audio file. # Translators: This is the text displayed in the attachments dialog, when the user adds an audio file.
info = [_(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.attachments.insert_item(False, *info)
self.dialog.remove.Enable(True) self.dialog.remove.Enable(True)
@ -95,7 +96,7 @@ class attach(object):
audioInfo = {"type": "voice_message", "file": a.file, "from": "local"} audioInfo = {"type": "voice_message", "file": a.file, "from": "local"}
self.attachments.append(audioInfo) self.attachments.append(audioInfo)
# Translators: This is the text displayed in the attachments dialog, when the user adds an audio file. # Translators: This is the text displayed in the attachments dialog, when the user adds an audio file.
info = [_(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.attachments.insert_item(False, *info)
self.dialog.remove.Enable(True) self.dialog.remove.Enable(True)
@ -105,8 +106,8 @@ class attach(object):
list_of_audios = self.session.db["me_audio"]["items"] list_of_audios = self.session.db["me_audio"]["items"]
audios = [] audios = []
for i in list_of_audios: for i in list_of_audios:
audios.append(u"{0}, {1}".format(i["title"], i["artist"])) audios.append("{0}, {1}".format(i["title"], i["artist"]))
select = selector.selectAttachment(_(u"Select the audio files you want to send"), audios) select = selector.selectAttachment(_("Select the audio files you want to send"), audios)
if select.get_response() == widgetUtils.OK and select.attachments.GetCount() > 0: if select.get_response() == widgetUtils.OK and select.attachments.GetCount() > 0:
attachments = select.get_all_attachments() attachments = select.get_all_attachments()
for i in attachments: for i in attachments:
@ -114,7 +115,7 @@ class attach(object):
info["from"] = "online" info["from"] = "online"
self.attachments.append(info) self.attachments.append(info)
# Translators: This is the text displayed in the attachments dialog, when the user adds an audio file. # Translators: This is the text displayed in the attachments dialog, when the user adds an audio file.
info2 = [_(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.dialog.attachments.insert_item(False, *info2)
self.check_remove_status() self.check_remove_status()

View File

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

View File

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

View File

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

View File

@ -1,19 +1,21 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from __future__ import unicode_literals
from builtins import range
import time import time
import os import os
import wx import wx
import widgetUtils import widgetUtils
import messages from . import messages
import buffers from . import buffers
import configuration from . import configuration
import player from . import player
import posts from . import posts
import profiles from . import profiles
import webbrowser import webbrowser
import logging import logging
import output import output
import longpollthread from . import longpollthread
import selector from . import selector
from vk_api.exceptions import LoginRequired, VkApiError from vk_api.exceptions import LoginRequired, VkApiError
from requests.exceptions import ConnectionError from requests.exceptions import ConnectionError
from pubsub import pub from pubsub import pub
@ -32,7 +34,7 @@ log = logging.getLogger("controller.main")
class Controller(object): class Controller(object):
def search(self, tab_name): 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: if self.buffers[i].name == tab_name:
return self.buffers[i] return self.buffers[i]
return False return False
@ -51,8 +53,8 @@ class Controller(object):
player.setup() player.setup()
self.window = mainWindow.mainWindow() self.window = mainWindow.mainWindow()
log.debug("Main window created") log.debug("Main window created")
self.window.change_status(_(u"Ready")) self.window.change_status(_("Ready"))
self.session = session.sessions[session.sessions.keys()[0]] self.session = session.sessions[list(session.sessions.keys())[0]]
self.create_controls() self.create_controls()
self.window.Show() self.window.Show()
self.connect_events() self.connect_events()
@ -63,11 +65,11 @@ class Controller(object):
posts_ = buffers.empty(parent=self.window.tb, name="posts") posts_ = buffers.empty(parent=self.window.tb, name="posts")
self.buffers.append(posts_) self.buffers.append(posts_)
# Translators: Name for the posts tab in the tree view. # 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"]) 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) self.buffers.append(home)
# Translators: Newsfeed's name in the tree view. # 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 = RepeatingTimer(120, self.update_all_buffers)
self.repeatedUpdate.start() self.repeatedUpdate.start()
self.readMarker = RepeatingTimer(60, self.mark_as_read) 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"]) 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) self.buffers.append(feed)
# Translators: Own user's wall name in the tree view. # 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") audios = buffers.empty(parent=self.window.tb, name="audios")
self.buffers.append(audios) self.buffers.append(audios)
# Translators: name for the music category in the tree view. # 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") 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.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: 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"]) 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.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"]) 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.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") albums = buffers.empty(parent=self.window.tb, name="albums")
self.buffers.append(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") videos = buffers.empty(parent=self.window.tb, name="videos")
self.buffers.append(videos) self.buffers.append(videos)
# Translators: name for the videos category in the tree view. # 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"]) 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.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") video_albums = buffers.empty(parent=self.window.tb, name="video_albums")
self.buffers.append(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") people = buffers.empty(parent=self.window.tb, name="people")
self.buffers.append(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") 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.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") requests_ = buffers.empty(parent=self.window.tb, name="requests")
self.buffers.append(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) 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.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) 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.buffers.append(outgoing_requests)
self.window.insert_buffer(outgoing_requests.tab, _(u"I follow"), self.window.search("requests")) self.window.insert_buffer(outgoing_requests.tab, _("I follow"), self.window.search("requests"))
# communities= buffers.empty(parent=self.window.tb, name="communities") communities= buffers.empty(parent=self.window.tb, name="communities")
# self.buffers.append(communities) self.buffers.append(communities)
# Translators: name for the videos category in the tree view. # 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") chats = buffers.empty(parent=self.window.tb, name="chats")
self.buffers.append(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") timelines = buffers.empty(parent=self.window.tb, name="timelines")
self.buffers.append(timelines) self.buffers.append(timelines)
self.window.add_buffer(timelines.tab, _(u"Timelines")) self.window.add_buffer(timelines.tab, _("Timelines"))
self.window.realize() self.window.realize()
def connect_events(self): def connect_events(self):
@ -193,15 +195,15 @@ class Controller(object):
commonMessages.bad_authorisation() commonMessages.bad_authorisation()
def login(self): def login(self):
self.window.change_status(_(u"Logging in VK")) self.window.change_status(_("Logging in VK"))
self.session.login() self.session.login()
self.window.change_status(_(u"Ready")) self.window.change_status(_("Ready"))
for i in self.buffers: for i in self.buffers:
if hasattr(i, "get_items"): if hasattr(i, "get_items"):
# Translators: {0} will be replaced with the name of a buffer. # 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() i.get_items()
self.window.change_status(_(u"Ready")) self.window.change_status(_("Ready"))
self.create_longpoll_thread() self.create_longpoll_thread()
self.status_setter = RepeatingTimer(280, self.set_online) self.status_setter = RepeatingTimer(280, self.set_online)
self.status_setter.start() self.status_setter.start()
@ -216,7 +218,7 @@ class Controller(object):
self.longpoll = longpollthread.worker(self.session) self.longpoll = longpollthread.worker(self.session)
self.longpoll.start() self.longpoll.start()
if notify: if notify:
self.notify(message=_(u"Chat server reconnected")) self.notify(message=_("Chat server reconnected"))
except ConnectionError: except ConnectionError:
pub.sendMessage("longpoll-read-timeout") pub.sendMessage("longpoll-read-timeout")
@ -233,17 +235,17 @@ class Controller(object):
for i in self.buffers: for i in self.buffers:
if hasattr(i, "get_items"): if hasattr(i, "get_items"):
i.get_items() i.get_items()
log.debug(u"Updated %s" % (i.name)) log.debug("Updated %s" % (i.name))
def download(self, url, filename): 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) call_threaded(utils.download_file, url, filename, self.window)
def play_audio(self, audio_object): def play_audio(self, audio_object):
# Restricted audios does not include an URL paramether. # Restricted audios does not include an URL paramether.
# Restriction can be due to licensed content to unauthorized countries. # Restriction can be due to licensed content to unauthorized countries.
if "url" in audio_object and audio_object["url"] =="": 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 return
call_threaded(player.player.play, audio_object) call_threaded(player.player.play, audio_object)
@ -279,11 +281,11 @@ class Controller(object):
dlg = searchDialogs.searchAudioDialog() dlg = searchDialogs.searchAudioDialog()
if dlg.get_response() == widgetUtils.OK: if dlg.get_response() == widgetUtils.OK:
q = dlg.get("term").encode("utf-8") 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) self.buffers.append(newbuff)
call_threaded(newbuff.get_items) call_threaded(newbuff.get_items)
# Translators: {0} will be replaced with the search term. # 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): def search_videos(self, *args, **kwargs):
dlg = searchDialogs.searchVideoDialog() dlg = searchDialogs.searchVideoDialog()
@ -297,11 +299,11 @@ class Controller(object):
params["adult"] = dlg.get_checkable("safe_search") params["adult"] = dlg.get_checkable("safe_search")
params["sort"] = dlg.get_sort_order() params["sort"] = dlg.get_sort_order()
params["filters"] = "youtube, vimeo, short, long" 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) self.buffers.append(newbuff)
call_threaded(newbuff.get_items) call_threaded(newbuff.get_items)
# Translators: {0} will be replaced with the search term. # 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): def update_status_bar(self, status):
self.window.change_status(status) self.window.change_status(status)
@ -350,15 +352,15 @@ class Controller(object):
if buffertype == "audio": 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) 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. # 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": 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) 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. # 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": 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) 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. # 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) self.buffers.append(buffer)
call_threaded(self.complete_buffer_creation, buffer=buffer, name_=name_, position=self.window.search("timelines")) 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): def search_chat_buffer(self, user_id):
for i in self.buffers: for i in self.buffers:
if "_messages" in i.name: 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 return None
def chat_from_id(self, user_id, setfocus=True, unread=False): 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") 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) self.buffers.append(buffer)
# Translators: {0} will be replaced with an user. # 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: if setfocus:
pos = self.window.search(buffer.name) pos = self.window.search(buffer.name)
self.window.change_buffer(pos) self.window.change_buffer(pos)
@ -400,7 +402,7 @@ class Controller(object):
if self.session.settings["chat"]["notify_online"] == False: if self.session.settings["chat"]["notify_online"] == False:
return return
user_name = self.session.get_user_name(event.user_id, "nom") 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" sound = "friend_online.ogg"
self.notify(msg, sound, self.session.settings["chat"]["notifications"]) self.notify(msg, sound, self.session.settings["chat"]["notifications"])
@ -408,7 +410,7 @@ class Controller(object):
if self.session.settings["chat"]["notify_offline"] == False: if self.session.settings["chat"]["notify_offline"] == False:
return return
user_name = self.session.get_user_name(event.user_id, "nom") 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" sound = "friend_offline.ogg"
self.notify(msg, sound, self.session.settings["chat"]["notifications"]) 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 = 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 buffer.can_get_items = False
# Translators: {0} Will be replaced with an audio album's title. # 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.buffers.append(buffer)
self.window.insert_buffer(buffer.tab, name_, self.window.search("albums")) self.window.insert_buffer(buffer.tab, name_, self.window.search("albums"))
# buffer.get_items() # 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 = 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 buffer.can_get_items = False
# Translators: {0} Will be replaced with a video album's title. # 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.buffers.append(buffer)
self.window.insert_buffer(buffer.tab, name_, self.window.search("video_albums")) self.window.insert_buffer(buffer.tab, name_, self.window.search("video_albums"))
# buffer.get_items() # buffer.get_items()
@ -529,14 +531,14 @@ class Controller(object):
def get_communities(self, user_id=None, create_buffers=True): def get_communities(self, user_id=None, create_buffers=True):
log.debug("Create community buffers...") 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") 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"] self.session.groups=groups["items"]
# Let's feed the local database cache with new groups coming from here. # Let's feed the local database cache with new groups coming from here.
data= dict(profiles=[], groups=groups["items"]) data= dict(profiles=[], groups=groups["items"])
self.session.process_usernames(data) self.session.process_usernames(data)
if create_buffers: if create_buffers:
for i in groups["items"]: 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 = 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 buffer.can_get_items = False
# Translators: {0} Will be replaced with a video album's title. # Translators: {0} Will be replaced with a video album's title.
@ -551,19 +553,19 @@ class Controller(object):
d = creation.audio_album() d = creation.audio_album()
if d.get_response() == widgetUtils.OK and d.get("title") != "": if d.get_response() == widgetUtils.OK and d.get("title") != "":
response = self.session.vk.client.audio.addAlbum(title=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"] 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 = 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 buffer.can_get_items = False
# Translators: {0} will be replaced with an audio album's title. # 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.buffers.append(buffer)
self.window.insert_buffer(buffer.tab, name_, self.window.search("albums")) self.window.insert_buffer(buffer.tab, name_, self.window.search("albums"))
buffer.get_items() buffer.get_items()
self.session.audio_albums = self.session.vk.client.audio.getAlbums(owner_id=self.session.user_id)["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): 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: if answer.item == None:
return return
response = commonMessages.delete_audio_album() response = commonMessages.delete_audio_album()
@ -580,19 +582,19 @@ class Controller(object):
d = creation.audio_album() d = creation.audio_album()
if d.get_response() == widgetUtils.OK and d.get("title") != "": if d.get_response() == widgetUtils.OK and d.get("title") != "":
response = self.session.vk.client.video.addAlbum(title=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"] 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 = 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 buffer.can_get_items = False
# Translators: {0} will be replaced with a video album's title. # 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.buffers.append(buffer)
self.window.insert_buffer(buffer.tab, name_, self.window.search("video_albums")) self.window.insert_buffer(buffer.tab, name_, self.window.search("video_albums"))
buffer.get_items() buffer.get_items()
self.session.video_albums = self.session.vk.client.video.getAlbums(owner_id=self.session.user_id)["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): 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: if answer.item == None:
return return
response = commonMessages.delete_audio_album() response = commonMessages.delete_audio_album()
@ -674,14 +676,14 @@ class Controller(object):
def handle_longpoll_read_timeout(self): def handle_longpoll_read_timeout(self):
if hasattr(self, "longpoll"): 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) time.sleep(60)
if hasattr(self, "longpoll"): if hasattr(self, "longpoll"):
del self.longpoll del self.longpoll
self.create_longpoll_thread(notify=True) self.create_longpoll_thread(notify=True)
def set_status(self, *args, **kwargs): 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: if dlg.ShowModal() == widgetUtils.OK:
result = dlg.GetValue() result = dlg.GetValue()
info = self.session.vk.client.account.saveProfileInfo(status=result) info = self.session.vk.client.account.saveProfileInfo(status=result)

View File

@ -1,9 +1,10 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from __future__ import unicode_literals
import time import time
import widgetUtils import widgetUtils
import output import output
from pubsub import pub from pubsub import pub
import attach from . import attach
from wxUI.dialogs import message, selector from wxUI.dialogs import message, selector
from extra import SpellChecker, translator from extra import SpellChecker, translator
from logging import getLogger from logging import getLogger
@ -26,9 +27,9 @@ class post(object):
def get_privacy_options(self): def get_privacy_options(self):
p = self.message.get("privacy") p = self.message.get("privacy")
if p == _(u"Friends of friends"): if p == _("Friends of friends"):
privacy = 0 privacy = 0
elif p == _(u"All users"): elif p == _("All users"):
privacy = 1 privacy = 1
return privacy return privacy
@ -42,14 +43,14 @@ class post(object):
return self.mention(*args, **kwargs) return self.mention(*args, **kwargs)
users = [] users = []
for i in friends["items"]: 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) select = selector.selectPeople(users)
if select.get_response() == widgetUtils.OK and select.users.GetCount() > 0: if select.get_response() == widgetUtils.OK and select.users.GetCount() > 0:
self.tagged_people = [] self.tagged_people = []
tagged_users = select.get_all_users() tagged_users = select.get_all_users()
for i in tagged_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.tagged_people.append("[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.message.text.SetValue(self.message.text.GetValue()+ ", ".join(self.tagged_people))
def translate(self, *args, **kwargs): def translate(self, *args, **kwargs):
dlg = translator.gui.translateDialog() dlg = translator.gui.translateDialog()
@ -59,7 +60,7 @@ class post(object):
msg = translator.translator.translate(text_to_translate, dest) msg = translator.translator.translate(text_to_translate, dest)
self.message.set_text(msg) self.message.set_text(msg)
self.message.text_focus() self.message.text_focus()
output.speak(_(u"Translated")) output.speak(_("Translated"))
dlg.Destroy() dlg.Destroy()
def spellcheck(self, event=None): def spellcheck(self, event=None):
@ -77,4 +78,4 @@ class post(object):
class comment(post): class comment(post):
def __init__(self, session, title, caption, text): def __init__(self, session, title, caption, text):
super(comment, self).__init__(session, title, caption, text, "comment") 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 -*- # -*- coding: utf-8 -*-
from __future__ import unicode_literals
import random import random
import output import output
import sound_lib import sound_lib
@ -43,13 +44,13 @@ class audioPlayer(object):
if self.is_working == False: if self.is_working == False:
self.is_working = True self.is_working = True
try: try:
self.stream = URLStream(url=url["url"]) self.stream = URLStream(url=bytes(url["url"], "utf-8"))
except BassError: except BassError:
log.debug("Error when playing the file %r") % (url,) log.debug("Error when playing the file %r") % (url,)
return return
# Translators: {0} will be replaced with a song's title and {1} with the artist. # Translators: {0} will be replaced with a song's title and {1} with the artist.
if set_info: if set_info:
msg = _(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) pub.sendMessage("update-status-bar", status=msg)
self.stream.volume = self.vol/100.0 self.stream.volume = self.vol/100.0
self.stream.play() self.stream.play()

View File

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

View File

@ -1,6 +1,9 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
""" A profile viewer and editor for VK user objects.""" """ 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 webbrowser
import logging import logging
import arrow import arrow
@ -27,7 +30,7 @@ class userProfile(object):
self.person = None self.person = None
self.session = session self.session = session
self.user_id = user_id 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.create_controls("main_info")
self.dialog.realice() self.dialog.realice()
self.get_basic_information() 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) person = self.session.vk.client.users.get(user_ids=self.user_id, fields=fields)
# If VK does not return anything it is very likely we have found a community. # If VK does not return anything it is very likely we have found a community.
if len(person) == 0: if len(person) == 0:
return output.speak(_(u"Information for groups is not supported, yet.")) return output.speak(_("Information for groups is not supported, yet."))
person = person[0] person = person[0]
# toDo: remove this print when I will be done with creation of profile viewer logic. # toDo: remove this print when I will be done with creation of profile viewer logic.
print(person) print(person)
# From this part we will format data from VK so users will see it in the GUI control. # From this part we will format data from VK so users will see it in the GUI control.
# Format full name. # Format full name.
n = u"{0} {1}".format(person["first_name"], person["last_name"]) n = "{0} {1}".format(person["first_name"], person["last_name"])
# Format birthdate. # Format birthdate.
if person.has_key("bdate") and person["bdate"] != "": if "bdate" in person and person["bdate"] != "":
self.dialog.main_info.enable("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. # VK can display dd.mm or dd.mm.yyyy birthdates. So let's compare the string lenght to handle both cases accordingly.
if len(person["bdate"]) <= 5: # dd.mm if len(person["bdate"]) <= 5: # dd.mm
d = arrow.get(person["bdate"], "D.M") d = arrow.get(person["bdate"], "D.M")
self.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 else: # mm.dd.yyyy
d = arrow.get(person["bdate"], "D.M.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 # Format current city and home town
city = "" 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"] home_town = person["home_town"]
self.dialog.main_info.enable("home_town") self.dialog.main_info.enable("home_town")
self.dialog.main_info.set("home_town", 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"] city = person["city"]["title"]
if person.has_key("country") and person["country"] != "": if "country" in person and person["country"] != "":
if city != "": if city != "":
city = city+u", {0}".format(person["country"]["title"]) city = city+", {0}".format(person["country"]["title"])
else: else:
city = person["country"]["title"] city = person["country"]["title"]
self.dialog.main_info.enable("city") self.dialog.main_info.enable("city")
self.dialog.main_info.set("city", city) self.dialog.main_info.set("city", city)
self.dialog.main_info.set("name", n) 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). # 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.enable("website")
self.dialog.main_info.set("website", person["site"]) self.dialog.main_info.set("website", person["site"])
self.dialog.main_info.enable("go_site") self.dialog.main_info.enable("go_site")
widgetUtils.connect_event(self.dialog.main_info.go_site, widgetUtils.BUTTON_PRESSED, self.visit_website) widgetUtils.connect_event(self.dialog.main_info.go_site, widgetUtils.BUTTON_PRESSED, self.visit_website)
# Format status message. # 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.enable("status")
self.dialog.main_info.set("status", person["status"]) self.dialog.main_info.set("status", person["status"])
# Format occupation. # Format occupation.
# toDo: Research in this field is needed. Sometimes it returns university information even if users have active work places. # toDo: Research in this field is needed. Sometimes it returns university information even if users have active work places.
if person.has_key("occupation") and person["occupation"] != None: if "occupation" in person and person["occupation"] != None:
if person["occupation"]["type"] == "work": c1 = _(u"Work ") if person["occupation"]["type"] == "work": c1 = _("Work ")
elif person["occupation"]["type"] == "school": c1 = _(u"Student ") elif person["occupation"]["type"] == "school": c1 = _("Student ")
elif person["occupation"]["type"] == "university": c1 = _(u"Student ") elif person["occupation"]["type"] == "university": c1 = _("Student ")
if person["occupation"].has_key("name") and person["occupation"]["name"] != "": if "name" in person["occupation"] and person["occupation"]["name"] != "":
c2 = _(u"In {0}").format(person["occupation"]["name"],) c2 = _("In {0}").format(person["occupation"]["name"],)
else: else:
c2 = "" c2 = ""
self.dialog.main_info.enable("occupation") self.dialog.main_info.enable("occupation")
self.dialog.main_info.set("occupation", c1+c2) self.dialog.main_info.set("occupation", c1+c2)
# format relationship status. # format relationship status.
# ToDo: When dating someone, the button associated to the information should point to the profile of the user. # ToDo: When dating someone, the button associated to the information should point to the profile of the user.
if person.has_key("relation") and person["relation"] != 0: if "relation" in person and person["relation"] != 0:
if person["relation"] == 1: if person["relation"] == 1:
r = _(u"Single") r = _("Single")
elif person["relation"] == 2: elif person["relation"] == 2:
if person.has_key("relation_partner"): if "relation_partner" in person:
r = _(u"Dating with {0} {1}").format(person["relation_partner"]["first_name"], person["relation_partner"]["last_name"]) r = _("Dating with {0} {1}").format(person["relation_partner"]["first_name"], person["relation_partner"]["last_name"])
else: else:
r = _(u"Dating") r = _("Dating")
elif person["relation"] == 3: 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: 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: elif person["relation"] == 5:
r = _(u"It's complicated") r = _("It's complicated")
elif person["relation"] == 6: elif person["relation"] == 6:
r = _(u"Actively searching") r = _("Actively searching")
elif person["relation"] == 7: elif person["relation"] == 7:
r = _(u"In love") r = _("In love")
self.dialog.main_info.enable("relation") 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. # 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"]) original_date = arrow.get(person["last_seen"]["time"])
# Translators: This is the date of last seen # Translators: This is the date of last seen
last_seen = _(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.enable("last_seen")
self.dialog.main_info.set("last_seen", last_seen) self.dialog.main_info.set("last_seen", last_seen)
self.person = person self.person = person
# Adds photo to the dialog. # Adds photo to the dialog.
# ToDo: Need to ask if this has a visible effect in the dialog. # ToDo: Need to ask if this has a visible effect in the dialog.
if person.has_key("photo_200_orig"): if "photo_200_orig" in person:
img = requests.get(person["photo_200_orig"]) 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: try:
self.dialog.image.SetBitmap(wx.Bitmap(image)) self.dialog.image.SetBitmap(wx.Bitmap(image))
except ValueError: 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. # Let's search for URLS with a regexp, as there are users with multiple websites in their profiles.
urls = utils.find_urls_in_text(text) urls = utils.find_urls_in_text(text)
if len(urls) == 0: if len(urls) == 0:
output.speak(_(u"No URL addresses were detected.")) output.speak(_("No URL addresses were detected."))
return return
elif len(urls) == 1: elif len(urls) == 1:
selected_url = urls[0] selected_url = urls[0]
@ -157,5 +160,5 @@ class userProfile(object):
if dialog.get_response() != widgetUtils.OK: if dialog.get_response() != widgetUtils.OK:
return return
selected_url = urls[dialog.get_item()] selected_url = urls[dialog.get_item()]
output.speak(_(u"Opening URL...")) output.speak(_("Opening URL..."))
webbrowser.open_new_tab(selected_url) webbrowser.open_new_tab(selected_url)

View File

@ -1,4 +1,4 @@
import spellchecker from . import spellchecker
import platform import platform
if platform.system() == "Windows": if platform.system() == "Windows":
from wx_ui import * from .wx_ui import *

View File

@ -1,6 +1,6 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from __future__ import unicode_literals
import logging import logging
import wx_ui
import widgetUtils import widgetUtils
import output import output
import config import config
@ -8,6 +8,7 @@ import languageHandler
from enchant.checker import SpellChecker from enchant.checker import SpellChecker
from enchant.errors import DictNotFoundError from enchant.errors import DictNotFoundError
from enchant import tokenize from enchant import tokenize
from . import wx_ui
log = logging.getLogger("extra.SpellChecker.spellChecker") log = logging.getLogger("extra.SpellChecker.spellChecker")
@ -25,7 +26,7 @@ class spellChecker(object):
self.checker = SpellChecker(languageHandler.curLang, filters=[tokenize.EmailFilter, tokenize.URLFilter]) self.checker = SpellChecker(languageHandler.curLang, filters=[tokenize.EmailFilter, tokenize.URLFilter])
self.checker.set_text(text) self.checker.set_text(text)
except DictNotFoundError: except DictNotFoundError:
print "no dict" print("no dict")
log.exception("Dictionary for language %s not found." % (dictionary,)) log.exception("Dictionary for language %s not found." % (dictionary,))
wx_ui.dict_not_found_error() wx_ui.dict_not_found_error()
self.active = False self.active = False
@ -42,9 +43,9 @@ class spellChecker(object):
def check(self): def check(self):
try: try:
self.checker.next() next(self.checker)
textToSay = _(u"Misspelled word: %s") % (self.checker.word,) textToSay = _("Misspelled word: %s") % (self.checker.word,)
context = u"... %s %s %s" % (self.checker.leading_context(10), self.checker.word, self.checker.trailing_context(10)) context = "... %s %s %s" % (self.checker.leading_context(10), self.checker.word, self.checker.trailing_context(10))
self.dialog.set_title(textToSay) self.dialog.set_title(textToSay)
output.speak(textToSay) output.speak(textToSay)
self.dialog.set_word_and_suggestions(word=self.checker.word, context=context, suggestions=self.checker.suggest()) self.dialog.set_word_and_suggestions(word=self.checker.word, context=context, suggestions=self.checker.suggest())

View File

@ -16,6 +16,7 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
# #
############################################################ ############################################################
from __future__ import unicode_literals
import wx import wx
import application import application
@ -24,25 +25,25 @@ class spellCheckerDialog(wx.Dialog):
super(spellCheckerDialog, self).__init__(None, 1) super(spellCheckerDialog, self).__init__(None, 1)
panel = wx.Panel(self) panel = wx.Panel(self)
sizer = wx.BoxSizer(wx.VERTICAL) sizer = wx.BoxSizer(wx.VERTICAL)
word = wx.StaticText(panel, -1, _(u"&Misspelled word")) word = wx.StaticText(panel, -1, _("&Misspelled word"))
self.word = wx.TextCtrl(panel, -1) self.word = wx.TextCtrl(panel, -1)
wordBox = wx.BoxSizer(wx.HORIZONTAL) wordBox = wx.BoxSizer(wx.HORIZONTAL)
wordBox.Add(word, 0, wx.ALL, 5) wordBox.Add(word, 0, wx.ALL, 5)
wordBox.Add(self.word, 0, wx.ALL, 5) wordBox.Add(self.word, 0, wx.ALL, 5)
context = wx.StaticText(panel, -1, _(u"Con&text")) context = wx.StaticText(panel, -1, _("Con&text"))
self.context = wx.TextCtrl(panel, -1) self.context = wx.TextCtrl(panel, -1)
contextBox = wx.BoxSizer(wx.HORIZONTAL) contextBox = wx.BoxSizer(wx.HORIZONTAL)
contextBox.Add(context, 0, wx.ALL, 5) contextBox.Add(context, 0, wx.ALL, 5)
contextBox.Add(self.context, 0, wx.ALL, 5) contextBox.Add(self.context, 0, wx.ALL, 5)
suggest = wx.StaticText(panel, -1, _(u"&Suggestions")) suggest = wx.StaticText(panel, -1, _("&Suggestions"))
self.suggestions = wx.ListBox(panel, -1, choices=[], style=wx.LB_SINGLE) self.suggestions = wx.ListBox(panel, -1, choices=[], style=wx.LB_SINGLE)
suggestionsBox = wx.BoxSizer(wx.HORIZONTAL) suggestionsBox = wx.BoxSizer(wx.HORIZONTAL)
suggestionsBox.Add(suggest, 0, wx.ALL, 5) suggestionsBox.Add(suggest, 0, wx.ALL, 5)
suggestionsBox.Add(self.suggestions, 0, wx.ALL, 5) suggestionsBox.Add(self.suggestions, 0, wx.ALL, 5)
self.ignore = wx.Button(panel, -1, _(u"&Ignore")) self.ignore = wx.Button(panel, -1, _("&Ignore"))
self.ignoreAll = wx.Button(panel, -1, _(u"Ignore &all")) self.ignoreAll = wx.Button(panel, -1, _("Ignore &all"))
self.replace = wx.Button(panel, -1, _(u"&Replace")) self.replace = wx.Button(panel, -1, _("&Replace"))
self.replaceAll = wx.Button(panel, -1, _(u"Replace a&ll")) self.replaceAll = wx.Button(panel, -1, _("Replace a&ll"))
close = wx.Button(panel, wx.ID_CANCEL) close = wx.Button(panel, wx.ID_CANCEL)
btnBox = wx.BoxSizer(wx.HORIZONTAL) btnBox = wx.BoxSizer(wx.HORIZONTAL)
btnBox.Add(self.ignore, 0, wx.ALL, 5) btnBox.Add(self.ignore, 0, wx.ALL, 5)
@ -73,7 +74,7 @@ class spellCheckerDialog(wx.Dialog):
return self.suggestions.GetStringSelection() return self.suggestions.GetStringSelection()
def dict_not_found_error(): def dict_not_found_error():
wx.MessageDialog(None, _(u"An error has occurred. There are no dictionaries available for the selected language in {0}").format(application.name,), _(u"Error"), wx.ICON_ERROR).ShowModal() wx.MessageDialog(None, _("An error has occurred. There are no dictionaries available for the selected language in {0}").format(application.name,), _("Error"), wx.ICON_ERROR).ShowModal()
def finished(): def finished():
wx.MessageDialog(None, _(u"Spell check complete."), application.name, style=wx.OK).ShowModal() wx.MessageDialog(None, _("Spell check complete."), application.name, style=wx.OK).ShowModal()

View File

@ -1,6 +1,6 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import translator
import platform import platform
from . import translator
if platform.system() == "Windows": if platform.system() == "Windows":
import wx_ui as gui from . import wx_ui as gui

View File

@ -1,4 +1,6 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from __future__ import unicode_literals
from builtins import zip
from yandex_translate import YandexTranslate from yandex_translate import YandexTranslate
def translate(text="", target="en"): def translate(text="", target="en"):
@ -9,97 +11,97 @@ def translate(text="", target="en"):
supported_langs = None supported_langs = None
d = None d = None
languages = { languages = {
"af": _(u"Afrikaans"), "af": _("Afrikaans"),
"sq": _(u"Albanian"), "sq": _("Albanian"),
"am": _(u"Amharic"), "am": _("Amharic"),
"ar": _(u"Arabic"), "ar": _("Arabic"),
"hy": _(u"Armenian"), "hy": _("Armenian"),
"az": _(u"Azerbaijani"), "az": _("Azerbaijani"),
"eu": _(u"Basque"), "eu": _("Basque"),
"be": _(u"Belarusian"), "be": _("Belarusian"),
"bn": _(u"Bengali"), "bn": _("Bengali"),
"bh": _(u"Bihari"), "bh": _("Bihari"),
"bg": _(u"Bulgarian"), "bg": _("Bulgarian"),
"my": _(u"Burmese"), "my": _("Burmese"),
"ca": _(u"Catalan"), "ca": _("Catalan"),
"chr": _(u"Cherokee"), "chr": _("Cherokee"),
"zh": _(u"Chinese"), "zh": _("Chinese"),
"zh-CN": _(u"Chinese_simplified"), "zh-CN": _("Chinese_simplified"),
"zh-TW": _(u"Chinese_traditional"), "zh-TW": _("Chinese_traditional"),
"hr": _(u"Croatian"), "hr": _("Croatian"),
"cs": _(u"Czech"), "cs": _("Czech"),
"da": _(u"Danish"), "da": _("Danish"),
"dv": _(u"Dhivehi"), "dv": _("Dhivehi"),
"nl": _(u"Dutch"), "nl": _("Dutch"),
"en": _(u"English"), "en": _("English"),
"eo": _(u"Esperanto"), "eo": _("Esperanto"),
"et": _(u"Estonian"), "et": _("Estonian"),
"tl": _(u"Filipino"), "tl": _("Filipino"),
"fi": _(u"Finnish"), "fi": _("Finnish"),
"fr": _(u"French"), "fr": _("French"),
"gl": _(u"Galician"), "gl": _("Galician"),
"ka": _(u"Georgian"), "ka": _("Georgian"),
"de": _(u"German"), "de": _("German"),
"el": _(u"Greek"), "el": _("Greek"),
"gn": _(u"Guarani"), "gn": _("Guarani"),
"gu": _(u"Gujarati"), "gu": _("Gujarati"),
"iw": _(u"Hebrew"), "iw": _("Hebrew"),
"hi": _(u"Hindi"), "hi": _("Hindi"),
"hu": _(u"Hungarian"), "hu": _("Hungarian"),
"is": _(u"Icelandic"), "is": _("Icelandic"),
"id": _(u"Indonesian"), "id": _("Indonesian"),
"iu": _(u"Inuktitut"), "iu": _("Inuktitut"),
"ga": _(u"Irish"), "ga": _("Irish"),
"it": _(u"Italian"), "it": _("Italian"),
"ja": _(u"Japanese"), "ja": _("Japanese"),
"kn": _(u"Kannada"), "kn": _("Kannada"),
"kk": _(u"Kazakh"), "kk": _("Kazakh"),
"km": _(u"Khmer"), "km": _("Khmer"),
"ko": _(u"Korean"), "ko": _("Korean"),
"ku": _(u"Kurdish"), "ku": _("Kurdish"),
"ky": _(u"Kyrgyz"), "ky": _("Kyrgyz"),
"lo": _(u"Laothian"), "lo": _("Laothian"),
"lv": _(u"Latvian"), "lv": _("Latvian"),
"lt": _(u"Lithuanian"), "lt": _("Lithuanian"),
"mk": _(u"Macedonian"), "mk": _("Macedonian"),
"ms": _(u"Malay"), "ms": _("Malay"),
"ml": _(u"Malayalam"), "ml": _("Malayalam"),
"mt": _(u"Maltese"), "mt": _("Maltese"),
"mr": _(u"Marathi"), "mr": _("Marathi"),
"mn": _(u"Mongolian"), "mn": _("Mongolian"),
"ne": _(u"Nepali"), "ne": _("Nepali"),
"no": _(u"Norwegian"), "no": _("Norwegian"),
"or": _(u"Oriya"), "or": _("Oriya"),
"ps": _(u"Pashto"), "ps": _("Pashto"),
"fa": _(u"Persian"), "fa": _("Persian"),
"pl": _(u"Polish"), "pl": _("Polish"),
"pt": _(u"Portuguese"), "pt": _("Portuguese"),
"pa": _(u"Punjabi"), "pa": _("Punjabi"),
"ro": _(u"Romanian"), "ro": _("Romanian"),
"ru": _(u"Russian"), "ru": _("Russian"),
"sa": _(u"Sanskrit"), "sa": _("Sanskrit"),
"sr": _(u"Serbian"), "sr": _("Serbian"),
"sd": _(u"Sindhi"), "sd": _("Sindhi"),
"si": _(u"Sinhalese"), "si": _("Sinhalese"),
"sk": _(u"Slovak"), "sk": _("Slovak"),
"sl": _(u"Slovenian"), "sl": _("Slovenian"),
"es": _(u"Spanish"), "es": _("Spanish"),
"sw": _(u"Swahili"), "sw": _("Swahili"),
"sv": _(u"Swedish"), "sv": _("Swedish"),
"tg": _(u"Tajik"), "tg": _("Tajik"),
"ta": _(u"Tamil"), "ta": _("Tamil"),
"tl": _(u"Tagalog"), "tl": _("Tagalog"),
"te": _(u"Telugu"), "te": _("Telugu"),
"th": _(u"Thai"), "th": _("Thai"),
"bo": _(u"Tibetan"), "bo": _("Tibetan"),
"tr": _(u"Turkish"), "tr": _("Turkish"),
"uk": _(u"Ukrainian"), "uk": _("Ukrainian"),
"ur": _(u"Urdu"), "ur": _("Urdu"),
"uz": _(u"Uzbek"), "uz": _("Uzbek"),
"ug": _(u"Uighur"), "ug": _("Uighur"),
"vi": _(u"Vietnamese"), "vi": _("Vietnamese"),
"cy": _(u"Welsh"), "cy": _("Welsh"),
"yi": _(u"Yiddish") "yi": _("Yiddish")
} }
def available_languages(): def available_languages():

View File

@ -16,15 +16,16 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
# #
############################################################ ############################################################
import translator from __future__ import unicode_literals
import wx import wx
from . import translator
class translateDialog(wx.Dialog): class translateDialog(wx.Dialog):
def __init__(self): def __init__(self):
super(translateDialog, self).__init__(None, -1, title=_(u"Translate message")) super(translateDialog, self).__init__(None, -1, title=_("Translate message"))
panel = wx.Panel(self) panel = wx.Panel(self)
sizer = wx.BoxSizer(wx.VERTICAL) sizer = wx.BoxSizer(wx.VERTICAL)
staticDest = wx.StaticText(panel, -1, _(u"Target language")) staticDest = wx.StaticText(panel, -1, _("Target language"))
self.dest_lang = wx.ComboBox(panel, -1, choices=[x[1] for x in translator.available_languages()], style = wx.CB_READONLY) self.dest_lang = wx.ComboBox(panel, -1, choices=[x[1] for x in translator.available_languages()], style = wx.CB_READONLY)
self.dest_lang.SetFocus() self.dest_lang.SetFocus()
self.dest_lang.SetSelection(0) self.dest_lang.SetSelection(0)

View File

@ -1,4 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from __future__ import unicode_literals
import sys import sys
from . import fix_requests from . import fix_requests

View File

@ -1,4 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from __future__ import unicode_literals
import requests import requests
import paths import paths
import os import os
@ -7,5 +8,5 @@ log = logging.getLogger("fixes.fix_requests")
def fix(): def fix():
log.debug("Applying fix for requests...") log.debug("Applying fix for requests...")
os.environ["REQUESTS_CA_BUNDLE"] = os.path.join(paths.app_path().decode(paths.fsencoding), "cacert.pem").encode(paths.fsencoding) os.environ["REQUESTS_CA_BUNDLE"] = os.path.join(paths.app_path(), "cacert.pem")#.encode(paths.fsencoding)
log.debug("Changed CA path to %s" % (os.environ["REQUESTS_CA_BUNDLE"].decode(paths.fsencoding))) # log.debug("Changed CA path to %s" % (os.environ["REQUESTS_CA_BUNDLE"]))#.decode(paths.fsencoding)))

View File

@ -1,3 +1,4 @@
from __future__ import unicode_literals
import win32com.client import win32com.client
def fix(): def fix():
if win32com.client.gencache.is_readonly == True: if win32com.client.gencache.is_readonly == True:

View File

@ -16,6 +16,7 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
# #
############################################################ ############################################################
from __future__ import unicode_literals
import wx import wx
import platform import platform
import requests import requests
@ -51,7 +52,7 @@ class reportBug(object):
issue_type = "issue" # for now just have issue issue_type = "issue" # for now just have issue
app_type = paths.mode app_type = paths.mode
app_version = application.version app_version = application.version
reporter_name = u"{first_name} {last_name}".format(first_name=self.dialog.get("first_name"), last_name=self.dialog.get("last_name")) reporter_name = "{first_name} {last_name}".format(first_name=self.dialog.get("first_name"), last_name=self.dialog.get("last_name"))
reporter_contact_type = "email" # For now just email is supported in the issue reporter reporter_contact_type = "email" # For now just email is supported in the issue reporter
reporter_contact_handle = self.dialog.get("email") reporter_contact_handle = self.dialog.get("email")
operating_system = platform.platform() operating_system = platform.platform()

View File

@ -16,6 +16,7 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
# #
############################################################ ############################################################
from __future__ import unicode_literals
import wx import wx
import widgetUtils import widgetUtils
import application import application
@ -23,11 +24,11 @@ import application
class reportBugDialog(widgetUtils.BaseDialog): class reportBugDialog(widgetUtils.BaseDialog):
def __init__(self): def __init__(self):
super(reportBugDialog, self).__init__(parent=None, id=wx.NewId()) super(reportBugDialog, self).__init__(parent=None, id=wx.NewId())
self.SetTitle(_(u"Report an error")) self.SetTitle(_("Report an error"))
panel = wx.Panel(self) panel = wx.Panel(self)
sizer = wx.BoxSizer(wx.VERTICAL) sizer = wx.BoxSizer(wx.VERTICAL)
summaryLabel = wx.StaticText(panel, -1, _(u"Briefly describe what happened. You will be able to thoroughly explain it later"), size=wx.DefaultSize) summaryLabel = wx.StaticText(panel, -1, _("Briefly describe what happened. You will be able to thoroughly explain it later"), size=wx.DefaultSize)
self.summary = wx.TextCtrl(panel, -1) self.summary = wx.TextCtrl(panel, -1)
dc = wx.WindowDC(self.summary) dc = wx.WindowDC(self.summary)
dc.SetFont(self.summary.GetFont()) dc.SetFont(self.summary.GetFont())
@ -37,7 +38,7 @@ class reportBugDialog(widgetUtils.BaseDialog):
summaryB.Add(self.summary, 0, wx.ALL, 5) summaryB.Add(self.summary, 0, wx.ALL, 5)
sizer.Add(summaryB, 0, wx.ALL, 5) sizer.Add(summaryB, 0, wx.ALL, 5)
first_nameLabel = wx.StaticText(panel, -1, _(u"First Name"), size=wx.DefaultSize) first_nameLabel = wx.StaticText(panel, -1, _("First Name"), size=wx.DefaultSize)
self.first_name = wx.TextCtrl(panel, -1) self.first_name = wx.TextCtrl(panel, -1)
dc = wx.WindowDC(self.first_name) dc = wx.WindowDC(self.first_name)
dc.SetFont(self.first_name.GetFont()) dc.SetFont(self.first_name.GetFont())
@ -47,7 +48,7 @@ class reportBugDialog(widgetUtils.BaseDialog):
first_nameB.Add(self.first_name, 0, wx.ALL, 5) first_nameB.Add(self.first_name, 0, wx.ALL, 5)
sizer.Add(first_nameB, 0, wx.ALL, 5) sizer.Add(first_nameB, 0, wx.ALL, 5)
last_nameLabel = wx.StaticText(panel, -1, _(u"Last Name"), size=wx.DefaultSize) last_nameLabel = wx.StaticText(panel, -1, _("Last Name"), size=wx.DefaultSize)
self.last_name = wx.TextCtrl(panel, -1) self.last_name = wx.TextCtrl(panel, -1)
dc = wx.WindowDC(self.last_name) dc = wx.WindowDC(self.last_name)
dc.SetFont(self.last_name.GetFont()) dc.SetFont(self.last_name.GetFont())
@ -57,7 +58,7 @@ class reportBugDialog(widgetUtils.BaseDialog):
last_nameB.Add(self.last_name, 0, wx.ALL, 5) last_nameB.Add(self.last_name, 0, wx.ALL, 5)
sizer.Add(last_nameB, 0, wx.ALL, 5) sizer.Add(last_nameB, 0, wx.ALL, 5)
emailLabel = wx.StaticText(panel, -1, _(u"Email address (Will not be public)"), size=wx.DefaultSize) emailLabel = wx.StaticText(panel, -1, _("Email address (Will not be public)"), size=wx.DefaultSize)
self.email = wx.TextCtrl(panel, -1) self.email = wx.TextCtrl(panel, -1)
dc = wx.WindowDC(self.email) dc = wx.WindowDC(self.email)
dc.SetFont(self.email.GetFont()) dc.SetFont(self.email.GetFont())
@ -67,7 +68,7 @@ class reportBugDialog(widgetUtils.BaseDialog):
emailB.Add(self.email, 0, wx.ALL, 5) emailB.Add(self.email, 0, wx.ALL, 5)
sizer.Add(emailB, 0, wx.ALL, 5) sizer.Add(emailB, 0, wx.ALL, 5)
descriptionLabel = wx.StaticText(panel, -1, _(u"Here, you can describe the bug in detail"), size=wx.DefaultSize) descriptionLabel = wx.StaticText(panel, -1, _("Here, you can describe the bug in detail"), size=wx.DefaultSize)
self.description = wx.TextCtrl(panel, -1, style=wx.TE_MULTILINE) self.description = wx.TextCtrl(panel, -1, style=wx.TE_MULTILINE)
dc = wx.WindowDC(self.description) dc = wx.WindowDC(self.description)
dc.SetFont(self.description.GetFont()) dc.SetFont(self.description.GetFont())
@ -77,12 +78,12 @@ class reportBugDialog(widgetUtils.BaseDialog):
descBox.Add(descriptionLabel, 0, wx.ALL, 5) descBox.Add(descriptionLabel, 0, wx.ALL, 5)
descBox.Add(self.description, 0, wx.ALL, 5) descBox.Add(self.description, 0, wx.ALL, 5)
sizer.Add(descBox, 0, wx.ALL, 5) sizer.Add(descBox, 0, wx.ALL, 5)
self.agree = wx.CheckBox(panel, -1, _(u"I know that the {0} bug system will get my email address to contact me and fix the bug quickly").format(application.name,)) self.agree = wx.CheckBox(panel, -1, _("I know that the {0} bug system will get my email address to contact me and fix the bug quickly").format(application.name,))
self.agree.SetValue(False) self.agree.SetValue(False)
sizer.Add(self.agree, 0, wx.ALL, 5) sizer.Add(self.agree, 0, wx.ALL, 5)
self.ok = wx.Button(panel, wx.ID_OK, _(u"Send report")) self.ok = wx.Button(panel, wx.ID_OK, _("Send report"))
self.ok.SetDefault() self.ok.SetDefault()
cancel = wx.Button(panel, wx.ID_CANCEL, _(u"Cancel")) cancel = wx.Button(panel, wx.ID_CANCEL, _("Cancel"))
btnBox = wx.BoxSizer(wx.HORIZONTAL) btnBox = wx.BoxSizer(wx.HORIZONTAL)
btnBox.Add(self.ok, 0, wx.ALL, 5) btnBox.Add(self.ok, 0, wx.ALL, 5)
btnBox.Add(cancel, 0, wx.ALL, 5) btnBox.Add(cancel, 0, wx.ALL, 5)
@ -91,19 +92,19 @@ class reportBugDialog(widgetUtils.BaseDialog):
self.SetClientSize(sizer.CalcMin()) self.SetClientSize(sizer.CalcMin())
def no_filled(self): def no_filled(self):
wx.MessageDialog(self, _(u"You must fill out the following fields: first name, last name, email address and issue information."), _(u"Error"), wx.OK|wx.ICON_ERROR).ShowModal() wx.MessageDialog(self, _("You must fill out the following fields: first name, last name, email address and issue information."), _("Error"), wx.OK|wx.ICON_ERROR).ShowModal()
def no_checkbox(self): def no_checkbox(self):
wx.MessageDialog(self, _(u"You need to mark the checkbox to provide us your email address to contact you if it is necessary."), _(u"Error"), wx.ICON_ERROR).ShowModal() wx.MessageDialog(self, _("You need to mark the checkbox to provide us your email address to contact you if it is necessary."), _("Error"), wx.ICON_ERROR).ShowModal()
def success(self, id): def success(self, id):
wx.MessageDialog(self, _(u"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), _(u"reported"), wx.OK).ShowModal() wx.MessageDialog(self, _("Thanks for reporting this bug! In future versions, you may be able to find it in the changes list. You have received an email with more information regarding your report. You've reported the bug number %i") % (id), _("reported"), wx.OK).ShowModal()
self.Destroy() self.Destroy()
def error(self): def error(self):
wx.MessageDialog(self, _(u"Something unexpected occurred while trying to report the bug. Please, try again later"), _(u"Error while reporting"), wx.ICON_ERROR|wx.OK).ShowModal() wx.MessageDialog(self, _("Something unexpected occurred while trying to report the bug. Please, try again later"), _("Error while reporting"), wx.ICON_ERROR|wx.OK).ShowModal()
self.Destroy() self.Destroy()
def show_progress(self): def show_progress(self):
self.progress = wx.ProgressDialog(title=_(u"Sending report..."), message=_(u"Please wait while your report is being send."), maximum=100, parent=self) self.progress = wx.ProgressDialog(title=_("Sending report..."), message=_("Please wait while your report is being send."), maximum=100, parent=self)
self.progress.ShowModal() self.progress.ShowModal()

View File

@ -1,4 +1,9 @@
import __builtin__ from __future__ import unicode_literals
from future import standard_library
standard_library.install_aliases()
from builtins import zip
from builtins import str
import builtins
import os import os
import sys import sys
import ctypes import ctypes
@ -25,12 +30,12 @@ def localeNameToWindowsLCID(localeName):
func_LocaleNameToLCID=getattr(ctypes.windll.kernel32,'LocaleNameToLCID',None) func_LocaleNameToLCID=getattr(ctypes.windll.kernel32,'LocaleNameToLCID',None)
if func_LocaleNameToLCID is not None: if func_LocaleNameToLCID is not None:
localeName=localeName.replace('_','-') localeName=localeName.replace('_','-')
LCID=func_LocaleNameToLCID(unicode(localeName),0) LCID=func_LocaleNameToLCID(str(localeName),0)
else: #Windows doesn't have this functionality, manually search Python's windows_locale dictionary for the LCID else: #Windows doesn't have this functionality, manually search Python's windows_locale dictionary for the LCID
localeName=locale.normalize(localeName) localeName=locale.normalize(localeName)
if '.' in localeName: if '.' in localeName:
localeName=localeName.split('.')[0] localeName=localeName.split('.')[0]
LCList=[x[0] for x in locale.windows_locale.iteritems() if x[1]==localeName] LCList=[x[0] for x in locale.windows_locale.items() if x[1]==localeName]
if len(LCList)>0: if len(LCList)>0:
LCID=LCList[0] LCID=LCList[0]
else: else:
@ -93,7 +98,7 @@ def getAvailableLanguages():
# Translators: the label for the Windows default NVDA interface language. # Translators: the label for the Windows default NVDA interface language.
d.append(_("User default")) d.append(_("User default"))
#return a zipped up version of both the lists (a list with tuples of locale,label) #return a zipped up version of both the lists (a list with tuples of locale,label)
return zip(l,d) return list(zip(l,d))
def makePgettext(translations): def makePgettext(translations):
"""Obtaina pgettext function for use with a gettext translations instance. """Obtaina pgettext function for use with a gettext translations instance.
@ -103,15 +108,15 @@ def makePgettext(translations):
""" """
if isinstance(translations, gettext.GNUTranslations): if isinstance(translations, gettext.GNUTranslations):
def pgettext(context, message): def pgettext(context, message):
message = unicode(message) message = str(message)
try: try:
# Look up the message with its context. # Look up the message with its context.
return translations._catalog[u"%s\x04%s" % (context, message)] return translations._catalog["%s\x04%s" % (context, message)]
except KeyError: except KeyError:
return message return message
else: else:
def pgettext(context, message): def pgettext(context, message):
return unicode(message) return str(message)
return pgettext return pgettext
def setLanguage(lang): def setLanguage(lang):
@ -161,7 +166,10 @@ def setLanguage(lang):
except IOError: except IOError:
trans=gettext.translation(application.short_name, fallback=True) trans=gettext.translation(application.short_name, fallback=True)
curLang="en" curLang="en"
trans.install(unicode=True) if sys.version[0] == "3":
trans.install()
else:
trans.install(unicode=True)
# Install our pgettext function. # Install our pgettext function.
# __builtin__.__dict__["pgettext"] = makePgettext(trans) # __builtin__.__dict__["pgettext"] = makePgettext(trans)

View File

@ -1,5 +1,4 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from __future__ import unicode_literals
import os import os
import logging import logging
from logging.handlers import RotatingFileHandler from logging.handlers import RotatingFileHandler
@ -8,10 +7,10 @@ import sys
APP_LOG_FILE = 'debug.log' APP_LOG_FILE = 'debug.log'
ERROR_LOG_FILE = "error.log" ERROR_LOG_FILE = "error.log"
MESSAGE_FORMAT = u"%(asctime)s %(name)s %(levelname)s: %(message)s" MESSAGE_FORMAT = "%(asctime)s %(name)s %(levelname)s: %(message)s"
DATE_FORMAT = u"%d/%m/%Y %H:%M:%S" DATE_FORMAT = "%d/%m/%Y %H:%M:%S"
formatter = logging.Formatter(MESSAGE_FORMAT.decode("utf-8"), datefmt=DATE_FORMAT) formatter = logging.Formatter(MESSAGE_FORMAT, datefmt=DATE_FORMAT)
requests_log = logging.getLogger("requests") requests_log = logging.getLogger("requests")
requests_log.setLevel(logging.WARNING) requests_log.setLevel(logging.WARNING)
@ -21,12 +20,12 @@ logger.setLevel(logging.DEBUG)
#handlers #handlers
app_handler = RotatingFileHandler(os.path.join(paths.logs_path(), APP_LOG_FILE), mode="w") app_handler = RotatingFileHandler(os.path.join(paths.logs_path(), APP_LOG_FILE), mode="w", encoding="utf-8")
app_handler.setFormatter(formatter) app_handler.setFormatter(formatter)
app_handler.setLevel(logging.DEBUG) app_handler.setLevel(logging.DEBUG)
logger.addHandler(app_handler) logger.addHandler(app_handler)
error_handler = logging.FileHandler(os.path.join(paths.logs_path(), ERROR_LOG_FILE), mode="w") error_handler = logging.FileHandler(os.path.join(paths.logs_path(), ERROR_LOG_FILE), mode="w", encoding="utf-8")
error_handler.setFormatter(formatter) error_handler.setFormatter(formatter)
error_handler.setLevel(logging.ERROR) error_handler.setLevel(logging.ERROR)
logger.addHandler(error_handler) logger.addHandler(error_handler)

View File

@ -21,7 +21,7 @@ def setup():
log.debug("Starting Socializer %s" % (application.version,)) log.debug("Starting Socializer %s" % (application.version,))
config.setup() config.setup()
log.debug("Using %s %s" % (platform.system(), platform.architecture()[0])) log.debug("Using %s %s" % (platform.system(), platform.architecture()[0]))
log.debug("Application path is %s" % (paths.app_path().decode(paths.fsencoding),)) log.debug("Application path is %s" % (paths.app_path(),))
log.debug("config path is %s" % (paths.config_path(),)) log.debug("config path is %s" % (paths.config_path(),))
output.setup() output.setup()
languageHandler.setLanguage(config.app["app-settings"]["language"]) languageHandler.setLanguage(config.app["app-settings"]["language"])

39
src/main.spec Normal file
View File

@ -0,0 +1,39 @@
# -*- mode: python -*-
block_cipher = None
a = Analysis(['main.py'],
pathex=['.'],
binaries=[("sounds", "sounds"),
("locales", "locales"),
("oggenc2.exe", "."),
("bootstrap.exe", "."),
("app-configuration.defaults", "."),
("session.defaults", "."),
("cacert.pem", "."),
],
datas=[],
hiddenimports=[],
hookspath=[],
runtime_hooks=[],
excludes=[],
win_no_prefer_redirects=False,
win_private_assemblies=False,
cipher=block_cipher)
pyz = PYZ(a.pure, a.zipped_data,
cipher=block_cipher)
exe = EXE(pyz,
a.scripts,
exclude_binaries=True,
name='socializer',
debug=False,
strip=False,
upx=True,
console=False )
coll = COLLECT(exe,
a.binaries,
a.zipfiles,
a.datas,
strip=False,
upx=True,
name='main')

View File

@ -1,3 +1,4 @@
from __future__ import unicode_literals
import os import os
import languageHandler import languageHandler
import logging import logging

View File

@ -1,152 +0,0 @@
# encoding: utf-8
import requests
class LongPoll(object):
def __init__(self, vk, wait=25, use_ssl=True, mode=34):
self.vk = vk
self.wait = wait
self.use_ssl = use_ssl
self.mode = mode
self.get_longpoll_server()
self.url = 'https' if use_ssl else 'http'
self.url += '://' + self.server
def get_longpoll_server(self, update_ts=True):
values = {
'use_ssl': '1' if self.use_ssl else '0',
'need_pts': '1'
}
response = self.vk.messages.getLongPollServer(**values)
self.key = response['key']
self.server = response['server']
if update_ts:
self.ts = response['ts']
self.pts = response['pts']
def check(self):
values = {
'act': 'a_check',
'key': self.key,
'ts': self.ts,
'wait': self.wait,
'mode': self.mode
}
response = requests.get(self.url, params=values,
timeout=self.wait + 10).json()
events = []
if 'failed' not in response:
self.ts = response['ts']
self.pts = response['pts']
for raw_event in response['updates']:
events.append(Event(raw_event))
# http://vk.com/dev/using_longpoll
else:
self.get_longpoll_server(update_ts=False)
return events
CHAT_START_ID = int(2E9)
EVENT_TYPES = {
0: 'message_delete',
1: 'message_flags_replace',
2: 'message_flags_put',
3: 'message_flags_reset',
4: 'message_new',
8: 'user_online',
9: 'user_offline',
51: 'chat_new',
61: 'user_typing',
62: 'user_typing_in_chat',
70: 'user_call',
}
ASSOCIATIVES = {
0: ['message_id'],
1: ['message_id', 'flags'],
2: ['message_id', 'mask', 'user_id'],
3: ['message_id', 'mask', 'user_id', 'timestamp', 'subject',
'text', 'attachments'],
4: ['message_id', 'flags', 'from_id', 'timestamp', 'subject',
'text', 'attachments'],
8: ['user_id', 'flags'],
9: ['user_id', 'flags'],
51: ['chat_id', 'byself'],
61: ['user_id', 'flags'],
62: ['user_id', 'chat_id'],
70: ['user_id', 'call_id'],
}
MESSAGE_FLAGS = [
'unread', 'outbox', 'replied', 'important', 'chat', 'friends', 'spam',
'deleted', 'fixed', 'media'
]
class Event(object):
def __init__(self, raw):
self.raw = raw
self.message_id = None
self.flags = None
self.mask = None
self.user_id = None
self.from_id = None
self.timestamp = None
self.subject = None
self.text = None
self.attachments = None
self.call_id = None
self.chat_id = None
self.byself = None
cmd = raw[0]
self.message_flags = {}
self.type = EVENT_TYPES.get(cmd)
self._list_to_attr(raw[1:], ASSOCIATIVES.get(cmd))
if cmd == 4:
self._parse_message_flags()
self.text = self.text.replace('<br>', '\n')
if self.from_id > CHAT_START_ID:
self.chat_id = self.from_id - CHAT_START_ID
self.from_id = self.attachments['from']
elif cmd in [2, 3]:
if self.user_id > CHAT_START_ID:
self.chat_id = self.user_id - CHAT_START_ID
self.user_id = None
elif cmd in [8, 9]:
self.user_id = abs(self.user_id)
def _parse_message_flags(self):
x = 1
for i in MESSAGE_FLAGS:
if self.flags & x:
self.message_flags.update({i: True})
x *= 2
def _list_to_attr(self, l, associative):
if not associative:
return
for i in range(len(l)):
try:
name = associative[i]
except IndexError:
return True
value = l[i]
self.__setattr__(name, value)

View File

@ -1,3 +1,4 @@
from __future__ import unicode_literals
import threading import threading
import logging import logging
log = logging.getLogger("mysc.repeating_timer") log = logging.getLogger("mysc.repeating_timer")

View File

@ -1,4 +1,5 @@
# -*- coding: cp1252 # -*- coding: cp1252
from __future__ import unicode_literals
import sys, os import sys, os
def restart_program(): def restart_program():

View File

@ -1,4 +1,7 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from __future__ import unicode_literals
from future import standard_library
standard_library.install_aliases()
import threading import threading
def call_threaded(func, *args, **kwargs): def call_threaded(func, *args, **kwargs):

View File

@ -3,7 +3,6 @@ from __future__ import unicode_literals
import sys import sys
import platform import platform
import os import os
import sys
#import logging #import logging
from platform_utils import paths as paths_ from platform_utils import paths as paths_
@ -21,10 +20,10 @@ def app_path():
def config_path(): def config_path():
global mode, directory global mode, directory
if mode == "portable": if mode == "portable":
if directory != None: path = os.path.join(directory.decode(fsencoding), "config") if directory != None: path = os.path.join(directory, "config")
elif directory == None: path = os.path.join(app_path().decode(fsencoding), "config") elif directory == None: path = os.path.join(app_path(), "config")
elif mode == "installed": elif mode == "installed":
path = os.path.join(data_path().decode(fsencoding), "config") path = os.path.join(data_path(), "config")
if not os.path.exists(path): if not os.path.exists(path):
# log.debug("%s path does not exist, creating..." % (path,)) # log.debug("%s path does not exist, creating..." % (path,))
os.mkdir(path) os.mkdir(path)
@ -33,10 +32,10 @@ def config_path():
def logs_path(): def logs_path():
global mode, directory global mode, directory
if mode == "portable": if mode == "portable":
if directory != None: path = os.path.join(directory.decode(fsencoding), "logs") if directory != None: path = os.path.join(directory, "logs")
elif directory == None: path = os.path.join(app_path().decode(fsencoding), "logs") elif directory == None: path = os.path.join(app_path(), "logs")
elif mode == "installed": elif mode == "installed":
path = os.path.join(data_path().decode(fsencoding), "logs") path = os.path.join(data_path(), "logs")
if not os.path.exists(path): if not os.path.exists(path):
# log.debug("%s path does not exist, creating..." % (path,)) # log.debug("%s path does not exist, creating..." % (path,))
os.mkdir(path) os.mkdir(path)
@ -52,18 +51,18 @@ def data_path(app_name='socializer'):
return data_path return data_path
def locale_path(): def locale_path():
return os.path.join(app_path().decode(fsencoding), "locales") return os.path.join(app_path(), "locales")
def sound_path(): def sound_path():
return os.path.join(app_path().decode(fsencoding), "sounds") return os.path.join(app_path(), "sounds")
def com_path(): def com_path():
global mode, directory global mode, directory
if mode == "portable": if mode == "portable":
if directory != None: path = os.path.join(directory.decode(fsencoding), "com_cache") if directory != None: path = os.path.join(directory, "com_cache")
elif directory == None: path = os.path.join(app_path().decode(fsencoding), "com_cache") elif directory == None: path = os.path.join(app_path(), "com_cache")
elif mode == "installed": elif mode == "installed":
path = os.path.join(data_path().decode(fsencoding), "com_cache") path = os.path.join(data_path(), "com_cache")
if not os.path.exists(path): if not os.path.exists(path):
# log.debug("%s path does not exist, creating..." % (path,)) # log.debug("%s path does not exist, creating..." % (path,))
os.mkdir(path) os.mkdir(path)

View File

@ -1,6 +1,6 @@
import os import os
import ssl import ssl
import utils from . import utils
try: try:
context = ssl.create_default_context() context = ssl.create_default_context()

View File

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from UserDict import UserDict from collections import UserDict
from configobj import ConfigObj, ParseError from configobj import ConfigObj, ParseError
from validate import Validator, VdtValueError from validate import Validator, VdtValueError
import os import os

View File

@ -1,9 +1,11 @@
import _sslfixer from builtins import range
import webbrowser import webbrowser
import random import random
import requests import requests
import string import string
from wxUI import two_factor_auth from . import _sslfixer
from .wxUI import two_factor_auth
class AuthenticationError(Exception): class AuthenticationError(Exception):
pass pass

View File

@ -1,10 +1,12 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
""" this module contains everything used to render different kind of posts (posts in the home buffer, """ this module contains everything used to render different kind of posts (posts in the home buffer,
Chat messages, audios, videos, photos, comments in posts, etc)""" Chat messages, audios, videos, photos, comments in posts, etc)"""
from __future__ import unicode_literals
from builtins import range
import arrow import arrow
import languageHandler import languageHandler
import logging import logging
import utils from . utils import seconds_to_string
log = logging.getLogger(__file__) log = logging.getLogger(__file__)
@ -15,29 +17,29 @@ def extract_attachment(attachment):
This will produce a result like: This will produce a result like:
'website: http://url.com'. 'website: http://url.com'.
'photo: A forest'.""" 'photo: A forest'."""
msg = u"" msg = ""
if attachment["type"] == "link": if attachment["type"] == "link":
msg = u"{0}: {1}".format(attachment["link"]["title"], attachment["link"]["url"]) msg = "{0}: {1}".format(attachment["link"]["title"], attachment["link"]["url"])
elif attachment["type"] == "photo": elif attachment["type"] == "photo":
msg = attachment["photo"]["text"] msg = attachment["photo"]["text"]
if msg == "": if msg == "":
return _(u"photo with no description available") return _("photo with no description available")
elif attachment["type"] == "video": elif attachment["type"] == "video":
msg = _(u"video: {0}").format(attachment["video"]["title"],) msg = _("video: {0}").format(attachment["video"]["title"],)
return msg return msg
def short_text(status): def short_text(status):
""" This shorts the text to 140 characters for displaying it in the list control of buffers.""" """ This shorts the text to 140 characters for displaying it in the list control of buffers."""
message = "" message = ""
# copy_story indicates that the post is a shared repost. # copy_story indicates that the post is a shared repost.
if status.has_key("copy_history"): if "copy_history" in status:
txt = status["copy_history"][0]["text"] txt = status["copy_history"][0]["text"]
else: else:
txt = status["text"] txt = status["text"]
if len(txt) < 140: if len(txt) < 140:
message = utils.clean_text(txt) message = clean_text(txt)
else: else:
message = utils.clean_text(txt[:139]) message = clean_text(txt[:139])
return message return message
def clean_audio(audio): def clean_audio(audio):
@ -48,20 +50,53 @@ def clean_audio(audio):
audio["count"] = audio["count"] -1 audio["count"] = audio["count"] -1
return audio return audio
def clean_text(text):
""" Replaces all HTML entities and put the plain text equivalent if it's possible."""
text = text.replace("<br>", "\n")
text = text.replace("\\n", "\n")
return text
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")
else:
print(attachment)
return [tpe, msg]
### Render functions ### Render functions
def render_person(status, session): def render_person(status, session):
""" Render users in people buffers such as everything related to friendships or buffers created with only people. """ Render users in people buffers such as everything related to friendships or buffers created with only people.
Example result: ["John Doe", "An hour ago"] Example result: ["John Doe", "An hour ago"]
Reference: https://vk.com/dev/fields""" Reference: https://vk.com/dev/fields"""
if status.has_key("last_seen"): if "last_seen" in status:
original_date = arrow.get(status["last_seen"]["time"]) original_date = arrow.get(status["last_seen"]["time"])
# Translators: This is the date of last seen # 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]),)
# Account suspended or deleted. # Account suspended or deleted.
elif status.has_key("last_seen") == False and status.has_key("deactivated"): elif ("last_seen" in status) == False and "deactivated" in status:
last_seen = _(u"Account deactivated") last_seen = _("Account deactivated")
return [u"{0} {1}".format(status["first_name"], status["last_name"]), last_seen] return ["{0} {1}".format(status["first_name"], status["last_name"]), last_seen]
def render_newsfeed_item(status, session): def render_newsfeed_item(status, session):
""" This me☻thod is used to render an item of the news feed. """ This me☻thod is used to render an item of the news feed.
@ -72,15 +107,15 @@ def render_newsfeed_item(status, session):
""" """
user = session.get_user_name(status["source_id"], case_name="nom") user = session.get_user_name(status["source_id"], case_name="nom")
# See if this is a post or repost. # See if this is a post or repost.
if status.has_key("copy_history"): if "copy_history" in status:
user = _(u"{0} has shared the {1}'s post").format(user, session.get_user_name(status["copy_history"][0]["owner_id"])) user = _("{0} has shared the {1}'s post").format(user, session.get_user_name(status["copy_history"][0]["owner_id"]))
message = "" message = ""
original_date = arrow.get(status["date"]) original_date = arrow.get(status["date"])
created_at = original_date.humanize(locale=languageHandler.curLang[:2]) created_at = original_date.humanize(locale=languageHandler.curLang[:2])
# handle status updates. # handle status updates.
if status["type"] == "post": if status["type"] == "post":
message += short_text(status) message += short_text(status)
if status.has_key("attachment") and len(status["attachment"]) > 0: if "attachment" in status and len(status["attachment"]) > 0:
message += extract_attachment(status["attachment"]) message += extract_attachment(status["attachment"])
# If there is no message after adding text, it's because a pphoto with no description has been found. # If there is no message after adding text, it's because a pphoto with no description has been found.
# so let's manually add the "no description" tag here. # so let's manually add the "no description" tag here.
@ -91,43 +126,43 @@ def render_newsfeed_item(status, session):
# removes deleted audios. # removes deleted audios.
status["audio"] = clean_audio(status["audio"]) status["audio"] = clean_audio(status["audio"])
if status["audio"]["count"] == 1: if status["audio"]["count"] == 1:
message = _(u"{0} has added an audio: {1}").format(user, u", ".join(render_audio(status["audio"]["items"][0], session)),) message = _("{0} has added an audio: {1}").format(user, ", ".join(render_audio(status["audio"]["items"][0], session)),)
else: else:
prem = "" prem = ""
for i in xrange(0, status["audio"]["count"]): for i in range(0, status["audio"]["count"]):
composed_audio = render_audio(status["audio"]["items"][i], session) composed_audio = render_audio(status["audio"]["items"][i], session)
prem += u"{0} - {1}, ".format(composed_audio[0], composed_audio[1]) prem += "{0} - {1}, ".format(composed_audio[0], composed_audio[1])
message = _(u"{0} has added {1} audios: {2}").format(user, status["audio"]["count"], prem) message = _("{0} has added {1} audios: {2}").format(user, status["audio"]["count"], prem)
# Handle audio playlists # Handle audio playlists
elif status["type"] == "audio_playlist": elif status["type"] == "audio_playlist":
if status["audio_playlist"]["count"] == 1: if status["audio_playlist"]["count"] == 1:
message = _(u"{0} has added an audio album: {1}, {2}").format(user, status["audio_playlist"]["items"][0]["title"], status["audio_playlist"]["items"][0]["description"]) message = _("{0} has added an audio album: {1}, {2}").format(user, status["audio_playlist"]["items"][0]["title"], status["audio_playlist"]["items"][0]["description"])
else: else:
prestring = "" prestring = ""
for i in xrange(0, status["audio_playlist"]["count"]): for i in range(0, status["audio_playlist"]["count"]):
prestring += u"{0} - {1}, ".format(status["audio_playlist"]["items"][i]["title"], status["audio_playlist"]["items"][i]["description"]) prestring += "{0} - {1}, ".format(status["audio_playlist"]["items"][i]["title"], status["audio_playlist"]["items"][i]["description"])
message = _(u"{0} has added {1} audio albums: {2}").format(user, status["audio_playlist"]["count"], prestring) message = _("{0} has added {1} audio albums: {2}").format(user, status["audio_playlist"]["count"], prestring)
# handle new friends for people in the news buffer. # handle new friends for people in the news buffer.
elif status["type"] == "friend": elif status["type"] == "friend":
msg_users = u"" msg_users = ""
if status.has_key("friends"): if "friends" in status:
for i in status["friends"]["items"]: for i in status["friends"]["items"]:
msg_users = msg_users + u"{0}, ".format(session.get_user_name(i["user_id"], "nom")) msg_users = msg_users + "{0}, ".format(session.get_user_name(i["user_id"], "nom"))
else: else:
print status.keys() print(list(status.keys()))
message = _(u"{0} added friends: {1}").format(user, msg_users) message = _("{0} added friends: {1}").format(user, msg_users)
elif status["type"] == "video": elif status["type"] == "video":
if status["video"]["count"] == 1: if status["video"]["count"] == 1:
message = _(u"{0} has added a video: {1}").format(user, u", ".join(render_video(status["video"]["items"][0], session)),) message = _("{0} has added a video: {1}").format(user, ", ".join(render_video(status["video"]["items"][0], session)),)
else: else:
prem = "" prem = ""
for i in xrange(0, status["video"]["count"]): for i in range(0, status["video"]["count"]):
composed_video = render_video(status["video"]["items"][i], session) composed_video = render_video(status["video"]["items"][i], session)
prem += u"{0} - {1}, ".format(composed_video[0], composed_video[1]) prem += "{0} - {1}, ".format(composed_video[0], composed_video[1])
message = _(u"{0} has added {1} videos: {2}").format(user, status["video"]["count"], prem) message = _("{0} has added {1} videos: {2}").format(user, status["video"]["count"], prem)
else: else:
if status["type"] != "post": print status if status["type"] != "post": print(status)
return [user, message, created_at] return [user, message, created_at]
def render_message(message, session): def render_message(message, session):
@ -139,30 +174,30 @@ def render_message(message, session):
original_date = original_date.to(now.tzinfo) original_date = original_date.to(now.tzinfo)
# Format the date here differently depending in if this is the same day for both dates or not. # Format the date here differently depending in if this is the same day for both dates or not.
if original_date.day == now.day: if original_date.day == now.day:
created_at = original_date.format(_(u"H:mm."), locale=languageHandler.curLang[:2]) created_at = original_date.format(_("H:mm."), locale=languageHandler.curLang[:2])
else: else:
created_at = original_date.format(_(u"H:mm. dddd, MMMM D, YYYY"), locale=languageHandler.curLang[:2]) created_at = original_date.format(_("H:mm. dddd, MMMM D, YYYY"), locale=languageHandler.curLang[:2])
# No idea why some messages send "text" instead "body" # No idea why some messages send "text" instead "body"
if message.has_key("body"): if "body" in message:
body = message["body"] body = message["body"]
else: else:
body = message["text"] body = message["text"]
return [u"{2}, {0} {1}".format(body, created_at, user)] return ["{2}, {0} {1}".format(body, created_at, user)]
def render_status(status, session): def render_status(status, session):
""" Render a wall post (shown in user's wall, not in newsfeed). """ Render a wall post (shown in user's wall, not in newsfeed).
Reference: https://vk.com/dev/post""" Reference: https://vk.com/dev/post"""
user = session.get_user_name(status["from_id"], "nom") user = session.get_user_name(status["from_id"], "nom")
if status.has_key("copy_history"): if "copy_history" in status:
user = _(u"{0} has shared the {1}'s post").format(user, session.get_user_name(status["copy_history"][0]["owner_id"])) user = _("{0} has shared the {1}'s post").format(user, session.get_user_name(status["copy_history"][0]["owner_id"]))
message = "" message = ""
original_date = arrow.get(status["date"]) original_date = arrow.get(status["date"])
created_at = original_date.humanize(locale=languageHandler.curLang[:2]) created_at = original_date.humanize(locale=languageHandler.curLang[:2])
if status.has_key("copy_owner_id"): if "copy_owner_id" in status:
user = _(u"{0} has shared the {1}'s post").format(user, session.get_user_name(status["copy_owner_id"])) user = _("{0} has shared the {1}'s post").format(user, session.get_user_name(status["copy_owner_id"]))
if status["post_type"] == "post" or status["post_type"] == "copy": if status["post_type"] == "post" or status["post_type"] == "copy":
message += short_text(status) message += short_text(status)
if status.has_key("attachment") and len(status["attachment"]) > 0: if "attachment" in status and len(status["attachment"]) > 0:
message += extract_attachment(status["attachment"]) message += extract_attachment(status["attachment"])
if message == "": if message == "":
message = "no description available" message = "no description available"
@ -173,8 +208,8 @@ def render_audio(audio, session=None):
Example result: Example result:
["Song title", "Artist", "03:15"] ["Song title", "Artist", "03:15"]
reference: https://vk.com/dev/audio_object""" reference: https://vk.com/dev/audio_object"""
if audio == False: return [_(u"Audio removed from library"), "", ""] if audio == False: return [_("Audio removed from library"), "", ""]
return [audio["title"], audio["artist"], utils.seconds_to_string(audio["duration"])] return [audio["title"], audio["artist"], seconds_to_string(audio["duration"])]
def render_video(video, session=None): def render_video(video, session=None):
""" Render a video file from VK. """ Render a video file from VK.
@ -182,13 +217,13 @@ def render_video(video, session=None):
["Video title", "Video description", "01:30:28"] ["Video title", "Video description", "01:30:28"]
Reference: https://vk.com/dev/video_object""" Reference: https://vk.com/dev/video_object"""
if video == False: if video == False:
return [_(u"Video not available"), "", ""] return [_("Video not available"), "", ""]
return [video["title"], video["description"], utils.seconds_to_string(video["duration"])] return [video["title"], video["description"], seconds_to_string(video["duration"])]
def render_audio_message(audio_message, session=None): def render_audio_message(audio_message, session=None):
""" Render a voice message from VK """ Render a voice message from VK
Example result: Example result:
["Voice message", "01:30:28"]""" ["Voice message", "01:30:28"]"""
if audio_message == False: if audio_message == False:
return [_(u"Voice message not available"), "", ""] return [_("Voice message not available"), "", ""]
return [utils.seconds_to_string(audio_message["duration"])] return [seconds_to_string(audio_message["duration"])]

View File

@ -1,12 +1,13 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
""" Session object for Socializer. A session is the only object to call VK API methods, save settings and access to the cache database and sound playback mechanisms. """ """ Session object for Socializer. A session is the only object to call VK API methods, save settings and access to the cache database and sound playback mechanisms. """
from __future__ import unicode_literals
import os import os
import logging import logging
import languageHandler import languageHandler
import paths import paths
import vkSessionHandler from . import vkSessionHandler
import sound import sound
from config_utils import Configuration, ConfigurationResetException from .config_utils import Configuration, ConfigurationResetException
from pubsub import pub from pubsub import pub
from vk_api.exceptions import LoginRequired, VkApiError from vk_api.exceptions import LoginRequired, VkApiError
@ -31,14 +32,14 @@ def find_item(list, item):
global identifiers global identifiers
identifier = None identifier = None
for i in identifiers: for i in identifiers:
if item.has_key(i): if i in item:
identifier = i identifier = i
break break
if identifier == None: if identifier == None:
# if there are objects that can't be processed by lack of identifier, let's print keys for finding one. # if there are objects that can't be processed by lack of identifier, let's print keys for finding one.
log.exception("Can't find an identifier for the following object: %r" % (item.keys(),)) log.exception("Can't find an identifier for the following object: %r" % (list(item.keys()),))
for i in list: for i in list:
if i.has_key(identifier) and i[identifier] == item[identifier]: if identifier in i and i[identifier] == item[identifier]:
return True return True
return False return False
@ -53,12 +54,12 @@ class vkSession(object):
global post_types global post_types
first_addition = False first_addition = False
num = 0 num = 0
if self.db.has_key(name) == False: if (name in self.db) == False:
self.db[name] = {} self.db[name] = {}
self.db[name]["items"] = [] self.db[name]["items"] = []
first_addition = True first_addition = True
for i in data: for i in data:
if i.has_key("type") and (i["type"] == "wall_photo" or i["type"] == "photo_tag" or i["type"] == "photo"): if "type" in i and (i["type"] == "wall_photo" or i["type"] == "photo_tag" or i["type"] == "photo"):
log.debug("Skipping unsupported item... %r" % (i,)) log.debug("Skipping unsupported item... %r" % (i,))
continue continue
# for some reason, VK sends post data if the post has been deleted already. # for some reason, VK sends post data if the post has been deleted already.
@ -127,7 +128,7 @@ class vkSession(object):
def get_newsfeed(self, name="newsfeed", show_nextpage=False, endpoint="", *args, **kwargs): def get_newsfeed(self, name="newsfeed", show_nextpage=False, endpoint="", *args, **kwargs):
log.debug("Updating news feed...") log.debug("Updating news feed...")
if show_nextpage == True and self.db[name].has_key("cursor"): if show_nextpage == True and "cursor" in self.db[name]:
log.debug("user has requested previous items") log.debug("user has requested previous items")
kwargs["start_from"] = self.db[name]["cursor"] kwargs["start_from"] = self.db[name]["cursor"]
log.debug("Params for sending to vk: %r" % (kwargs,)) log.debug("Params for sending to vk: %r" % (kwargs,))
@ -138,8 +139,8 @@ class vkSession(object):
# else: # else:
# print data.keys(), len(data["items"]), data["next_from"] # print data.keys(), len(data["items"]), data["next_from"]
num = self.order_buffer(name, data["items"], show_nextpage) num = self.order_buffer(name, data["items"], show_nextpage)
log.debug("Keys of the returned data for debug purposes: %r" % (data.keys(),)) log.debug("Keys of the returned data for debug purposes: %r" % (list(data.keys()),))
if data.has_key("next_from"): if "next_from" in data:
self.db[name]["cursor"] = data["next_from"] self.db[name]["cursor"] = data["next_from"]
return num return num
@ -150,7 +151,7 @@ class vkSession(object):
c = self.vk.client_audio c = self.vk.client_audio
else: else:
c = self.vk.client c = self.vk.client
if kwargs.has_key("parent_endpoint"): if "parent_endpoint" in kwargs:
p = kwargs["parent_endpoint"] p = kwargs["parent_endpoint"]
if "audio" in p and self.settings["vk"]["use_alternative_tokens"]: if "audio" in p and self.settings["vk"]["use_alternative_tokens"]:
log.info("Using alternative audio methods.") log.info("Using alternative audio methods.")
@ -165,12 +166,12 @@ class vkSession(object):
if data != None: if data != None:
if type(data) == dict: if type(data) == dict:
num = self.order_buffer(name, data["items"], show_nextpage) num = self.order_buffer(name, data["items"], show_nextpage)
if len(data["items"]) > 0 and data["items"][0].has_key("first_name"): if len(data["items"]) > 0 and "first_name" in data["items"][0]:
data2 = {"profiles": [], "groups": []} data2 = {"profiles": [], "groups": []}
for i in data["items"]: for i in data["items"]:
data2["profiles"].append(i) data2["profiles"].append(i)
self.process_usernames(data2) self.process_usernames(data2)
if data.has_key("profiles") and data.has_key("groups"): if "profiles" in data and "groups" in data:
self.process_usernames(data) self.process_usernames(data)
else: else:
num = self.order_buffer(name, data, show_nextpage) num = self.order_buffer(name, data, show_nextpage)
@ -185,15 +186,15 @@ class vkSession(object):
def get_user_name(self, user_id, case_name="gen"): def get_user_name(self, user_id, case_name="gen"):
if user_id > 0: if user_id > 0:
if self.db["users"].has_key(user_id): if user_id in self.db["users"]:
if self.db["users"][user_id].has_key(case_name): if case_name in self.db["users"][user_id]:
return self.db["users"][user_id][case_name] return self.db["users"][user_id][case_name]
else: else:
return self.db["users"][user_id]["nom"] return self.db["users"][user_id]["nom"]
else: else:
return "no specified user" return "no specified user"
else: else:
if self.db["groups"].has_key(abs(user_id)): if abs(user_id) in self.db["groups"]:
return self.db["groups"][abs(user_id)]["nom"] return self.db["groups"][abs(user_id)]["nom"]
else: else:
return "no specified community" return "no specified community"
@ -203,7 +204,7 @@ class vkSession(object):
if user_ids != None: if user_ids != None:
u = self.vk.client.users.get(user_ids=user_ids, fields="uid, first_name, last_name") u = self.vk.client.users.get(user_ids=user_ids, fields="uid, first_name, last_name")
for i in u: for i in u:
self.db["users"][i["id"]] = u"{0} {1}".format(i["first_name"], i["last_name"]) self.db["users"][i["id"]] = "{0} {1}".format(i["first_name"], i["last_name"])
if group_ids != None: if group_ids != None:
g = self.vk.client.groups.getById(group_ids=group_ids, fields="name") g = self.vk.client.groups.getById(group_ids=group_ids, fields="name")
for i in g: for i in g:
@ -217,8 +218,8 @@ class vkSession(object):
log.debug("Adding usernames to the local database...") log.debug("Adding usernames to the local database...")
ids = "" ids = ""
for i in data["profiles"]: for i in data["profiles"]:
if self.db["users"].has_key(i["id"]) == False: if (i["id"] in self.db["users"]) == False:
self.db["users"][i["id"]] = dict(nom=u"{0} {1}".format(i["first_name"], i["last_name"])) self.db["users"][i["id"]] = dict(nom="{0} {1}".format(i["first_name"], i["last_name"]))
ids = ids + "{0},".format(i["id"],) ids = ids + "{0},".format(i["id"],)
gids = "" gids = ""
for i in data["groups"]: for i in data["groups"]:
@ -230,11 +231,11 @@ class vkSession(object):
users_genitive = self.vk.client.users.get(user_ids=ids, fields="first_name, last_name", name_case="gen") users_genitive = self.vk.client.users.get(user_ids=ids, fields="first_name, last_name", name_case="gen")
users_instrumental = self.vk.client.users.get(user_ids=ids, fields="first_name, last_name", name_case="ins") users_instrumental = self.vk.client.users.get(user_ids=ids, fields="first_name, last_name", name_case="ins")
for i in users_genitive: for i in users_genitive:
if self.db["users"].has_key(i["id"]): if i["id"] in self.db["users"]:
self.db["users"][i["id"]]["gen"] = u"{0} {1}".format(i["first_name"], i["last_name"]) self.db["users"][i["id"]]["gen"] = "{0} {1}".format(i["first_name"], i["last_name"])
for i in users_instrumental: for i in users_instrumental:
if self.db["users"].has_key(i["id"]): if i["id"] in self.db["users"]:
self.db["users"][i["id"]]["ins"] = u"{0} {1}".format(i["first_name"], i["last_name"]) self.db["users"][i["id"]]["ins"] = "{0} {1}".format(i["first_name"], i["last_name"])
def get_my_data(self): def get_my_data(self):
log.debug("Getting user identifier...") log.debug("Getting user identifier...")

View File

@ -2,12 +2,12 @@
import os import os
import sys import sys
import widgetUtils import widgetUtils
import wxUI as view from . import wxUI as view
import paths import paths
import time import time
import logging import logging
import session from . import session
from config_utils import Configuration from .config_utils import Configuration
log = logging.getLogger("sessionmanager.sessionManager") log = logging.getLogger("sessionmanager.sessionManager")

View File

@ -1,10 +1,12 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
""" Some utilities. I no have idea how I should put these, so...""" """ Some utilities. I no have idea how I should put these, so..."""
from __future__ import division
from __future__ import unicode_literals
import os import os
import requests import requests
import re import re
import logging import logging
from sessionmanager import renderers
log = logging.getLogger("utils") log = logging.getLogger("utils")
url_re = re.compile("(?:\w+://|www\.)[^ ,.?!#%=+][^ ]*") url_re = re.compile("(?:\w+://|www\.)[^ ,.?!#%=+][^ ]*")
bad_chars = '\'\\.,[](){}:;"' bad_chars = '\'\\.,[](){}:;"'
@ -18,21 +20,21 @@ def seconds_to_string(seconds, precision=0):
sec_string = sec.__format__(sec_spec) sec_string = sec.__format__(sec_spec)
string = "" string = ""
if day == 1: if day == 1:
string += _(u"%d day, ") % day string += _("%d day, ") % day
elif day >= 2: elif day >= 2:
string += _(u"%d days, ") % day string += _("%d days, ") % day
if (hour == 1): if (hour == 1):
string += _(u"%d hour, ") % hour string += _("%d hour, ") % hour
elif (hour >= 2): elif (hour >= 2):
string += _("%d hours, ") % hour string += _("%d hours, ") % hour
if (min == 1): if (min == 1):
string += _(u"%d minute, ") % min string += _("%d minute, ") % min
elif (min >= 2): elif (min >= 2):
string += _(u"%d minutes, ") % min string += _("%d minutes, ") % min
if sec >= 0 and sec <= 2: if sec >= 0 and sec <= 2:
string += _(u"%s second") % sec_string string += _("%s second") % sec_string
else: else:
string += _(u"%s seconds") % sec_string string += _("%s seconds") % sec_string
return string return string
def find_urls_in_text(text): def find_urls_in_text(text):
@ -40,7 +42,7 @@ def find_urls_in_text(text):
def download_file(url, local_filename, window): def download_file(url, local_filename, window):
r = requests.get(url, stream=True) r = requests.get(url, stream=True)
window.change_status(_(u"Downloading {0}").format(local_filename,)) window.change_status(_("Downloading {0}").format(local_filename,))
total_length = r.headers.get("content-length") total_length = r.headers.get("content-length")
dl = 0 dl = 0
total_length = int(total_length) total_length = int(total_length)
@ -49,42 +51,9 @@ def download_file(url, local_filename, window):
if chunk: # filter out keep-alive new chunks if chunk: # filter out keep-alive new chunks
dl += len(chunk) dl += len(chunk)
f.write(chunk) f.write(chunk)
done = int(100 * dl / total_length) done = int(100 * dl/total_length)
msg = _(u"Downloading {0} ({1}%)").format(os.path.basename(local_filename), done) msg = _("Downloading {0} ({1}%)").format(os.path.basename(local_filename), done)
window.change_status(msg) window.change_status(msg)
window.change_status(_(u"Ready")) window.change_status(_("Ready"))
return local_filename return local_filename
def clean_text(text):
""" Replaces all HTML entities and put the plain text equivalent if it's possible."""
text = text.replace("<br>", "\n")
text = text.replace("\\n", "\n")
return text
def add_attachment(attachment):
msg = u""
tpe = ""
if attachment["type"] == "link":
msg = u"{0}: {1}".format(attachment["link"]["title"], attachment["link"]["url"])
tpe = _(u"Link")
elif attachment["type"] == "photo":
tpe = _(u"Photo")
msg = attachment["photo"]["text"]
if msg == "":
msg = _(u"no description available")
elif attachment["type"] == "video":
msg = u"{0}".format(attachment["video"]["title"],)
tpe = _(u"Video")
elif attachment["type"] == "audio":
msg = u"{0}".format(" ".join(renderers.render_audio(attachment["audio"])))
tpe = _(u"Audio")
elif attachment["type"] == "doc":
msg = u"{0}".format(attachment["doc"]["title"])
tpe = _(u"{0} file").format(attachment["doc"]["ext"])
elif attachment["type"] == "audio_message":
msg = u"{0}".format(" ".join(renderers.render_audio_message(attachment["audio_message"])))
tpe = _(u"Voice message")
else:
print attachment
return [tpe, msg]

View File

@ -1,9 +1,9 @@
#!/usr/bin/python #!/usr/bin/python
import keys import keys
import logging import logging
import core from . import core
from vk_api.audio import VkAudio from vk_api.audio import VkAudio
from wxUI import two_factor_auth from . wxUI import two_factor_auth
log = logging.getLogger("vkSessionHandler") log = logging.getLogger("vkSessionHandler")
@ -16,7 +16,7 @@ class vkObject(object):
if alt_token == False: if alt_token == False:
log.info("Using kate's token...") log.info("Using kate's token...")
# Let's import the patched vk_api module for using a different user agent # Let's import the patched vk_api module for using a different user agent
import vk_api_patched as vk_api from . import vk_api_patched as vk_api
if token == "" or token == None: if token == "" or token == None:
log.info("Token is not valid. Generating one...") log.info("Token is not valid. Generating one...")
token = core.requestAuth(user, password) token = core.requestAuth(user, password)

View File

@ -5,7 +5,7 @@ import logging
import vk_api import vk_api
import threading import threading
import requests import requests
import jconfig_patched as jconfig from . import jconfig_patched as jconfig
from vk_api.enums import VkUserPermissions from vk_api.enums import VkUserPermissions
from vk_api.exceptions import * from vk_api.exceptions import *

View File

@ -1,4 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from __future__ import unicode_literals
import time import time
import wx import wx
import widgetUtils import widgetUtils
@ -7,7 +8,7 @@ code = None
remember = True remember = True
def new_account_dialog(): def new_account_dialog():
return wx.MessageDialog(None, _(u"In order to continue, you need to configure your VK account before. Would you like to autorhise a new account now?"), _(u"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()
def two_factor_auth(): def two_factor_auth():
global code, remember global code, remember
@ -18,7 +19,7 @@ def two_factor_auth():
def get_code(): def get_code():
global code, remember global code, remember
dlg = wx.TextEntryDialog(None, _(u"Please provide the authentication code you have received from VK."), _(u"Two factor authentication code")) dlg = wx.TextEntryDialog(None, _("Please provide the authentication code you have received from VK."), _("Two factor authentication code"))
response = dlg.ShowModal() response = dlg.ShowModal()
if response == widgetUtils.OK: if response == widgetUtils.OK:
code = dlg.GetValue() code = dlg.GetValue()
@ -27,11 +28,11 @@ def get_code():
class newSessionDialog(widgetUtils.BaseDialog): class newSessionDialog(widgetUtils.BaseDialog):
def __init__(self): def __init__(self):
super(newSessionDialog, self).__init__(parent=None, id=wx.NewId(), title=_(u"Authorise VK")) super(newSessionDialog, self).__init__(parent=None, id=wx.NewId(), title=_("Authorise VK"))
panel = wx.Panel(self) panel = wx.Panel(self)
lbl1 = wx.StaticText(panel, -1, _(u"&Email or phone number")) lbl1 = wx.StaticText(panel, -1, _("&Email or phone number"))
self.email = wx.TextCtrl(panel, -1) self.email = wx.TextCtrl(panel, -1)
lbl2 = wx.StaticText(panel, -1, _(u"&Password")) lbl2 = wx.StaticText(panel, -1, _("&Password"))
self.passw = wx.TextCtrl(panel, -1, style=wx.TE_PASSWORD) self.passw = wx.TextCtrl(panel, -1, style=wx.TE_PASSWORD)
sizer = wx.BoxSizer() sizer = wx.BoxSizer()
b1 = wx.BoxSizer(wx.HORIZONTAL) b1 = wx.BoxSizer(wx.HORIZONTAL)

View File

@ -1,6 +1,6 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
""" Sound utilities for socializer.""" """ Sound utilities for socializer."""
from __future__ import unicode_literals from builtins import range
import sys import sys
import os import os
import glob import glob
@ -70,7 +70,7 @@ class soundSystem(object):
def clear_list(self): def clear_list(self):
if len(self.files) == 0: return if len(self.files) == 0: return
try: try:
for i in xrange(0, len(self.files)): for i in range(0, len(self.files)):
if self.files[i].is_playing == False: if self.files[i].is_playing == False:
self.files[i].free() self.files[i].free()
self.files.pop(i) self.files.pop(i)

View File

@ -1,5 +1,6 @@
from __future__ import unicode_literals
import unittest import unittest
import testconfig from . import testconfig
import languageHandler import languageHandler
from sessionmanager import utils from sessionmanager import utils
from sessionmanager import renderers from sessionmanager import renderers
@ -20,8 +21,8 @@ class renderersTestCase(unittest.TestCase):
rendered_object = renderers.render_person(user, user["last_seen"]) rendered_object = renderers.render_person(user, user["last_seen"])
self.assertIsInstance(rendered_object, list) self.assertIsInstance(rendered_object, list)
self.assertEquals(len(rendered_object), 2) self.assertEquals(len(rendered_object), 2)
self.assertIsInstance(rendered_object[0], unicode) self.assertIsInstance(rendered_object[0], str)
self.assertIsInstance(rendered_object[1], unicode) self.assertIsInstance(rendered_object[1], str)
if __name__ == "__main__": if __name__ == "__main__":
unittest.main() unittest.main()

View File

@ -1,3 +1,4 @@
from __future__ import unicode_literals
import os import os
from vk_api import VkApi from vk_api import VkApi

View File

@ -1,11 +1,11 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import application import application
import update
import platform import platform
import logging import logging
import output import output
from requests.exceptions import ConnectionError from requests.exceptions import ConnectionError
from wxUpdater import * from . import update
from .wxUpdater import *
logger = logging.getLogger("updater") logger = logging.getLogger("updater")
def do_update(update_type="stable"): def do_update(update_type="stable"):

View File

@ -1,4 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from __future__ import unicode_literals
def convert_bytes(n): def convert_bytes(n):
K, M, G, T, P = 1 << 10, 1 << 20, 1 << 30, 1 << 40, 1 << 50 K, M, G, T, P = 1 << 10, 1 << 20, 1 << 30, 1 << 40, 1 << 50
@ -24,19 +25,19 @@ def seconds_to_string(seconds, precision=0):
sec_string = sec.__format__(sec_spec) sec_string = sec.__format__(sec_spec)
string = "" string = ""
if day == 1: if day == 1:
string += _(u"%d day, ") % day string += _("%d day, ") % day
elif day >= 2: elif day >= 2:
string += _(u"%d days, ") % day string += _("%d days, ") % day
if (hour == 1): if (hour == 1):
string += _(u"%d hour, ") % hour string += _("%d hour, ") % hour
elif (hour >= 2): elif (hour >= 2):
string += _("%d hours, ") % hour string += _("%d hours, ") % hour
if (min == 1): if (min == 1):
string += _(u"%d minute, ") % min string += _("%d minute, ") % min
elif (min >= 2): elif (min >= 2):
string += _(u"%d minutes, ") % min string += _("%d minutes, ") % min
if sec >= 0 and sec <= 2: if sec >= 0 and sec <= 2:
string += _(u"%s second") % sec_string string += _("%s second") % sec_string
else: else:
string += _(u"%s seconds") % sec_string string += _("%s seconds") % sec_string
return string return string

View File

@ -1,19 +1,21 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from __future__ import division
from __future__ import unicode_literals
import wx import wx
import application import application
import utils from . import utils
progress_dialog = None progress_dialog = None
def available_update_dialog(version, description): def available_update_dialog(version, description):
dialog = wx.MessageDialog(None, _(u"There's a new %s version available. Would you like to download it now?\n\n %s version: %s\n\nChanges:\n%s") % (application.name, application.name, version, description), _(u"New version for %s") % application.name, style=wx.YES|wx.NO|wx.ICON_WARNING) dialog = wx.MessageDialog(None, _("There's a new %s version available. Would you like to download it now?\n\n %s version: %s\n\nChanges:\n%s") % (application.name, application.name, version, description), _("New version for %s") % application.name, style=wx.YES|wx.NO|wx.ICON_WARNING)
if dialog.ShowModal() == wx.ID_YES: if dialog.ShowModal() == wx.ID_YES:
return True return True
else: else:
return False return False
def create_progress_dialog(): def create_progress_dialog():
return wx.ProgressDialog(_(u"Download in Progress"), _(u"Downloading the new version..."), parent=None, maximum=100) return wx.ProgressDialog(_("Download in Progress"), _("Downloading the new version..."), parent=None, maximum=100)
def progress_callback(total_downloaded, total_size): def progress_callback(total_downloaded, total_size):
wx.CallAfter(_progress_callback, total_downloaded, total_size) wx.CallAfter(_progress_callback, total_downloaded, total_size)
@ -26,7 +28,7 @@ def _progress_callback(total_downloaded, total_size):
if total_downloaded == total_size: if total_downloaded == total_size:
progress_dialog.Destroy() progress_dialog.Destroy()
else: else:
progress_dialog.Update((total_downloaded*100)/total_size, _(u"Updating... %s of %s") % (str(utils.convert_bytes(total_downloaded)), str(utils.convert_bytes(total_size)))) progress_dialog.Update((total_downloaded*100)/total_size, _("Updating... %s of %s") % (utils.convert_bytes(total_downloaded), utils.convert_bytes(total_size)))
def update_finished(): def update_finished():
return wx.MessageDialog(None, _(u"The update has been downloaded and installed successfully. Press OK to continue."), _(u"Done!")).ShowModal() return wx.MessageDialog(None, _("The update has been downloaded and installed successfully. Press OK to continue."), _("Done!")).ShowModal()

View File

@ -1,3 +1,4 @@
#from __future__ import unicode_literals
import platform import platform
#if platform.system() == "Windows": #if platform.system() == "Windows":
from .wxUtils import * from .wxUtils import *

View File

@ -1,3 +1,7 @@
# -*- coding: utf-8 -*-
#from __future__ import unicode_literals
from __future__ import unicode_literals
from builtins import range
import wx import wx
toolkit = "wx" toolkit = "wx"
@ -144,7 +148,7 @@ class list(object):
def create_list(self, parent): def create_list(self, parent):
self.list = wx.ListCtrl(parent, -1, **self.listArguments) self.list = wx.ListCtrl(parent, -1, **self.listArguments)
for i in range(0, len(self.columns)): for i in range(0, len(self.columns)):
self.list.InsertColumn(i, u"%s" % (self.columns[i])) self.list.InsertColumn(i, "%s" % (self.columns[i]))
def insert_item(self, reversed, *item): def insert_item(self, reversed, *item):
""" Inserts an item on the list.""" """ Inserts an item on the list."""

View File

@ -1,38 +1,39 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from __future__ import unicode_literals
import wx import wx
import application import application
def no_data_entered(): def no_data_entered():
return wx.MessageDialog(None, _(u"You must provide Both user and password."), _(u"Information needed"), wx.ICON_ERROR).ShowModal() return wx.MessageDialog(None, _("You must provide Both user and password."), _("Information needed"), wx.ICON_ERROR).ShowModal()
def no_update_available(): def no_update_available():
return wx.MessageDialog(None, _(u"Your {0} version is up to date").format(application.name,), _(u"Update"), style=wx.OK).ShowModal() return wx.MessageDialog(None, _("Your {0} version is up to date").format(application.name,), _("Update"), style=wx.OK).ShowModal()
def remove_buffer(): def remove_buffer():
return wx.MessageDialog(None, _(u"Do you really want to dismiss this buffer?"), _(u"Attention"), style=wx.ICON_QUESTION|wx.YES_NO).ShowModal() return wx.MessageDialog(None, _("Do you really want to dismiss this buffer?"), _("Attention"), style=wx.ICON_QUESTION|wx.YES_NO).ShowModal()
def no_user_exist(): def no_user_exist():
wx.MessageDialog(None, _(u"This user does not exist"), _(u"Error"), style=wx.ICON_ERROR).ShowModal() wx.MessageDialog(None, _("This user does not exist"), _("Error"), style=wx.ICON_ERROR).ShowModal()
def show_error_code(code): def show_error_code(code):
title = "" title = ""
message = "" message = ""
if code == 201: if code == 201:
title = _(u"Restricted access") title = _("Restricted access")
message = _(u"Access to user's audio is denied by the owner. Error code {0}").format(code,) message = _("Access to user's audio is denied by the owner. Error code {0}").format(code,)
return wx.MessageDialog(None, message, title, style=wx.ICON_ERROR).ShowModal() return wx.MessageDialog(None, message, title, style=wx.ICON_ERROR).ShowModal()
def bad_authorisation(): def bad_authorisation():
return wx.MessageDialog(None, _(u"authorisation failed. Your configuration will not be saved. Please close and open again the application for authorising your account. Make sure you have typed your credentials correctly."), _(u"Error"), style=wx.ICON_ERROR).ShowModal() return wx.MessageDialog(None, _("authorisation failed. Your configuration will not be saved. Please close and open again the application for authorising your account. Make sure you have typed your credentials correctly."), _("Error"), style=wx.ICON_ERROR).ShowModal()
def no_audio_albums(): def no_audio_albums():
return wx.MessageDialog(None, _(u"You do not have audio albums to add tis file."), _(u"Error"), style=wx.ICON_ERROR).ShowModal() return wx.MessageDialog(None, _("You do not have audio albums to add tis file."), _("Error"), style=wx.ICON_ERROR).ShowModal()
def no_video_albums(): def no_video_albums():
return wx.MessageDialog(None, _(u"You do not have video albums to add tis file."), _(u"Error"), style=wx.ICON_ERROR).ShowModal() return wx.MessageDialog(None, _("You do not have video albums to add tis file."), _("Error"), style=wx.ICON_ERROR).ShowModal()
def delete_audio_album(): def delete_audio_album():
return wx.MessageDialog(None, _(u"Do you really want to delete this Album? this will be deleted from VK too."), _(u"Attention"), style=wx.ICON_QUESTION|wx.YES_NO).ShowModal() return wx.MessageDialog(None, _("Do you really want to delete this Album? this will be deleted from VK too."), _("Attention"), style=wx.ICON_QUESTION|wx.YES_NO).ShowModal()
def updated_status(): def updated_status():
return wx.MessageDialog(None, _(u"Your status message has been successfully updated."), _(u"Success")).ShowModal() return wx.MessageDialog(None, _("Your status message has been successfully updated."), _("Success")).ShowModal()

View File

@ -1 +0,0 @@
import message

View File

@ -1,24 +1,25 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from __future__ import unicode_literals
import wx import wx
import widgetUtils import widgetUtils
class attachDialog(widgetUtils.BaseDialog): class attachDialog(widgetUtils.BaseDialog):
def __init__(self, voice_messages=False): def __init__(self, voice_messages=False):
super(attachDialog, self).__init__(None, title=_(u"Add an attachment")) super(attachDialog, self).__init__(None, title=_("Add an attachment"))
panel = wx.Panel(self) panel = wx.Panel(self)
sizer = wx.BoxSizer(wx.VERTICAL) sizer = wx.BoxSizer(wx.VERTICAL)
lbl1 = wx.StaticText(panel, wx.NewId(), _(u"Attachments")) lbl1 = wx.StaticText(panel, wx.NewId(), _("Attachments"))
self.attachments = widgetUtils.list(panel, _(u"Type"), _(u"Title"), style=wx.LC_REPORT) self.attachments = widgetUtils.list(panel, _("Type"), _("Title"), style=wx.LC_REPORT)
box = wx.BoxSizer(wx.HORIZONTAL) box = wx.BoxSizer(wx.HORIZONTAL)
box.Add(lbl1, 0, wx.ALL, 5) box.Add(lbl1, 0, wx.ALL, 5)
box.Add(self.attachments.list, 0, wx.ALL, 5) box.Add(self.attachments.list, 0, wx.ALL, 5)
sizer.Add(box, 0, wx.ALL, 5) sizer.Add(box, 0, wx.ALL, 5)
static = wx.StaticBox(panel, label=_(u"Add attachments")) static = wx.StaticBox(panel, label=_("Add attachments"))
self.photo = wx.Button(panel, wx.NewId(), _(u"&Photo")) self.photo = wx.Button(panel, wx.NewId(), _("&Photo"))
self.audio = wx.Button(panel, wx.NewId(), _(u"Audio file")) self.audio = wx.Button(panel, wx.NewId(), _("Audio file"))
if voice_messages: if voice_messages:
self.voice_message = wx.Button(panel, wx.NewId(), _(u"Voice message")) self.voice_message = wx.Button(panel, wx.NewId(), _("Voice message"))
self.remove = wx.Button(panel, wx.NewId(), _(u"Remove attachment")) self.remove = wx.Button(panel, wx.NewId(), _("Remove attachment"))
self.remove.Enable(False) self.remove.Enable(False)
btnsizer = wx.StaticBoxSizer(static, wx.HORIZONTAL) btnsizer = wx.StaticBoxSizer(static, wx.HORIZONTAL)
btnsizer.Add(self.photo, 0, wx.ALL, 5) btnsizer.Add(self.photo, 0, wx.ALL, 5)
@ -37,21 +38,21 @@ class attachDialog(widgetUtils.BaseDialog):
self.SetClientSize(sizer.CalcMin()) self.SetClientSize(sizer.CalcMin())
def get_image(self): def get_image(self):
openFileDialog = wx.FileDialog(self, _(u"Select the picture to be uploaded"), "", "", _("Image files (*.png, *.jpg, *.gif)|*.png; *.jpg; *.gif"), wx.FD_OPEN | wx.FD_FILE_MUST_EXIST) openFileDialog = wx.FileDialog(self, _("Select the picture to be uploaded"), "", "", _("Image files (*.png, *.jpg, *.gif)|*.png; *.jpg; *.gif"), wx.FD_OPEN | wx.FD_FILE_MUST_EXIST)
if openFileDialog.ShowModal() == wx.ID_CANCEL: if openFileDialog.ShowModal() == wx.ID_CANCEL:
return None return None
dsc = self.ask_description() dsc = self.ask_description()
return (openFileDialog.GetPath(), dsc) return (openFileDialog.GetPath(), dsc)
def ask_description(self): def ask_description(self):
dlg = wx.TextEntryDialog(self, _(u"please provide a description"), _(u"Description")) dlg = wx.TextEntryDialog(self, _("please provide a description"), _("Description"))
dlg.ShowModal() dlg.ShowModal()
result = dlg.GetValue() result = dlg.GetValue()
dlg.Destroy() dlg.Destroy()
return result return result
def get_audio(self): def get_audio(self):
openFileDialog = wx.FileDialog(self, _(u"Select the audio file to be uploaded"), "", "", _("Audio files (*.mp3)|*.mp3"), wx.FD_OPEN | wx.FD_FILE_MUST_EXIST) openFileDialog = wx.FileDialog(self, _("Select the audio file to be uploaded"), "", "", _("Audio files (*.mp3)|*.mp3"), wx.FD_OPEN | wx.FD_FILE_MUST_EXIST)
if openFileDialog.ShowModal() == wx.ID_CANCEL: if openFileDialog.ShowModal() == wx.ID_CANCEL:
return None return None
return openFileDialog.GetPath() return openFileDialog.GetPath()

View File

@ -1,4 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from __future__ import unicode_literals
import wx import wx
import widgetUtils import widgetUtils
@ -6,24 +7,24 @@ class general(wx.Panel, widgetUtils.BaseDialog):
def __init__(self, panel): def __init__(self, panel):
super(general, self).__init__(panel) super(general, self).__init__(panel)
sizer = wx.BoxSizer(wx.VERTICAL) sizer = wx.BoxSizer(wx.VERTICAL)
lbl1 = wx.StaticText(self, wx.NewId(), _(u"Number of items to load for newsfeed and wall buffers (maximun 100)")) lbl1 = wx.StaticText(self, wx.NewId(), _("Number of items to load for newsfeed and wall buffers (maximun 100)"))
self.wall_buffer_count = wx.SpinCtrl(self, wx.NewId()) self.wall_buffer_count = wx.SpinCtrl(self, wx.NewId())
self.wall_buffer_count.SetRange(1, 100) self.wall_buffer_count.SetRange(1, 100)
box1 = wx.BoxSizer(wx.HORIZONTAL) box1 = wx.BoxSizer(wx.HORIZONTAL)
box1.Add(lbl1, 0, wx.ALL, 5) box1.Add(lbl1, 0, wx.ALL, 5)
box1.Add(self.wall_buffer_count, 0, wx.ALL, 5) box1.Add(self.wall_buffer_count, 0, wx.ALL, 5)
sizer.Add(box1, 0, wx.ALL, 5) sizer.Add(box1, 0, wx.ALL, 5)
lbl3 = wx.StaticText(self, wx.NewId(), _(u"Number of items to load in video buffers (maximun 200)")) lbl3 = wx.StaticText(self, wx.NewId(), _("Number of items to load in video buffers (maximun 200)"))
self.video_buffers_count = wx.SpinCtrl(self, wx.NewId()) self.video_buffers_count = wx.SpinCtrl(self, wx.NewId())
self.video_buffers_count.SetRange(1, 200) self.video_buffers_count.SetRange(1, 200)
box3 = wx.BoxSizer(wx.HORIZONTAL) box3 = wx.BoxSizer(wx.HORIZONTAL)
box3.Add(lbl3, 0, wx.ALL, 5) box3.Add(lbl3, 0, wx.ALL, 5)
box3.Add(self.video_buffers_count, 0, wx.ALL, 5) box3.Add(self.video_buffers_count, 0, wx.ALL, 5)
sizer.Add(box3, 0, wx.ALL, 5) sizer.Add(box3, 0, wx.ALL, 5)
self.load_images = wx.CheckBox(self, wx.NewId(), _(u"Load images in posts")) self.load_images = wx.CheckBox(self, wx.NewId(), _("Load images in posts"))
sizer.Add(self.load_images, 0, wx.ALL, 5) sizer.Add(self.load_images, 0, wx.ALL, 5)
lbl4 = wx.StaticText(self, wx.NewId(), _(u"Update channel")) lbl4 = wx.StaticText(self, wx.NewId(), _("Update channel"))
self.update_channel = wx.ComboBox(self, wx.NewId(), choices=[_(u"Stable"), _(u"Alpha")], value=_(u"Native"), style=wx.CB_READONLY) self.update_channel = wx.ComboBox(self, wx.NewId(), choices=[_("Stable"), _("Alpha")], value=_("Native"), style=wx.CB_READONLY)
box4 = wx.BoxSizer(wx.HORIZONTAL) box4 = wx.BoxSizer(wx.HORIZONTAL)
box4.Add(lbl4, 0, wx.ALL, 5) box4.Add(lbl4, 0, wx.ALL, 5)
box4.Add(self.update_channel, 0, wx.ALL, 5) box4.Add(self.update_channel, 0, wx.ALL, 5)
@ -34,16 +35,16 @@ class chat(wx.Panel, widgetUtils.BaseDialog):
def __init__(self, panel): def __init__(self, panel):
super(chat, self).__init__(panel) super(chat, self).__init__(panel)
sizer = wx.BoxSizer(wx.VERTICAL) sizer = wx.BoxSizer(wx.VERTICAL)
self.notify_online = wx.CheckBox(self, wx.NewId(), _(u"Show notifications when users are online")) self.notify_online = wx.CheckBox(self, wx.NewId(), _("Show notifications when users are online"))
sizer.Add(self.notify_online, 0, wx.ALL, 5) sizer.Add(self.notify_online, 0, wx.ALL, 5)
self.notify_offline = wx.CheckBox(self, wx.NewId(), _(u"Show notifications when users are offline")) self.notify_offline = wx.CheckBox(self, wx.NewId(), _("Show notifications when users are offline"))
sizer.Add(self.notify_offline, 0, wx.ALL, 5) sizer.Add(self.notify_offline, 0, wx.ALL, 5)
self.open_unread_conversations = wx.CheckBox(self, wx.NewId(), _(u"Open unread conversations at startup")) self.open_unread_conversations = wx.CheckBox(self, wx.NewId(), _("Open unread conversations at startup"))
sizer.Add(self.open_unread_conversations, 0, wx.ALL, 5) sizer.Add(self.open_unread_conversations, 0, wx.ALL, 5)
self.automove_to_conversations = wx.CheckBox(self, wx.NewId(), _(u"Move focus to new conversations")) self.automove_to_conversations = wx.CheckBox(self, wx.NewId(), _("Move focus to new conversations"))
sizer.Add(self.automove_to_conversations, 0, wx.ALL, 5) sizer.Add(self.automove_to_conversations, 0, wx.ALL, 5)
lbl = wx.StaticText(self, wx.NewId(), _(u"Notification type")) lbl = wx.StaticText(self, wx.NewId(), _("Notification type"))
self.notifications = wx.ComboBox(self, wx.NewId(), choices=[_(u"Native"), _(u"Custom"),], value=_(u"Native"), style=wx.CB_READONLY) self.notifications = wx.ComboBox(self, wx.NewId(), choices=[_("Native"), _("Custom"),], value=_("Native"), style=wx.CB_READONLY)
nbox = wx.BoxSizer(wx.HORIZONTAL) nbox = wx.BoxSizer(wx.HORIZONTAL)
nbox.Add(lbl, 0, wx.ALL, 5) nbox.Add(lbl, 0, wx.ALL, 5)
nbox.Add(self.notifications, 0, wx.ALL, 5) nbox.Add(self.notifications, 0, wx.ALL, 5)
@ -60,20 +61,20 @@ class configurationDialog(widgetUtils.BaseDialog):
def create_general(self): def create_general(self):
self.general = general(self.notebook) self.general = general(self.notebook)
self.notebook.AddPage(self.general, _(u"General")) self.notebook.AddPage(self.general, _("General"))
self.general.SetFocus() self.general.SetFocus()
def create_chat(self): def create_chat(self):
self.chat = chat(self.notebook) self.chat = chat(self.notebook)
self.notebook.AddPage(self.chat, _(u"Chat settings")) self.notebook.AddPage(self.chat, _("Chat settings"))
def realize(self): def realize(self):
self.sizer.Add(self.notebook, 0, wx.ALL, 5) self.sizer.Add(self.notebook, 0, wx.ALL, 5)
ok_cancel_box = wx.BoxSizer(wx.HORIZONTAL) ok_cancel_box = wx.BoxSizer(wx.HORIZONTAL)
ok = wx.Button(self.panel, wx.ID_OK, _(u"Save")) ok = wx.Button(self.panel, wx.ID_OK, _("Save"))
ok.SetDefault() ok.SetDefault()
cancel = wx.Button(self.panel, wx.ID_CANCEL, _(u"Close")) cancel = wx.Button(self.panel, wx.ID_CANCEL, _("Close"))
self.SetEscapeId(cancel.GetId()) self.SetEscapeId(cancel.GetId())
ok_cancel_box.Add(ok, 0, wx.ALL, 5) ok_cancel_box.Add(ok, 0, wx.ALL, 5)
ok_cancel_box.Add(cancel, 0, wx.ALL, 5) ok_cancel_box.Add(cancel, 0, wx.ALL, 5)
@ -91,7 +92,7 @@ class configurationDialog(widgetUtils.BaseDialog):
getattr(control, "SetValue")(value) getattr(control, "SetValue")(value)
def alpha_channel(): def alpha_channel():
return wx.MessageDialog(None, _(u"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?"), _(u"Attention"), style=wx.ICON_QUESTION|wx.YES_NO).ShowModal() return wx.MessageDialog(None, _("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(): def weekly_channel():
return wx.MessageDialog(None, _(u"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?"), _(u"Attention"), style=wx.ICON_QUESTION|wx.YES_NO).ShowModal() return wx.MessageDialog(None, _("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()

View File

@ -1,21 +1,23 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
import wx import wx
import widgetUtils import widgetUtils
class audio_album(widgetUtils.BaseDialog): class audio_album(widgetUtils.BaseDialog):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
super(audio_album, self).__init__(title=_(u"Create a new album"), parent=None) super(audio_album, self).__init__(title=_("Create a new album"), parent=None)
panel = wx.Panel(self) panel = wx.Panel(self)
sizer = wx.BoxSizer(wx.VERTICAL) sizer = wx.BoxSizer(wx.VERTICAL)
lbl = wx.StaticText(panel, wx.NewId(), _(u"Album title")) lbl = wx.StaticText(panel, wx.NewId(), _("Album title"))
self.title = wx.TextCtrl(panel, wx.NewId()) self.title = wx.TextCtrl(panel, wx.NewId())
box = wx.BoxSizer(wx.HORIZONTAL) box = wx.BoxSizer(wx.HORIZONTAL)
box.Add(lbl, 1, wx.ALL, 5) box.Add(lbl, 1, wx.ALL, 5)
box.Add(self.title, 1, wx.ALL, 5) box.Add(self.title, 1, wx.ALL, 5)
sizer.Add(box, 1, wx.ALL, 5) sizer.Add(box, 1, wx.ALL, 5)
ok = wx.Button(panel, wx.ID_OK, _(u"&OK")) ok = wx.Button(panel, wx.ID_OK, _("&OK"))
ok.SetDefault() ok.SetDefault()
cancel = wx.Button(panel, wx.ID_CANCEL, _(u"&Close")) cancel = wx.Button(panel, wx.ID_CANCEL, _("&Close"))
btnsizer = wx.BoxSizer() btnsizer = wx.BoxSizer()
btnsizer.Add(ok, 0, wx.ALL, 5) btnsizer.Add(ok, 0, wx.ALL, 5)
btnsizer.Add(cancel, 0, wx.ALL, 5) btnsizer.Add(cancel, 0, wx.ALL, 5)

View File

@ -1,4 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from __future__ import unicode_literals
import wx import wx
import widgetUtils import widgetUtils
@ -16,8 +17,8 @@ class textMessage(widgetUtils.BaseDialog):
self.textBox.Add(self.text, 0, wx.ALL, 5) self.textBox.Add(self.text, 0, wx.ALL, 5)
def create_privacy_box(self): def create_privacy_box(self):
lbl = wx.StaticText(self.panel, wx.NewId(), _(u"&Privacy")) lbl = wx.StaticText(self.panel, wx.NewId(), _("&Privacy"))
self.privacy = wx.ComboBox(self.panel, wx.NewId(), choices=[_(u"All users"), _(u"Friends of friends"),], value=_(u"All users"), style=wx.CB_READONLY) self.privacy = wx.ComboBox(self.panel, wx.NewId(), choices=[_("All users"), _("Friends of friends"),], value=_("All users"), style=wx.CB_READONLY)
self.privacyBox = wx.BoxSizer(wx.HORIZONTAL) self.privacyBox = wx.BoxSizer(wx.HORIZONTAL)
self.privacyBox.Add(lbl, 0, wx.ALL, 5) self.privacyBox.Add(lbl, 0, wx.ALL, 5)
self.privacyBox.Add(self.privacy, 0, wx.ALL, 5) self.privacyBox.Add(self.privacy, 0, wx.ALL, 5)
@ -58,13 +59,13 @@ class post(textMessage):
self.mainBox.Add(self.textBox, 0, wx.ALL, 5) self.mainBox.Add(self.textBox, 0, wx.ALL, 5)
self.create_privacy_box() self.create_privacy_box()
self.mainBox.Add(self.privacyBox, 0, wx.ALL, 5) self.mainBox.Add(self.privacyBox, 0, wx.ALL, 5)
self.attach = wx.Button(self.panel, -1, _(u"Attach"), size=wx.DefaultSize) self.attach = wx.Button(self.panel, -1, _("Attach"), size=wx.DefaultSize)
self.mention = wx.Button(self.panel, wx.NewId(), _(u"Tag a friend")) self.mention = wx.Button(self.panel, wx.NewId(), _("Tag a friend"))
self.spellcheck = wx.Button(self.panel, -1, _("Spelling &correction"), size=wx.DefaultSize) self.spellcheck = wx.Button(self.panel, -1, _("Spelling &correction"), size=wx.DefaultSize)
self.translateButton = wx.Button(self.panel, -1, _(u"&Translate message"), size=wx.DefaultSize) self.translateButton = wx.Button(self.panel, -1, _("&Translate message"), size=wx.DefaultSize)
self.okButton = wx.Button(self.panel, wx.ID_OK, _(u"Send"), size=wx.DefaultSize) self.okButton = wx.Button(self.panel, wx.ID_OK, _("Send"), size=wx.DefaultSize)
self.okButton.SetDefault() self.okButton.SetDefault()
cancelButton = wx.Button(self.panel, wx.ID_CANCEL, _(u"Close"), size=wx.DefaultSize) cancelButton = wx.Button(self.panel, wx.ID_CANCEL, _("Close"), size=wx.DefaultSize)
self.buttonsBox1 = wx.BoxSizer(wx.HORIZONTAL) self.buttonsBox1 = wx.BoxSizer(wx.HORIZONTAL)
self.buttonsBox1.Add(self.attach, 0, wx.ALL, 10) self.buttonsBox1.Add(self.attach, 0, wx.ALL, 10)
self.buttonsBox1.Add(self.mention, 0, wx.ALL, 10) self.buttonsBox1.Add(self.mention, 0, wx.ALL, 10)
@ -94,11 +95,11 @@ class comment(textMessage):
self.createTextArea(message, text) self.createTextArea(message, text)
self.mainBox.Add(self.textBox, 0, wx.ALL, 5) self.mainBox.Add(self.textBox, 0, wx.ALL, 5)
self.spellcheck = wx.Button(self.panel, -1, _("Spelling correction"), size=wx.DefaultSize) self.spellcheck = wx.Button(self.panel, -1, _("Spelling correction"), size=wx.DefaultSize)
self.mention = wx.Button(self.panel, wx.NewId(), _(u"Tag a friend")) self.mention = wx.Button(self.panel, wx.NewId(), _("Tag a friend"))
self.translateButton = wx.Button(self.panel, -1, _(u"Translate message"), size=wx.DefaultSize) self.translateButton = wx.Button(self.panel, -1, _("Translate message"), size=wx.DefaultSize)
self.okButton = wx.Button(self.panel, wx.ID_OK, _(u"Send"), size=wx.DefaultSize) self.okButton = wx.Button(self.panel, wx.ID_OK, _("Send"), size=wx.DefaultSize)
self.okButton.SetDefault() self.okButton.SetDefault()
cancelButton = wx.Button(self.panel, wx.ID_CANCEL, _(u"Close"), size=wx.DefaultSize) cancelButton = wx.Button(self.panel, wx.ID_CANCEL, _("Close"), size=wx.DefaultSize)
self.buttonsBox1 = wx.BoxSizer(wx.HORIZONTAL) self.buttonsBox1 = wx.BoxSizer(wx.HORIZONTAL)
self.buttonsBox1.Add(self.spellcheck, 0, wx.ALL, 10) self.buttonsBox1.Add(self.spellcheck, 0, wx.ALL, 10)
self.buttonsBox1.Add(self.mention, 0, wx.ALL, 10) self.buttonsBox1.Add(self.mention, 0, wx.ALL, 10)

View File

@ -1,9 +1,10 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from __future__ import unicode_literals
import wx import wx
import widgetUtils import widgetUtils
class audioPlayerDialog(widgetUtils.BaseDialog): class audioPlayerDialog(widgetUtils.BaseDialog):
def __init__(self): def __init__(self):
super(audioPlayerDialog, self).__init__(None, wx.NewId(), _(u"Audio player")) super(audioPlayerDialog, self).__init__(None, wx.NewId(), _("Audio player"))
sizer = wx.BoxSizer(wx.VERTICAL) sizer = wx.BoxSizer(wx.VERTICAL)

View File

@ -1,4 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from __future__ import unicode_literals
import wx import wx
import widgetUtils import widgetUtils
@ -12,7 +13,7 @@ class basicPost(widgetUtils.BaseDialog):
self.panel.SetSizer(self.sizer) self.panel.SetSizer(self.sizer)
self.SetClientSize(self.sizer.CalcMin()) self.SetClientSize(self.sizer.CalcMin())
def create_post_view(self, label=_(u"Message")): def create_post_view(self, label=_("Message")):
lbl = wx.StaticText(self.panel, -1, label) lbl = wx.StaticText(self.panel, -1, label)
self.post_view = wx.TextCtrl(self.panel, -1, size=(730, -1), style=wx.TE_READONLY|wx.TE_MULTILINE) self.post_view = wx.TextCtrl(self.panel, -1, size=(730, -1), style=wx.TE_READONLY|wx.TE_MULTILINE)
box = wx.BoxSizer(wx.HORIZONTAL) box = wx.BoxSizer(wx.HORIZONTAL)
@ -21,16 +22,16 @@ class basicPost(widgetUtils.BaseDialog):
return box return box
def create_comments_list(self): def create_comments_list(self):
lbl = wx.StaticText(self.panel, -1, _(u"Comments")) lbl = wx.StaticText(self.panel, -1, _("Comments"))
self.comments = widgetUtils.list(self.panel, _(u"User"), _(u"Comment"), _(u"Date"), _(u"Likes"), style=wx.LC_REPORT) self.comments = widgetUtils.list(self.panel, _("User"), _("Comment"), _("Date"), _("Likes"), style=wx.LC_REPORT)
box = wx.BoxSizer(wx.HORIZONTAL) box = wx.BoxSizer(wx.HORIZONTAL)
box.Add(lbl, 0, wx.ALL, 5) box.Add(lbl, 0, wx.ALL, 5)
box.Add(self.comments.list, 0, wx.ALL, 5) box.Add(self.comments.list, 0, wx.ALL, 5)
return box return box
def create_attachments(self): def create_attachments(self):
lbl = wx.StaticText(self.panel, -1, _(u"Attachments")) lbl = wx.StaticText(self.panel, -1, _("Attachments"))
self.attachments = widgetUtils.list(self.panel, _(u"Type"), _(u"Title"), style=wx.LC_REPORT) self.attachments = widgetUtils.list(self.panel, _("Type"), _("Title"), style=wx.LC_REPORT)
box = wx.BoxSizer(wx.HORIZONTAL) box = wx.BoxSizer(wx.HORIZONTAL)
box.Add(lbl, 0, wx.ALL, 5) box.Add(lbl, 0, wx.ALL, 5)
box.Add(self.attachments.list, 0, wx.ALL, 5) box.Add(self.attachments.list, 0, wx.ALL, 5)
@ -39,9 +40,9 @@ class basicPost(widgetUtils.BaseDialog):
def create_photo_viewer(self): def create_photo_viewer(self):
self.image = wx.StaticBitmap(self.panel, bitmap=wx.Bitmap(1280, 860), size=(604, 604)) self.image = wx.StaticBitmap(self.panel, bitmap=wx.Bitmap(1280, 860), size=(604, 604))
self.sizer.Add(self.image, 1, wx.ALL, 10) self.sizer.Add(self.image, 1, wx.ALL, 10)
self.previous_photo = wx.Button(self.panel, wx.NewId(), _(u"Previous photo")) self.previous_photo = wx.Button(self.panel, wx.NewId(), _("Previous photo"))
self.view_photo = wx.Button(self.panel, wx.NewId(), _(u"View in full screen")) self.view_photo = wx.Button(self.panel, wx.NewId(), _("View in full screen"))
self.next_photo = wx.Button(self.panel, wx.NewId(), _(u"Next photo")) self.next_photo = wx.Button(self.panel, wx.NewId(), _("Next photo"))
actionsS = wx.BoxSizer(wx.HORIZONTAL) actionsS = wx.BoxSizer(wx.HORIZONTAL)
actionsS.Add(self.previous_photo, 0, wx.ALL, 5) actionsS.Add(self.previous_photo, 0, wx.ALL, 5)
actionsS.Add(self.view_photo, 0, wx.ALL, 5) actionsS.Add(self.view_photo, 0, wx.ALL, 5)
@ -59,27 +60,27 @@ class basicPost(widgetUtils.BaseDialog):
def create_likes_box(self): def create_likes_box(self):
self.likes = wx.Button(self.panel, -1, _(u"Loading data...")) self.likes = wx.Button(self.panel, -1, _("Loading data..."))
return self.likes return self.likes
def create_shares_box(self): def create_shares_box(self):
self.shares = wx.Button(self.panel, -1, _(u"Loading data...")) self.shares = wx.Button(self.panel, -1, _("Loading data..."))
return self.shares return self.shares
def create_action_buttons(self, comment=True): def create_action_buttons(self, comment=True):
self.like = wx.Button(self.panel, -1, _(u"&Like")) self.like = wx.Button(self.panel, -1, _("&Like"))
self.repost = wx.Button(self.panel, -1, _(u"Repost")) self.repost = wx.Button(self.panel, -1, _("Repost"))
if comment: self.comment = wx.Button(self.panel, -1, _(u"Add comment")) if comment: self.comment = wx.Button(self.panel, -1, _("Add comment"))
box = wx.BoxSizer(wx.HORIZONTAL) box = wx.BoxSizer(wx.HORIZONTAL)
box.Add(self.like, 0, wx.ALL, 5) box.Add(self.like, 0, wx.ALL, 5)
if comment: box.Add(self.comment, 0, wx.ALL, 5) if comment: box.Add(self.comment, 0, wx.ALL, 5)
return box return box
def create_tools_button(self): def create_tools_button(self):
self.tools = wx.Button(self.panel, -1, _(u"Actions")) self.tools = wx.Button(self.panel, -1, _("Actions"))
def create_dialog_buttons(self): def create_dialog_buttons(self):
self.close = wx.Button(self.panel, wx.ID_CANCEL, _(u"Close")) self.close = wx.Button(self.panel, wx.ID_CANCEL, _("Close"))
return self.close return self.close
def set_post(self, text): def set_post(self, text):
@ -98,13 +99,13 @@ class basicPost(widgetUtils.BaseDialog):
def set_likes(self, likes): def set_likes(self, likes):
if hasattr(self, "likes"): if hasattr(self, "likes"):
self.likes.SetLabel(_(u"{0} people like this").format(likes,)) self.likes.SetLabel(_("{0} people like this").format(likes,))
else: else:
return False return False
def set_shares(self, shares): def set_shares(self, shares):
if hasattr(self, "shares"): if hasattr(self, "shares"):
self.shares.SetLabel(_(u"Shared {0} times").format(shares,)) self.shares.SetLabel(_("Shared {0} times").format(shares,))
else: else:
return False return False
@ -150,40 +151,40 @@ class audio(widgetUtils.BaseDialog):
super(audio, self).__init__(parent=None, *args, **kwargs) super(audio, self).__init__(parent=None, *args, **kwargs)
panel = wx.Panel(self) panel = wx.Panel(self)
sizer = wx.BoxSizer(wx.VERTICAL) sizer = wx.BoxSizer(wx.VERTICAL)
lbl_list = wx.StaticText(panel, wx.NewId(), _(u"Audio &files")) lbl_list = wx.StaticText(panel, wx.NewId(), _("Audio &files"))
self.list = wx.ListBox(panel, wx.NewId()) self.list = wx.ListBox(panel, wx.NewId())
listS = wx.BoxSizer(wx.HORIZONTAL) listS = wx.BoxSizer(wx.HORIZONTAL)
listS.Add(lbl_list, 0, wx.ALL, 5) listS.Add(lbl_list, 0, wx.ALL, 5)
listS.Add(self.list, 0, wx.ALL, 5) listS.Add(self.list, 0, wx.ALL, 5)
sizer.Add(listS, 0, wx.ALL, 5) sizer.Add(listS, 0, wx.ALL, 5)
lbl_title = wx.StaticText(panel, wx.NewId(), _(u"&Title")) lbl_title = wx.StaticText(panel, wx.NewId(), _("&Title"))
self.title = wx.TextCtrl(panel, wx.NewId(), size=(413, -1), style=wx.TE_READONLY|wx.TE_MULTILINE) self.title = wx.TextCtrl(panel, wx.NewId(), size=(413, -1), style=wx.TE_READONLY|wx.TE_MULTILINE)
titleBox = wx.BoxSizer(wx.HORIZONTAL) titleBox = wx.BoxSizer(wx.HORIZONTAL)
titleBox.Add(lbl_title, 0, wx.ALL, 5) titleBox.Add(lbl_title, 0, wx.ALL, 5)
titleBox.Add(self.title, 0, wx.ALL, 5) titleBox.Add(self.title, 0, wx.ALL, 5)
sizer.Add(titleBox, 0, wx.ALL, 5) sizer.Add(titleBox, 0, wx.ALL, 5)
lbl_artist = wx.StaticText(panel, wx.NewId(), _(u"&Artist")) lbl_artist = wx.StaticText(panel, wx.NewId(), _("&Artist"))
self.artist = wx.TextCtrl(panel, wx.NewId(), size=(413, -1), style=wx.TE_READONLY|wx.TE_MULTILINE) self.artist = wx.TextCtrl(panel, wx.NewId(), size=(413, -1), style=wx.TE_READONLY|wx.TE_MULTILINE)
artistBox = wx.BoxSizer(wx.HORIZONTAL) artistBox = wx.BoxSizer(wx.HORIZONTAL)
artistBox.Add(lbl_artist, 0, wx.ALL, 5) artistBox.Add(lbl_artist, 0, wx.ALL, 5)
artistBox.Add(self.artist, 0, wx.ALL, 5) artistBox.Add(self.artist, 0, wx.ALL, 5)
sizer.Add(artistBox, 0, wx.ALL, 5) sizer.Add(artistBox, 0, wx.ALL, 5)
lbl_duration = wx.StaticText(panel, wx.NewId(), _(u"&Duration")) lbl_duration = wx.StaticText(panel, wx.NewId(), _("&Duration"))
self.duration = wx.TextCtrl(panel, wx.NewId(), size=(413, -1), style=wx.TE_READONLY|wx.TE_MULTILINE) self.duration = wx.TextCtrl(panel, wx.NewId(), size=(413, -1), style=wx.TE_READONLY|wx.TE_MULTILINE)
durationBox = wx.BoxSizer(wx.HORIZONTAL) durationBox = wx.BoxSizer(wx.HORIZONTAL)
durationBox.Add(lbl_duration, 0, wx.ALL, 5) durationBox.Add(lbl_duration, 0, wx.ALL, 5)
durationBox.Add(self.duration, 0, wx.ALL, 5) durationBox.Add(self.duration, 0, wx.ALL, 5)
sizer.Add(durationBox, 0, wx.ALL, 5) sizer.Add(durationBox, 0, wx.ALL, 5)
lbl_lyrics = wx.StaticText(panel, wx.NewId(), _(u"&Lyric")) lbl_lyrics = wx.StaticText(panel, wx.NewId(), _("&Lyric"))
self.lyric = wx.TextCtrl(panel, wx.NewId(), size=(500, 500), style=wx.TE_READONLY|wx.TE_MULTILINE) self.lyric = wx.TextCtrl(panel, wx.NewId(), size=(500, 500), style=wx.TE_READONLY|wx.TE_MULTILINE)
lbox = wx.BoxSizer(wx.HORIZONTAL) lbox = wx.BoxSizer(wx.HORIZONTAL)
lbox.Add(lbl_lyrics, 0, wx.ALL, 5) lbox.Add(lbl_lyrics, 0, wx.ALL, 5)
lbox.Add(self.lyric, 0, wx.ALL, 5) lbox.Add(self.lyric, 0, wx.ALL, 5)
sizer.Add(lbox, 0, wx.ALL, 5) sizer.Add(lbox, 0, wx.ALL, 5)
self.play = wx.Button(panel, wx.NewId(), _(u"&Play")) self.play = wx.Button(panel, wx.NewId(), _("&Play"))
self.download = wx.Button(panel, wx.NewId(), _(u"&Download")) self.download = wx.Button(panel, wx.NewId(), _("&Download"))
self.add = wx.Button(panel, wx.NewId(), _(u"&Add to your library")) self.add = wx.Button(panel, wx.NewId(), _("&Add to your library"))
self.remove = wx.Button(panel, wx.NewId(), _(u"&Remove from your library")) self.remove = wx.Button(panel, wx.NewId(), _("&Remove from your library"))
self.add.Enable(False) self.add.Enable(False)
self.remove.Enable(False) self.remove.Enable(False)
close = wx.Button(panel, wx.ID_CANCEL) close = wx.Button(panel, wx.ID_CANCEL)
@ -198,7 +199,7 @@ class audio(widgetUtils.BaseDialog):
getattr(self, button_name).Enable(state) getattr(self, button_name).Enable(state)
def get_destination_path(self, filename): def get_destination_path(self, filename):
saveFileDialog = wx.FileDialog(self, _(u"Save this file"), "", filename, _(u"Audio Files(*.mp3)|*.mp3"), wx.FD_SAVE | wx.FD_OVERWRITE_PROMPT) saveFileDialog = wx.FileDialog(self, _("Save this file"), "", filename, _("Audio Files(*.mp3)|*.mp3"), wx.FD_SAVE | wx.FD_OVERWRITE_PROMPT)
if saveFileDialog.ShowModal() == wx.ID_OK: if saveFileDialog.ShowModal() == wx.ID_OK:
return saveFileDialog.GetPath() return saveFileDialog.GetPath()
saveFileDialog.Destroy() saveFileDialog.Destroy()
@ -214,7 +215,7 @@ class friendship(widgetUtils.BaseDialog):
super(friendship, self).__init__(parent=None) super(friendship, self).__init__(parent=None)
panel = wx.Panel(self) panel = wx.Panel(self)
sizer = wx.BoxSizer(wx.VERTICAL) sizer = wx.BoxSizer(wx.VERTICAL)
self.friends = widgetUtils.list(panel, [_(u"Friend")], style=wx.LC_REPORT) self.friends = widgetUtils.list(panel, [_("Friend")], style=wx.LC_REPORT)
sizer.Add(self.friends.list, 0, wx.ALL, 5) sizer.Add(self.friends.list, 0, wx.ALL, 5)
close = wx.Button(panel, wx.ID_CANCEL) close = wx.Button(panel, wx.ID_CANCEL)
btnbox = wx.BoxSizer(wx.HORIZONTAL) btnbox = wx.BoxSizer(wx.HORIZONTAL)

View File

@ -1,5 +1,6 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
""" A set of dialogs related to user and community profiles.""" """ A set of dialogs related to user and community profiles."""
from __future__ import unicode_literals
import wx import wx
import widgetUtils import widgetUtils
@ -42,7 +43,7 @@ class mainInfo(wx.Panel):
def __init__(self, panel): def __init__(self, panel):
super(mainInfo, self).__init__(panel) super(mainInfo, self).__init__(panel)
sizer = wx.BoxSizer(wx.VERTICAL) sizer = wx.BoxSizer(wx.VERTICAL)
lblName = wx.StaticText(self, wx.NewId(), _(u"Name")) lblName = wx.StaticText(self, wx.NewId(), _("Name"))
self.name = wx.TextCtrl(self, wx.NewId(), style=wx.TE_READONLY|wx.TE_MULTILINE) self.name = wx.TextCtrl(self, wx.NewId(), style=wx.TE_READONLY|wx.TE_MULTILINE)
self.name.SetMinSize(text_size(self.name, 60)) self.name.SetMinSize(text_size(self.name, 60))
sizerName = wx.BoxSizer(wx.HORIZONTAL) sizerName = wx.BoxSizer(wx.HORIZONTAL)
@ -50,7 +51,7 @@ class mainInfo(wx.Panel):
sizerName.Add(self.name, 0, wx.ALL, 5) sizerName.Add(self.name, 0, wx.ALL, 5)
sizer.Add(sizerName, 0, wx.ALL, 5) sizer.Add(sizerName, 0, wx.ALL, 5)
lblStatus = wx.StaticText(self, wx.NewId(), _(u"Status")) lblStatus = wx.StaticText(self, wx.NewId(), _("Status"))
self.status = wx.TextCtrl(self, wx.NewId(), style=wx.TE_READONLY|wx.TE_MULTILINE) self.status = wx.TextCtrl(self, wx.NewId(), style=wx.TE_READONLY|wx.TE_MULTILINE)
self.status.Enable(False) self.status.Enable(False)
self.status.SetMinSize(text_size(self.status, 300)) self.status.SetMinSize(text_size(self.status, 300))
@ -59,7 +60,7 @@ class mainInfo(wx.Panel):
sizerStatus.Add(self.status, 0, wx.ALL, 5) sizerStatus.Add(self.status, 0, wx.ALL, 5)
sizer.Add(sizerStatus, 0, wx.ALL, 5) sizer.Add(sizerStatus, 0, wx.ALL, 5)
lblLastSeen = wx.StaticText(self, wx.NewId(), _(u"Last seen")) lblLastSeen = wx.StaticText(self, wx.NewId(), _("Last seen"))
self.last_seen = wx.TextCtrl(self, wx.NewId(), style=wx.TE_READONLY|wx.TE_MULTILINE) self.last_seen = wx.TextCtrl(self, wx.NewId(), style=wx.TE_READONLY|wx.TE_MULTILINE)
self.last_seen.Enable(False) self.last_seen.Enable(False)
sizerLastSeen = wx.BoxSizer(wx.HORIZONTAL) sizerLastSeen = wx.BoxSizer(wx.HORIZONTAL)
@ -67,7 +68,7 @@ class mainInfo(wx.Panel):
sizerLastSeen.Add(self.last_seen, 0, wx.ALL, 5) sizerLastSeen.Add(self.last_seen, 0, wx.ALL, 5)
sizer.Add(sizerLastSeen, 0, wx.ALL, 5) sizer.Add(sizerLastSeen, 0, wx.ALL, 5)
lblBDate = wx.StaticText(self, wx.NewId(), _(u"Birthdate")) lblBDate = wx.StaticText(self, wx.NewId(), _("Birthdate"))
self.bdate = wx.TextCtrl(self, wx.NewId(), style=wx.TE_READONLY|wx.TE_MULTILINE) self.bdate = wx.TextCtrl(self, wx.NewId(), style=wx.TE_READONLY|wx.TE_MULTILINE)
self.bdate.Enable(False) self.bdate.Enable(False)
sizerBDate = wx.BoxSizer(wx.HORIZONTAL) sizerBDate = wx.BoxSizer(wx.HORIZONTAL)
@ -79,7 +80,7 @@ class mainInfo(wx.Panel):
self.relation.Enable(False) self.relation.Enable(False)
sizer.Add(self.relation, 0, wx.ALL, 5) sizer.Add(self.relation, 0, wx.ALL, 5)
lblCity = wx.StaticText(self, wx.NewId(), _(u"Current city")) lblCity = wx.StaticText(self, wx.NewId(), _("Current city"))
self.city = wx.TextCtrl(self, wx.NewId(), style=wx.TE_READONLY|wx.TE_MULTILINE) self.city = wx.TextCtrl(self, wx.NewId(), style=wx.TE_READONLY|wx.TE_MULTILINE)
self.city.SetMinSize(text_size(self.city, 40)) self.city.SetMinSize(text_size(self.city, 40))
self.city.Enable(False) self.city.Enable(False)
@ -88,7 +89,7 @@ class mainInfo(wx.Panel):
sizerCity.Add(self.city, 0, wx.ALL, 5) sizerCity.Add(self.city, 0, wx.ALL, 5)
sizer.Add(sizerCity, 0, wx.ALL, 5) sizer.Add(sizerCity, 0, wx.ALL, 5)
lblHometown = wx.StaticText(self, wx.NewId(), _(u"Home Town")) lblHometown = wx.StaticText(self, wx.NewId(), _("Home Town"))
self.home_town = wx.TextCtrl(self, wx.NewId(), style=wx.TE_READONLY|wx.TE_MULTILINE) self.home_town = wx.TextCtrl(self, wx.NewId(), style=wx.TE_READONLY|wx.TE_MULTILINE)
self.home_town.SetMinSize(text_size(self.home_town, 40)) self.home_town.SetMinSize(text_size(self.home_town, 40))
self.home_town.Enable(False) self.home_town.Enable(False)
@ -97,11 +98,11 @@ class mainInfo(wx.Panel):
sizerHometown.Add(self.home_town, 0, wx.ALL, 5) sizerHometown.Add(self.home_town, 0, wx.ALL, 5)
sizer.Add(sizerHometown, 0, wx.ALL, 5) sizer.Add(sizerHometown, 0, wx.ALL, 5)
lblWebsite = wx.StaticText(self, wx.NewId(), _(u"Website")) lblWebsite = wx.StaticText(self, wx.NewId(), _("Website"))
self.website = wx.TextCtrl(self, wx.NewId(), style=wx.TE_READONLY|wx.TE_MULTILINE)#size=(500, -1)) self.website = wx.TextCtrl(self, wx.NewId(), style=wx.TE_READONLY|wx.TE_MULTILINE)#size=(500, -1))
self.website.SetMinSize(text_size(self.website, 90)) self.website.SetMinSize(text_size(self.website, 90))
self.website.Enable(False) self.website.Enable(False)
self.go_site = wx.Button(self, -1, _(u"Visit website")) self.go_site = wx.Button(self, -1, _("Visit website"))
self.go_site.Enable(False) self.go_site.Enable(False)
sizerWebsite = wx.BoxSizer(wx.HORIZONTAL) sizerWebsite = wx.BoxSizer(wx.HORIZONTAL)
sizerWebsite.Add(lblWebsite, 0, wx.ALL, 5) sizerWebsite.Add(lblWebsite, 0, wx.ALL, 5)
@ -109,7 +110,7 @@ class mainInfo(wx.Panel):
sizerWebsite.Add(self.go_site, 1, wx.ALL, 5) sizerWebsite.Add(self.go_site, 1, wx.ALL, 5)
sizer.Add(sizerWebsite, 1, wx.ALL, 5) sizer.Add(sizerWebsite, 1, wx.ALL, 5)
lblOccupation = wx.StaticText(self, wx.NewId(), _(u"Occupation")) lblOccupation = wx.StaticText(self, wx.NewId(), _("Occupation"))
self.occupation = wx.TextCtrl(self, wx.NewId(), style=wx.TE_READONLY|wx.TE_MULTILINE) self.occupation = wx.TextCtrl(self, wx.NewId(), style=wx.TE_READONLY|wx.TE_MULTILINE)
self.occupation.SetMinSize(text_size(self.occupation, 90)) self.occupation.SetMinSize(text_size(self.occupation, 90))
self.occupation.Enable(False) self.occupation.Enable(False)
@ -129,7 +130,7 @@ class userProfile(widgetUtils.BaseDialog):
def create_controls(self, section): def create_controls(self, section):
if section == "main_info": if section == "main_info":
self.main_info = mainInfo(self.notebook) self.main_info = mainInfo(self.notebook)
self.notebook.AddPage(self.main_info, _(u"Basic information")) self.notebook.AddPage(self.main_info, _("Basic information"))
self.main_info.SetFocus() self.main_info.SetFocus()
def realice(self): def realice(self):

View File

@ -1,4 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from __future__ import unicode_literals
import widgetUtils import widgetUtils
import wx import wx
@ -7,17 +8,17 @@ class searchAudioDialog(widgetUtils.BaseDialog):
super(searchAudioDialog, self).__init__(None, -1) super(searchAudioDialog, self).__init__(None, -1)
panel = wx.Panel(self) panel = wx.Panel(self)
sizer = wx.BoxSizer(wx.VERTICAL) sizer = wx.BoxSizer(wx.VERTICAL)
self.SetTitle(_(u"audio Search")) self.SetTitle(_("audio Search"))
label = wx.StaticText(panel, -1, _(u"&Search")) label = wx.StaticText(panel, -1, _("&Search"))
self.term = wx.TextCtrl(panel, -1, value) self.term = wx.TextCtrl(panel, -1, value)
dc = wx.WindowDC(self.term) dc = wx.WindowDC(self.term)
dc.SetFont(self.term.GetFont()) dc.SetFont(self.term.GetFont())
self.term.SetSize(dc.GetTextExtent("0"*40)) self.term.SetSize(dc.GetTextExtent("0"*40))
sizer.Add(label, 0, wx.ALL, 5) sizer.Add(label, 0, wx.ALL, 5)
sizer.Add(self.term, 0, wx.ALL, 5) sizer.Add(self.term, 0, wx.ALL, 5)
ok = wx.Button(panel, wx.ID_OK, _(u"&OK")) ok = wx.Button(panel, wx.ID_OK, _("&OK"))
ok.SetDefault() ok.SetDefault()
cancel = wx.Button(panel, wx.ID_CANCEL, _(u"&Close")) cancel = wx.Button(panel, wx.ID_CANCEL, _("&Close"))
btnsizer = wx.BoxSizer() btnsizer = wx.BoxSizer()
btnsizer.Add(ok, 0, wx.ALL, 5) btnsizer.Add(ok, 0, wx.ALL, 5)
btnsizer.Add(cancel, 0, wx.ALL, 5) btnsizer.Add(cancel, 0, wx.ALL, 5)
@ -30,29 +31,29 @@ class searchVideoDialog(widgetUtils.BaseDialog):
super(searchVideoDialog, self).__init__(None, -1) super(searchVideoDialog, self).__init__(None, -1)
panel = wx.Panel(self) panel = wx.Panel(self)
sizer = wx.BoxSizer(wx.VERTICAL) sizer = wx.BoxSizer(wx.VERTICAL)
self.SetTitle(_(u"video Search")) self.SetTitle(_("video Search"))
label = wx.StaticText(panel, -1, _(u"&Search")) label = wx.StaticText(panel, -1, _("&Search"))
self.term = wx.TextCtrl(panel, -1, value) self.term = wx.TextCtrl(panel, -1, value)
dc = wx.WindowDC(self.term) dc = wx.WindowDC(self.term)
dc.SetFont(self.term.GetFont()) dc.SetFont(self.term.GetFont())
self.term.SetSize(dc.GetTextExtent("0"*40)) self.term.SetSize(dc.GetTextExtent("0"*40))
sizer.Add(label, 0, wx.ALL, 5) sizer.Add(label, 0, wx.ALL, 5)
sizer.Add(self.term, 0, wx.ALL, 5) sizer.Add(self.term, 0, wx.ALL, 5)
sort_order = wx.StaticText(panel, -1, _(U"&Sort order by: ")) sort_order = wx.StaticText(panel, -1, _("&Sort order by: "))
self.sortorder = wx.ComboBox(panel, wx.NewId(), choices=[_(u"Date added"), _(u"Duration"), _(u"Popularity")], value=_(u"Popularity"), style=wx.CB_READONLY) self.sortorder = wx.ComboBox(panel, wx.NewId(), choices=[_("Date added"), _("Duration"), _("Popularity")], value=_("Popularity"), style=wx.CB_READONLY)
rBox = wx.BoxSizer(wx.HORIZONTAL) rBox = wx.BoxSizer(wx.HORIZONTAL)
rBox.Add(sort_order, 0, wx.ALL, 5) rBox.Add(sort_order, 0, wx.ALL, 5)
rBox.Add(self.sortorder, 0, wx.ALL, 5) rBox.Add(self.sortorder, 0, wx.ALL, 5)
sizer.Add(rBox, 0, wx.ALL, 5) sizer.Add(rBox, 0, wx.ALL, 5)
self.hd = wx.CheckBox(panel, wx.NewId(), _(u"Search only for videos in &High definition")) self.hd = wx.CheckBox(panel, wx.NewId(), _("Search only for videos in &High definition"))
self.hd.SetValue(False) self.hd.SetValue(False)
sizer.Add(self.hd, 0, wx.ALL, 5) sizer.Add(self.hd, 0, wx.ALL, 5)
self.safe_search = wx.CheckBox(panel, wx.NewId(), _(u"S&afe search")) self.safe_search = wx.CheckBox(panel, wx.NewId(), _("S&afe search"))
self.safe_search.SetValue(True) self.safe_search.SetValue(True)
sizer.Add(self.safe_search, 0, wx.ALL, 5) sizer.Add(self.safe_search, 0, wx.ALL, 5)
ok = wx.Button(panel, wx.ID_OK, _(u"&OK")) ok = wx.Button(panel, wx.ID_OK, _("&OK"))
ok.SetDefault() ok.SetDefault()
cancel = wx.Button(panel, wx.ID_CANCEL, _(u"&Close")) cancel = wx.Button(panel, wx.ID_CANCEL, _("&Close"))
btnsizer = wx.BoxSizer() btnsizer = wx.BoxSizer()
btnsizer.Add(ok, 0, wx.ALL, 5) btnsizer.Add(ok, 0, wx.ALL, 5)
btnsizer.Add(cancel, 0, wx.ALL, 5) btnsizer.Add(cancel, 0, wx.ALL, 5)

View File

@ -1,4 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from __future__ import unicode_literals
import wx import wx
import widgetUtils import widgetUtils
@ -34,33 +35,33 @@ class selectAlbum(wx.Dialog):
class selectPeople(widgetUtils.BaseDialog): class selectPeople(widgetUtils.BaseDialog):
def __init__(self, users=[]): def __init__(self, users=[]):
super(selectPeople, self).__init__(parent=None, title=_(u"Tag friends")) super(selectPeople, self).__init__(parent=None, title=_("Tag friends"))
self.indexes = [] self.indexes = []
self.users_list = users self.users_list = users
panel = wx.Panel(self) panel = wx.Panel(self)
sizer = wx.BoxSizer(wx.HORIZONTAL) sizer = wx.BoxSizer(wx.HORIZONTAL)
userLabel = wx.StaticText(panel, -1, _(u"All friends")) userLabel = wx.StaticText(panel, -1, _("All friends"))
self.cb = wx.ComboBox(panel, -1, choices=users, value=users[0]) self.cb = wx.ComboBox(panel, -1, choices=users, value=users[0])
self.cb.SetFocus() self.cb.SetFocus()
userSizer = wx.BoxSizer() userSizer = wx.BoxSizer()
userSizer.Add(userLabel, 0, wx.ALL, 5) userSizer.Add(userLabel, 0, wx.ALL, 5)
userSizer.Add(self.cb, 0, wx.ALL, 5) userSizer.Add(self.cb, 0, wx.ALL, 5)
self.add = wx.Button(panel, wx.NewId(), _(u"Select")) self.add = wx.Button(panel, wx.NewId(), _("Select"))
self.add.Bind(wx.EVT_BUTTON, self.add_user) self.add.Bind(wx.EVT_BUTTON, self.add_user)
userSizer.Add(self.add, 0, wx.ALL, 5) userSizer.Add(self.add, 0, wx.ALL, 5)
sizer.Add(userSizer, 0, wx.ALL, 5) sizer.Add(userSizer, 0, wx.ALL, 5)
lbl = wx.StaticText(panel, wx.NewId(), _(u"Tagged users")) lbl = wx.StaticText(panel, wx.NewId(), _("Tagged users"))
self.users = wx.ListBox(panel, -1) self.users = wx.ListBox(panel, -1)
self.remove = wx.Button(panel, wx.NewId(), _(u"Remove")) self.remove = wx.Button(panel, wx.NewId(), _("Remove"))
self.remove.Bind(wx.EVT_BUTTON, self.remove_user) self.remove.Bind(wx.EVT_BUTTON, self.remove_user)
selectionSizer = wx.BoxSizer(wx.HORIZONTAL) selectionSizer = wx.BoxSizer(wx.HORIZONTAL)
selectionSizer.Add(lbl, 0, wx.ALL, 5) selectionSizer.Add(lbl, 0, wx.ALL, 5)
selectionSizer.Add(self.users, 0, wx.ALL, 5) selectionSizer.Add(self.users, 0, wx.ALL, 5)
selectionSizer.Add(self.remove, 0, wx.ALL, 5) selectionSizer.Add(self.remove, 0, wx.ALL, 5)
sizer.Add(selectionSizer, 0, wx.ALL, 5) sizer.Add(selectionSizer, 0, wx.ALL, 5)
ok = wx.Button(panel, wx.ID_OK, _(u"&OK")) ok = wx.Button(panel, wx.ID_OK, _("&OK"))
ok.SetDefault() ok.SetDefault()
cancel = wx.Button(panel, wx.ID_CANCEL, _(u"&Close")) cancel = wx.Button(panel, wx.ID_CANCEL, _("&Close"))
btnsizer = wx.BoxSizer() btnsizer = wx.BoxSizer()
btnsizer.Add(ok, 0, wx.ALL, 5) btnsizer.Add(ok, 0, wx.ALL, 5)
btnsizer.Add(cancel, 0, wx.ALL, 5) btnsizer.Add(cancel, 0, wx.ALL, 5)
@ -93,28 +94,28 @@ class selectAttachment(widgetUtils.BaseDialog):
self.attachments_list = attachments self.attachments_list = attachments
panel = wx.Panel(self) panel = wx.Panel(self)
sizer = wx.BoxSizer(wx.HORIZONTAL) sizer = wx.BoxSizer(wx.HORIZONTAL)
label = wx.StaticText(panel, -1, _(u"Available attachments")) label = wx.StaticText(panel, -1, _("Available attachments"))
self.cb = wx.ComboBox(panel, -1, choices=attachments, value=attachments[0]) self.cb = wx.ComboBox(panel, -1, choices=attachments, value=attachments[0])
self.cb.SetFocus() self.cb.SetFocus()
attachmentSizer = wx.BoxSizer() attachmentSizer = wx.BoxSizer()
attachmentSizer.Add(label, 0, wx.ALL, 5) attachmentSizer.Add(label, 0, wx.ALL, 5)
attachmentSizer.Add(self.cb, 0, wx.ALL, 5) attachmentSizer.Add(self.cb, 0, wx.ALL, 5)
self.add = wx.Button(panel, wx.NewId(), _(u"Select")) self.add = wx.Button(panel, wx.NewId(), _("Select"))
self.add.Bind(wx.EVT_BUTTON, self.add_attachment) self.add.Bind(wx.EVT_BUTTON, self.add_attachment)
attachmentSizer.Add(self.add, 0, wx.ALL, 5) attachmentSizer.Add(self.add, 0, wx.ALL, 5)
sizer.Add(attachmentSizer, 0, wx.ALL, 5) sizer.Add(attachmentSizer, 0, wx.ALL, 5)
lbl = wx.StaticText(panel, wx.NewId(), _(u"Selected attachments")) lbl = wx.StaticText(panel, wx.NewId(), _("Selected attachments"))
self.attachments = wx.ListBox(panel, -1) self.attachments = wx.ListBox(panel, -1)
self.remove = wx.Button(panel, wx.NewId(), _(u"Remove")) self.remove = wx.Button(panel, wx.NewId(), _("Remove"))
self.remove.Bind(wx.EVT_BUTTON, self.remove_attachment) self.remove.Bind(wx.EVT_BUTTON, self.remove_attachment)
selectionSizer = wx.BoxSizer(wx.HORIZONTAL) selectionSizer = wx.BoxSizer(wx.HORIZONTAL)
selectionSizer.Add(lbl, 0, wx.ALL, 5) selectionSizer.Add(lbl, 0, wx.ALL, 5)
selectionSizer.Add(self.attachments, 0, wx.ALL, 5) selectionSizer.Add(self.attachments, 0, wx.ALL, 5)
selectionSizer.Add(self.remove, 0, wx.ALL, 5) selectionSizer.Add(self.remove, 0, wx.ALL, 5)
sizer.Add(selectionSizer, 0, wx.ALL, 5) sizer.Add(selectionSizer, 0, wx.ALL, 5)
ok = wx.Button(panel, wx.ID_OK, _(u"&OK")) ok = wx.Button(panel, wx.ID_OK, _("&OK"))
ok.SetDefault() ok.SetDefault()
cancel = wx.Button(panel, wx.ID_CANCEL, _(u"&Close")) cancel = wx.Button(panel, wx.ID_CANCEL, _("&Close"))
btnsizer = wx.BoxSizer() btnsizer = wx.BoxSizer()
btnsizer.Add(ok, 0, wx.ALL, 5) btnsizer.Add(ok, 0, wx.ALL, 5)
btnsizer.Add(cancel, 0, wx.ALL, 5) btnsizer.Add(cancel, 0, wx.ALL, 5)

View File

@ -1,31 +1,32 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from __future__ import unicode_literals
import wx import wx
import widgetUtils import widgetUtils
class timelineDialog(widgetUtils.BaseDialog): class timelineDialog(widgetUtils.BaseDialog):
def __init__(self, users=[]): def __init__(self, users=[]):
super(timelineDialog, self).__init__(parent=None, title=_(u"New timeline for {0}").format(users[0],)) super(timelineDialog, self).__init__(parent=None, title=_("New timeline for {0}").format(users[0],))
panel = wx.Panel(self) panel = wx.Panel(self)
sizer = wx.BoxSizer(wx.HORIZONTAL) sizer = wx.BoxSizer(wx.HORIZONTAL)
userLabel = wx.StaticText(panel, -1, _(u"User")) userLabel = wx.StaticText(panel, -1, _("User"))
self.cb = wx.ComboBox(panel, -1, choices=users, value=users[0]) self.cb = wx.ComboBox(panel, -1, choices=users, value=users[0])
self.cb.SetFocus() self.cb.SetFocus()
userSizer = wx.BoxSizer() userSizer = wx.BoxSizer()
userSizer.Add(userLabel, 0, wx.ALL, 5) userSizer.Add(userLabel, 0, wx.ALL, 5)
userSizer.Add(self.cb, 0, wx.ALL, 5) userSizer.Add(self.cb, 0, wx.ALL, 5)
actionsstatic = wx.StaticBox(panel, label=_(u"Buffer type")) actionsstatic = wx.StaticBox(panel, label=_("Buffer type"))
self.wall = wx.RadioButton(panel, wx.NewId(), _(u"&Wall posts"), style=wx.RB_GROUP) self.wall = wx.RadioButton(panel, wx.NewId(), _("&Wall posts"), style=wx.RB_GROUP)
self.audio = wx.RadioButton(panel, wx.NewId(), _(u"Audio")) self.audio = wx.RadioButton(panel, wx.NewId(), _("Audio"))
self.friends = wx.RadioButton(panel, wx.NewId(), _(u"Friends")) self.friends = wx.RadioButton(panel, wx.NewId(), _("Friends"))
radioSizer = wx.StaticBoxSizer(actionsstatic, wx.HORIZONTAL) radioSizer = wx.StaticBoxSizer(actionsstatic, wx.HORIZONTAL)
radioSizer.Add(self.wall, 0, wx.ALL, 5) radioSizer.Add(self.wall, 0, wx.ALL, 5)
radioSizer.Add(self.audio, 0, wx.ALL, 5) radioSizer.Add(self.audio, 0, wx.ALL, 5)
radioSizer.Add(self.friends, 0, wx.ALL, 5) radioSizer.Add(self.friends, 0, wx.ALL, 5)
sizer.Add(radioSizer, 0, wx.ALL, 5) sizer.Add(radioSizer, 0, wx.ALL, 5)
ok = wx.Button(panel, wx.ID_OK, _(u"&OK")) ok = wx.Button(panel, wx.ID_OK, _("&OK"))
ok.SetDefault() ok.SetDefault()
cancel = wx.Button(panel, wx.ID_CANCEL, _(u"&Close")) cancel = wx.Button(panel, wx.ID_CANCEL, _("&Close"))
btnsizer = wx.BoxSizer() btnsizer = wx.BoxSizer()
btnsizer.Add(ok, 0, wx.ALL, 5) btnsizer.Add(ok, 0, wx.ALL, 5)
btnsizer.Add(cancel, 0, wx.ALL, 5) btnsizer.Add(cancel, 0, wx.ALL, 5)

View File

@ -1,9 +1,10 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from __future__ import unicode_literals
import wx import wx
class urlList(wx.Dialog): class urlList(wx.Dialog):
def __init__(self): def __init__(self):
super(urlList, self).__init__(parent=None, title=_(u"Select URL")) super(urlList, self).__init__(parent=None, title=_("Select URL"))
panel = wx.Panel(self) panel = wx.Panel(self)
self.lista = wx.ListBox(panel, -1) self.lista = wx.ListBox(panel, -1)
self.lista.SetFocus() self.lista.SetFocus()

View File

@ -1,4 +1,6 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from __future__ import unicode_literals
from builtins import range
import wx import wx
import wx.adv import wx.adv
import application import application
@ -9,51 +11,51 @@ class mainWindow(wx.Frame):
mb = wx.MenuBar() mb = wx.MenuBar()
app_ = wx.Menu() app_ = wx.Menu()
create = wx.Menu() create = wx.Menu()
# self.audio_album = create.Append(wx.NewId(), _(u"Audio album")) # self.audio_album = create.Append(wx.NewId(), _("Audio album"))
self.video_album = create.Append(wx.NewId(), _(u"Video album")) self.video_album = create.Append(wx.NewId(), _("Video album"))
app_.Append(wx.NewId(), _(u"Create"), create) app_.Append(wx.NewId(), _("Create"), create)
delete = wx.Menu() delete = wx.Menu()
# self.delete_audio_album = delete.Append(wx.NewId(), _(u"Audio album")) # self.delete_audio_album = delete.Append(wx.NewId(), _("Audio album"))
self.delete_video_album = delete.Append(wx.NewId(), _(u"Video album")) self.delete_video_album = delete.Append(wx.NewId(), _("Video album"))
app_.Append(wx.NewId(), _(u"Delete"), delete) app_.Append(wx.NewId(), _("Delete"), delete)
self.settings_dialog = app_.Append(wx.NewId(), _(u"Preferences")) self.settings_dialog = app_.Append(wx.NewId(), _("Preferences"))
me = wx.Menu() me = wx.Menu()
profile = wx.Menu() profile = wx.Menu()
self.view_profile = profile.Append(wx.NewId(), _(u"View profile")) self.view_profile = profile.Append(wx.NewId(), _("View profile"))
# self.edit_profile = profile.Append(wx.NewId(), _(u"Edit profile")) # self.edit_profile = profile.Append(wx.NewId(), _("Edit profile"))
self.open_in_browser = profile.Append(wx.NewId(), _(u"Open in browser")) self.open_in_browser = profile.Append(wx.NewId(), _("Open in browser"))
me.Append(wx.NewId(), _(u"Profile"), profile) me.Append(wx.NewId(), _("Profile"), profile)
self.set_status = me.Append(wx.NewId(), _(u"Set status message")) self.set_status = me.Append(wx.NewId(), _("Set status message"))
buffer = wx.Menu() buffer = wx.Menu()
search = wx.Menu() search = wx.Menu()
self.search_audios = search.Append(wx.NewId(), _(u"Audio")) self.search_audios = search.Append(wx.NewId(), _("Audio"))
self.search_videos = search.Append(wx.NewId(), _(u"Video")) self.search_videos = search.Append(wx.NewId(), _("Video"))
self.timeline = buffer.Append(wx.NewId(), _(u"&New timeline")) self.timeline = buffer.Append(wx.NewId(), _("&New timeline"))
buffer.Append(wx.NewId(), _(u"Search"), search) buffer.Append(wx.NewId(), _("Search"), search)
self.update_buffer = buffer.Append(wx.NewId(), _(u"Update current buffer")) self.update_buffer = buffer.Append(wx.NewId(), _("Update current buffer"))
self.load_previous_items = buffer.Append(wx.NewId(), _(u"Load previous items")) self.load_previous_items = buffer.Append(wx.NewId(), _("Load previous items"))
self.remove_buffer_ = buffer.Append(wx.NewId(), _(u"&Remove buffer")) self.remove_buffer_ = buffer.Append(wx.NewId(), _("&Remove buffer"))
mb.Append(app_, _(u"Application")) mb.Append(app_, _("Application"))
mb.Append(me, _(u"Me")) mb.Append(me, _("Me"))
mb.Append(buffer, _(u"Buffer")) mb.Append(buffer, _("Buffer"))
player = wx.Menu() player = wx.Menu()
self.player_play = player.Append(wx.NewId(), _(u"Play")) self.player_play = player.Append(wx.NewId(), _("Play"))
self.player_play_all = player.Append(wx.NewId(), _(u"Play all")) self.player_play_all = player.Append(wx.NewId(), _("Play all"))
self.player_stop = player.Append(wx.NewId(), _(u"Stop")) self.player_stop = player.Append(wx.NewId(), _("Stop"))
self.player_previous = player.Append(wx.NewId(), _(u"Previous")) self.player_previous = player.Append(wx.NewId(), _("Previous"))
self.player_next = player.Append(wx.NewId(), _(u"Next")) self.player_next = player.Append(wx.NewId(), _("Next"))
self.player_shuffle = player.AppendCheckItem(wx.NewId(), _(u"Shuffle")) self.player_shuffle = player.AppendCheckItem(wx.NewId(), _("Shuffle"))
self.player_volume_up = player.Append(wx.NewId(), _(u"Volume up")) self.player_volume_up = player.Append(wx.NewId(), _("Volume up"))
self.player_volume_down = player.Append(wx.NewId(), _(u"Volume down")) self.player_volume_down = player.Append(wx.NewId(), _("Volume down"))
self.player_mute = player.Append(wx.NewId(), _(u"Mute")) self.player_mute = player.Append(wx.NewId(), _("Mute"))
help_ = wx.Menu() help_ = wx.Menu()
self.about = help_.Append(wx.NewId(), _(u"About {0}").format(application.name,)) self.about = help_.Append(wx.NewId(), _("About {0}").format(application.name,))
self.documentation = help_.Append(wx.NewId(), _(u"Manual")) self.documentation = help_.Append(wx.NewId(), _("Manual"))
self.check_for_updates = help_.Append(wx.NewId(), _(u"Check for updates")) self.check_for_updates = help_.Append(wx.NewId(), _("Check for updates"))
self.changelog = help_.Append(wx.NewId(), _(u"Chan&gelog")) self.changelog = help_.Append(wx.NewId(), _("Chan&gelog"))
self.report = help_.Append(wx.NewId(), _(u"Report an error")) self.report = help_.Append(wx.NewId(), _("Report an error"))
mb.Append(player, _(u"Audio player")) mb.Append(player, _("Audio player"))
mb.Append(help_, _(u"Help")) mb.Append(help_, _("Help"))
self.SetMenuBar(mb) self.SetMenuBar(mb)
def __init__(self): def __init__(self):
@ -76,7 +78,7 @@ class mainWindow(wx.Frame):
self.sb.SetStatusText(status) self.sb.SetStatusText(status)
def connection_error(self): def connection_error(self):
wx.MessageDialog(self, _(u"There is a connection error. Check your internet connection and try again later."), _(u"Connection error"), wx.ICON_ERROR).ShowModal() wx.MessageDialog(self, _("There is a connection error. Check your internet connection and try again later."), _("Connection error"), wx.ICON_ERROR).ShowModal()
def get_buffer_count(self): def get_buffer_count(self):
return self.tb.GetPageCount() return self.tb.GetPageCount()
@ -88,7 +90,7 @@ class mainWindow(wx.Frame):
return self.tb.InsertSubPage(pos, buffer, name) return self.tb.InsertSubPage(pos, buffer, name)
def search(self, name_): def search(self, name_):
for i in xrange(0, self.tb.GetPageCount()): for i in range(0, self.tb.GetPageCount()):
if self.tb.GetPage(i).name == name_: return i if self.tb.GetPage(i).name == name_: return i
def get_current_buffer(self): def get_current_buffer(self):

View File

@ -1,41 +1,42 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from __future__ import unicode_literals
import wx import wx
class postMenu(wx.Menu): class postMenu(wx.Menu):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
super(postMenu, self).__init__(*args, **kwargs) super(postMenu, self).__init__(*args, **kwargs)
self.open = wx.MenuItem(self, wx.NewId(), _(u"Open")) self.open = wx.MenuItem(self, wx.NewId(), _("Open"))
self.Append(self.open) self.Append(self.open)
self.like = wx.MenuItem(self, wx.NewId(), _(u"Like")) self.like = wx.MenuItem(self, wx.NewId(), _("Like"))
self.Append(self.like) self.Append(self.like)
self.dislike = wx.MenuItem(self, wx.NewId(), _(u"Dislike")) self.dislike = wx.MenuItem(self, wx.NewId(), _("Dislike"))
self.dislike.Enable(False) self.dislike.Enable(False)
self.Append(self.dislike) self.Append(self.dislike)
self.comment = wx.MenuItem(self, wx.NewId(), _(u"Add comment")) self.comment = wx.MenuItem(self, wx.NewId(), _("Add comment"))
self.Append(self.comment) self.Append(self.comment)
self.post_in_wall = wx.MenuItem(self, wx.NewId(), _(u"Post to this profile")) self.post_in_wall = wx.MenuItem(self, wx.NewId(), _("Post to this profile"))
self.post_in_wall.Enable(False) self.post_in_wall.Enable(False)
self.Append(self.post_in_wall) self.Append(self.post_in_wall)
self.view_profile = wx.MenuItem(self, wx.NewId(), _(u"View user profile")) self.view_profile = wx.MenuItem(self, wx.NewId(), _("View user profile"))
self.Append(self.view_profile) self.Append(self.view_profile)
def create_specific_post_options(self): def create_specific_post_options(self):
self.update = wx.MenuItem(self, wx.NewId(), _(u"Update")) self.update = wx.MenuItem(self, wx.NewId(), _("Update"))
self.Append(self.update) self.Append(self.update)
self.delete = wx.MenuItem(self, wx.NewId(), _(u"Delete")) self.delete = wx.MenuItem(self, wx.NewId(), _("Delete"))
self.Append(self.delete) self.Append(self.delete)
class audioMenu(wx.Menu): class audioMenu(wx.Menu):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
super(audioMenu, self).__init__(*args, **kwargs) super(audioMenu, self).__init__(*args, **kwargs)
self.open = wx.MenuItem(self, wx.NewId(), _(u"&Open")) self.open = wx.MenuItem(self, wx.NewId(), _("&Open"))
self.Append(self.open) self.Append(self.open)
self.play = wx.MenuItem(self, wx.NewId(), _(u"&Play")) self.play = wx.MenuItem(self, wx.NewId(), _("&Play"))
self.Append(self.play) self.Append(self.play)
self.library = wx.MenuItem(self, wx.NewId(), _(u"&Add to library")) self.library = wx.MenuItem(self, wx.NewId(), _("&Add to library"))
self.Append(self.library) self.Append(self.library)
self.move = wx.MenuItem(self, wx.NewId(), _(u"Move to album")) self.move = wx.MenuItem(self, wx.NewId(), _("Move to album"))
self.Append(self.move) self.Append(self.move)
class peopleMenu(wx.Menu): class peopleMenu(wx.Menu):
@ -43,47 +44,47 @@ class peopleMenu(wx.Menu):
super(peopleMenu, self).__init__(*args, **kwargs) super(peopleMenu, self).__init__(*args, **kwargs)
if is_request: if is_request:
self.create_extra_items() self.create_extra_items()
self.view_profile = wx.MenuItem(self, wx.NewId(), _(u"View profile")) self.view_profile = wx.MenuItem(self, wx.NewId(), _("View profile"))
self.Append(self.view_profile) self.Append(self.view_profile)
self.message = wx.MenuItem(self, wx.NewId(), _(u"Send a message")) self.message = wx.MenuItem(self, wx.NewId(), _("Send a message"))
self.Append(self.message) self.Append(self.message)
self.timeline = wx.MenuItem(self, wx.NewId(), _(u"Open timeline")) self.timeline = wx.MenuItem(self, wx.NewId(), _("Open timeline"))
self.Append(self.timeline) self.Append(self.timeline)
self.common_friends = wx.MenuItem(self, wx.NewId(), _(u"View friends in common")) self.common_friends = wx.MenuItem(self, wx.NewId(), _("View friends in common"))
self.Append(self.common_friends) self.Append(self.common_friends)
def create_extra_items(self): def create_extra_items(self):
self.accept = wx.MenuItem(self, wx.NewId(), _(u"Accept")) self.accept = wx.MenuItem(self, wx.NewId(), _("Accept"))
self.Append(self.accept) self.Append(self.accept)
self.decline = wx.MenuItem(self, wx.NewId(), _(u"Decline")) self.decline = wx.MenuItem(self, wx.NewId(), _("Decline"))
self.Append(self.decline) self.Append(self.decline)
self.keep_as_follower = wx.MenuItem(self, wx.NewId(), _(u"Keep as follower")) self.keep_as_follower = wx.MenuItem(self, wx.NewId(), _("Keep as follower"))
self.Append(self.keep_as_follower) self.Append(self.keep_as_follower)
class commentMenu(wx.Menu): class commentMenu(wx.Menu):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
super(commentMenu, self).__init__(*args, **kwargs) super(commentMenu, self).__init__(*args, **kwargs)
self.open = wx.MenuItem(self, wx.NewId(), _(u"Open")) self.open = wx.MenuItem(self, wx.NewId(), _("Open"))
self.Append(self.open) self.Append(self.open)
self.like = wx.MenuItem(self, wx.NewId(), _(u"Like")) self.like = wx.MenuItem(self, wx.NewId(), _("Like"))
self.Append(self.like) self.Append(self.like)
self.unlike = wx.MenuItem(self, -1, _(u"Unlike")) self.unlike = wx.MenuItem(self, -1, _("Unlike"))
self.Append(self.unlike) self.Append(self.unlike)
def create_specific_comment_options(self): def create_specific_comment_options(self):
self.delete = wx.MenuItem(self, wx.NewId(), _(u"Delete")) self.delete = wx.MenuItem(self, wx.NewId(), _("Delete"))
self.Append(self.delete) self.Append(self.delete)
class notificationsMenu(wx.Menu): class notificationsMenu(wx.Menu):
def __init__(self): def __init__(self):
super(notificationsMenu, self).__init__() super(notificationsMenu, self).__init__()
self.mark_as_read = wx.MenuItem(self, wx.NewId(), _(u"Mark as read")) self.mark_as_read = wx.MenuItem(self, wx.NewId(), _("Mark as read"))
self.Append(self.mark_as_read) self.Append(self.mark_as_read)
class attachMenu(wx.Menu): class attachMenu(wx.Menu):
def __init__(self): def __init__(self):
super(attachMenu, self).__init__() super(attachMenu, self).__init__()
self.upload = wx.MenuItem(self, wx.NewId(), _(u"Upload from computer")) self.upload = wx.MenuItem(self, wx.NewId(), _("Upload from computer"))
self.Append(self.upload) self.Append(self.upload)
self.add = wx.MenuItem(self, wx.NewId(), _(u"Add from VK")) self.add = wx.MenuItem(self, wx.NewId(), _("Add from VK"))
self.Append(self.add) self.Append(self.add)

View File

@ -1,4 +1,6 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
#from __future__ import unicode_literals
from __future__ import unicode_literals
import wx import wx
import widgetUtils import widgetUtils
from pubsub import pub from pubsub import pub
@ -6,8 +8,8 @@ from pubsub import pub
class homeTab(wx.Panel): class homeTab(wx.Panel):
def create_list(self): def create_list(self):
self.lbl = wx.StaticText(self, wx.NewId(), _(u"Po&sts")) self.lbl = wx.StaticText(self, wx.NewId(), _("Po&sts"))
self.list = widgetUtils.list(self, *[_(u"User"), _(u"Text"), _(u"Date")], style=wx.LC_REPORT) self.list = widgetUtils.list(self, *[_("User"), _("Text"), _("Date")], style=wx.LC_REPORT)
self.list.set_windows_size(0, 200) self.list.set_windows_size(0, 200)
self.list.set_windows_size(1, 300) self.list.set_windows_size(1, 300)
self.list.set_windows_size(2, 250) self.list.set_windows_size(2, 250)
@ -15,7 +17,7 @@ class homeTab(wx.Panel):
self.list.list.Bind(wx.EVT_LIST_ITEM_ACTIVATED, self.OnKeyDown) self.list.list.Bind(wx.EVT_LIST_ITEM_ACTIVATED, self.OnKeyDown)
def create_post_buttons(self): def create_post_buttons(self):
self.post = wx.Button(self, -1, _(u"&Post")) self.post = wx.Button(self, -1, _("&Post"))
self.postBox = wx.BoxSizer(wx.HORIZONTAL) self.postBox = wx.BoxSizer(wx.HORIZONTAL)
self.postBox.Add(self.post, 0, wx.ALL, 5) self.postBox.Add(self.post, 0, wx.ALL, 5)
@ -54,16 +56,16 @@ class feedTab(homeTab):
class communityTab(feedTab): class communityTab(feedTab):
def create_post_buttons(self): def create_post_buttons(self):
self.load = wx.Button(self, wx.NewId(), _(u"Load community")) self.load = wx.Button(self, wx.NewId(), _("Load community"))
self.post = wx.Button(self, -1, _(u"&Post")) self.post = wx.Button(self, -1, _("&Post"))
self.postBox = wx.BoxSizer(wx.HORIZONTAL) self.postBox = wx.BoxSizer(wx.HORIZONTAL)
self.postBox.Add(self.load, 0, wx.ALL, 5) self.postBox.Add(self.load, 0, wx.ALL, 5)
self.postBox.Add(self.post, 0, wx.ALL, 5) self.postBox.Add(self.post, 0, wx.ALL, 5)
class audioTab(homeTab): class audioTab(homeTab):
def create_list(self): def create_list(self):
self.lbl = wx.StaticText(self, wx.NewId(), _(u"Mu&sic")) self.lbl = wx.StaticText(self, wx.NewId(), _("Mu&sic"))
self.list = widgetUtils.list(self, *[_(u"Title"), _(u"Artist"), _(u"Duration")], style=wx.LC_REPORT) self.list = widgetUtils.list(self, *[_("Title"), _("Artist"), _("Duration")], style=wx.LC_REPORT)
self.list.set_windows_size(0, 160) self.list.set_windows_size(0, 160)
self.list.set_windows_size(1, 380) self.list.set_windows_size(1, 380)
self.list.set_windows_size(2, 80) self.list.set_windows_size(2, 80)
@ -71,9 +73,9 @@ class audioTab(homeTab):
self.list.list.Bind(wx.EVT_LIST_ITEM_ACTIVATED, self.OnKeyDown) self.list.list.Bind(wx.EVT_LIST_ITEM_ACTIVATED, self.OnKeyDown)
def create_post_buttons(self): def create_post_buttons(self):
self.post = wx.Button(self, -1, _(u"&Post")) self.post = wx.Button(self, -1, _("&Post"))
self.play = wx.Button(self, -1, _(u"P&lay")) self.play = wx.Button(self, -1, _("P&lay"))
self.play_all = wx.Button(self, -1, _(u"Play &All")) self.play_all = wx.Button(self, -1, _("Play &All"))
self.postBox = wx.BoxSizer(wx.HORIZONTAL) self.postBox = wx.BoxSizer(wx.HORIZONTAL)
self.postBox.Add(self.post, 0, wx.ALL, 5) self.postBox.Add(self.post, 0, wx.ALL, 5)
self.postBox.Add(self.play, 0, wx.ALL, 5) self.postBox.Add(self.play, 0, wx.ALL, 5)
@ -82,10 +84,10 @@ class audioTab(homeTab):
class audioAlbumTab(audioTab): class audioAlbumTab(audioTab):
def create_post_buttons(self): def create_post_buttons(self):
self.load = wx.Button(self, wx.NewId(), _(u"Load album")) self.load = wx.Button(self, wx.NewId(), _("Load album"))
self.post = wx.Button(self, -1, _(u"&Post")) self.post = wx.Button(self, -1, _("&Post"))
self.play = wx.Button(self, -1, _(u"P&lay")) self.play = wx.Button(self, -1, _("P&lay"))
self.play_all = wx.Button(self, -1, _(u"Play &All")) self.play_all = wx.Button(self, -1, _("Play &All"))
self.postBox = wx.BoxSizer(wx.HORIZONTAL) self.postBox = wx.BoxSizer(wx.HORIZONTAL)
self.postBox.Add(self.load, 0, wx.ALL, 5) self.postBox.Add(self.load, 0, wx.ALL, 5)
self.postBox.Add(self.post, 0, wx.ALL, 5) self.postBox.Add(self.post, 0, wx.ALL, 5)
@ -102,7 +104,7 @@ class notificationsTab(homeTab):
ev.Skip() ev.Skip()
def create_list(self): def create_list(self):
self.list = widgetUtils.list(self, *[_(u"Notification")], style=wx.LC_REPORT) self.list = widgetUtils.list(self, *[_("Notification")], style=wx.LC_REPORT)
self.list.set_windows_size(0, 190) self.list.set_windows_size(0, 190)
self.list.list.Bind(wx.EVT_LIST_ITEM_ACTIVATED, self.OnKeyDown) self.list.list.Bind(wx.EVT_LIST_ITEM_ACTIVATED, self.OnKeyDown)
@ -116,7 +118,7 @@ class albumTab(homeTab):
ev.Skip() ev.Skip()
def create_list(self): def create_list(self):
self.list = widgetUtils.list(self, *[_(u"User"), _(u"Name"), _(u"Description"), _(u"Photos"), _(u"Created at")], style=wx.LC_REPORT) self.list = widgetUtils.list(self, *[_("User"), _("Name"), _("Description"), _("Photos"), _("Created at")], style=wx.LC_REPORT)
self.list.set_windows_size(0, 190) self.list.set_windows_size(0, 190)
self.list.set_windows_size(1, 320) self.list.set_windows_size(1, 320)
self.list.set_windows_size(2, 513) self.list.set_windows_size(2, 513)
@ -130,7 +132,7 @@ class friendsTab(homeTab):
ev.Skip() ev.Skip()
def create_list(self): def create_list(self):
self.list = widgetUtils.list(self, *[_(u"Name")], style=wx.LC_REPORT) self.list = widgetUtils.list(self, *[_("Name")], style=wx.LC_REPORT)
self.list.set_windows_size(0, 400) self.list.set_windows_size(0, 400)
self.list.list.Bind(wx.EVT_LIST_ITEM_ACTIVATED, self.OnKeyDown) self.list.list.Bind(wx.EVT_LIST_ITEM_ACTIVATED, self.OnKeyDown)
@ -153,14 +155,14 @@ class chatTab(wx.Panel):
sizer.Add(self.create_controls()) sizer.Add(self.create_controls())
sizer.Add(self.create_attachments(), 0, wx.ALL, 5) sizer.Add(self.create_attachments(), 0, wx.ALL, 5)
sizer.Add(self.create_chat(), 0, wx.ALL, 5) sizer.Add(self.create_chat(), 0, wx.ALL, 5)
self.attachment = wx.Button(self, wx.NewId(), _(u"Add")) self.attachment = wx.Button(self, wx.NewId(), _("Add"))
sizer.Add(self.attachment, 0, wx.ALL, 5) sizer.Add(self.attachment, 0, wx.ALL, 5)
self.send = wx.Button(self, -1, _(u"Send")) self.send = wx.Button(self, -1, _("Send"))
sizer.Add(self.send, 0, wx.ALL, 5) sizer.Add(self.send, 0, wx.ALL, 5)
self.SetSizer(sizer) self.SetSizer(sizer)
def create_controls(self): def create_controls(self):
lbl1 = wx.StaticText(self, wx.NewId(), _(u"History")) lbl1 = wx.StaticText(self, wx.NewId(), _("History"))
self.history = wx.TextCtrl(self, wx.NewId(), style=wx.TE_READONLY|wx.TE_MULTILINE, size=(500, 300)) self.history = wx.TextCtrl(self, wx.NewId(), style=wx.TE_READONLY|wx.TE_MULTILINE, size=(500, 300))
box = wx.BoxSizer(wx.HORIZONTAL) box = wx.BoxSizer(wx.HORIZONTAL)
box.Add(lbl1, 0, wx.ALL, 5) box.Add(lbl1, 0, wx.ALL, 5)
@ -168,8 +170,8 @@ class chatTab(wx.Panel):
return box return box
def create_attachments(self): def create_attachments(self):
lbl = wx.StaticText(self, -1, _(u"Attachments")) lbl = wx.StaticText(self, -1, _("Attachments"))
self.attachments = widgetUtils.list(self, _(u"Type"), _(u"Title"), style=wx.LC_REPORT) self.attachments = widgetUtils.list(self, _("Type"), _("Title"), style=wx.LC_REPORT)
box = wx.BoxSizer(wx.HORIZONTAL) box = wx.BoxSizer(wx.HORIZONTAL)
box.Add(lbl, 0, wx.ALL, 5) box.Add(lbl, 0, wx.ALL, 5)
box.Add(self.attachments.list, 0, wx.ALL, 5) box.Add(self.attachments.list, 0, wx.ALL, 5)
@ -177,7 +179,7 @@ class chatTab(wx.Panel):
return box return box
def create_chat(self): def create_chat(self):
lbl2 = wx.StaticText(self, -1, _(u"Write a message")) lbl2 = wx.StaticText(self, -1, _("Write a message"))
self.text = wx.TextCtrl(self, -1, size=(400, -1), style=wx.TE_MULTILINE) self.text = wx.TextCtrl(self, -1, size=(400, -1), style=wx.TE_MULTILINE)
box = wx.BoxSizer(wx.HORIZONTAL) box = wx.BoxSizer(wx.HORIZONTAL)
box.Add(lbl2, 0, wx.ALL, 20) box.Add(lbl2, 0, wx.ALL, 20)
@ -201,24 +203,24 @@ class chatTab(wx.Panel):
class peopleTab(homeTab): class peopleTab(homeTab):
def create_list(self): def create_list(self):
self.lbl = wx.StaticText(self, wx.NewId(), _(u"Friends")) self.lbl = wx.StaticText(self, wx.NewId(), _("Friends"))
self.list = widgetUtils.list(self, *[_(u"Name"), _(u"Last seen")], style=wx.LC_REPORT) self.list = widgetUtils.list(self, *[_("Name"), _("Last seen")], style=wx.LC_REPORT)
self.list.set_windows_size(0, 190) self.list.set_windows_size(0, 190)
self.list.set_windows_size(1, 100) self.list.set_windows_size(1, 100)
self.list.set_size() self.list.set_size()
self.list.list.Bind(wx.EVT_LIST_ITEM_ACTIVATED, self.OnKeyDown) self.list.list.Bind(wx.EVT_LIST_ITEM_ACTIVATED, self.OnKeyDown)
def create_post_buttons(self): def create_post_buttons(self):
self.post = wx.Button(self, -1, _(u"&Post")) self.post = wx.Button(self, -1, _("&Post"))
self.new_chat = wx.Button(self, wx.NewId(), _(u"Send message")) self.new_chat = wx.Button(self, wx.NewId(), _("Send message"))
self.postBox = wx.BoxSizer(wx.HORIZONTAL) self.postBox = wx.BoxSizer(wx.HORIZONTAL)
self.postBox.Add(self.post, 0, wx.ALL, 5) self.postBox.Add(self.post, 0, wx.ALL, 5)
self.postBox.Add(self.new_chat, 0, wx.ALL, 5) self.postBox.Add(self.new_chat, 0, wx.ALL, 5)
class videoTab(homeTab): class videoTab(homeTab):
def create_list(self): def create_list(self):
self.lbl = wx.StaticText(self, wx.NewId(), _(u"Video&s")) self.lbl = wx.StaticText(self, wx.NewId(), _("Video&s"))
self.list = widgetUtils.list(self, *[_(u"Title"), _(u"Description"), _(u"Duration")], style=wx.LC_REPORT) self.list = widgetUtils.list(self, *[_("Title"), _("Description"), _("Duration")], style=wx.LC_REPORT)
self.list.set_windows_size(0, 160) self.list.set_windows_size(0, 160)
self.list.set_windows_size(1, 380) self.list.set_windows_size(1, 380)
self.list.set_windows_size(2, 80) self.list.set_windows_size(2, 80)
@ -226,8 +228,8 @@ class videoTab(homeTab):
self.list.list.Bind(wx.EVT_LIST_ITEM_ACTIVATED, self.OnKeyDown) self.list.list.Bind(wx.EVT_LIST_ITEM_ACTIVATED, self.OnKeyDown)
def create_post_buttons(self): def create_post_buttons(self):
self.post = wx.Button(self, -1, _(u"&Post")) self.post = wx.Button(self, -1, _("&Post"))
self.play = wx.Button(self, -1, _(u"P&lay")) self.play = wx.Button(self, -1, _("P&lay"))
self.postBox = wx.BoxSizer(wx.HORIZONTAL) self.postBox = wx.BoxSizer(wx.HORIZONTAL)
self.postBox.Add(self.post, 0, wx.ALL, 5) self.postBox.Add(self.post, 0, wx.ALL, 5)
self.postBox.Add(self.play, 0, wx.ALL, 5) self.postBox.Add(self.play, 0, wx.ALL, 5)
@ -235,9 +237,9 @@ class videoTab(homeTab):
class videoAlbumTab(videoTab): class videoAlbumTab(videoTab):
def create_post_buttons(self): def create_post_buttons(self):
self.load = wx.Button(self, wx.NewId(), _(u"Load album")) self.load = wx.Button(self, wx.NewId(), _("Load album"))
self.post = wx.Button(self, -1, _(u"&Post")) self.post = wx.Button(self, -1, _("&Post"))
self.play = wx.Button(self, -1, _(u"P&lay")) self.play = wx.Button(self, -1, _("P&lay"))
self.postBox = wx.BoxSizer(wx.HORIZONTAL) self.postBox = wx.BoxSizer(wx.HORIZONTAL)
self.postBox.Add(self.post, 0, wx.ALL, 5) self.postBox.Add(self.post, 0, wx.ALL, 5)
self.postBox.Add(self.play, 0, wx.ALL, 5) self.postBox.Add(self.play, 0, wx.ALL, 5)

View File

@ -1,22 +1,23 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from __future__ import unicode_literals
import wx import wx
import widgetUtils import widgetUtils
class audioRecorderDialog(widgetUtils.BaseDialog): class audioRecorderDialog(widgetUtils.BaseDialog):
def __init__(self): def __init__(self):
super(audioRecorderDialog, self).__init__(None, title=_(u"Record voice message")) super(audioRecorderDialog, self).__init__(None, title=_("Record voice message"))
panel = wx.Panel(self) panel = wx.Panel(self)
sizer = wx.BoxSizer(wx.VERTICAL) sizer = wx.BoxSizer(wx.VERTICAL)
self.play = wx.Button(panel, -1, _(u"&Play")) self.play = wx.Button(panel, -1, _("&Play"))
self.play.Disable() self.play.Disable()
self.pause = wx.Button(panel, -1, _(u"&Pause")) self.pause = wx.Button(panel, -1, _("&Pause"))
self.pause.Disable() self.pause.Disable()
self.record = wx.Button(panel, -1, _(u"&Record")) self.record = wx.Button(panel, -1, _("&Record"))
self.record.SetFocus() self.record.SetFocus()
self.discard = wx.Button(panel, -1, _(u"&Discard")) self.discard = wx.Button(panel, -1, _("&Discard"))
self.discard.Disable() self.discard.Disable()
ok = wx.Button(panel, wx.ID_OK, _(u"&Add")) ok = wx.Button(panel, wx.ID_OK, _("&Add"))
cancel = wx.Button(panel, wx.ID_CANCEL, _(u"&Cancel")) cancel = wx.Button(panel, wx.ID_CANCEL, _("&Cancel"))
btnSizer = wx.BoxSizer(wx.HORIZONTAL) btnSizer = wx.BoxSizer(wx.HORIZONTAL)
btnSizer2 = wx.BoxSizer(wx.HORIZONTAL) btnSizer2 = wx.BoxSizer(wx.HORIZONTAL)
btnSizer.Add(self.play, 0, wx.ALL, 5) btnSizer.Add(self.play, 0, wx.ALL, 5)