Update API version
This commit is contained in:
parent
2c6704ae9e
commit
ead1f186f0
@ -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)
|
||||
|
||||
|
@ -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
|
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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,6 +375,7 @@ class postController(object):
|
||||
log.debug("Unhandled attachment: %r" % (attachment,))
|
||||
|
||||
def __del__(self):
|
||||
if hasattr(self, "worker"):
|
||||
self.worker.finished.set()
|
||||
|
||||
class comment(object):
|
||||
|
@ -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()
|
||||
|
20
src/sessionmanager/vkscrap.py
Normal file
20
src/sessionmanager/vkscrap.py
Normal 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)
|
29
src/utils.py
29
src/utils.py
@ -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 = '\'\\.,[](){}:;"'
|
||||
@ -59,3 +60,31 @@ def clean_text(text):
|
||||
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(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]
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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 *
|
||||
|
@ -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()
|
||||
|
@ -84,3 +84,57 @@ class selectPeople(widgetUtils.BaseDialog):
|
||||
|
||||
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
|
@ -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"))
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user