Update API version

This commit is contained in:
Manuel Cortez 2017-03-13 02:16:34 -06:00
parent 2c6704ae9e
commit ead1f186f0
17 changed files with 199 additions and 52 deletions

View File

@ -4,12 +4,13 @@
* Added a new menu in the menu bar that allows you to control the audio playback. For some actions (like play, next and back), if you are not focusing an audio buffer, the program will take the song from the "my audios" buffer.
* Added two more buffers: "Followers" and "I follow", located in the people buffer, under "friendship requests".
* Added an experimental photo viewer. Will show options for seeing the next and previous photo if the current post contains multiple images.
* Added an experimental photo viewer. Will show options for seeing the next and previous photo if the current post contains multiple images. Fullscreen button still doesn't work.
* Improved chats, now they should be more stable. Also you will be able to send the message by pressing enter in the text box. If you are trying to send the same message multiple times, you will be warned.
* Added video management (my videos, video albums and video search). For playing videos, you will be redirected to a website in your browser.
* Added video management (my videos, video albums and video search). For playing videos, you will be redirected to a website in your browser due to the VK'S policy.
* Added a setting that allows you to specify if you want socializer to load images when you are opening posts. It could be useful for slow connections or those who don't want images to be loaded.
* Added basic tagging for users in posts and comments. You can tag only people in your friends buffer.
* Added a basic user profile viewer.
* Added support for listening voice messages in chats. Currently it is not possible to send them, until the new API will be released.
## Changes in build 2016.07.08 (08/07/2016)

View File

@ -1,14 +1,17 @@
# -*- coding: utf-8 -*-
""" Attachment upload methods for different kind of posts in VK."""
import os
import widgetUtils
import logging
from wxUI.dialogs import attach as gui
from wxUI.dialogs import selector
log = logging.getLogger("controller.attach")
class attach(object):
def __init__(self):
class attachmentUploader(object):
def __init__(self, voice_messages=False):
self.attachments = list()
self.dialog = gui.attachDialog()
self.type = "local"
self.dialog = gui.attachDialog(voice_messages)
widgetUtils.connect_event(self.dialog.photo, widgetUtils.BUTTON_PRESSED, self.upload_image)
widgetUtils.connect_event(self.dialog.remove, widgetUtils.BUTTON_PRESSED, self.remove_attachment)
self.dialog.get_response()
@ -37,3 +40,36 @@ class attach(object):
def check_remove_status(self):
if len(self.attachments) == 0 and self.dialog.attachments.get_count() == 0:
self.dialog.remove.Enable(False)
class attach(object):
def __init__(self, session):
self.session = session
self.attachments = list()
self.type = "online"
self.dialog = gui.attachDialog()
widgetUtils.connect_event(self.dialog.audio, widgetUtils.BUTTON_PRESSED, self.add_audio)
# widgetUtils.connect_event(self.dialog.remove, widgetUtils.BUTTON_PRESSED, self.remove_attachment)
self.dialog.get_response()
log.debug("Attachments controller started.")
def add_audio(self, *args, **kwargs):
list_of_audios = self.session.vk.client.audio.get(count=1000)
list_of_audios = list_of_audios["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)
if select.get_response() == widgetUtils.OK and select.attachments.GetCount() > 0:
attachments = select.get_all_attachments()
for i in attachments:
print list_of_audios[i].keys()
list_of_audios[i]["type"] = "audio"
self.attachments.append(list_of_audios[i])
def parse_attachments(self):
result = ""
for i in self.attachments:
preresult = "{0}{1}_{2}".format(i["type"], i["owner_id"], i["id"])
result = preresult+","
return result

View File

@ -12,6 +12,7 @@ import logging
import selector
import webbrowser
import posts
import attach
from wxUI.tabs import home
from pubsub import pub
from sessionmanager import session
@ -19,6 +20,7 @@ from mysc.thread_utils import call_threaded
from wxUI import commonMessages, menus
from vk import upload
from vk.exceptions import VkAPIMethodError
from utils import add_attachment
log = logging.getLogger("controller.buffers")
@ -591,6 +593,7 @@ class chatBuffer(baseBuffer):
def connect_events(self):
widgetUtils.connect_event(self.tab.send, widgetUtils.BUTTON_PRESSED, self.send_chat_to_user)
widgetUtils.connect_event(self.tab.attachment, widgetUtils.BUTTON_PRESSED, self.add_attachment)
self.tab.set_focus_function(self.onFocus)
def get_items(self, show_nextpage=False):
@ -615,19 +618,29 @@ class chatBuffer(baseBuffer):
[self.insert(i, False) for i in self.session.db[self.name]["items"][:num]]
return retrieved
def add_attachment(self, *args, **kwargs):
a = attach.attach(self.session)
r = a.parse_attachments()
if r != "":
self.attachments_to_be_sent = r
def send_chat_to_user(self, *args, **kwargs):
text = self.tab.text.GetValue()
if text == "": return
# if text == "" and not hasattr(self, "attachments_to_be_sent"): return
call_threaded(self._send_message, text=text)
def _send_message(self, text):
try:
# try:
if hasattr(self, "attachments_to_be_sent"):
response = self.session.vk.client.messages.send(user_id=self.kwargs["user_id"], message=text, attachment=self.attachments_to_be_sent)
print self.attachments_to_be_sent
else:
response = self.session.vk.client.messages.send(user_id=self.kwargs["user_id"], message=text)
except VkAPIMethodError 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."))
finally:
self.tab.text.SetValue("")
# except VkAPIMethodError 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."))
# finally:
# self.tab.text.SetValue("")
def __init__(self, *args, **kwargs):
super(chatBuffer, self).__init__(*args, **kwargs)
@ -635,7 +648,7 @@ class chatBuffer(baseBuffer):
def parse_attachments(self, post):
attachments = []
from posts import add_attachment
if post.has_key("attachments"):
for i in post["attachments"]:
# We don't need the photos_list attachment, so skip it.

View File

@ -220,7 +220,7 @@ class Controller(object):
call_threaded(player.player.play, audio_object)
def play_audios(self, audios):
player.player.play_all(audios)
player.player.play_all(audios, shuffle=self.window.player_shuffle.IsChecked())
def view_post(self, post_object, controller_):
p = getattr(posts, controller_)(self.session, post_object)
@ -385,6 +385,12 @@ class Controller(object):
return
# If the chat already exists, let's create a dictionary wich will contains data of the received message.
message = {"id": obj.message_id, "user_id": obj.user_id, "date": obj.timestamp, "body": obj.text, "attachments": obj.attachments}
# if attachments is true, let's request for the full message with attachments formatted in a better way.
# Todo: code improvements. We shouldn't need to request the same message again just for these attachments.
if len(message["attachments"]) != 0:
message_ids = message["id"]
results = self.session.vk.client.messages.getById(message_ids=message_ids)
message = results["items"][0]
# If outbox it's true, it means that message["from_id"] should be the current user. If not, the obj.user_id should be taken.
if obj.message_flags.has_key("outbox") == True:
message["from_id"] = self.session.user_id

View File

@ -71,7 +71,7 @@ class post(object):
checker.clean()
def show_attach_dialog(self, *args, **kwargs):
a = attach.attach()
a = attach.attachmentUploader()
if len(a.attachments) != 0:
self.attachments = a.attachments

View File

@ -1,4 +1,5 @@
# -*- coding: utf-8 -*-
import random
import output
import sound_lib
import logging
@ -88,9 +89,11 @@ class audioPlayer(object):
if self.stream != None:
self.stream.volume = self.vol/100.0
def play_all(self, list_of_urls):
def play_all(self, list_of_urls, shuffle=False):
self.stop()
self.queue = list_of_urls
if shuffle:
random.shuffle(self.queue)
self.play(self.queue[0])
self.queue.remove(self.queue[0])
self.worker = RepeatingTimer(5, self.player_function)

View File

@ -20,6 +20,7 @@ from wxUI.dialogs import postDialogs, urlList
from extra import SpellChecker, translator
from mysc.thread_utils import call_threaded
from wxUI import menus
from utils import add_attachment
log = logging.getLogger("controller.post")
@ -31,32 +32,6 @@ def get_user(id, profiles):
# Translators: This string is user when socializer can't find the right user information.
return _(u"Unknown username")
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(session.compose_audio(attachment["audio"])))
tpe = _(u"Audio")
elif attachment["type"] == "doc":
if attachment["doc"].has_key("preview") and attachment["doc"]["preview"].has_key("audio_msg"):
tpe = _(u"Voice message")
msg = utils.seconds_to_string(attachment["doc"]["preview"]["audio_msg"]["duration"])
else:
msg = u"{0}".format(attachment["doc"]["title"])
tpe = _(u"{0} file").format(attachment["doc"]["ext"])
return [tpe, msg]
def get_message(status):
message = ""
if status.has_key("text"):
@ -400,7 +375,8 @@ class postController(object):
log.debug("Unhandled attachment: %r" % (attachment,))
def __del__(self):
self.worker.finished.set()
if hasattr(self, "worker"):
self.worker.finished.set()
class comment(object):
def __init__(self, session, comment_object):

View File

@ -1,7 +1,8 @@
# -*- coding: utf-8 -*-
import sys
import fix_requests
import fix_win32com
if hasattr(sys, "frozen"):
import fix_win32com
def setup():
fix_requests.fix()

View File

@ -37,4 +37,4 @@ def setup():
call_threaded(r.login)
app.run()
setup()
setup()

View File

@ -0,0 +1,20 @@
#!/usr/bin/python
import requests
from bs4 import BeautifulSoup as bs
class client(object):
""" uses the movile version of the VK website for retrieving some information that is not available in the API, such as audio items."""
def __init__(self, email, password):
super(client, self).__init__()
self.session = requests.session()
self.email = email
self.password = password
def login(self):
self.headers={"Referer": "https://m.vk.com/login?role=fast&to=&s=1&m=1&email=%s" % (self.email,),
'User-Agent':'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.12; rv:50.0) Gecko/20100101 Firefox/50.0'}
payload = {"email": self.email, "pass": self.password}
page = self.session.get("https://m.vk.com/login")
soup = bs(page.content, "lxml")
url = soup.find('form')['action']
p = self.session.post(url, data=payload, headers=self.headers)

View File

@ -4,6 +4,7 @@ import os
import requests
import re
import logging
from sessionmanager import session
log = logging.getLogger("utils")
url_re = re.compile("(?:\w+://|www\.)[^ ,.?!#%=+][^ ]*")
bad_chars = '\'\\.,[](){}:;"'
@ -58,4 +59,32 @@ 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
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(session.compose_audio(attachment["audio"])))
tpe = _(u"Audio")
elif attachment["type"] == "doc":
if attachment["doc"].has_key("preview") and attachment["doc"]["preview"].has_key("audio_msg"):
tpe = _(u"Voice message")
msg = seconds_to_string(attachment["doc"]["preview"]["audio_msg"]["duration"])
print attachment["doc"]["ext"]
else:
msg = u"{0}".format(attachment["doc"]["title"])
tpe = _(u"{0} file").format(attachment["doc"]["ext"])
return [tpe, msg]

View File

@ -1,7 +1,6 @@
# -*- coding: utf-8 -*-
import requests
class VkUpload(object):
def __init__(self, vk):
"""
@ -111,10 +110,10 @@ class VkUpload(object):
"""
values = {'group_id': group_id}
url = self.vk.method('docs.getUploadServer', values)['upload_url']
url = self.vk.docs.getUploadServer(values)['upload_url']
with open(file_path, 'rb') as file:
response = self.vk.http.post(url, files={'file': file}).json()
response = self.session.post(url, files={'file': file}).json()
response.update({
'title': title,

View File

@ -1,5 +1,5 @@
import platform
if platform.system() == "Windows":
from wxUtils import *
#if platform.system() == "Windows":
from wxUtils import *
#elif platform.system() == "Linux":
# from gtkUtils import *

View File

@ -3,7 +3,7 @@ import wx
import widgetUtils
class attachDialog(widgetUtils.BaseDialog):
def __init__(self):
def __init__(self, voice_messages=False):
super(attachDialog, self).__init__(None, title=_(u"Add an attachment"))
panel = wx.Panel(self)
sizer = wx.BoxSizer(wx.VERTICAL)
@ -15,10 +15,16 @@ class attachDialog(widgetUtils.BaseDialog):
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"))
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.remove.Enable(False)
btnsizer = wx.StaticBoxSizer(static, wx.HORIZONTAL)
btnsizer.Add(self.photo, 0, wx.ALL, 5)
btnsizer.Add(self.audio, 0, wx.ALL, 5)
if voice_messages:
btnsizer.Add(self.voice_message, 0, wx.ALL, 5)
sizer.Add(btnsizer, 0, wx.ALL, 5)
ok = wx.Button(panel, wx.ID_OK)
ok.SetDefault()

View File

@ -83,4 +83,58 @@ class selectPeople(widgetUtils.BaseDialog):
self.indexes.remove(n)
def get_all_users(self):
return self.indexes
class selectAttachment(widgetUtils.BaseDialog):
def __init__(self, title="", attachments=[]):
super(selectAttachment, self).__init__(parent=None, title=title)
self.indexes = []
self.attachments_list = attachments
panel = wx.Panel(self)
sizer = wx.BoxSizer(wx.HORIZONTAL)
label = wx.StaticText(panel, -1, _(u"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.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"))
self.attachments = wx.ListBox(panel, -1)
self.remove = wx.Button(panel, wx.NewId(), _(u"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.SetDefault()
cancel = wx.Button(panel, wx.ID_CANCEL, _(u"&Close"))
btnsizer = wx.BoxSizer()
btnsizer.Add(ok, 0, wx.ALL, 5)
btnsizer.Add(cancel, 0, wx.ALL, 5)
sizer.Add(btnsizer, 0, wx.ALL, 5)
panel.SetSizer(sizer)
self.SetClientSize(sizer.CalcMin())
def get_attachment(self):
return self.cb.GetValue()
def add_attachment(self, *args, **kwargs):
selection = self.get_attachment()
if selection in self.attachments_list:
self.attachments.Append(selection)
self.indexes.append(self.cb.GetSelection())
def remove_attachment(self, *args, **kwargs):
n = self.attachments.GetSelection()
self.attachments.Delete(n)
self.indexes.remove(n)
def get_all_attachments(self):
return self.indexes

View File

@ -32,6 +32,7 @@ class mainWindow(wx.Frame):
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_down = player.Append(wx.NewId(), _(u"Volume down"))
self.player_volume_up = player.Append(wx.NewId(), _(u"Volume up"))
self.player_mute = player.Append(wx.NewId(), _(u"Mute"))

View File

@ -143,6 +143,8 @@ 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"))
sizer.Add(self.attachment, 0, wx.ALL, 5)
self.send = wx.Button(self, -1, _(u"Send"))
self.send.SetDefault()
sizer.Add(self.send, 0, wx.ALL, 5)