docstrings and new commands
This commit is contained in:
parent
33051bb986
commit
45f7c534cc
1 changed files with 166 additions and 31 deletions
|
|
@ -16,7 +16,7 @@
|
||||||
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
|
|
||||||
from datetime import datetime
|
from datetime import datetime, timedelta
|
||||||
import re
|
import re
|
||||||
import sys
|
import sys
|
||||||
from urlparse import urlsplit
|
from urlparse import urlsplit
|
||||||
|
|
@ -42,6 +42,9 @@ class Task(object):
|
||||||
self.date = None
|
self.date = None
|
||||||
self.branch = u''
|
self.branch = u''
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return '<Task (%s,%s)>' % (self.backend, self.capability)
|
||||||
|
|
||||||
class Member(object):
|
class Member(object):
|
||||||
def __init__(self, id, name):
|
def __init__(self, id, name):
|
||||||
self.name = name
|
self.name = name
|
||||||
|
|
@ -81,6 +84,16 @@ class Event(object):
|
||||||
delta = self.end - self.begin
|
delta = self.end - self.begin
|
||||||
return '%02d:%02d' % (delta.seconds/3600, delta.seconds%3600)
|
return '%02d:%02d' % (delta.seconds/3600, delta.seconds%3600)
|
||||||
|
|
||||||
|
def check_time_coherence(self):
|
||||||
|
"""
|
||||||
|
Check if the end's day is before the begin's one, in
|
||||||
|
case it stops at the next day (eg. 15h->1h).
|
||||||
|
|
||||||
|
If it occures, add a day.
|
||||||
|
"""
|
||||||
|
if self.begin > self.end:
|
||||||
|
self.end = self.end + timedelta(1)
|
||||||
|
|
||||||
def load(self):
|
def load(self):
|
||||||
self.content = self.backend.get_content(self.name)
|
self.content = self.backend.get_content(self.name)
|
||||||
self.members.clear()
|
self.members.clear()
|
||||||
|
|
@ -115,6 +128,7 @@ class Event(object):
|
||||||
self.begin = self.parse_time(value)
|
self.begin = self.parse_time(value)
|
||||||
elif key == 'End':
|
elif key == 'End':
|
||||||
self.end = self.parse_time(value)
|
self.end = self.parse_time(value)
|
||||||
|
self.check_time_coherence()
|
||||||
elif key == 'Location':
|
elif key == 'Location':
|
||||||
self.location = value
|
self.location = value
|
||||||
else:
|
else:
|
||||||
|
|
@ -145,9 +159,9 @@ class Event(object):
|
||||||
task.date = datetime(self.date.year,
|
task.date = datetime(self.date.year,
|
||||||
self.date.month,
|
self.date.month,
|
||||||
self.date.day,
|
self.date.day,
|
||||||
int(m.group(1)),
|
int(mm.group(1)),
|
||||||
int(m.group(2)))
|
int(mm.group(2)))
|
||||||
task.branch = m.group(3)
|
task.branch = mm.group(3)
|
||||||
|
|
||||||
def parse_date(self, value):
|
def parse_date(self, value):
|
||||||
try:
|
try:
|
||||||
|
|
@ -263,6 +277,8 @@ class Boobathon(ReplApplication):
|
||||||
def save_event(self, message):
|
def save_event(self, message):
|
||||||
if self.ask("Do you confirm your changes?", default=True):
|
if self.ask("Do you confirm your changes?", default=True):
|
||||||
self.event.save(message)
|
self.event.save(message)
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
def edit_event(self):
|
def edit_event(self):
|
||||||
self.event.title = self.ask('Enter a title', default=self.event.title)
|
self.event.title = self.ask('Enter a title', default=self.event.title)
|
||||||
|
|
@ -272,16 +288,21 @@ class Boobathon(ReplApplication):
|
||||||
regexp='^(\d{4}-\d{2}-\d{2})?$')
|
regexp='^(\d{4}-\d{2}-\d{2})?$')
|
||||||
if self.event.date:
|
if self.event.date:
|
||||||
self.event.date = datetime.strptime(self.event.date, '%Y-%m-%d')
|
self.event.date = datetime.strptime(self.event.date, '%Y-%m-%d')
|
||||||
self.event.begin = self.ask('Begin at (HH:MM)',
|
|
||||||
default=self.event.begin.strftime('%H:%M') if self.event.begin else '',
|
s = self.ask('Begin at (HH:MM)',
|
||||||
regexp='^(\d{2}:\d{2})?$')
|
default=self.event.begin.strftime('%H:%M') if self.event.begin else '',
|
||||||
if self.event.begin:
|
regexp='^(\d{2}:\d{2})?$')
|
||||||
self.event.begin = datetime.strptime(self.event.begin, '%H:%M')
|
if s:
|
||||||
self.event.end = self.ask('End at (HH:MM)',
|
h, m = s.split(':')
|
||||||
default=self.event.end.strftime('%H:%M') if self.event.end else '',
|
self.event.begin = self.event.date.replace(hour=int(h), minute=int(m))
|
||||||
regexp='^(\d{2}:\d{2})?$')
|
s = self.ask('End at (HH:MM)',
|
||||||
if self.event.end:
|
default=self.event.end.strftime('%H:%M') if self.event.end else '',
|
||||||
self.event.end = datetime.strptime(self.event.end, '%H:%M')
|
regexp='^(\d{2}:\d{2})?$')
|
||||||
|
if s:
|
||||||
|
h, m = s.split(':')
|
||||||
|
self.event.end = self.event.date.replace(hour=int(h), minute=int(m))
|
||||||
|
self.event.check_time_coherence()
|
||||||
|
|
||||||
self.event.location = self.ask('Enter a location', default=self.event.location)
|
self.event.location = self.ask('Enter a location', default=self.event.location)
|
||||||
|
|
||||||
self.save_event('Event edited')
|
self.save_event('Event edited')
|
||||||
|
|
@ -295,6 +316,11 @@ class Boobathon(ReplApplication):
|
||||||
member.hardware = self.ask('Enter your hardware', default=member.hardware)
|
member.hardware = self.ask('Enter your hardware', default=member.hardware)
|
||||||
|
|
||||||
def do_progress(self, line):
|
def do_progress(self, line):
|
||||||
|
"""
|
||||||
|
progress
|
||||||
|
|
||||||
|
Display progress of members.
|
||||||
|
"""
|
||||||
self.event.load()
|
self.event.load()
|
||||||
for member in self.event.members.itervalues():
|
for member in self.event.members.itervalues():
|
||||||
s = u' %s %20s %s|' % ('->' if member.is_me else ' ', member.name, self.BOLD)
|
s = u' %s %20s %s|' % ('->' if member.is_me else ' ', member.name, self.BOLD)
|
||||||
|
|
@ -309,6 +335,11 @@ class Boobathon(ReplApplication):
|
||||||
print s
|
print s
|
||||||
|
|
||||||
def do_tasks(self, line):
|
def do_tasks(self, line):
|
||||||
|
"""
|
||||||
|
tasks
|
||||||
|
|
||||||
|
Display all tasks of members.
|
||||||
|
"""
|
||||||
self.event.load()
|
self.event.load()
|
||||||
tasks = []
|
tasks = []
|
||||||
members = []
|
members = []
|
||||||
|
|
@ -343,26 +374,41 @@ class Boobathon(ReplApplication):
|
||||||
sys.stdout.write('\n')
|
sys.stdout.write('\n')
|
||||||
|
|
||||||
def do_edit(self, line):
|
def do_edit(self, line):
|
||||||
|
"""
|
||||||
|
edit
|
||||||
|
|
||||||
|
Edit the event information.
|
||||||
|
"""
|
||||||
self.event.load()
|
self.event.load()
|
||||||
self.edit_event()
|
self.edit_event()
|
||||||
|
|
||||||
def do_info(self, line):
|
def do_info(self, line):
|
||||||
|
"""
|
||||||
|
info
|
||||||
|
|
||||||
|
Display information about this event.
|
||||||
|
"""
|
||||||
self.event.load()
|
self.event.load()
|
||||||
print self.event.title
|
print self.event.title
|
||||||
print '-' * len(self.event.title)
|
print '-' * len(self.event.title)
|
||||||
print self.event.description
|
print self.event.description
|
||||||
print ''
|
print ''
|
||||||
print 'Date:', self.event.date
|
print 'Date:', self.event.date.strftime('%Y-%m-%d') if self.event.date else 'Unknown'
|
||||||
print 'Begin:', self.event.begin
|
print 'Begin:', self.event.begin.strftime('%H:%M') if self.event.begin else 'Unknown'
|
||||||
print 'End:', self.event.end
|
print 'End:', self.event.end.strftime('%H:%M') if self.event.end else 'Unknown'
|
||||||
print 'Duration:', self.event.format_duration()
|
print 'Duration:', self.event.format_duration() or 'Unknown'
|
||||||
print 'Location:', self.event.location
|
print 'Location:', self.event.location or 'Unknown'
|
||||||
print ''
|
print ''
|
||||||
print 'There are %d members, use the "members" command to list them' % len(self.event.members)
|
print 'There are %d members, use the "members" command to list them' % len(self.event.members)
|
||||||
if self.event.get_me() is None:
|
if self.event.get_me() is None:
|
||||||
print 'To join this event, use the command "join".'
|
print 'To join this event, use the command "join".'
|
||||||
|
|
||||||
def do_members(self, line):
|
def do_members(self, line):
|
||||||
|
"""
|
||||||
|
members
|
||||||
|
|
||||||
|
Display members informations.
|
||||||
|
"""
|
||||||
self.event.load()
|
self.event.load()
|
||||||
for member in self.event.members.itervalues():
|
for member in self.event.members.itervalues():
|
||||||
print member.name
|
print member.name
|
||||||
|
|
@ -380,18 +426,37 @@ class Boobathon(ReplApplication):
|
||||||
print 'Use the "tasks" command to display all tasks'
|
print 'Use the "tasks" command to display all tasks'
|
||||||
|
|
||||||
def do_join(self, line):
|
def do_join(self, line):
|
||||||
|
"""
|
||||||
|
join
|
||||||
|
|
||||||
|
Join this event.
|
||||||
|
"""
|
||||||
self.event.load()
|
self.event.load()
|
||||||
if self.event.backend.browser.get_userid() in self.event.members:
|
if self.event.backend.browser.get_userid() in self.event.members:
|
||||||
print 'You have already joined this event.'
|
print 'You have already joined this event.'
|
||||||
return
|
return
|
||||||
|
|
||||||
|
if self.event.currently_in_event():
|
||||||
|
print 'Unable to join during the event.'
|
||||||
|
return
|
||||||
|
|
||||||
m = Member(self.event.backend.browser.get_userid(), 'Unknown')
|
m = Member(self.event.backend.browser.get_userid(), 'Unknown')
|
||||||
self.edit_member(m)
|
self.edit_member(m)
|
||||||
self.event.members[m.id] = m
|
self.event.members[m.id] = m
|
||||||
self.save_event('Joined the event')
|
self.save_event('Joined the event')
|
||||||
|
|
||||||
def do_leave(self, line):
|
def do_leave(self, line):
|
||||||
|
"""
|
||||||
|
leave
|
||||||
|
|
||||||
|
Leave this event.
|
||||||
|
"""
|
||||||
self.event.load()
|
self.event.load()
|
||||||
|
|
||||||
|
if self.event.currently_in_event():
|
||||||
|
print 'Unable to leave during the event, loser!'
|
||||||
|
return
|
||||||
|
|
||||||
try:
|
try:
|
||||||
self.event.members.pop(self.event.backend.browser.get_userid())
|
self.event.members.pop(self.event.backend.browser.get_userid())
|
||||||
except KeyError:
|
except KeyError:
|
||||||
|
|
@ -399,7 +464,38 @@ class Boobathon(ReplApplication):
|
||||||
else:
|
else:
|
||||||
self.save_event('Left the event')
|
self.save_event('Left the event')
|
||||||
|
|
||||||
|
def do_remtask(self, line):
|
||||||
|
"""
|
||||||
|
remtask TASK_ID
|
||||||
|
|
||||||
|
Remove a task.
|
||||||
|
"""
|
||||||
|
self.event.load()
|
||||||
|
mem = self.event.get_me()
|
||||||
|
if not mem:
|
||||||
|
print 'You have not joined this event.'
|
||||||
|
return
|
||||||
|
|
||||||
|
try:
|
||||||
|
task_id = int(line)
|
||||||
|
except ValueError:
|
||||||
|
print 'The task ID might be a number'
|
||||||
|
return
|
||||||
|
|
||||||
|
try:
|
||||||
|
task = mem.tasks.pop(task_id)
|
||||||
|
except IndexError:
|
||||||
|
print 'Unable to find task #%d' % task_id
|
||||||
|
else:
|
||||||
|
print 'Removing task #%d (%s,%s).' % (task_id, task.backend, task.capability)
|
||||||
|
self.save_event('Remove task')
|
||||||
|
|
||||||
def do_addtask(self, line):
|
def do_addtask(self, line):
|
||||||
|
"""
|
||||||
|
addtask BACKEND CAPABILITY
|
||||||
|
|
||||||
|
Add a new task.
|
||||||
|
"""
|
||||||
self.event.load()
|
self.event.load()
|
||||||
mem = self.event.get_me()
|
mem = self.event.get_me()
|
||||||
if not mem:
|
if not mem:
|
||||||
|
|
@ -407,6 +503,13 @@ class Boobathon(ReplApplication):
|
||||||
return
|
return
|
||||||
|
|
||||||
backend, capability = self.parse_command_args(line, 2, 2)
|
backend, capability = self.parse_command_args(line, 2, 2)
|
||||||
|
if not backend[0].isupper():
|
||||||
|
print 'The backend name "%s" needs to start with a capital.' % backend
|
||||||
|
return
|
||||||
|
if not capability.startswith('Cap') or not capability[3].isupper():
|
||||||
|
print '"%s" is not a right capability name.' % capability
|
||||||
|
return
|
||||||
|
|
||||||
for task in mem.tasks:
|
for task in mem.tasks:
|
||||||
if (task.backend,task.capability) == (backend,capability):
|
if (task.backend,task.capability) == (backend,capability):
|
||||||
print 'A task already exists for that.'
|
print 'A task already exists for that.'
|
||||||
|
|
@ -417,6 +520,12 @@ class Boobathon(ReplApplication):
|
||||||
self.save_event('New task')
|
self.save_event('New task')
|
||||||
|
|
||||||
def do_start(self, line):
|
def do_start(self, line):
|
||||||
|
"""
|
||||||
|
start [TASK_ID]
|
||||||
|
|
||||||
|
Start a task. If you don't give a task ID, the first available
|
||||||
|
task will be taken.
|
||||||
|
"""
|
||||||
self.event.load()
|
self.event.load()
|
||||||
mem = self.event.get_me()
|
mem = self.event.get_me()
|
||||||
if not mem:
|
if not mem:
|
||||||
|
|
@ -443,7 +552,7 @@ class Boobathon(ReplApplication):
|
||||||
elif task.status == task.STATUS_PROGRESS:
|
elif task.status == task.STATUS_PROGRESS:
|
||||||
task.status = task.STATUS_NONE
|
task.status = task.STATUS_NONE
|
||||||
|
|
||||||
if i == task_id or task.status == task.STATUS_NONE:
|
if (i == task_id or task_id < 0) and task.status == task.STATUS_NONE:
|
||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
print 'Task not found.'
|
print 'Task not found.'
|
||||||
|
|
@ -454,35 +563,61 @@ class Boobathon(ReplApplication):
|
||||||
|
|
||||||
task.status = task.STATUS_PROGRESS
|
task.status = task.STATUS_PROGRESS
|
||||||
mem.tasks.remove(task)
|
mem.tasks.remove(task)
|
||||||
mem.tasks.insert(last_done, task)
|
mem.tasks.insert(last_done + 1, task)
|
||||||
|
print task
|
||||||
|
print mem.tasks
|
||||||
self.save_event('Started a task')
|
self.save_event('Started a task')
|
||||||
|
|
||||||
def do_done(self, line):
|
def do_done(self, line):
|
||||||
|
"""
|
||||||
|
done
|
||||||
|
|
||||||
|
Set the current task as done.
|
||||||
|
"""
|
||||||
self.event.load()
|
self.event.load()
|
||||||
mem = self.event.get_me()
|
mem = self.event.get_me()
|
||||||
if not mem:
|
if not mem:
|
||||||
print 'You have not joined this event.'
|
print 'You have not joined this event.'
|
||||||
return
|
return
|
||||||
|
|
||||||
if len(mem.tasks) == 0:
|
for i, task in enumerate(mem.tasks):
|
||||||
print "You don't have any task to do."
|
if task.status == task.STATUS_PROGRESS:
|
||||||
return
|
print 'Task (%s,%s) done! (%d%%)' % (task.backend, task.capability, (i+1)*100/len(mem.tasks))
|
||||||
|
if self.event.currently_in_event():
|
||||||
|
task.status = task.STATUS_DONE
|
||||||
|
task.date = datetime.now()
|
||||||
|
task.branch = self.ask('Enter name of branch')
|
||||||
|
self.save_event('Task accomplished')
|
||||||
|
else:
|
||||||
|
task.status = task.STATUS_NONE
|
||||||
|
print 'Oops, you are out of event. Canceling the task...'
|
||||||
|
self.save_event('Cancel task')
|
||||||
|
return
|
||||||
|
|
||||||
if not self.event.currently_in_event():
|
print "There isn't any task in progress."
|
||||||
print "You can't start a task, we are not in event."
|
|
||||||
|
def do_cancel(self, line):
|
||||||
|
"""
|
||||||
|
cancel
|
||||||
|
|
||||||
|
Cancel the current task.
|
||||||
|
"""
|
||||||
|
self.event.load()
|
||||||
|
mem = self.event.get_me()
|
||||||
|
if not mem:
|
||||||
|
print 'You have not joined this event.'
|
||||||
return
|
return
|
||||||
|
|
||||||
for task in mem.tasks:
|
for task in mem.tasks:
|
||||||
if task.status == task.STATUS_PROGRESS:
|
if task.status == task.STATUS_PROGRESS:
|
||||||
print 'Task: %s,%s' % (task.backend, task.capability)
|
print 'Task (%s,%s) canceled.' % (task.backend, task.capability)
|
||||||
task.status = task.STATUS_DONE
|
task.status = task.STATUS_NONE
|
||||||
task.date = datetime.now()
|
self.save_event('Cancel task')
|
||||||
task.branch = self.ask('Enter name of branch')
|
|
||||||
self.save_event('Task accomplished')
|
|
||||||
return
|
return
|
||||||
|
|
||||||
print "There isn't any task in progress."
|
print "There isn't any task in progress."
|
||||||
|
|
||||||
|
|
||||||
def load_default_backends(self):
|
def load_default_backends(self):
|
||||||
"""
|
"""
|
||||||
Overload a BaseApplication method.
|
Overload a BaseApplication method.
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue