Port socializer to Python 3. #16

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

1
.gitignore vendored
View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -16,15 +16,16 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
############################################################
import translator
from __future__ import unicode_literals
import wx
from . import translator
class translateDialog(wx.Dialog):
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)
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.SetFocus()
self.dest_lang.SetSelection(0)

View File

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

View File

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

View File

@ -1,3 +1,4 @@
from __future__ import unicode_literals
import win32com.client
def fix():
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/>.
#
############################################################
from __future__ import unicode_literals
import wx
import platform
import requests
@ -51,7 +52,7 @@ class reportBug(object):
issue_type = "issue" # for now just have issue
app_type = paths.mode
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_handle = self.dialog.get("email")
operating_system = platform.platform()

View File

@ -16,6 +16,7 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
############################################################
from __future__ import unicode_literals
import wx
import widgetUtils
import application
@ -23,11 +24,11 @@ import application
class reportBugDialog(widgetUtils.BaseDialog):
def __init__(self):
super(reportBugDialog, self).__init__(parent=None, id=wx.NewId())
self.SetTitle(_(u"Report an error"))
self.SetTitle(_("Report an error"))
panel = wx.Panel(self)
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)
dc = wx.WindowDC(self.summary)
dc.SetFont(self.summary.GetFont())
@ -37,7 +38,7 @@ class reportBugDialog(widgetUtils.BaseDialog):
summaryB.Add(self.summary, 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)
dc = wx.WindowDC(self.first_name)
dc.SetFont(self.first_name.GetFont())
@ -47,7 +48,7 @@ class reportBugDialog(widgetUtils.BaseDialog):
first_nameB.Add(self.first_name, 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)
dc = wx.WindowDC(self.last_name)
dc.SetFont(self.last_name.GetFont())
@ -57,7 +58,7 @@ class reportBugDialog(widgetUtils.BaseDialog):
last_nameB.Add(self.last_name, 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)
dc = wx.WindowDC(self.email)
dc.SetFont(self.email.GetFont())
@ -67,7 +68,7 @@ class reportBugDialog(widgetUtils.BaseDialog):
emailB.Add(self.email, 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)
dc = wx.WindowDC(self.description)
dc.SetFont(self.description.GetFont())
@ -77,12 +78,12 @@ class reportBugDialog(widgetUtils.BaseDialog):
descBox.Add(descriptionLabel, 0, wx.ALL, 5)
descBox.Add(self.description, 0, wx.ALL, 5)
sizer.Add(descBox, 0, wx.ALL, 5)
self.agree = wx.CheckBox(panel, -1, _(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)
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()
cancel = wx.Button(panel, wx.ID_CANCEL, _(u"Cancel"))
cancel = wx.Button(panel, wx.ID_CANCEL, _("Cancel"))
btnBox = wx.BoxSizer(wx.HORIZONTAL)
btnBox.Add(self.ok, 0, wx.ALL, 5)
btnBox.Add(cancel, 0, wx.ALL, 5)
@ -91,19 +92,19 @@ class reportBugDialog(widgetUtils.BaseDialog):
self.SetClientSize(sizer.CalcMin())
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):
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):
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()
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()
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()

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 sys
import ctypes
@ -25,12 +30,12 @@ def localeNameToWindowsLCID(localeName):
func_LocaleNameToLCID=getattr(ctypes.windll.kernel32,'LocaleNameToLCID',None)
if func_LocaleNameToLCID is not None:
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
localeName=locale.normalize(localeName)
if '.' in localeName:
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:
LCID=LCList[0]
else:
@ -93,7 +98,7 @@ def getAvailableLanguages():
# Translators: the label for the Windows default NVDA interface language.
d.append(_("User default"))
#return a zipped up version of both the lists (a list with tuples of locale,label)
return zip(l,d)
return list(zip(l,d))
def makePgettext(translations):
"""Obtaina pgettext function for use with a gettext translations instance.
@ -103,15 +108,15 @@ def makePgettext(translations):
"""
if isinstance(translations, gettext.GNUTranslations):
def pgettext(context, message):
message = unicode(message)
message = str(message)
try:
# 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:
return message
else:
def pgettext(context, message):
return unicode(message)
return str(message)
return pgettext
def setLanguage(lang):
@ -161,6 +166,9 @@ def setLanguage(lang):
except IOError:
trans=gettext.translation(application.short_name, fallback=True)
curLang="en"
if sys.version[0] == "3":
trans.install()
else:
trans.install(unicode=True)
# Install our pgettext function.
# __builtin__.__dict__["pgettext"] = makePgettext(trans)

View File

@ -1,5 +1,4 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
import os
import logging
from logging.handlers import RotatingFileHandler
@ -8,10 +7,10 @@ import sys
APP_LOG_FILE = 'debug.log'
ERROR_LOG_FILE = "error.log"
MESSAGE_FORMAT = u"%(asctime)s %(name)s %(levelname)s: %(message)s"
DATE_FORMAT = u"%d/%m/%Y %H:%M:%S"
MESSAGE_FORMAT = "%(asctime)s %(name)s %(levelname)s: %(message)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.setLevel(logging.WARNING)
@ -21,12 +20,12 @@ logger.setLevel(logging.DEBUG)
#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.setLevel(logging.DEBUG)
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.setLevel(logging.ERROR)
logger.addHandler(error_handler)

View File

@ -21,7 +21,7 @@ def setup():
log.debug("Starting Socializer %s" % (application.version,))
config.setup()
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(),))
output.setup()
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 languageHandler
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 logging
log = logging.getLogger("mysc.repeating_timer")

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,12 +1,13 @@
# -*- 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. """
from __future__ import unicode_literals
import os
import logging
import languageHandler
import paths
import vkSessionHandler
from . import vkSessionHandler
import sound
from config_utils import Configuration, ConfigurationResetException
from .config_utils import Configuration, ConfigurationResetException
from pubsub import pub
from vk_api.exceptions import LoginRequired, VkApiError
@ -31,14 +32,14 @@ def find_item(list, item):
global identifiers
identifier = None
for i in identifiers:
if item.has_key(i):
if i in item:
identifier = i
break
if identifier == None:
# if there are objects that can't be processed by lack of identifier, let's print keys for finding one.
log.exception("Can't find an identifier for the following object: %r" % (item.keys(),))
log.exception("Can't find an identifier for the following object: %r" % (list(item.keys()),))
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 False
@ -53,12 +54,12 @@ class vkSession(object):
global post_types
first_addition = False
num = 0
if self.db.has_key(name) == False:
if (name in self.db) == False:
self.db[name] = {}
self.db[name]["items"] = []
first_addition = True
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,))
continue
# 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):
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")
kwargs["start_from"] = self.db[name]["cursor"]
log.debug("Params for sending to vk: %r" % (kwargs,))
@ -138,8 +139,8 @@ class vkSession(object):
# else:
# print data.keys(), len(data["items"]), data["next_from"]
num = self.order_buffer(name, data["items"], show_nextpage)
log.debug("Keys of the returned data for debug purposes: %r" % (data.keys(),))
if data.has_key("next_from"):
log.debug("Keys of the returned data for debug purposes: %r" % (list(data.keys()),))
if "next_from" in data:
self.db[name]["cursor"] = data["next_from"]
return num
@ -150,7 +151,7 @@ class vkSession(object):
c = self.vk.client_audio
else:
c = self.vk.client
if kwargs.has_key("parent_endpoint"):
if "parent_endpoint" in kwargs:
p = kwargs["parent_endpoint"]
if "audio" in p and self.settings["vk"]["use_alternative_tokens"]:
log.info("Using alternative audio methods.")
@ -165,12 +166,12 @@ class vkSession(object):
if data != None:
if type(data) == dict:
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": []}
for i in data["items"]:
data2["profiles"].append(i)
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)
else:
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"):
if user_id > 0:
if self.db["users"].has_key(user_id):
if self.db["users"][user_id].has_key(case_name):
if user_id in self.db["users"]:
if case_name in self.db["users"][user_id]:
return self.db["users"][user_id][case_name]
else:
return self.db["users"][user_id]["nom"]
else:
return "no specified user"
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"]
else:
return "no specified community"
@ -203,7 +204,7 @@ class vkSession(object):
if user_ids != None:
u = self.vk.client.users.get(user_ids=user_ids, fields="uid, first_name, last_name")
for i in u:
self.db["users"][i["id"]] = 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:
g = self.vk.client.groups.getById(group_ids=group_ids, fields="name")
for i in g:
@ -217,8 +218,8 @@ class vkSession(object):
log.debug("Adding usernames to the local database...")
ids = ""
for i in data["profiles"]:
if self.db["users"].has_key(i["id"]) == False:
self.db["users"][i["id"]] = dict(nom=u"{0} {1}".format(i["first_name"], i["last_name"]))
if (i["id"] in self.db["users"]) == False:
self.db["users"][i["id"]] = dict(nom="{0} {1}".format(i["first_name"], i["last_name"]))
ids = ids + "{0},".format(i["id"],)
gids = ""
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_instrumental = self.vk.client.users.get(user_ids=ids, fields="first_name, last_name", name_case="ins")
for i in users_genitive:
if self.db["users"].has_key(i["id"]):
self.db["users"][i["id"]]["gen"] = u"{0} {1}".format(i["first_name"], i["last_name"])
if i["id"] in self.db["users"]:
self.db["users"][i["id"]]["gen"] = "{0} {1}".format(i["first_name"], i["last_name"])
for i in users_instrumental:
if self.db["users"].has_key(i["id"]):
self.db["users"][i["id"]]["ins"] = u"{0} {1}".format(i["first_name"], i["last_name"])
if i["id"] in self.db["users"]:
self.db["users"][i["id"]]["ins"] = "{0} {1}".format(i["first_name"], i["last_name"])
def get_my_data(self):
log.debug("Getting user identifier...")

View File

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

View File

@ -1,10 +1,12 @@
# -*- coding: utf-8 -*-
""" Some utilities. I no have idea how I should put these, so..."""
from __future__ import division
from __future__ import unicode_literals
import os
import requests
import re
import logging
from sessionmanager import renderers
log = logging.getLogger("utils")
url_re = re.compile("(?:\w+://|www\.)[^ ,.?!#%=+][^ ]*")
bad_chars = '\'\\.,[](){}:;"'
@ -18,21 +20,21 @@ def seconds_to_string(seconds, precision=0):
sec_string = sec.__format__(sec_spec)
string = ""
if day == 1:
string += _(u"%d day, ") % day
string += _("%d day, ") % day
elif day >= 2:
string += _(u"%d days, ") % day
string += _("%d days, ") % day
if (hour == 1):
string += _(u"%d hour, ") % hour
string += _("%d hour, ") % hour
elif (hour >= 2):
string += _("%d hours, ") % hour
if (min == 1):
string += _(u"%d minute, ") % min
string += _("%d minute, ") % min
elif (min >= 2):
string += _(u"%d minutes, ") % min
string += _("%d minutes, ") % min
if sec >= 0 and sec <= 2:
string += _(u"%s second") % sec_string
string += _("%s second") % sec_string
else:
string += _(u"%s seconds") % sec_string
string += _("%s seconds") % sec_string
return string
def find_urls_in_text(text):
@ -40,7 +42,7 @@ def find_urls_in_text(text):
def download_file(url, local_filename, window):
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")
dl = 0
total_length = int(total_length)
@ -49,42 +51,9 @@ def download_file(url, local_filename, window):
if chunk: # filter out keep-alive new chunks
dl += len(chunk)
f.write(chunk)
done = int(100 * dl / total_length)
msg = _(u"Downloading {0} ({1}%)").format(os.path.basename(local_filename), done)
done = int(100 * dl/total_length)
msg = _("Downloading {0} ({1}%)").format(os.path.basename(local_filename), done)
window.change_status(msg)
window.change_status(_(u"Ready"))
window.change_status(_("Ready"))
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
import keys
import logging
import core
from . import core
from vk_api.audio import VkAudio
from wxUI import two_factor_auth
from . wxUI import two_factor_auth
log = logging.getLogger("vkSessionHandler")
@ -16,7 +16,7 @@ class vkObject(object):
if alt_token == False:
log.info("Using kate's token...")
# 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:
log.info("Token is not valid. Generating one...")
token = core.requestAuth(user, password)

View File

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

View File

@ -1,4 +1,5 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
import time
import wx
import widgetUtils
@ -7,7 +8,7 @@ code = None
remember = True
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():
global code, remember
@ -18,7 +19,7 @@ def two_factor_auth():
def get_code():
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()
if response == widgetUtils.OK:
code = dlg.GetValue()
@ -27,11 +28,11 @@ def get_code():
class newSessionDialog(widgetUtils.BaseDialog):
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)
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)
lbl2 = wx.StaticText(panel, -1, _(u"&Password"))
lbl2 = wx.StaticText(panel, -1, _("&Password"))
self.passw = wx.TextCtrl(panel, -1, style=wx.TE_PASSWORD)
sizer = wx.BoxSizer()
b1 = wx.BoxSizer(wx.HORIZONTAL)

View File

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

View File

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

View File

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

View File

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

View File

@ -1,4 +1,5 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
def convert_bytes(n):
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)
string = ""
if day == 1:
string += _(u"%d day, ") % day
string += _("%d day, ") % day
elif day >= 2:
string += _(u"%d days, ") % day
string += _("%d days, ") % day
if (hour == 1):
string += _(u"%d hour, ") % hour
string += _("%d hour, ") % hour
elif (hour >= 2):
string += _("%d hours, ") % hour
if (min == 1):
string += _(u"%d minute, ") % min
string += _("%d minute, ") % min
elif (min >= 2):
string += _(u"%d minutes, ") % min
string += _("%d minutes, ") % min
if sec >= 0 and sec <= 2:
string += _(u"%s second") % sec_string
string += _("%s second") % sec_string
else:
string += _(u"%s seconds") % sec_string
string += _("%s seconds") % sec_string
return string

View File

@ -1,19 +1,21 @@
# -*- coding: utf-8 -*-
from __future__ import division
from __future__ import unicode_literals
import wx
import application
import utils
from . import utils
progress_dialog = None
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:
return True
else:
return False
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):
wx.CallAfter(_progress_callback, total_downloaded, total_size)
@ -26,7 +28,7 @@ def _progress_callback(total_downloaded, total_size):
if total_downloaded == total_size:
progress_dialog.Destroy()
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():
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
#if platform.system() == "Windows":
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
toolkit = "wx"
@ -144,7 +148,7 @@ class list(object):
def create_list(self, parent):
self.list = wx.ListCtrl(parent, -1, **self.listArguments)
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):
""" Inserts an item on the list."""

View File

@ -1,38 +1,39 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
import wx
import application
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():
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():
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():
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):
title = ""
message = ""
if code == 201:
title = _(u"Restricted access")
message = _(u"Access to user's audio is denied by the owner. Error code {0}").format(code,)
title = _("Restricted access")
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()
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():
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():
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():
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():
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 -*-
from __future__ import unicode_literals
import wx
import widgetUtils
class attachDialog(widgetUtils.BaseDialog):
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)
sizer = wx.BoxSizer(wx.VERTICAL)
lbl1 = wx.StaticText(panel, wx.NewId(), _(u"Attachments"))
self.attachments = widgetUtils.list(panel, _(u"Type"), _(u"Title"), style=wx.LC_REPORT)
lbl1 = wx.StaticText(panel, wx.NewId(), _("Attachments"))
self.attachments = widgetUtils.list(panel, _("Type"), _("Title"), style=wx.LC_REPORT)
box = wx.BoxSizer(wx.HORIZONTAL)
box.Add(lbl1, 0, wx.ALL, 5)
box.Add(self.attachments.list, 0, wx.ALL, 5)
sizer.Add(box, 0, wx.ALL, 5)
static = wx.StaticBox(panel, label=_(u"Add attachments"))
self.photo = wx.Button(panel, wx.NewId(), _(u"&Photo"))
self.audio = wx.Button(panel, wx.NewId(), _(u"Audio file"))
static = wx.StaticBox(panel, label=_("Add attachments"))
self.photo = wx.Button(panel, wx.NewId(), _("&Photo"))
self.audio = wx.Button(panel, wx.NewId(), _("Audio file"))
if voice_messages:
self.voice_message = wx.Button(panel, wx.NewId(), _(u"Voice message"))
self.remove = wx.Button(panel, wx.NewId(), _(u"Remove attachment"))
self.voice_message = wx.Button(panel, wx.NewId(), _("Voice message"))
self.remove = wx.Button(panel, wx.NewId(), _("Remove attachment"))
self.remove.Enable(False)
btnsizer = wx.StaticBoxSizer(static, wx.HORIZONTAL)
btnsizer.Add(self.photo, 0, wx.ALL, 5)
@ -37,21 +38,21 @@ class attachDialog(widgetUtils.BaseDialog):
self.SetClientSize(sizer.CalcMin())
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:
return None
dsc = self.ask_description()
return (openFileDialog.GetPath(), dsc)
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()
result = dlg.GetValue()
dlg.Destroy()
return result
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:
return None
return openFileDialog.GetPath()

View File

@ -1,4 +1,5 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
import wx
import widgetUtils
@ -6,24 +7,24 @@ class general(wx.Panel, widgetUtils.BaseDialog):
def __init__(self, panel):
super(general, self).__init__(panel)
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.SetRange(1, 100)
box1 = wx.BoxSizer(wx.HORIZONTAL)
box1.Add(lbl1, 0, wx.ALL, 5)
box1.Add(self.wall_buffer_count, 0, wx.ALL, 5)
sizer.Add(box1, 0, wx.ALL, 5)
lbl3 = wx.StaticText(self, wx.NewId(), _(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.SetRange(1, 200)
box3 = wx.BoxSizer(wx.HORIZONTAL)
box3.Add(lbl3, 0, wx.ALL, 5)
box3.Add(self.video_buffers_count, 0, wx.ALL, 5)
sizer.Add(box3, 0, wx.ALL, 5)
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)
lbl4 = wx.StaticText(self, wx.NewId(), _(u"Update channel"))
self.update_channel = wx.ComboBox(self, wx.NewId(), choices=[_(u"Stable"), _(u"Alpha")], value=_(u"Native"), style=wx.CB_READONLY)
lbl4 = wx.StaticText(self, wx.NewId(), _("Update channel"))
self.update_channel = wx.ComboBox(self, wx.NewId(), choices=[_("Stable"), _("Alpha")], value=_("Native"), style=wx.CB_READONLY)
box4 = wx.BoxSizer(wx.HORIZONTAL)
box4.Add(lbl4, 0, wx.ALL, 5)
box4.Add(self.update_channel, 0, wx.ALL, 5)
@ -34,16 +35,16 @@ class chat(wx.Panel, widgetUtils.BaseDialog):
def __init__(self, panel):
super(chat, self).__init__(panel)
sizer = wx.BoxSizer(wx.VERTICAL)
self.notify_online = wx.CheckBox(self, wx.NewId(), _(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)
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)
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)
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)
lbl = wx.StaticText(self, wx.NewId(), _(u"Notification type"))
self.notifications = wx.ComboBox(self, wx.NewId(), choices=[_(u"Native"), _(u"Custom"),], value=_(u"Native"), style=wx.CB_READONLY)
lbl = wx.StaticText(self, wx.NewId(), _("Notification type"))
self.notifications = wx.ComboBox(self, wx.NewId(), choices=[_("Native"), _("Custom"),], value=_("Native"), style=wx.CB_READONLY)
nbox = wx.BoxSizer(wx.HORIZONTAL)
nbox.Add(lbl, 0, wx.ALL, 5)
nbox.Add(self.notifications, 0, wx.ALL, 5)
@ -60,20 +61,20 @@ class configurationDialog(widgetUtils.BaseDialog):
def create_general(self):
self.general = general(self.notebook)
self.notebook.AddPage(self.general, _(u"General"))
self.notebook.AddPage(self.general, _("General"))
self.general.SetFocus()
def create_chat(self):
self.chat = chat(self.notebook)
self.notebook.AddPage(self.chat, _(u"Chat settings"))
self.notebook.AddPage(self.chat, _("Chat settings"))
def realize(self):
self.sizer.Add(self.notebook, 0, wx.ALL, 5)
ok_cancel_box = wx.BoxSizer(wx.HORIZONTAL)
ok = wx.Button(self.panel, wx.ID_OK, _(u"Save"))
ok = wx.Button(self.panel, wx.ID_OK, _("Save"))
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())
ok_cancel_box.Add(ok, 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)
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():
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 widgetUtils
class audio_album(widgetUtils.BaseDialog):
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)
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())
box = wx.BoxSizer(wx.HORIZONTAL)
box.Add(lbl, 1, wx.ALL, 5)
box.Add(self.title, 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()
cancel = wx.Button(panel, wx.ID_CANCEL, _(u"&Close"))
cancel = wx.Button(panel, wx.ID_CANCEL, _("&Close"))
btnsizer = wx.BoxSizer()
btnsizer.Add(ok, 0, wx.ALL, 5)
btnsizer.Add(cancel, 0, wx.ALL, 5)

View File

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

View File

@ -1,9 +1,10 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
import wx
import widgetUtils
class audioPlayerDialog(widgetUtils.BaseDialog):
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)

View File

@ -1,4 +1,5 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
import wx
import widgetUtils
@ -12,7 +13,7 @@ class basicPost(widgetUtils.BaseDialog):
self.panel.SetSizer(self.sizer)
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)
self.post_view = wx.TextCtrl(self.panel, -1, size=(730, -1), style=wx.TE_READONLY|wx.TE_MULTILINE)
box = wx.BoxSizer(wx.HORIZONTAL)
@ -21,16 +22,16 @@ class basicPost(widgetUtils.BaseDialog):
return box
def create_comments_list(self):
lbl = wx.StaticText(self.panel, -1, _(u"Comments"))
self.comments = widgetUtils.list(self.panel, _(u"User"), _(u"Comment"), _(u"Date"), _(u"Likes"), style=wx.LC_REPORT)
lbl = wx.StaticText(self.panel, -1, _("Comments"))
self.comments = widgetUtils.list(self.panel, _("User"), _("Comment"), _("Date"), _("Likes"), style=wx.LC_REPORT)
box = wx.BoxSizer(wx.HORIZONTAL)
box.Add(lbl, 0, wx.ALL, 5)
box.Add(self.comments.list, 0, wx.ALL, 5)
return box
def create_attachments(self):
lbl = wx.StaticText(self.panel, -1, _(u"Attachments"))
self.attachments = widgetUtils.list(self.panel, _(u"Type"), _(u"Title"), style=wx.LC_REPORT)
lbl = wx.StaticText(self.panel, -1, _("Attachments"))
self.attachments = widgetUtils.list(self.panel, _("Type"), _("Title"), style=wx.LC_REPORT)
box = wx.BoxSizer(wx.HORIZONTAL)
box.Add(lbl, 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):
self.image = wx.StaticBitmap(self.panel, bitmap=wx.Bitmap(1280, 860), size=(604, 604))
self.sizer.Add(self.image, 1, wx.ALL, 10)
self.previous_photo = wx.Button(self.panel, wx.NewId(), _(u"Previous photo"))
self.view_photo = wx.Button(self.panel, wx.NewId(), _(u"View in full screen"))
self.next_photo = wx.Button(self.panel, wx.NewId(), _(u"Next photo"))
self.previous_photo = wx.Button(self.panel, wx.NewId(), _("Previous photo"))
self.view_photo = wx.Button(self.panel, wx.NewId(), _("View in full screen"))
self.next_photo = wx.Button(self.panel, wx.NewId(), _("Next photo"))
actionsS = wx.BoxSizer(wx.HORIZONTAL)
actionsS.Add(self.previous_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):
self.likes = wx.Button(self.panel, -1, _(u"Loading data..."))
self.likes = wx.Button(self.panel, -1, _("Loading data..."))
return self.likes
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
def create_action_buttons(self, comment=True):
self.like = wx.Button(self.panel, -1, _(u"&Like"))
self.repost = wx.Button(self.panel, -1, _(u"Repost"))
if comment: self.comment = wx.Button(self.panel, -1, _(u"Add comment"))
self.like = wx.Button(self.panel, -1, _("&Like"))
self.repost = wx.Button(self.panel, -1, _("Repost"))
if comment: self.comment = wx.Button(self.panel, -1, _("Add comment"))
box = wx.BoxSizer(wx.HORIZONTAL)
box.Add(self.like, 0, wx.ALL, 5)
if comment: box.Add(self.comment, 0, wx.ALL, 5)
return box
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):
self.close = wx.Button(self.panel, wx.ID_CANCEL, _(u"Close"))
self.close = wx.Button(self.panel, wx.ID_CANCEL, _("Close"))
return self.close
def set_post(self, text):
@ -98,13 +99,13 @@ class basicPost(widgetUtils.BaseDialog):
def set_likes(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:
return False
def set_shares(self, shares):
if hasattr(self, "shares"):
self.shares.SetLabel(_(u"Shared {0} times").format(shares,))
self.shares.SetLabel(_("Shared {0} times").format(shares,))
else:
return False
@ -150,40 +151,40 @@ class audio(widgetUtils.BaseDialog):
super(audio, self).__init__(parent=None, *args, **kwargs)
panel = wx.Panel(self)
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())
listS = wx.BoxSizer(wx.HORIZONTAL)
listS.Add(lbl_list, 0, wx.ALL, 5)
listS.Add(self.list, 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)
titleBox = wx.BoxSizer(wx.HORIZONTAL)
titleBox.Add(lbl_title, 0, wx.ALL, 5)
titleBox.Add(self.title, 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)
artistBox = wx.BoxSizer(wx.HORIZONTAL)
artistBox.Add(lbl_artist, 0, wx.ALL, 5)
artistBox.Add(self.artist, 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)
durationBox = wx.BoxSizer(wx.HORIZONTAL)
durationBox.Add(lbl_duration, 0, wx.ALL, 5)
durationBox.Add(self.duration, 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)
lbox = wx.BoxSizer(wx.HORIZONTAL)
lbox.Add(lbl_lyrics, 0, wx.ALL, 5)
lbox.Add(self.lyric, 0, wx.ALL, 5)
sizer.Add(lbox, 0, wx.ALL, 5)
self.play = wx.Button(panel, wx.NewId(), _(u"&Play"))
self.download = wx.Button(panel, wx.NewId(), _(u"&Download"))
self.add = wx.Button(panel, wx.NewId(), _(u"&Add to your library"))
self.remove = wx.Button(panel, wx.NewId(), _(u"&Remove from your library"))
self.play = wx.Button(panel, wx.NewId(), _("&Play"))
self.download = wx.Button(panel, wx.NewId(), _("&Download"))
self.add = wx.Button(panel, wx.NewId(), _("&Add to your library"))
self.remove = wx.Button(panel, wx.NewId(), _("&Remove from your library"))
self.add.Enable(False)
self.remove.Enable(False)
close = wx.Button(panel, wx.ID_CANCEL)
@ -198,7 +199,7 @@ class audio(widgetUtils.BaseDialog):
getattr(self, button_name).Enable(state)
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:
return saveFileDialog.GetPath()
saveFileDialog.Destroy()
@ -214,7 +215,7 @@ class friendship(widgetUtils.BaseDialog):
super(friendship, self).__init__(parent=None)
panel = wx.Panel(self)
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)
close = wx.Button(panel, wx.ID_CANCEL)
btnbox = wx.BoxSizer(wx.HORIZONTAL)

View File

@ -1,5 +1,6 @@
# -*- coding: utf-8 -*-
""" A set of dialogs related to user and community profiles."""
from __future__ import unicode_literals
import wx
import widgetUtils
@ -42,7 +43,7 @@ class mainInfo(wx.Panel):
def __init__(self, panel):
super(mainInfo, self).__init__(panel)
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.SetMinSize(text_size(self.name, 60))
sizerName = wx.BoxSizer(wx.HORIZONTAL)
@ -50,7 +51,7 @@ class mainInfo(wx.Panel):
sizerName.Add(self.name, 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.Enable(False)
self.status.SetMinSize(text_size(self.status, 300))
@ -59,7 +60,7 @@ class mainInfo(wx.Panel):
sizerStatus.Add(self.status, 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.Enable(False)
sizerLastSeen = wx.BoxSizer(wx.HORIZONTAL)
@ -67,7 +68,7 @@ class mainInfo(wx.Panel):
sizerLastSeen.Add(self.last_seen, 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.Enable(False)
sizerBDate = wx.BoxSizer(wx.HORIZONTAL)
@ -79,7 +80,7 @@ class mainInfo(wx.Panel):
self.relation.Enable(False)
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.SetMinSize(text_size(self.city, 40))
self.city.Enable(False)
@ -88,7 +89,7 @@ class mainInfo(wx.Panel):
sizerCity.Add(self.city, 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.SetMinSize(text_size(self.home_town, 40))
self.home_town.Enable(False)
@ -97,11 +98,11 @@ class mainInfo(wx.Panel):
sizerHometown.Add(self.home_town, 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.SetMinSize(text_size(self.website, 90))
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)
sizerWebsite = wx.BoxSizer(wx.HORIZONTAL)
sizerWebsite.Add(lblWebsite, 0, wx.ALL, 5)
@ -109,7 +110,7 @@ class mainInfo(wx.Panel):
sizerWebsite.Add(self.go_site, 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.SetMinSize(text_size(self.occupation, 90))
self.occupation.Enable(False)
@ -129,7 +130,7 @@ class userProfile(widgetUtils.BaseDialog):
def create_controls(self, section):
if section == "main_info":
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()
def realice(self):

View File

@ -1,4 +1,5 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
import widgetUtils
import wx
@ -7,17 +8,17 @@ class searchAudioDialog(widgetUtils.BaseDialog):
super(searchAudioDialog, self).__init__(None, -1)
panel = wx.Panel(self)
sizer = wx.BoxSizer(wx.VERTICAL)
self.SetTitle(_(u"audio Search"))
label = wx.StaticText(panel, -1, _(u"&Search"))
self.SetTitle(_("audio Search"))
label = wx.StaticText(panel, -1, _("&Search"))
self.term = wx.TextCtrl(panel, -1, value)
dc = wx.WindowDC(self.term)
dc.SetFont(self.term.GetFont())
self.term.SetSize(dc.GetTextExtent("0"*40))
sizer.Add(label, 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()
cancel = wx.Button(panel, wx.ID_CANCEL, _(u"&Close"))
cancel = wx.Button(panel, wx.ID_CANCEL, _("&Close"))
btnsizer = wx.BoxSizer()
btnsizer.Add(ok, 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)
panel = wx.Panel(self)
sizer = wx.BoxSizer(wx.VERTICAL)
self.SetTitle(_(u"video Search"))
label = wx.StaticText(panel, -1, _(u"&Search"))
self.SetTitle(_("video Search"))
label = wx.StaticText(panel, -1, _("&Search"))
self.term = wx.TextCtrl(panel, -1, value)
dc = wx.WindowDC(self.term)
dc.SetFont(self.term.GetFont())
self.term.SetSize(dc.GetTextExtent("0"*40))
sizer.Add(label, 0, wx.ALL, 5)
sizer.Add(self.term, 0, wx.ALL, 5)
sort_order = wx.StaticText(panel, -1, _(U"&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)
sort_order = wx.StaticText(panel, -1, _("&Sort order by: "))
self.sortorder = wx.ComboBox(panel, wx.NewId(), choices=[_("Date added"), _("Duration"), _("Popularity")], value=_("Popularity"), style=wx.CB_READONLY)
rBox = wx.BoxSizer(wx.HORIZONTAL)
rBox.Add(sort_order, 0, wx.ALL, 5)
rBox.Add(self.sortorder, 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)
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)
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()
cancel = wx.Button(panel, wx.ID_CANCEL, _(u"&Close"))
cancel = wx.Button(panel, wx.ID_CANCEL, _("&Close"))
btnsizer = wx.BoxSizer()
btnsizer.Add(ok, 0, wx.ALL, 5)
btnsizer.Add(cancel, 0, wx.ALL, 5)

View File

@ -1,4 +1,5 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
import wx
import widgetUtils
@ -34,33 +35,33 @@ class selectAlbum(wx.Dialog):
class selectPeople(widgetUtils.BaseDialog):
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.users_list = users
panel = wx.Panel(self)
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.SetFocus()
userSizer = wx.BoxSizer()
userSizer.Add(userLabel, 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)
userSizer.Add(self.add, 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.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)
selectionSizer = wx.BoxSizer(wx.HORIZONTAL)
selectionSizer.Add(lbl, 0, wx.ALL, 5)
selectionSizer.Add(self.users, 0, wx.ALL, 5)
selectionSizer.Add(self.remove, 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()
cancel = wx.Button(panel, wx.ID_CANCEL, _(u"&Close"))
cancel = wx.Button(panel, wx.ID_CANCEL, _("&Close"))
btnsizer = wx.BoxSizer()
btnsizer.Add(ok, 0, wx.ALL, 5)
btnsizer.Add(cancel, 0, wx.ALL, 5)
@ -93,28 +94,28 @@ class selectAttachment(widgetUtils.BaseDialog):
self.attachments_list = attachments
panel = wx.Panel(self)
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.SetFocus()
attachmentSizer = wx.BoxSizer()
attachmentSizer.Add(label, 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)
attachmentSizer.Add(self.add, 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.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)
selectionSizer = wx.BoxSizer(wx.HORIZONTAL)
selectionSizer.Add(lbl, 0, wx.ALL, 5)
selectionSizer.Add(self.attachments, 0, wx.ALL, 5)
selectionSizer.Add(self.remove, 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()
cancel = wx.Button(panel, wx.ID_CANCEL, _(u"&Close"))
cancel = wx.Button(panel, wx.ID_CANCEL, _("&Close"))
btnsizer = wx.BoxSizer()
btnsizer.Add(ok, 0, wx.ALL, 5)
btnsizer.Add(cancel, 0, wx.ALL, 5)

View File

@ -1,31 +1,32 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
import wx
import widgetUtils
class timelineDialog(widgetUtils.BaseDialog):
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)
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.SetFocus()
userSizer = wx.BoxSizer()
userSizer.Add(userLabel, 0, wx.ALL, 5)
userSizer.Add(self.cb, 0, wx.ALL, 5)
actionsstatic = wx.StaticBox(panel, label=_(u"Buffer type"))
self.wall = wx.RadioButton(panel, wx.NewId(), _(u"&Wall posts"), style=wx.RB_GROUP)
self.audio = wx.RadioButton(panel, wx.NewId(), _(u"Audio"))
self.friends = wx.RadioButton(panel, wx.NewId(), _(u"Friends"))
actionsstatic = wx.StaticBox(panel, label=_("Buffer type"))
self.wall = wx.RadioButton(panel, wx.NewId(), _("&Wall posts"), style=wx.RB_GROUP)
self.audio = wx.RadioButton(panel, wx.NewId(), _("Audio"))
self.friends = wx.RadioButton(panel, wx.NewId(), _("Friends"))
radioSizer = wx.StaticBoxSizer(actionsstatic, wx.HORIZONTAL)
radioSizer.Add(self.wall, 0, wx.ALL, 5)
radioSizer.Add(self.audio, 0, wx.ALL, 5)
radioSizer.Add(self.friends, 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()
cancel = wx.Button(panel, wx.ID_CANCEL, _(u"&Close"))
cancel = wx.Button(panel, wx.ID_CANCEL, _("&Close"))
btnsizer = wx.BoxSizer()
btnsizer.Add(ok, 0, wx.ALL, 5)
btnsizer.Add(cancel, 0, wx.ALL, 5)

View File

@ -1,9 +1,10 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
import wx
class urlList(wx.Dialog):
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)
self.lista = wx.ListBox(panel, -1)
self.lista.SetFocus()

View File

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

View File

@ -1,41 +1,42 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
import wx
class postMenu(wx.Menu):
def __init__(self, *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.like = wx.MenuItem(self, wx.NewId(), _(u"Like"))
self.like = wx.MenuItem(self, wx.NewId(), _("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.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.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.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)
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.delete = wx.MenuItem(self, wx.NewId(), _(u"Delete"))
self.delete = wx.MenuItem(self, wx.NewId(), _("Delete"))
self.Append(self.delete)
class audioMenu(wx.Menu):
def __init__(self, *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.play = wx.MenuItem(self, wx.NewId(), _(u"&Play"))
self.play = wx.MenuItem(self, wx.NewId(), _("&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.move = wx.MenuItem(self, wx.NewId(), _(u"Move to album"))
self.move = wx.MenuItem(self, wx.NewId(), _("Move to album"))
self.Append(self.move)
class peopleMenu(wx.Menu):
@ -43,47 +44,47 @@ class peopleMenu(wx.Menu):
super(peopleMenu, self).__init__(*args, **kwargs)
if is_request:
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.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.timeline = wx.MenuItem(self, wx.NewId(), _(u"Open timeline"))
self.timeline = wx.MenuItem(self, wx.NewId(), _("Open 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)
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.decline = wx.MenuItem(self, wx.NewId(), _(u"Decline"))
self.decline = wx.MenuItem(self, wx.NewId(), _("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)
class commentMenu(wx.Menu):
def __init__(self, *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.like = wx.MenuItem(self, wx.NewId(), _(u"Like"))
self.like = wx.MenuItem(self, wx.NewId(), _("Like"))
self.Append(self.like)
self.unlike = wx.MenuItem(self, -1, _(u"Unlike"))
self.unlike = wx.MenuItem(self, -1, _("Unlike"))
self.Append(self.unlike)
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)
class notificationsMenu(wx.Menu):
def __init__(self):
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)
class attachMenu(wx.Menu):
def __init__(self):
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.add = wx.MenuItem(self, wx.NewId(), _(u"Add from VK"))
self.add = wx.MenuItem(self, wx.NewId(), _("Add from VK"))
self.Append(self.add)

View File

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

View File

@ -1,22 +1,23 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
import wx
import widgetUtils
class audioRecorderDialog(widgetUtils.BaseDialog):
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)
sizer = wx.BoxSizer(wx.VERTICAL)
self.play = wx.Button(panel, -1, _(u"&Play"))
self.play = wx.Button(panel, -1, _("&Play"))
self.play.Disable()
self.pause = wx.Button(panel, -1, _(u"&Pause"))
self.pause = wx.Button(panel, -1, _("&Pause"))
self.pause.Disable()
self.record = wx.Button(panel, -1, _(u"&Record"))
self.record = wx.Button(panel, -1, _("&Record"))
self.record.SetFocus()
self.discard = wx.Button(panel, -1, _(u"&Discard"))
self.discard = wx.Button(panel, -1, _("&Discard"))
self.discard.Disable()
ok = wx.Button(panel, wx.ID_OK, _(u"&Add"))
cancel = wx.Button(panel, wx.ID_CANCEL, _(u"&Cancel"))
ok = wx.Button(panel, wx.ID_OK, _("&Add"))
cancel = wx.Button(panel, wx.ID_CANCEL, _("&Cancel"))
btnSizer = wx.BoxSizer(wx.HORIZONTAL)
btnSizer2 = wx.BoxSizer(wx.HORIZONTAL)
btnSizer.Add(self.play, 0, wx.ALL, 5)