From 454b461e89ff326101a4555323b76a7d44bb2dc8 Mon Sep 17 00:00:00 2001 From: Manuel Cortez Date: Tue, 5 Mar 2019 05:58:41 -0600 Subject: [PATCH] Added basic support to polls (only voting and seeing results is implemented) --- changelog.md | 3 ++ src/interactors/postDisplayer.py | 6 ++++ src/presenters/postDisplayer.py | 48 ++++++++++++++++++++++++++------ src/views/dialogs/postDisplay.py | 22 ++++++++++++++- 4 files changed, 69 insertions(+), 10 deletions(-) diff --git a/changelog.md b/changelog.md index 0727e43..7e14e8e 100644 --- a/changelog.md +++ b/changelog.md @@ -7,6 +7,9 @@ * Added experimental support to "subscribers" buffer, inside frienship requests. This shows friend requests that have been declined by the current user. * the message when an user is typing in conversation buffers will be announced only if the socializer window is focused. * In "my audios" buffer, there is a button that allows a direct audio upload from your computer. The audio will be placed in your library. +* Added experimental support to user and community polls: + * If the poll is already closed or the user has send a vote to the poll previously, it will display only the results of the poll. + * Otherwise it will display a dialog from where the user can vote in the current poll. * Fixed an error in Socializer that was making it unable to detect unread messages properly. * Socializer should save all tracebacks directly to error.log instead of displaying an error message during exit. ([#27,](https://code.manuelcortez.net/manuelcortez/socializer/issues/27)) * When displaying user profiles, fixed an error where a married person without specifing relation partner would cause an error in the program. ([#29,](https://code.manuelcortez.net/manuelcortez/socializer/issues/29)) diff --git a/src/interactors/postDisplayer.py b/src/interactors/postDisplayer.py index dff2fe5..decbdba 100644 --- a/src/interactors/postDisplayer.py +++ b/src/interactors/postDisplayer.py @@ -210,6 +210,12 @@ class displayPollInteractor(base.baseInteractor): pub.unsubscribe(self.done, self.modulename+"_done") pub.unsubscribe(self.add_options, self.modulename+"_add_options") + def start(self, *args, **kwargs): + super(displayPollInteractor, self).start(*args, **kwargs) + if self.result == widgetUtils.OK: # USer votd. + answers = self.view.get_answers() + self.presenter.vote(answers) + class displayFriendshipInteractor(base.baseInteractor): def add_items(self, control, items): diff --git a/src/presenters/postDisplayer.py b/src/presenters/postDisplayer.py index cb20d00..1e23bbe 100644 --- a/src/presenters/postDisplayer.py +++ b/src/presenters/postDisplayer.py @@ -639,24 +639,54 @@ class displayTopicPresenter(displayPostPresenter): class displayPollPresenter(base.basePresenter): - def __init__(self, session, poll, view, interactor): + def __init__(self, session, poll, view, interactor, show_results=False): super(displayPollPresenter, self).__init__(view=view, interactor=interactor, modulename="display_poll") self.poll = poll["poll"] self.session = session - self.load_poll() + self.get_poll() + self.load_poll(show_results) self.run() - def load_poll(self): + def get_poll(self): + # Retrieve the poll again so we will have a fresh and updated object. + data = dict(owner_id=self.poll["owner_id"], is_board=int(self.poll["is_board"]), poll_id=self.poll["id"]) + self.poll = self.session.vk.client.polls.getById(**data) + + def load_poll(self, load_results=False): user = self.session.get_user(self.poll["author_id"]) title = _("Poll from {user1_nom}").format(**user) self.send_message("set_title", value=title) self.send_message("set", control="question", value=self.poll["question"]) - options = [] - for i in self.poll["answers"]: - options.append(i["text"]) - self.send_message("add_options", options=options, multiple=self.poll["multiple"]) - print(self.poll) - self.send_message("done") + if len(self.poll["answer_ids"]) > 0 or ("is_closed" in self.poll and self.poll["is_closed"] == True) or load_results == True: + options = [] + for i in self.poll["answers"]: + options.append((i["text"], i["votes"], i["rate"])) + self.send_message("add_options", options=options, multiple=self.poll["multiple"]) + self.send_message("done") + self.send_message("disable_control", control="ok") + else: + options = [] + for i in self.poll["answers"]: + options.append(i["text"]) + self.send_message("add_options", options=options, multiple=self.poll["multiple"]) + self.send_message("done") + + def vote(self, answers): + ids = "" + for i in range(0, len(self.poll["answers"])): + if answers[i] == True: + ids = ids+"{answer_id},".format(answer_id=self.poll["answers"][i]["id"]) + if self.poll["multiple"] == False: + break + if ids == "": + log.exception("An error occurred when retrieving answer IDS for the following poll: %r. Provided answer list: %r" % (self.poll, answers)) + return + data = dict(owner_id=self.poll["owner_id"], poll_id=self.poll["id"], answer_ids=ids, is_board=int(self.poll["is_board"])) + result = self.session.vk.client.polls.addVote(**data) + if result == 1: + output.speak(_("Your vote has been added to this poll.")) + + class displayAudioPresenter(base.basePresenter): def __init__(self, session, postObject, view, interactor): diff --git a/src/views/dialogs/postDisplay.py b/src/views/dialogs/postDisplay.py index 958d91e..ad9c772 100644 --- a/src/views/dialogs/postDisplay.py +++ b/src/views/dialogs/postDisplay.py @@ -318,6 +318,8 @@ class displayPoll(widgetUtils.BaseDialog): self.sizer.Add(self.question, 0, wx.ALL, 5) def add_options(self, options, multiple=False): + if not isinstance(options[0], str): + return self.add_results(options) self.options = [] sizer = wx.StaticBoxSizer(parent=self.panel, orient=wx.VERTICAL, label=_("Options")) for i in options: @@ -332,6 +334,23 @@ class displayPoll(widgetUtils.BaseDialog): sizer.Add(control, 0, wx.ALL, 5) self.sizer.Add(sizer, 0, wx.ALL, 5) + def get_answers(self): + answers = [] + for i in self.options: + answers.append(i.GetValue()) + return answers + + def add_results(self, options): + sizer = wx.StaticBoxSizer(parent=self.panel, orient=wx.VERTICAL, label=_("Poll results")) + for i in options: + sizer2 = wx.StaticBoxSizer(parent=sizer.GetStaticBox(), orient=wx.HORIZONTAL, label=i[0]) + staticcontrol = wx.StaticText(sizer2.GetStaticBox(), wx.NewId(), i[0]) + control = wx.TextCtrl(sizer2.GetStaticBox(), wx.NewId(), _("{votes} votes ({rate}% rate)").format(votes=i[1], rate=i[2]), style=wx.TE_READONLY|wx.TE_MULTILINE) + sizer2.Add(staticcontrol, 0, wx.ALL, 5) + sizer2.Add(control, 0, wx.ALL, 5) + sizer.Add(sizer2, 0, wx.ALL, 5) + self.sizer.Add(sizer, 0, wx.ALL, 5) + def done(self): self.ok = wx.Button(self.panel, wx.ID_OK, _("Vote")) cancel = wx.Button(self.panel, wx.ID_CANCEL) @@ -339,4 +358,5 @@ class displayPoll(widgetUtils.BaseDialog): sizer.Add(self.ok, 0, wx.ALL, 5) sizer.Add(cancel, 0, wx.ALL, 5) self.panel.SetSizer(self.sizer) - self.SetClientSize(self.sizer.CalcMin()) \ No newline at end of file + self.SetClientSize(self.sizer.CalcMin()) +