예제 #1
0
파일: image.py 프로젝트: jsgf/imagestore2
    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
예제 #2
0
파일: upload.py 프로젝트: jsgf/imagestore2
        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)
예제 #3
0
파일: user.py 프로젝트: jsgf/imagestore2
    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()
예제 #4
0
파일: user.py 프로젝트: jsgf/imagestore2
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
예제 #5
0
파일: upload.py 프로젝트: jsgf/imagestore2
        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)
예제 #6
0
파일: upload.py 프로젝트: jsgf/imagestore2
        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)
예제 #7
0
파일: search.py 프로젝트: jsgf/imagestore2
    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()
예제 #8
0
파일: upload.py 프로젝트: jsgf/imagestore2
        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()
예제 #9
0
파일: search.py 프로젝트: jsgf/imagestore2
    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&ndash;%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()
예제 #10
0
파일: user.py 프로젝트: jsgf/imagestore2
            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()
    
    form.add(form2.StringWidget, 'username', title='User name')
    form.add(form2.StringWidget, 'fullname', title='Full name')
    form.add(form2.StringWidget, 'email', title='email address')