Page Source
from utils.display import Display, Arguments, Database, Modal
from utils.controls import *
from utils.output import *
from utils.web_exc import WebError
from utils import shapes, perms, shapes, actions
import queries, debugging
from config import docroot
import string, os
from mx import DateTime
VIDEO_FORMATS = ['mov', 'itunes_video']
AUDIO_FORMATS = ['mp3', 'itunes_audio']
class PeopleControl(SingleControl):
"""Output a comma seperated links to each instructors homepage"""
def __init__(self):
self.title = "People"
self.field = "people"
self.multi = 1
q = queries.Select(tables="people",
columns={ 'login' : 'login' ,
'name' : "concat(fname,' ',mname,' ',lname)"},
where='retired=0',
order=['lname'])
q.execute()
self.people_list = q.fetchall()
def input_form(self,display,form_fields):
if display.req.form_data.has_key(self.field):
if type(display.req.form_data[self.field]) == types.StringType and self.multi:
form_fields[self.field] = [ display.req.form_data[self.field] ]
else:
form_fields[self.field] = display.req.form_data[self.field]
for p in self.people_list:
p_org = p['login']+"_org"
form_fields[p_org] = display.req.form_data[p_org]
def output_disp(self,display,container):
"""All the people are in display.people, as a list of dictionaries. Each dictionary has
fullname, login"""
ans = []
for dict in display.people:
if dict['org'] == None:
dict['org'] = ""
else:
dict['org'] = ", " + dict['org']
ans = ans + ['%(fullname)s%(org)s' % dict]
container.append(string.join(ans,"; "))
def output_form(self,display,container):
tr = output.TR()
tr.append('<b>' + self.title + ':</b>')
s = """<div class="people"><table class="people"><thead><tr><th>Person</th><th>Organization</th></tr></thead><tbody>\n"""
checkbox_checked = ""
org_value = ""
for person in self.people_list:
for dp in display.people:
if person['login'] == dp['login']:
checkbox_checked = 'checked="checked"'
if dp['org'] != None:
org_value = dp['org']
break
s=s+"""<tr>\n <td class="people">"""
s=s+"""\n <input type="checkbox" %s """ % checkbox_checked
s=s+"""name="people" value="%(login)s" />\n <span class="person">%(name)s</span>\n\n </td>\n <td class="people">\n <input class="people" type="text" name="%(login)s_org" """ % person
s=s+"""value="%s" />""" % org_value
s=s+"""\n </td>\n</tr>\n"""
checkbox_checked = ""
org_value = ""
s = s+"""</tbody></table></div>"""
tr.append(output.TD(attrs={'colspan' : 2}, sub=s))
container.append(tr)
class RecordedEventTable(TABLE):
def __init__(self):
TABLE.__init__(self,attrs={'width':'100%'})
class RecordedEventsControl(MultipleControl):
"""Represent a Recorded Event in the list of Recorded Events.
"""
def output_disp(self, display, nest_container):
if display.req.login and perms.may(display.req.login, "delete", "videos"):
display.fields['delete_button'] = ("""[ <a href="%(action:)s&delete=""" % display.req.urls)
display.fields['delete_button'] += ("""%(recorded_event_id)s">Delete</a> ]""" % display.fields)
else:
display.fields['delete_button'] = ""
ans = []
for dict in display.people:
if dict['org'] == None:
dict['org'] = ""
else:
dict['org'] = ", " + dict['org']
ans = ans + ['%(fullname)s%(org)s' % dict]
if display.fields['screengrab_small_url'] == '':
display.fields['screengrab_small_url'] = '/i/fill.png'
if display.fields['event_date'] != None:
t = display.fields['event_date'].tuple()
display.fields['event_date'] = time.strftime("%B %e, %Y", t)
nest_container.append("""<tr><td>""")
nest_container.append("""<div class="video">""")
nest_container.append("""<span class="screengrab">""")
nest_container.append("""<a href="%(script)s/""" % display.req.urls)
nest_container.append("""%(recorded_event_id)s">""" % display.fields)
nest_container.append("""<img alt="Screenshot" class="screengrab-small" src="%(screengrab_small_url)s"/></a></span>""" % display.fields)
nest_container.append(""" <div class="video-info"> """)
nest_container.append(""" <div class="video-title"><a href="%(script)s/""" % display.req.urls)
nest_container.append("""%(recorded_event_id)s">%(title)s</a></div>""" % display.fields)
nest_container.append("""<div class="video-people">""")
nest_container.append(string.join(ans,"; "))
nest_container.append("""</div><div>""")
if display.fields['series'] != '':
nest_container.append("""<span class="video-series">%(series)s, </span>""" % display.fields)
nest_container.append("""<span>%(event_date)s</span>""" % display.fields)
nest_container.append("""</div></div> """)
nest_container.append("""</div>""" % display.fields)
nest_container.append("""%(delete_button)s""" % display.fields)
nest_container.append("""</td></tr>""")
output_form = output_disp
class RecordedEventTitleControl(TextFieldControl):
def output_disp(self, display, nest_container):
nest_container.append("""<div class="video-title">%(title)s</div>""" % display.fields)
class RecordedEventSeriesControl(TextFieldControl):
def output_disp(self, display, nest_container):
if display.fields['series'] != '':
nest_container.append("""<span>%(series)s</span>""" % display.fields)
class RecordedEventsDateControl(TextFieldControl, DateControl):
def output_disp(self,display,container):
if display.fields['event_date'] != None:
t = display.fields['event_date'].tuple()
display.fields['event_date'] = time.strftime("%B %e, %Y", t)
if display.fields['series'] != '':
container.append(", ")
container.append("""<span>%(event_date)s</span>""" % display.fields)
def output_form(self,display,container):
if display.fields['event_date'] != None:
t = display.fields['event_date'].tuple()
display.fields['event_date'] = time.strftime("%Y-%m-%d", t)
DateControl.output_form(self,display,container)
class RecordedEventScreengrabSmallControl(TextFieldControl):
def output_disp(self, display, nest_container):
pass
class RecordedEventScreengrabLargeControl(TextFieldControl):
def output_disp(self, display, nest_container):
if display.fields['screengrab_large_url'] == '':
display.fields['screengrab_large_url'] = '/i/fill.png'
nest_container.append("""<span class="screengrab"><img alt="Screenshot" class="screengrab-large" src="%(screengrab_large_url)s"/></span>""" % display.fields)
class RecordedEventInfoSummaryControl(TextAreaControl):
def output_disp(self, display, nest_container):
nest_container.append("""<div class="summary">%(info_summary)s</div>""" % display.fields)
class RecordedEventDeepLinkQTControl(TextFieldControl):
def output_disp(self,display,nest_container):
for dict in display.recordings:
if dict['format'] == "mov":
nest_container.append("""<span class="deeplink"><a class="deeplink" href="%(url)s">QuickTime</a></span>""" % dict)
def output_form(self, display, nest_container):
for dict in display.recordings:
if dict['format'] == "mov":
display.fields['deep_link_mov'] = dict['url']
TextFieldControl.output_form(self, display, nest_container)
class RecordedEventDeepLinkMP3Control(TextFieldControl):
def output_disp(self,display,nest_container):
for dict in display.recordings:
if dict['format'] == "mp3":
nest_container.append("""<span class="deeplink"><a class="deeplink" href="%(url)s">mp3</a></span>""" % dict)
def output_form(self, display, nest_container):
for dict in display.recordings:
if dict['format'] == "mp3":
display.fields['deep_link_mp3'] = dict['url']
TextFieldControl.output_form(self, display, nest_container)
class RecordedEventDeepLinkITunesvideoControl(TextFieldControl):
def output_disp(self,display,nest_container):
for dict in display.recordings:
if dict['format'] == "itunes_video":
nest_container.append("""<span class="deeplink"><a class="deeplink" href="%(url)s">iTunes video</a></span>""" % dict)
def output_form(self, display, nest_container):
for dict in display.recordings:
if dict['format'] == "itunes_video":
display.fields['deep_link_itunes_video'] = dict['url']
TextFieldControl.output_form(self, display, nest_container)
class RecordedEventDeepLinkITunesaudioControl(TextFieldControl):
def output_disp(self,display,nest_container):
for dict in display.recordings:
if dict['format'] == "itunes_audio":
nest_container.append("""<span class="deeplink"><a class="deeplink" href="%(url)s">iTunes audio</a></span>""" % dict)
def output_form(self, display, nest_container):
for dict in display.recordings:
if dict['format'] == "itunes_audio":
display.fields['deep_link_itunes_audio'] = dict['url']
TextFieldControl.output_form(self, display, nest_container)
class DeeplinksStartControl(TextControl):
def output_form(self,display,container):
pass
def output_disp(self,display,container):
if len(display.recordings) > 0:
f = "<div class=\"separator\">listen: "
for dict in display.recordings:
if dict['format'] in VIDEO_FORMATS:
f = "<div class=\"separator\">watch: "
break
container.append("<div class=\"deeplinks\">%s" % f)
class DeeplinksEndControl(TextControl):
def output_form(self,display,container):
pass
def output_disp(self,display,container):
if len(display.recordings) > 0:
container.append("</div></div>")
class DeeplinksSeparatorControl(TextControl):
def output_form(self,display,contaimer):
pass
def output_disp(self,display,container):
vcount = 0
acount = 0
sep = ""
for dict in display.recordings:
if dict['format'] in VIDEO_FORMATS:
vcount = vcount+1
elif dict['format'] in AUDIO_FORMATS:
acount = acount+1
if acount > 0 and vcount > 0:
sep = "</div><div class=\"separator\">listen: "
break
container.append("%s" % sep)
class RecordedEventDisplay(Display, Database, Arguments, Modal):
def __init__(self, req):
Display.__init__(self, req)
self.id = None
def get_multiple_title(self):
return "Videos"
multiple_container_control = SimpleContainerControl(NestContainer, Container, RecordedEventTable)
multiple_row_container_control = NullContainerControl()
multiple_controls = [ RecordedEventsControl() ]
def get_single_title(self):
return self.fields['title']
single_controls = [
"<div class=\"video-single\">",
RecordedEventScreengrabLargeControl("screengrab_large_url", title="Screengrab large", size=60),
RecordedEventScreengrabSmallControl("screengrab_small_url", title="Screengrab small", size=60),
"<div class=\"video-info-single\">",
RecordedEventTitleControl("title", title="Title", size=60),
DeeplinksStartControl(),
RecordedEventDeepLinkQTControl("deep_link_mov", title="Deep Link QuickTime", size=35),
RecordedEventDeepLinkITunesvideoControl("deep_link_itunes_video", title="Deep Link iTunes Video", size=35),
DeeplinksSeparatorControl(),
RecordedEventDeepLinkMP3Control("deep_link_mp3", title="Deep Link MP3", size=35),
RecordedEventDeepLinkITunesaudioControl("deep_link_itunes_audio", title="Deep Link iTunes Audio", size=35),
DeeplinksEndControl(),
PeopleControl(),
"<div>",
RecordedEventSeriesControl("series", title="Series", size=60),
RecordedEventsDateControl("event_date", title="Event Date", size=35),
"</div>",
"</div>",
RecordedEventInfoSummaryControl("info_summary", title="Information Summary",rows=10),
"</div>",
]
def perform_action(self):
# Check permission first
# This action can either be a DB action or a deletion of a row.
if self.req.url.internal.has_key('delete'):
if not self.permit_action('delete'):
raise WebError("Permission Denied",
"""You do not have permission to
delete a video.""")
# Delete a row
delete_id = int(self.req.url.internal['delete'][0])
self.db_delete_row(delete_id)
elif self.get_id_argument() == 'add':
if not self.permit_action('add'):
raise WebError("Permission Denied",
"""You do not have permission to
add a video.""")
self.perform_database_insert()
# go to the new video.
return "%(script)s/%(!id)s" % self.req.urls({'id' : self.id})
else:
if not self.permit_mode('edit'):
raise WebError("Permission Denied",
"""You do not have permission to
edit this video.""")
self.perform_database_update()
# display this data now
return self.req.urls['mode:display']
def make_page(self, page):
self.prep_database()
page.set_type("info")
self.shape = shapes.DISP
if self.is_add():
self.mode = 'edit'
# if logged in, show the possibities.
if self.req.login:
if self.permit_action('add'):
page.add_navigation("%(script)s/add" % self.req.urls, "Add a Recorded Event")
if self.id != 'all' and self.id != None:
page.add_navigation("%(script)s/all" % self.req.urls, "All Recorded Events")
if self.is_multiple():
page.set_title(self.get_multiple_title())
page.append("""<h1>%s</h1>""" % self.get_multiple_title())
page.append(self.multiple_database())
else:
if self.get_mode() == 'edit' or self.is_add():
self.shape = shapes.FORM
page.set_title(self.get_single_title())
if self.is_add():
page.append("<h1>Add a Recorded Event</h1>")
else:
self.add_modes_to_page(page) # Don't need modes in multiple or add
page.append(self.single_database())
def permit_mode(self, mode):
return ((mode == 'display') or
(mode == 'edit' and
perms.may(self.req.login, 'edit', 'videos')))
def permit_action(self, action):
return ((action == 'add' and
perms.may(self.req.login, 'add', 'videos')) or
(action == 'delete' and
perms.may(self.req.login, 'delete', 'videos')))
def get_id_argument(self):
if self.id: return self.id
if self.req.url.arguments:
arg = self.req.url.arguments[0]
# handle some special cases
if arg in ('add', 'all'):
self.id = arg
else:
try:
self.id = int(arg)
except (ValueError, TypeError):
pass
return self.id
def is_multiple(self):
return not self.get_id_argument() or self.get_id_argument() == 'all'
def is_add(self):
return (self.get_id_argument() and
self.get_id_argument() == 'add' and
self.permit_action('add'))
def db_rows(self):
return self.query.count()
def db_query(self):
id = self.get_id_argument()
# if this is an add, there's no querying to do.
if self.is_add():
return
q = queries.Select(tables="recorded_events",
columns={ "title" : "title",
"series" : "series",
"screengrab_small_url" : "screengrab_small_url",
"screengrab_large_url" : "screengrab_large_url",
"info_summary" : "info_summary",
"event_date" : "event_date",
"recorded_event_id" : "id"
},
order="event_date DESC"
)
if id != 'all' and id is not None:
q.where="""recorded_events.id=%s""" % queries.represent_value(id)
q.execute()
if q.count() == 0 and not self.is_multiple():
raise WebError("Recorded Event Not Found",
"""The indicated Recorded Event does not exist in this database.""")
self.query = q
def db_fetch(self):
id = self.get_id_argument()
# If we're adding, return some defaults
if self.is_add():
self.fields = {
"title" : "",
"info_summary" : "",
"series" : "",
"event_date" : DateTime.now(),
"screengrab_small_url" : "",
"screengrab_large_url" : "",
}
self.people = [{"login" : '', "fullname" : '', "org" : ''}]
self.recordings = [{"url" : '', "format" : ''}]
for f in VIDEO_FORMATS+AUDIO_FORMATS:
self.fields['deep_link_%s' % f] = ""
else:
# otherwise actually do the fetch.
self.fields = self.query.fetch()
if self.fields is not None:
recorded_event_id = self.fields['recorded_event_id']
ptables=["people","recorded_events_login"]
pcolumns={ "fullname" : "concat(fname,' ',mname,' ',lname)",
"login": "people.login",
"org" : "organization"}
pwc="people.login = recorded_events_login.login and recorded_events_login.recorded_event_id = %d" % recorded_event_id
p = queries.Select(tables=ptables, columns=pcolumns, where=pwc)
p.execute()
self.people = p.fetchall()
rtables=["recorded_events","recordings"]
rcolumns={ "url" : "url",
"format" : "format"}
rwc = "recorded_events.id = recordings.recorded_event_id and recorded_events.id = %d" % recorded_event_id
r = queries.Select(tables=rtables, columns=rcolumns, where=rwc)
r.execute()
self.recordings = r.fetchall()
for f in VIDEO_FORMATS+AUDIO_FORMATS:
self.fields['deep_link_%s' % f] = ""
return self.fields
def get_row_from_fields(self):
# Gather the data into a database row
row = {}
for field in ("title","series", "info_summary", "event_date", "screengrab_small_url","screengrab_large_url"):
row[field] = self.form_fields[field]
if row['title'] == '':
raise WebError("Must provide a title")
return row
def db_people(self,id):
if not self.form_fields.has_key('people'):
return
d = queries.Delete(table="recorded_events_login",
where="recorded_event_id=%d" % id)
d.execute()
self.people = self.form_fields['people']
rows = []
for person in self.people:
org = self.form_fields['%s_org' % person]
if org != '':
rows.append({'login' : person, 'recorded_event_id' : id, 'organization' : org})
else:
rows.append({'login' : person, 'recorded_event_id' : id})
ins = queries.Insert(table="recorded_events_login", rows=rows)
ins.execute()
def db_recordings(self,id):
urls = []
count = 0
for f in VIDEO_FORMATS+AUDIO_FORMATS:
dl = "deep_link_%s" % f
u = self.form_fields[dl]
if u != '':
count = count+1
if u != '' and u not in urls:
urls.append(u)
if len(urls) != count:
raise WebError("You need to provide distinct deep links.")
for f in VIDEO_FORMATS+AUDIO_FORMATS:
dl = "deep_link_%s" % f
d = queries.Delete(table="recordings",
where="recorded_event_id=%d and format=\"%s\"" % (id,f))
d.execute()
if self.form_fields[dl] != '':
row = [{ "recorded_event_id" : id,
"url" : self.form_fields[dl],
"format" : f }]
ins = queries.Insert(table="recordings", rows=row)
ins.execute()
def db_update(self):
id = self.get_id_argument()
row = self.get_row_from_fields()
u = queries.Update(table="recorded_events",
where="id = %d" % id,
sets=row)
u.execute()
self.db_people(id=id)
self.db_recordings(id=id)
actions.notify('videos',
"""\
User '%s' changed this recorded event as follows:
%s
""" % (self.req.login, self.represent_row(row)))
def represent_row(self, row):
# Represent a row (as a dictionary) in a manner suitable for
# emailing
return """
Title: %s
Series: %s
Information Summary: %s
Screengrab small URL: %s
Screengrab large URL: %s
""" % (row['title'], row['series'], row['info_summary'],
row['screengrab_small_url'], row['screengrab_large_url'])
def db_insert(self):
row = self.get_row_from_fields()
i = queries.Insert(table="recorded_events",
rows=[row])
i.execute()
# mark this down for later. See self.perform_action().
self.id = i.insert_id()
self.db_people(self.id)
self.db_recordings(self.id)
actions.notify('videos',
"""\
User '%s' added the following row to the recorded events table:
%s
""" % (self.req.login, self.represent_row(row)))
def represent_row(self, row):
# Represent a row (as a dictionary) in a manner suitable for
# emailing
return """
Title: %s
Series: %s
Information Summary: %s
Screengrab small URL: %s
Screengrab large URL: %s
""" % (row['title'], row['series'], row['info_summary'],
row['screengrab_small_url'], row['screengrab_large_url'])
def db_delete_row(self, id):
s = queries.Select(tables="recorded_events",
where="id = %d" % id)
s.execute()
row = s.fetch()
if row:
actions.notify('videos',
"""\
User '%s' deleted the following row from the recorded events table:
%s
""" % (self.req.login, self.represent_row(row)))
d = queries.Delete(table="recorded_events",
where="id = %d" % id)
d.execute()
f = queries.Delete(table="recorded_events_login",
where="recorded_event_id=%d" % id)
f.execute()
g = queries.Delete(table="recordings",
where="recorded_event_id=%d" % id)
g.execute()
def new(req):
return RecordedEventDisplay(req)