Fix AttributeError when saving data from the alternative tokens method
This commit is contained in:
@@ -911,10 +911,11 @@ class chatBuffer(baseBuffer):
|
||||
|
||||
def insert(self, item, reversed=False):
|
||||
""" Add a new item to the list. Uses session.composefunc for parsing the dictionary and create a valid result for putting it in the list."""
|
||||
# as this tab is based in a text control, we have to overwrite the defaults.
|
||||
item_ = getattr(renderers, self.compose_function)(item, self.session)
|
||||
# the self.chat dictionary will have (first_line, last_line) as keys and message ID as a value for looking into it when needed.
|
||||
# Here we will get first and last line of a chat message appended to the history.
|
||||
values = self.tab.add_message(item_[0])
|
||||
values = self.tab.add_message(item_[0], reverse=reversed)
|
||||
self.chats[values] = item["id"]
|
||||
|
||||
def get_focused_post(self):
|
||||
@@ -930,7 +931,6 @@ class chatBuffer(baseBuffer):
|
||||
# position[2]+1 is added because line may start with 0, while in wx.TextCtrl.GetNumberLines() that is not possible.
|
||||
if position[2]+1 >= i[0] and position[2]+1 < i[1]:
|
||||
id_ = self.chats[i]
|
||||
# print i
|
||||
break
|
||||
# Retrieve here the object based in id_
|
||||
if id_ != None:
|
||||
@@ -946,9 +946,10 @@ 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 "read_state" in msg and msg["read_state"] == 0 and msg["id"] not in self.reads and "out" in msg and msg["out"] == 0:
|
||||
# Mark unread conversations as read.
|
||||
if "read_state" in msg and msg["read_state"] == 0 and "out" in msg and msg["out"] == 0:
|
||||
self.session.soundplayer.play("message_unread.ogg")
|
||||
self.reads.append(msg["id"])
|
||||
call_threaded(self.session.vk.client.messages.markAsRead, peer_id=self.kwargs["peer_id"])
|
||||
self.session.db[self.name]["items"][-1]["read_state"] = 1
|
||||
if "attachments" in msg and len(msg["attachments"]) > 0:
|
||||
self.tab.attachments.list.Enable(True)
|
||||
@@ -985,10 +986,11 @@ class chatBuffer(baseBuffer):
|
||||
event.Skip()
|
||||
|
||||
def get_items(self, show_nextpage=False):
|
||||
""" Update buffer with newest items or get older items in the buffer."""
|
||||
if self.can_get_items == False: return
|
||||
retrieved = True # Control variable for handling unauthorised/connection errors.
|
||||
retrieved = True
|
||||
try:
|
||||
num = getattr(self.session, "get_messages")(name=self.name, *self.args, **self.kwargs)
|
||||
num = getattr(self.session, "get_page")(show_nextpage=show_nextpage, name=self.name, *self.args, **self.kwargs)
|
||||
except VkApiError as err:
|
||||
log.error("Error {0}: {1}".format(err.code, err.error))
|
||||
retrieved = err.code
|
||||
@@ -1001,20 +1003,38 @@ class chatBuffer(baseBuffer):
|
||||
self.create_tab(self.parent)
|
||||
# Add name to the new control so we could look for it when needed.
|
||||
self.tab.name = self.name
|
||||
|
||||
if show_nextpage == False:
|
||||
if self.tab.history.GetValue() != "" and num > 0:
|
||||
v = [i for i in self.session.db[self.name]["items"][:num]]
|
||||
# v.reverse()
|
||||
[self.insert(i, False) for i in v]
|
||||
else:
|
||||
[self.insert(i) for i in self.session.db[self.name]["items"][:num]]
|
||||
else:
|
||||
if num > 0:
|
||||
[self.insert(i, False) for i in self.session.db[self.name]["items"][:num]]
|
||||
# At this point we save more CPU and mathematical work if we just delete everything in the chat history and readd all messages.
|
||||
# Otherwise we'd have to insert new lines at the top and recalculate positions everywhere else.
|
||||
# Firstly, we'd have to save the current focused object so we will place the user in the right part of the text after loading everything again.
|
||||
focused_post = self.get_post()
|
||||
self.chats = dict()
|
||||
self.tab.history.SetValue("")
|
||||
v = [i for i in self.session.db[self.name]["items"]]
|
||||
[self.insert(i) for i in v]
|
||||
# Now it's time to set back the focus in the post.
|
||||
for i in self.chats.keys():
|
||||
if self.chats[i] == focused_post["id"]:
|
||||
line = i[0]
|
||||
self.tab.history.SetInsertionPoint(self.tab.history.XYToPosition(0, line))
|
||||
output.speak(_("Items loaded"))
|
||||
break
|
||||
if self.unread == True and num > 0:
|
||||
self.session.db[self.name]["items"][-1].update(read_state=0)
|
||||
return retrieved
|
||||
|
||||
def get_more_items(self):
|
||||
output.speak(_("Getting more items..."))
|
||||
call_threaded(self.get_items, show_nextpage=True)
|
||||
|
||||
def add_attachment(self, *args, **kwargs):
|
||||
a = presenters.attachPresenter(session=self.session, view=views.attachDialog(voice_messages=True), interactor=interactors.attachInteractor())
|
||||
if len(a.attachments) != 0:
|
||||
@@ -1093,7 +1113,6 @@ class chatBuffer(baseBuffer):
|
||||
def __init__(self, unread=False, *args, **kwargs):
|
||||
super(chatBuffer, self).__init__(*args, **kwargs)
|
||||
self.unread = unread
|
||||
self.reads = []
|
||||
self.chats = dict()
|
||||
self.peer_typing = 0
|
||||
self.last_keypress = time.time()
|
||||
|
@@ -114,8 +114,6 @@ class Controller(object):
|
||||
self.window.realize()
|
||||
self.repeatedUpdate = RepeatingTimer(120, self.update_all_buffers)
|
||||
self.repeatedUpdate.start()
|
||||
self.readMarker = RepeatingTimer(60, self.mark_as_read)
|
||||
self.readMarker.start()
|
||||
|
||||
def complete_buffer_creation(self, buffer, name_, position):
|
||||
answer = buffer.get_items()
|
||||
@@ -158,14 +156,6 @@ class Controller(object):
|
||||
call_threaded(self.chat_from_id, i["last_message"]["peer_id"], setfocus=False, unread=False)
|
||||
time.sleep(0.6)
|
||||
|
||||
def mark_as_read(self):
|
||||
for i in self.buffers:
|
||||
if hasattr(i, "reads") and len(i.reads) != 0:
|
||||
response = self.session.vk.client.messages.markAsRead(peer_id=i.kwargs["peer_id"])
|
||||
i.clear_reads()
|
||||
i.reads = []
|
||||
time.sleep(1)
|
||||
|
||||
def get_audio_albums(self, user_id=None, create_buffers=True, force_action=False):
|
||||
if self.session.settings["load_at_startup"]["audio_albums"] == False and force_action == False:
|
||||
return
|
||||
@@ -350,13 +340,13 @@ class Controller(object):
|
||||
if "url" in audio_object and audio_object["url"] =="":
|
||||
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, fresh=True)
|
||||
pub.sendMessage("play", object=audio_object, fresh=True)
|
||||
|
||||
def play_audios(self, audios):
|
||||
""" Play all audios passed in alist, putting the audio in a queue of the media player.
|
||||
@audios list: A list of Vk audio objects.
|
||||
"""
|
||||
player.player.play_all(audios, shuffle=self.window.player_shuffle.IsChecked())
|
||||
pub.sendMessage("play_all", list_of_songs=audios, shuffle=self.window.player_shuffle.IsChecked())
|
||||
|
||||
def view_post(self, post_object, controller_):
|
||||
""" Display the passed post in the passed post presenter.
|
||||
@@ -392,7 +382,7 @@ class Controller(object):
|
||||
elif user_id > 2000000000:
|
||||
chat = self.session.vk.client.messages.getChat(chat_id=user_id-2000000000)
|
||||
name = chat["title"]
|
||||
wx.CallAfter(pub.sendMessage, "create_buffer", buffer_type="chatBuffer", buffer_title=name, parent_tab="chats", get_items=True, kwargs=dict(parent=self.window.tb, name="{0}_messages".format(user_id,), composefunc="render_message", session=self.session, unread=unread, count=200, peer_id=user_id, rev=0, extended=True, fields="id, user_id, date, read_state, out, body, attachments, deleted"))
|
||||
wx.CallAfter(pub.sendMessage, "create_buffer", buffer_type="chatBuffer", buffer_title=name, parent_tab="chats", get_items=True, kwargs=dict(parent=self.window.tb, name="{0}_messages".format(user_id,), composefunc="render_message", parent_endpoint="messages", endpoint="getHistory", session=self.session, unread=unread, count=200, peer_id=user_id, rev=0, extended=True, fields="id, user_id, date, read_state, out, body, attachments, deleted"))
|
||||
# if setfocus:
|
||||
# pos = self.window.search(buffer.name)
|
||||
# self.window.change_buffer(pos)
|
||||
@@ -538,7 +528,7 @@ class Controller(object):
|
||||
data = [message]
|
||||
# Let's add this to the buffer.
|
||||
# ToDo: Clean this code and test how is the database working with this set to True.
|
||||
num = self.session.order_buffer(buffer.name, data, True)
|
||||
buffer.session.db[buffer.name]["items"].append(message)
|
||||
buffer.insert(self.session.db[buffer.name]["items"][-1], False)
|
||||
self.session.soundplayer.play("message_received.ogg")
|
||||
wx.CallAfter(self.reorder_buffer, buffer)
|
||||
@@ -883,6 +873,7 @@ class Controller(object):
|
||||
else:
|
||||
option = menu.Append(wx.NewId(), _("Discard groups"))
|
||||
widgetUtils.connect_event(menu, widgetUtils.MENU, self.unload_community_buffers, menuitem=option)
|
||||
# Deal with video and audio albums' sections.
|
||||
elif current_buffer.name == "audio_albums":
|
||||
menu = wx.Menu()
|
||||
if self.session.settings["load_at_startup"]["audio_albums"] == False and not hasattr(self.session, "audio_albums"):
|
||||
@@ -899,6 +890,9 @@ class Controller(object):
|
||||
else:
|
||||
option = menu.Append(wx.NewId(), _("Discard video albums"))
|
||||
widgetUtils.connect_event(menu, widgetUtils.MENU, self.unload_video_album_buffers, menuitem=option)
|
||||
elif current_buffer.name.endswith("_messages"):
|
||||
menu = menus.conversationBufferMenu()
|
||||
widgetUtils.connect_event(menu, widgetUtils.MENU, self.delete_conversation, menuitem=menu.delete)
|
||||
|
||||
if menu != None:
|
||||
self.window.PopupMenu(menu, self.window.FindFocus().GetPosition())
|
||||
@@ -1000,4 +994,13 @@ class Controller(object):
|
||||
buff = self.window.search(buffer.name)
|
||||
self.window.remove_buffer(buff)
|
||||
self.buffers.remove(buffer)
|
||||
del self.session.video_albums
|
||||
del self.session.video_albums
|
||||
|
||||
def delete_conversation(self, *args, **kwargs):
|
||||
current_buffer = self.get_current_buffer()
|
||||
d = commonMessages.delete_conversation()
|
||||
if d == widgetUtils.YES:
|
||||
results = self.session.vk.client.messages.deleteConversation(peer_id=current_buffer.kwargs["peer_id"])
|
||||
buff = self.window.search(current_buffer.name)
|
||||
self.window.remove_buffer(buff)
|
||||
self.buffers.remove(current_buffer)
|
@@ -1,40 +1,62 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
""" Audio player module for socializer.
|
||||
As this player does not have (still) an associated GUI, I have decided to place here the code for the interactor, which connects a bunch of pubsub events, and the presenter itself.
|
||||
"""
|
||||
import sys
|
||||
import random
|
||||
import output
|
||||
import sound_lib
|
||||
import logging
|
||||
import sound_lib
|
||||
import output
|
||||
import config
|
||||
from sound_lib.config import BassConfig
|
||||
from sound_lib.stream import URLStream
|
||||
from sound_lib.main import BassError
|
||||
from mysc.repeating_timer import RepeatingTimer
|
||||
from pubsub import pub
|
||||
from mysc.repeating_timer import RepeatingTimer
|
||||
|
||||
player = None
|
||||
log = logging.getLogger("player")
|
||||
|
||||
# This function will be deprecated when the player works with pubsub events, as will no longer be needed to instantiate and import the player directly.
|
||||
def setup():
|
||||
global player
|
||||
if player == None:
|
||||
player = audioPlayer()
|
||||
|
||||
class audioPlayer(object):
|
||||
""" A media player which will play all passed URLS."""
|
||||
|
||||
def __init__(self):
|
||||
# control variable for checking if another file has been sent to the player before,
|
||||
# thus avoiding double file playback and other oddities happening in sound_lib from time to time.
|
||||
self.is_playing = False
|
||||
# This will be the URLStream handler
|
||||
self.stream = None
|
||||
self.vol = config.app["sound"]["volume"]
|
||||
# this variable is set to true when the URLPlayer is decoding something, thus it will block other calls to the play method.
|
||||
self.is_working = False
|
||||
# Playback queue.
|
||||
self.queue = []
|
||||
# Index of the currently playing track.
|
||||
self.playing_track = 0
|
||||
# Status of the player.
|
||||
self.stopped = True
|
||||
# Modify some default settings present in Bass so it will increase timeout connection, thus causing less "connection timed out" errors when playing.
|
||||
bassconfig = BassConfig()
|
||||
# Set timeout connection to 30 seconds.
|
||||
bassconfig["net_timeout"] = 30000
|
||||
pub.subscribe(self.play, "play")
|
||||
pub.subscribe(self.play_all, "play_all")
|
||||
pub.subscribe(self.pause, "pause")
|
||||
pub.subscribe(self.stop, "stop")
|
||||
pub.subscribe(self.play_next, "play_next")
|
||||
pub.subscribe(self.play_previous, "play_previous")
|
||||
|
||||
def play(self, url, set_info=True, fresh=False):
|
||||
def play(self, object, set_info=True, fresh=False):
|
||||
""" Play an URl Stream.
|
||||
@object dict: typically an audio object as returned by VK, with a "url" component which must be a valid URL to a media file.
|
||||
@set_info bool: If true, will set information about the currently playing audio in the application status bar.
|
||||
@fresh bool: If True, will remove everything playing in the queue and start this file only. otherwise it will play the new file but not remove the current queue."""
|
||||
if self.stream != None and self.stream.is_playing == True:
|
||||
try:
|
||||
self.stream.stop()
|
||||
@@ -50,19 +72,15 @@ class audioPlayer(object):
|
||||
if self.is_working == False:
|
||||
self.is_working = True
|
||||
# Let's encode the URL as bytes if on Python 3
|
||||
if sys.version[0] == "3":
|
||||
url_ = bytes(url["url"], "utf-8")
|
||||
else:
|
||||
url_ = url["url"]
|
||||
url_ = bytes(object["url"], "utf-8")
|
||||
try:
|
||||
self.stream = URLStream(url=url_)
|
||||
except IndexError:
|
||||
log.error("Unable to play URL")
|
||||
log.error(url_)
|
||||
log.error("Unable to play URL %s" % (url_))
|
||||
return
|
||||
# Translators: {0} will be replaced with a song's title and {1} with the artist.
|
||||
if set_info:
|
||||
msg = _("Playing {0} by {1}").format(url["title"], url["artist"])
|
||||
msg = _("Playing {0} by {1}").format(object["title"], object["artist"])
|
||||
pub.sendMessage("update-status-bar", status=msg)
|
||||
self.stream.volume = self.vol/100.0
|
||||
self.stream.play()
|
||||
@@ -70,6 +88,7 @@ class audioPlayer(object):
|
||||
self.is_working = False
|
||||
|
||||
def stop(self):
|
||||
""" Stop audio playback. """
|
||||
if self.stream != None and self.stream.is_playing == True:
|
||||
self.stream.stop()
|
||||
self.stopped = True
|
||||
@@ -79,6 +98,7 @@ class audioPlayer(object):
|
||||
self.queue = []
|
||||
|
||||
def pause(self):
|
||||
""" pause the current playback, without destroying the queue or the current stream. If the stream is already paused this function will resume the playback. """
|
||||
if self.stream != None:
|
||||
if self.stream.is_playing == True:
|
||||
self.stream.pause()
|
||||
@@ -105,11 +125,14 @@ class audioPlayer(object):
|
||||
if self.stream != None:
|
||||
self.stream.volume = self.vol/100.0
|
||||
|
||||
def play_all(self, list_of_urls, shuffle=False):
|
||||
def play_all(self, list_of_songs, shuffle=False):
|
||||
""" Play all passed songs and adds all of those to the queue.
|
||||
@list_of_songs list: A list of audio objects returned by VK.
|
||||
@shuffle bool: If True, the files will be played randomly."""
|
||||
self.playing_track = 0
|
||||
self.stop()
|
||||
# Skip all country restricted tracks as they are not playable here.
|
||||
self.queue = [i for i in list_of_urls if i["url"] != ""]
|
||||
self.queue = [i for i in list_of_songs if i["url"] != ""]
|
||||
if shuffle:
|
||||
random.shuffle(self.queue)
|
||||
self.play(self.queue[self.playing_track])
|
||||
@@ -117,6 +140,7 @@ class audioPlayer(object):
|
||||
self.worker.start()
|
||||
|
||||
def player_function(self):
|
||||
""" Check if the stream has reached the end of the file so it will play the next song. """
|
||||
if self.stream != None and self.stream.is_playing == False and self.stopped == False and len(self.stream) == self.stream.position:
|
||||
if len(self.queue) == 0 or self.playing_track >= len(self.queue):
|
||||
self.worker.cancel()
|
||||
@@ -126,6 +150,7 @@ class audioPlayer(object):
|
||||
self.play(self.queue[self.playing_track])
|
||||
|
||||
def play_next(self):
|
||||
""" Play the next song in the queue. """
|
||||
if len(self.queue) == 0:
|
||||
return
|
||||
if self.playing_track < len(self.queue)-1:
|
||||
@@ -135,6 +160,7 @@ class audioPlayer(object):
|
||||
self.play(self.queue[self.playing_track])
|
||||
|
||||
def play_previous(self):
|
||||
""" Play the previous song in the queue. """
|
||||
if len(self.queue) == 0:
|
||||
return
|
||||
if self.playing_track <= 0:
|
||||
@@ -144,6 +170,7 @@ class audioPlayer(object):
|
||||
self.play(self.queue[self.playing_track])
|
||||
|
||||
def check_is_playing(self):
|
||||
""" check if the player is already playing a stream. """
|
||||
if self.stream == None:
|
||||
return False
|
||||
if self.stream != None and self.stream.is_playing == False:
|
||||
|
@@ -66,6 +66,9 @@ class vkSession(object):
|
||||
self.db[name] = {}
|
||||
self.db[name]["items"] = []
|
||||
first_addition = True
|
||||
# Handles chat messages case, as the buffer is inverted
|
||||
if name.endswith("_messages") and show_nextpage == True:
|
||||
show_nextpage = False
|
||||
for i in data:
|
||||
if "type" in i and not isinstance(i["type"], int) and (i["type"] == "wall_photo" or i["type"] == "photo_tag" or i["type"] == "photo"):
|
||||
log.debug("Skipping unsupported item... %r" % (i,))
|
||||
@@ -124,8 +127,11 @@ class vkSession(object):
|
||||
config_filename = os.path.join(paths.config_path(), self.session_id, "vkconfig.json")
|
||||
self.vk.login(self.settings["vk"]["user"], self.settings["vk"]["password"], token=self.settings["vk"]["token"], secret=self.settings["vk"]["secret"], device_id=self.settings["vk"]["device_id"], alt_token=self.settings["vk"]["use_alternative_tokens"], filename=config_filename)
|
||||
self.settings["vk"]["token"] = self.vk.session_object.token["access_token"]
|
||||
self.settings["vk"]["secret"] = self.vk.session_object.secret
|
||||
self.settings["vk"]["device_id"] = self.vk.session_object.device_id
|
||||
try:
|
||||
self.settings["vk"]["secret"] = self.vk.session_object.secret
|
||||
self.settings["vk"]["device_id"] = self.vk.session_object.device_id
|
||||
except AttributeError:
|
||||
pass
|
||||
self.settings.write()
|
||||
self.logged = True
|
||||
self.get_my_data()
|
||||
@@ -192,6 +198,10 @@ class vkSession(object):
|
||||
if data != None:
|
||||
if "count" not in kwargs:
|
||||
kwargs["count"] = 100
|
||||
# Let's handle a little exception when dealing with conversation buffers.
|
||||
# the first results of the query should be reversed before being sent to order_buffer.
|
||||
if type(data) == dict and "items" in data and endpoint == "getHistory" and kwargs["offset"] == 0:
|
||||
data["items"].reverse()
|
||||
if type(data) == dict:
|
||||
num = self.order_buffer(name, data["items"], show_nextpage)
|
||||
self.db[name]["offset"] = kwargs["offset"]+kwargs["count"]
|
||||
|
@@ -63,4 +63,7 @@ def restart_program():
|
||||
return wx.MessageDialog(None, _("In order to apply the changes you requested, you must restart the program. Do you want to restart Socializer now?"), _("Attention"), style=wx.ICON_QUESTION|wx.YES_NO).ShowModal()
|
||||
|
||||
def community_no_items():
|
||||
return wx.MessageDialog(None, _("There are 0 items for this community."), _("Error"), wx.ICON_ERROR).ShowModal()
|
||||
return wx.MessageDialog(None, _("There are 0 items for this community."), _("Error"), wx.ICON_ERROR).ShowModal()
|
||||
|
||||
def delete_conversation():
|
||||
return wx.MessageDialog(None, _("do you really want to delete all messages of this conversation in VK?"), _("Attention"), style=wx.ICON_QUESTION|wx.YES_NO).ShowModal()
|
||||
|
@@ -124,4 +124,9 @@ class communityBufferMenu(wx.Menu):
|
||||
self.load_audios = load.Append(wx.NewId(), _("Load audios"))
|
||||
self.load_videos = load.Append(wx.NewId(), _("Load videos"))
|
||||
self.load_documents = load.Append(wx.NewId(), _("Load documents"))
|
||||
self.Append(wx.NewId(), _("Load"), load)
|
||||
self.Append(wx.NewId(), _("Load"), load)
|
||||
|
||||
class conversationBufferMenu(wx.Menu):
|
||||
def __init__(self):
|
||||
super(conversationBufferMenu, self).__init__()
|
||||
self.delete = self.Append(wx.NewId(), _("Delete conversation"))
|
Reference in New Issue
Block a user