def editdetails(self, request, p): form = form2.Form(name='editdetails') form.add(form2.StringWidget, name='title', size=50, value=p.title or '', title='Title') form.add(form2.StringWidget, name='keywords', size=40, value=', '.join([ k.word for k in p.keywords]), title='Keywords') form.add(form2.StringWidget, name='description', size=50, value=p.description, title='Description') # FIXME form layout # form.add(form2.TextWidget, name='description', cols=50, rows=10, # value=p.description, title='Description') form.add(form2.SingleSelectWidget, name='owner', value=p.ownerID, title='Picture owner', options=imagestore.form.userOptList()) form.add(form2.SingleSelectWidget, name='visibility', value=p.visibility, title='Visibility', options=[ s for s in ['public', 'restricted', 'private']]) (prev,next) = request.session.get_results_neighbours(p.id) if next is not None: form.add_submit('submit-next', H('Update picture and go to next >>')) else: form.add_submit('submit', 'Update picture details') form.add_reset('reset', 'Revert changes') if not form.is_submitted() or form.has_errors(): from image_page import detail_table self.image.set_prevnext(request, p.id, urlfn=lambda pic, size, s=self.image: s.edit.path(pic)) ret = TemplateIO(html=True) ret += page.pre(request, 'Edit details', 'editdetails', trail=False) ret += page.menupane(request) ret += self.image.view_rotate_link(request, p, wantedit=True) ret += detail_table(p) ret += form.render() ret += page.post() ret = ret.getvalue() else: keywords = form['keywords'] keywords = imagestore.form.splitKeywords(keywords) p.setKeywords(keywords) p.visibility = form['visibility'] if form.get_submit() == 'submit-next' and next: ret = quixote.redirect(self.image.edit.path(db.Picture.get(next))) else: ret = quixote.redirect(request.get_path()) return ret
def upload(self, request): form = self.upload_form(request) if form.get_submit() != 'upload': r = TemplateIO(html=True) r += page.pre(request, 'Upload pictures', 'upload') r += page.menupane(request) r += form.render() #r += H(request.dump_html()) r += page.post() return r.getvalue() else: user = request.session.getuser() start = calendar.int_day.rounddown(gmt()) end = calendar.int_day.roundup(gmt()) upload = db.Upload.select(AND(db.Upload.q.import_time >= start, db.Upload.q.import_time < end, db.Upload.q.userID == user.id, db.Upload.q.collectionID == self.collection.db.id)) assert upload.count() == 0 or upload.count() == 1, \ 'Should be only one Upload per day per user' if upload.count() == 1: u = upload[0] else: u = db.Upload(user=user, collection=self.collection.db) c = int(form['camera']) if c == -2: camera = None # new camera elif c == -1: camera = None # guess else: camera = db.Camera.get(c) numfiles = int(form['numfiles']) keywords = form['keywords'] if keywords is not None: keywords = splitKeywords(keywords) print 'self.collection.db=%s' % self.collection.db request.response.buffered=False upload = self.do_upload(request, [ (f.fp, f.base_filename) for f in [ form['file.%d' % n] for n in range(numfiles) ] if f is not None], user, camera, keywords, form['visibility'], u) return quixote.http_response.Stream(upload)
def render(): ret = TemplateIO(html=True) ret += page.pre(request, 'User administration', 'editusers') ret += page.menupane(request) ret += H('<h1>User administration</h1>\n') ret += userform.render() ret += page.post() return ret.getvalue()
def newuser(request): user = admin.login_user(quiet=True) if not ((user and user.mayAdmin) or config.get('users', 'unpriv_newuser')): raise AccessError('You may not create a new user') form = form2.Form() form.add(form2.StringWidget, 'username', title='User name') form.add(form2.StringWidget, 'fullname', title='Full name') form.add(form2.StringWidget, 'email', title='email address') form.add(form2.PasswordWidget, 'pass1', title='Password') form.add(form2.PasswordWidget, 'pass2', title='Password verify') form.add_submit('create', 'Create user') ret = None if form.is_submitted(): username = form['username'].strip() if db.User.select(db.User.q.username == username).count() != 0: form.get_widget('username').set_error(H("Username '%s' already in use") % username) if form['pass1'] != form['pass2']: form.get_widget('pass1').set_error('Passwords do not match') fullname = form['fullname'].strip() if fullname == '': form.get_widget('fullname').set_error('Full name not set') email = form['email'].strip() if email == '': form.get_widget('email').set_error('Missing or bad email address') if not form.has_errors(): u = db.User(username=username, fullname=fullname, password=form['pass1'], email=email, mayAdmin=False, mayViewall=False, mayUpload=False, mayComment=config.get('users', 'mayComment'), mayRate=config.get('users', 'mayRate')) ret = quixote.redirect(path(u)) if ret is None: r = TemplateIO(html=True) r += page.pre(request, 'New User', 'newuser') r += page.menupane(request) r += form.render() r += page.post() ret = r.getvalue() return ret
def do_upload(self, request, files, user, camera, keywords, visibility, upload): r = page.pre(request, 'Uploading pictures', 'uploading', trail=False) r += H('<H1>Uploading pictures...</H1>\n') yield str(r) for (fp, base_filename) in files: for y in self.do_upload_file(fp, base_filename, None, user, camera, keywords, visibility, upload): yield y r = H('<p id="bottom"><a href="pending">Edit pending pictures</a>\n') r += H('<p><a href="%s">Upload more pictures</a>\n') % request.get_path() r += page.post() yield str(r)
def streamer(request=request, visibility=visibility, files=files, self=self): quixote.get_publisher()._set_request(request) r = page.pre(request, 'Uploading pictures', 'uploading', trail=False) r += H('<H1>Uploading pictures...</H1>\n') r += H('<dl>\n') yield str(r) for f in files: for y in self.do_upload_file(f.fp, f.base_filename, None, visibility): yield y r += H('</dl>\n') r += H('<p><a href="%s">Upload more pictures</a>\n') % self.path() r += page.post() yield str(r)
def _q_index(self, request): r = TemplateIO(html=True) kw = db.Keyword.select(db.Keyword.q.collectionID == self.col.db.id, orderBy=db.Keyword.q.word) r += page.pre(request, 'Keyword search', 'search', brieftitle='keywords') r += page.menupane(request) r += H('<div class="title-box kwlist">\n') r += H('<h2>%s</h2>\n') % page.plural(kw.count(), 'keyword') # XXX filter only keywords with (visible) pictures associated with them # (and perhaps weight by use) r += listkeywords('kw/', [ k.word for k in kw ], True) r += H('</div>\n') r += page.post(); return r.getvalue()
def pending(self, request): user = request.session.getuser() body = TemplateIO(html=True) results=[] for u in db.Upload.select(AND(db.Upload.q.collectionID == self.collection.db.id, db.Upload.q.userID == user.id), orderBy=db.Upload.q.import_time): pics = u.pictures if not pics: continue pics.sort(lambda a,b: cmp(a.record_time, b.record_time)) body += H('<div class="title-box upload">\n') body += H('<h2>Import into "%s" on %s</h2>\n') % (u.collection.name, u.import_time.strftime('%Y-%m-%d')) # XXX for (d, pics) in search.group_by_time(pics, calendar.int_day): body += H('<div id="%s" class="day">\n') % calendar.int_day.num_fmt(d) body += H('<h3>%s</h3>\n') % calendar.int_day.num_fmt(d) body += H('<div class="day-pics">\n') body += H('<form method="POST" action="commit">\n') kwset = [ k.word for k in search.commonKeywords(pics) ] kwset = ', '.join(list(kwset)) body += H('<label>Default keywords: <input type="text" name="keywords" value="%s"></label>\n') % kwset body += H('<label>Visibility: <select name="visibility">\n') for v in ['unchanged', 'public', 'restricted', 'private']: body += H(' <option value="%s">%s</option>\n') % (v, v.capitalize()) body += H('</select></label>\n') for p in pics: results.append(p) body += H('<div style="float: left">\n') body += image.ImageDir(self.collection).view_rotate_link(request, p, wantedit=True) body += H('<br>\n') body += H('<input title="Commit?" type="checkbox" name="pic" value="%d" checked>\n') % p.id if p.keywords: body += H('%s') % ', '.join([ k.word for k in p.keywords ]) body += H('</div>\n') body += H('</div>\n') body += H('<br style="clear: both">') body += H('<input type="submit" name="defaults" value="Apply defaults">\n') body += H('<input type="submit" name="commit" value="Commit pictures to collection">\n') body += H('</form>\n') body += H('</div>\n') body += H('</div>\n') r = TemplateIO(html=True) request.session.set_query_results(results) r += page.pre(request, 'Pending uploaded images for "%s"' % self.collection.db.name, 'pending', brieftitle='pending uploads') r += page.menupane(request) r += body.getvalue() r += page.post() return r.getvalue()
def _q_index(self, request): # Map keyword strings into Keywords; if any keyword is # unknown, then by definition we can't find any images tagged # with it try: kw = [ db.Keyword.byWord(k) for k in self.kw ] except SQLObjectNotFound: kw = [] # List of Sets of pictures for each keyword picsets = [ Set(k.pictures) for k in kw ] # Find intersection of all sets if picsets: pics = reduce(lambda a, b: a & b, picsets) else: pics = [] # Filter for visibility pics = [ p for p in pics if (not p.isPending() and self.col.mayView(p, quiet=True)) ] # Sort by time pics.sort(lambda a,b: cmp(a.record_time, b.record_time)) request.session.set_query_results(pics) resultsize = len(pics) # Present keyword operations on the full set of pictures, not # just the displayed set. # Useless keywords are the ones common to all images in this search useless = Set([ k.word for k in commonKeywords(pics) ]) # Union of all keywords used kwset = Set([ k.word for p in pics for k in p.keywords ]) # The refining set of keywords are the ones which will further # restrict the search results refining = kwset-useless #print 'useless=%s, kwset=' % useless # Limit the size of the displayed result set start = request.form.get('start') or 0 limit = request.form.get('limit') or self.RESULTLIMIT start = int(start) limit = int(limit) if start < 0 or start > len(pics): start = 0 if limit <= 0: limit = self.RESULTLIMIT end = start+limit if start > 0: p=start-limit request.navigation.set_prev(self.url(max(p, 0), limit)) request.navigation.set_first(self.url(limit=limit)) if end < len(pics): request.navigation.set_next(self.url(end, limit)) request.navigation.set_last(self.url(resultsize-limit, limit)) pics = pics[start:start+limit] r = TemplateIO(html=True) groups = group_by_time(pics, int_day) extra = [] if refining: extra += [ menu.Link('refine search', '#refine') ] if kwset: extra += [ menu.Link('new search', '#replace') ] if len(groups) > 1: skiplist = [ menu.Link(int_day.num_fmt(day), '#' + int_day.num_fmt(day)) for (day, dp) in groups ] if len(skiplist) > 15: factor = len(skiplist) / 15 skiplist = [ s for (n, s) in zip(range(len(skiplist)), skiplist) if n % factor == 0 ] extra += [ menu.SubMenu(heading='Skip to:', items=skiplist) ] if len(self.kw) > 1: searchstr = ' and '.join([ ', '.join(self.kw[:-1]), self.kw[-1] ]) elif len(self.kw) == 1: searchstr = self.kw[0] else: searchstr = '(nothing)' heading=H('Search for %s: ') % searchstr if start == 0 and end >= resultsize: heading += H('%s') % page.plural(resultsize, 'picture') elif start+1 == resultsize: heading += H('last of %d pictures') % (resultsize) else: heading += H('%d–%d of %d pictures') % (start+1, min(resultsize,end), resultsize) r += page.pre(request, heading, 'kwsearch', brieftitle=searchstr, trail=start==0) r += page.menupane(request, extra) r += H('<h1>%s</h1>\n') % heading r += self.col.calendar.ui.picsbyday(groups) if refining: # Refine by ANDing more keywords in r += H('<div class="title-box kwlist" id="refine">\n') r += H('<h2>Refine search</h2>\n') r += listkeywords(self.url(), list(refining)) r += H('</div>\n') if len(self.kw) > 1: r += H('<div id="expand" class="title-box kwlist">\n') r += H('<h2>Expand search (remove keyword)</h2>\n') for k in self.kw: cur = Set(self.kw) cur.remove(k) cur = list(cur) cur.sort() r += H('<a class="kw" href="%s">%s</a>\n') % (self.url(keywords=cur), k) r += H('</div>\n') if kwset: r += H('<div id="replace" class="title-box kwlist">\n') r += H('<h2>New search</h2>\n') r += listkeywords(self.url(keywords=[]), list(kwset)) r += H('</div>\n') r += page.post() return r.getvalue()
body += user_page.login_form(request, username=username) else: body += H('<p>Hi, %s, you\'ve logged in' % user.fullname) session.setuser(user.id) if referer is not None and referer != '': ret = quixote.redirect(referer) else: ret = quixote.redirect(path(user)) return ret else: body += user_page.login_form(request, referer=request.get_environ('HTTP_REFERER')) p = TemplateIO(html=True) p += page.pre(request, 'Imagestore Login', 'login', trail=False) p += page.menupane(request) p += body.getvalue() p += page.post() return p.getvalue() def newuser(request): user = admin.login_user(quiet=True) if not ((user and user.mayAdmin) or config.get('users', 'unpriv_newuser')): raise AccessError('You may not create a new user') form = form2.Form()