From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from pigeon.gentoo.org ([208.92.234.80] helo=lists.gentoo.org) by finch.gentoo.org with esmtp (Exim 4.60) (envelope-from ) id 1QaRT8-0006sv-FI for garchives@archives.gentoo.org; Sat, 25 Jun 2011 11:56:10 +0000 Received: from pigeon.gentoo.org (localhost [127.0.0.1]) by pigeon.gentoo.org (Postfix) with SMTP id 8C7DA1C06B; Sat, 25 Jun 2011 11:55:17 +0000 (UTC) Received: from smtp.gentoo.org (smtp.gentoo.org [140.211.166.183]) by pigeon.gentoo.org (Postfix) with ESMTP id 4BBC41C06B for ; Sat, 25 Jun 2011 11:55:17 +0000 (UTC) Received: from pelican.gentoo.org (unknown [66.219.59.40]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by smtp.gentoo.org (Postfix) with ESMTPS id A43721B4015 for ; Sat, 25 Jun 2011 11:55:16 +0000 (UTC) Received: from localhost.localdomain (localhost [127.0.0.1]) by pelican.gentoo.org (Postfix) with ESMTP id D5DCD8003C for ; Sat, 25 Jun 2011 11:55:15 +0000 (UTC) From: "Petteri Räty" To: gentoo-commits@lists.gentoo.org Content-type: text/plain; charset=UTF-8 Reply-To: gentoo-dev@lists.gentoo.org, "Petteri Räty" Message-ID: <62b3ba6efe4ac1de77f24527e844c9a70ed94b1b.betelgeuse@gentoo> Subject: [gentoo-commits] proj/council-webapp:master commit in: bot/tests/, bot/ircmeeting/ X-VCS-Repository: proj/council-webapp X-VCS-Files: bot/ircmeeting/agenda.py bot/ircmeeting/meeting.py bot/tests/run_test.py X-VCS-Directories: bot/tests/ bot/ircmeeting/ X-VCS-Committer: betelgeuse X-VCS-Committer-Name: Petteri Räty X-VCS-Revision: 62b3ba6efe4ac1de77f24527e844c9a70ed94b1b Date: Sat, 25 Jun 2011 11:55:15 +0000 (UTC) Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: List-Id: Gentoo Linux mail X-BeenThere: gentoo-commits@lists.gentoo.org Content-Transfer-Encoding: quoted-printable X-Archives-Salt: X-Archives-Hash: 7a6e61be7a3f1359a910c23e546e141b commit: 62b3ba6efe4ac1de77f24527e844c9a70ed94b1b Author: Joachim Filip Ignacy Bartosik gmail com= > AuthorDate: Wed Jun 22 07:28:20 2011 +0000 Commit: Petteri R=C3=A4ty gentoo org> CommitDate: Wed Jun 22 18:31:35 2011 +0000 URL: http://git.overlays.gentoo.org/gitweb/?p=3Dproj/council-webap= p.git;a=3Dcommit;h=3D62b3ba6e Add support for #timelimit (add|list|remove) commands --- bot/ircmeeting/agenda.py | 46 +++++++++++++++++++++++++++++++++++- bot/ircmeeting/meeting.py | 17 +++++++++++++- bot/tests/run_test.py | 56 +++++++++++++++++++++++++++++++++++++++= ++++++ 3 files changed, 116 insertions(+), 3 deletions(-) diff --git a/bot/ircmeeting/agenda.py b/bot/ircmeeting/agenda.py index 928ff5f..220acf9 100644 --- a/bot/ircmeeting/agenda.py +++ b/bot/ircmeeting/agenda.py @@ -1,7 +1,15 @@ import json +import threading import urllib import re =20 +class MessageSender: + def __init__(self, irc, message): + self.irc =3D irc + self.message =3D message + def send_message(self): + self.irc.reply(self.message) + class Agenda(object): =20 # Messages @@ -18,6 +26,10 @@ class Agenda(object): not_a_number_msg =3D "Your vote was not recognized as a number. Plea= se retry." out_of_range_msg =3D "Your vote was out of range!" vote_confirm_msg =3D "You voted for #{} - {}" + timelimit_added_msg =3D 'Added "{}" reminder in {}:{}' + timelimit_list_msg =3D 'Set reminders: "{}"' + timelimit_removed_msg =3D 'Reminder "{}" removed' + timelimit_missing_msg =3D 'No such reminder "{}"' =20 # Internal _voters =3D [] @@ -28,6 +40,7 @@ class Agenda(object): =20 def __init__(self, conf): self.conf =3D conf + self.reminders =3D {} =20 def get_agenda_item(self): if not self.conf.manage_agenda: @@ -37,6 +50,12 @@ class Agenda(object): else: return self.empty_agenda_msg =20 + def _swich_agenda_item_to(self, new_item): + self._current_item =3D new_item + for reminder in self.reminders.values(): + reminder.cancel() + self.reminders =3D {} + def next_agenda_item(self): if not self.conf.manage_agenda: return('') @@ -44,7 +63,7 @@ class Agenda(object): return self.voting_open_so_item_not_changed_msg else: if (self._current_item + 1) < len(self._agenda): - self._current_item +=3D 1 + self._swich_agenda_item_to(self._current_item + 1) return(self.get_agenda_item()) =20 def prev_agenda_item(self): @@ -54,7 +73,7 @@ class Agenda(object): return self.voting_open_so_item_not_changed_msg else: if self._current_item > 0: - self._current_item -=3D 1 + self._swich_agenda_item_to(self._current_item - 1) return(self.get_agenda_item()) =20 def start_vote(self): @@ -144,6 +163,29 @@ class Agenda(object): option =3D self._agenda[self._current_item][1].pop(opt) return str.format(self.removed_option_msg, str(opt), option) =20 + def add_timelimit(self, minutes, seconds, message, irc): + sender =3D MessageSender(irc, message) + reminder =3D (threading.Timer(60*minutes + seconds, sender.send_me= ssage)) + self.reminders[message] =3D reminder + reminder.start() + result =3D str.format(self.timelimit_added_msg, message, minutes, = seconds) + return(result) + + def list_timielimits(self): + keys =3D self.reminders.keys() + keys_str =3D '", "'.join(keys) + result =3D str.format(self.timelimit_list_msg, keys_str) + return(result) + + def remove_timelimit(self, message): + if message in self.reminders: + timer =3D self.reminders.pop(message) + timer.cancel() + result =3D str.format(self.timelimit_removed_msg, message) + else: + result =3D str.format(self.timelimit_missing_msg, message) + return(result) + def post_result(self): if not self.conf.manage_agenda: return('') diff --git a/bot/ircmeeting/meeting.py b/bot/ircmeeting/meeting.py index 84949ed..4bd3221 100644 --- a/bot/ircmeeting/meeting.py +++ b/bot/ircmeeting/meeting.py @@ -33,6 +33,7 @@ import time import os import re import stat +import threading =20 import writers import items @@ -301,7 +302,6 @@ else: # Subclass Config and LocalConfig, new type overrides Config. Config =3D type('Config', (LocalConfig, Config), {}) =20 - class MeetingCommands(object): # Command Definitions # generic parameters to these functions: @@ -328,6 +328,21 @@ class MeetingCommands(object): def do_previtem(self, nick, time_, line, **kwargs): self.reply(self.config.agenda.prev_agenda_item()) =20 + def do_timelimit(self, nick, time_, line, **kwargs): + reply =3D 'Usage "#timelimit add : " = or ' +\ + '"#timelimit list" or "#timelimit remove "' + match =3D re.match( ' *?add ([0-9]+):([0-9]+) (.*)', line) + if match: + reply =3D self.config.agenda.add_timelimit(int(match.group(1))= , + int(match.group(2)), match.group(3), self) + elif re.match( ' *?list', line): + reply =3D self.config.agenda.list_timielimits() + else: + match =3D re.match( ' *?remove (.*)', line) + if(match): + reply =3D self.config.agenda.remove_timelimit(match.group(1)= ) + self.reply(reply) + def do_startvote(self, nick, time_, line, **kwargs): for messageline in self.config.agenda.start_vote().split('\n'): self.reply(messageline) diff --git a/bot/tests/run_test.py b/bot/tests/run_test.py index 9808ee6..e3a9030 100644 --- a/bot/tests/run_test.py +++ b/bot/tests/run_test.py @@ -6,6 +6,8 @@ import re import shutil import sys import tempfile +import time +import threading import unittest =20 os.environ['MEETBOT_RUNNING_TESTS'] =3D '1' @@ -427,6 +429,60 @@ class MeetBotTest(unittest.TestCase): =20 assert(test.votes() =3D=3D {'first item': {u'x': 'opt2', u'z': '= opt1'}, 'second item': {}}) =20 + def test_agenda_time_limit_adding(self): + test =3D self.get_simple_agenda_test() + test.answer_should_match('20:13:50 #timelimit', 'Usage "#tim= elimit ' +\ + 'add : " or= "' +\ + '#timelimit list" or "#timelimit remov= e ' +\ + '"') + test.answer_should_match('20:13:50 #timelimit add 0:1 some o= ther message', + 'Added "some other message" reminder i= n 0:1') + test.answer_should_match('20:13:50 #timelimit add 1:0 some m= essage', + 'Added "some message" reminder in 1:0'= ) + time.sleep(2) + last_message =3D test.log[-1] + assert(last_message =3D=3D 'some other message') + reminders =3D test.M.config.agenda.reminders + assert(len(reminders) =3D=3D 2) + for reminder in reminders.values(): + assert(reminder.__class__ =3D=3D threading._Timer) + + test.process('20:13:50 #nextitem') + + def test_agenda_time_limit_removing_when_changing_item(self): + test =3D self.get_simple_agenda_test() + + test.process('20:13:50 #timelimit add 0:1 message') + assert(len(test.M.config.agenda.reminders) =3D=3D 1) + test.process('20:13:50 #nextitem') + assert(len(test.M.config.agenda.reminders) =3D=3D 0) + test.process('20:13:50 #timelimit add 0:1 message') + assert(len(test.M.config.agenda.reminders) =3D=3D 1) + test.process('20:13:50 #previtem') + assert(len(test.M.config.agenda.reminders) =3D=3D 0) + + def test_agenda_time_limit_manual_removing(self): + test =3D self.get_simple_agenda_test() + + test.process('20:13:50 #timelimit add 0:1 message') + test.process('20:13:50 #timelimit add 0:1 other message') + keys =3D test.M.config.agenda.reminders.keys() + keys.sort() + assert(keys =3D=3D ['message', 'other message']) + + test.answer_should_match('20:13:50 #timelimit remove other m= essage', 'Reminder "other message" removed') + keys =3D test.M.config.agenda.reminders.keys() + assert(keys =3D=3D ['message']) + + def test_agenda_time_limit_listing(self): + test =3D self.get_simple_agenda_test() + test.process('20:13:50 #timelimit add 0:1 message') + test.process('20:13:50 #timelimit add 0:1 other message') + test.process('20:13:50 #timelimit add 0:1 yet another messag= e') + keys =3D test.M.config.agenda.reminders.keys() + test.answer_should_match('20:13:50 #timelimit list', + 'Set reminders: "' + '", "'.join(keys)= + '"') + if __name__ =3D=3D '__main__': os.chdir(os.path.join(os.path.dirname(__file__), '.')) =20