def index(self): """GET /admin/gists: All items in the collection""" # url('gists') not_default_user = not c.authuser.is_default_user c.show_private = request.GET.get('private') and not_default_user c.show_public = request.GET.get('public') and not_default_user gists = Gist().query() \ .filter(or_(Gist.gist_expires == -1, Gist.gist_expires >= time.time())) \ .order_by(Gist.created_on.desc()) # MY private if c.show_private and not c.show_public: gists = gists.filter(Gist.gist_type == Gist.GIST_PRIVATE) \ .filter(Gist.gist_owner == c.authuser.user_id) # MY public elif c.show_public and not c.show_private: gists = gists.filter(Gist.gist_type == Gist.GIST_PUBLIC) \ .filter(Gist.gist_owner == c.authuser.user_id) # MY public+private elif c.show_private and c.show_public: gists = gists.filter(or_(Gist.gist_type == Gist.GIST_PUBLIC, Gist.gist_type == Gist.GIST_PRIVATE)) \ .filter(Gist.gist_owner == c.authuser.user_id) # default show ALL public gists if not c.show_public and not c.show_private: gists = gists.filter(Gist.gist_type == Gist.GIST_PUBLIC) c.gists = gists p = safe_int(request.GET.get('page', 1), 1) c.gists_pager = Page(c.gists, page=p, items_per_page=10) return render('admin/gists/index.html')
def index(self): not_default_user = not request.authuser.is_default_user c.show_private = request.GET.get('private') and not_default_user c.show_public = request.GET.get('public') and not_default_user gists = Gist().query() \ .filter_by(is_expired=False) \ .order_by(Gist.created_on.desc()) # MY private if c.show_private and not c.show_public: gists = gists.filter(Gist.gist_type == Gist.GIST_PRIVATE) \ .filter(Gist.owner_id == request.authuser.user_id) # MY public elif c.show_public and not c.show_private: gists = gists.filter(Gist.gist_type == Gist.GIST_PUBLIC) \ .filter(Gist.owner_id == request.authuser.user_id) # MY public+private elif c.show_private and c.show_public: gists = gists.filter(or_(Gist.gist_type == Gist.GIST_PUBLIC, Gist.gist_type == Gist.GIST_PRIVATE)) \ .filter(Gist.owner_id == request.authuser.user_id) # default show ALL public gists if not c.show_public and not c.show_private: gists = gists.filter(Gist.gist_type == Gist.GIST_PUBLIC) c.gists = gists p = safe_int(request.GET.get('page'), 1) c.gists_pager = Page(c.gists, page=p, items_per_page=10) return render('admin/gists/index.html')
def edit(self, gist_id, format='html'): """GET /admin/gists/gist_id/edit: Form to edit an existing item""" # url('edit_gist', gist_id=ID) c.gist = Gist.get_or_404(gist_id) #check if this gist is not expired if c.gist.gist_expires != -1: if time.time() > c.gist.gist_expires: log.error('Gist expired at %s' % (time_to_datetime(c.gist.gist_expires))) raise HTTPNotFound() try: c.file_changeset, c.files = GistModel().get_gist_files(gist_id) except VCSError: log.error(traceback.format_exc()) raise HTTPNotFound() self.__load_defaults(extra_values=('0', _('unmodified'))) rendered = render('admin/gists/edit.html') if request.POST: rpost = request.POST nodes = {} for org_filename, filename, mimetype, content in zip( rpost.getall('org_files'), rpost.getall('files'), rpost.getall('mimetypes'), rpost.getall('contents')): nodes[org_filename] = { 'org_filename': org_filename, 'filename': filename, 'content': content, 'lexer': mimetype, } try: GistModel().update( gist=c.gist, description=rpost['description'], owner=c.gist.owner, gist_mapping=nodes, gist_type=c.gist.gist_type, lifetime=rpost['lifetime'] ) Session().commit() h.flash(_('Successfully updated gist content'), category='success') except NodeNotChangedError: # raised if nothing was changed in repo itself. We anyway then # store only DB stuff for gist Session().commit() h.flash(_('Successfully updated gist data'), category='success') except Exception: log.error(traceback.format_exc()) h.flash(_('Error occurred during update of gist %s') % gist_id, category='error') return redirect(url('gist', gist_id=gist_id)) return rendered
def edit(self, gist_id, format='html'): """GET /admin/gists/gist_id/edit: Form to edit an existing item""" # url('edit_gist', gist_id=ID) c.gist = Gist.get_or_404(gist_id) #check if this gist is not expired if c.gist.gist_expires != -1: if time.time() > c.gist.gist_expires: log.error('Gist expired at %s', time_to_datetime(c.gist.gist_expires)) raise HTTPNotFound() try: c.file_changeset, c.files = GistModel().get_gist_files(gist_id) except VCSError: log.error(traceback.format_exc()) raise HTTPNotFound() self.__load_defaults(extra_values=('0', _('Unmodified'))) rendered = render('admin/gists/edit.html') if request.POST: rpost = request.POST nodes = {} for org_filename, filename, mimetype, content in zip( rpost.getall('org_files'), rpost.getall('files'), rpost.getall('mimetypes'), rpost.getall('contents')): nodes[org_filename] = { 'org_filename': org_filename, 'filename': filename, 'content': content, 'lexer': mimetype, } try: GistModel().update( gist=c.gist, description=rpost['description'], owner=c.gist.owner, gist_mapping=nodes, gist_type=c.gist.gist_type, lifetime=rpost['lifetime'] ) Session().commit() h.flash(_('Successfully updated gist content'), category='success') except NodeNotChangedError: # raised if nothing was changed in repo itself. We anyway then # store only DB stuff for gist Session().commit() h.flash(_('Successfully updated gist data'), category='success') except Exception: log.error(traceback.format_exc()) h.flash(_('Error occurred during update of gist %s') % gist_id, category='error') raise HTTPFound(location=url('gist', gist_id=gist_id)) return rendered
def destroy_gists(self, gistid=None): for g in Gist.query(): if gistid: if gistid == g.gist_access_id: GistModel().delete(g) else: GistModel().delete(g) Session().commit()
def get_gist_files(self, gist_access_id, revision=None): """ Get files for given gist :param gist_access_id: """ repo = Gist.get_by_access_id(gist_access_id) cs = repo.scm_instance.get_changeset(revision) return cs, [n for n in cs.get_node('/')]
def delete(self, gist, fs_remove=True): gist = Gist.guess_instance(gist) try: Session().delete(gist) if fs_remove: self.__delete_gist(gist) else: log.debug('skipping removal from filesystem') except Exception: log.error(traceback.format_exc()) raise
def update(self, gist, description, owner, ip_addr, gist_mapping, gist_type, lifetime): gist = Gist.guess_instance(gist) gist_repo = gist.scm_instance lifetime = safe_int(lifetime, -1) if lifetime == 0: # preserve old value gist_expires = gist.gist_expires else: gist_expires = time.time() + (lifetime * 60) if lifetime != -1 else -1 # calculate operation type based on given data gist_mapping_op = {} for k, v in gist_mapping.items(): # add, mod, del if not v['org_filename'] and v['filename']: op = 'add' elif v['org_filename'] and not v['filename']: op = 'del' else: op = 'mod' v['op'] = op gist_mapping_op[k] = v gist.gist_description = description gist.gist_expires = gist_expires gist.owner = owner gist.gist_type = gist_type message = 'updated file' message += 's: ' if len(gist_mapping) > 1 else ': ' message += ', '.join([x for x in gist_mapping]) # fake Kallithea Repository object fake_repo = AttributeDict( dict( repo_name=os.path.join(GIST_STORE_LOC, gist.gist_access_id), scm_instance_no_cache=lambda: gist_repo, )) self._store_metadata(gist_repo, gist.gist_id, gist.gist_access_id, owner.user_id, gist.gist_type, gist.gist_expires) ScmModel().update_nodes(user=owner.user_id, ip_addr=ip_addr, repo=fake_repo, message=message, nodes=gist_mapping_op, trigger_push_hook=False) return gist
def index(self): """GET /admin/gists: All items in the collection""" # url('gists') not_default_user = c.authuser.username != User.DEFAULT_USER c.show_private = request.GET.get('private') and not_default_user c.show_public = request.GET.get('public') and not_default_user gists = Gist().query()\ .filter(or_(Gist.gist_expires == -1, Gist.gist_expires >= time.time()))\ .order_by(Gist.created_on.desc()) # MY private if c.show_private and not c.show_public: gists = gists.filter(Gist.gist_type == Gist.GIST_PRIVATE)\ .filter(Gist.gist_owner == c.authuser.user_id) # MY public elif c.show_public and not c.show_private: gists = gists.filter(Gist.gist_type == Gist.GIST_PUBLIC)\ .filter(Gist.gist_owner == c.authuser.user_id) # MY public+private elif c.show_private and c.show_public: gists = gists.filter(or_(Gist.gist_type == Gist.GIST_PUBLIC, Gist.gist_type == Gist.GIST_PRIVATE))\ .filter(Gist.gist_owner == c.authuser.user_id) # default show ALL public gists if not c.show_public and not c.show_private: gists = gists.filter(Gist.gist_type == Gist.GIST_PUBLIC) c.gists = gists p = safe_int(request.GET.get('page', 1), 1) c.gists_pager = Page(c.gists, page=p, items_per_page=10) return render('admin/gists/index.html')
def update(self, gist, description, owner, gist_mapping, gist_type, lifetime): gist = Gist.guess_instance(gist) gist_repo = gist.scm_instance lifetime = safe_int(lifetime, -1) if lifetime == 0: # preserve old value gist_expires = gist.gist_expires else: gist_expires = time.time() + (lifetime * 60) if lifetime != -1 else -1 #calculate operation type based on given data gist_mapping_op = {} for k, v in gist_mapping.items(): # add, mod, del if not v['org_filename'] and v['filename']: op = 'add' elif v['org_filename'] and not v['filename']: op = 'del' else: op = 'mod' v['op'] = op gist_mapping_op[k] = v gist.gist_description = description gist.gist_expires = gist_expires gist.owner = owner gist.gist_type = gist_type message = 'updated file' message += 's: ' if len(gist_mapping) > 1 else ': ' message += ', '.join([x for x in gist_mapping]) #fake Kallithea Repository object fake_repo = AttributeDict(dict( repo_name=gist_repo.path, scm_instance_no_cache=lambda: gist_repo, )) self._store_metadata(gist_repo, gist.gist_id, gist.gist_access_id, owner.user_id, gist.gist_type, gist.gist_expires) ScmModel().update_nodes( user=owner.user_id, repo=fake_repo, message=message, nodes=gist_mapping_op, trigger_push_hook=False ) return gist
def check_revision(self, gist_id): c.gist = Gist.get_or_404(gist_id) last_rev = c.gist.scm_instance.get_changeset() success = True revision = request.POST.get('revision') ##TODO: maybe move this to model ? if revision != last_rev.raw_id: log.error('Last revision %s is different than submitted %s', revision, last_rev) # our gist has newer version than we success = False return {'success': success}
def check_revision(self, gist_id): c.gist = Gist.get_or_404(gist_id) last_rev = c.gist.scm_instance.get_changeset() success = True revision = request.POST.get('revision') ##TODO: maybe move this to model ? if revision != last_rev.raw_id: log.error('Last revision %s is different than submitted %s' % (revision, last_rev)) # our gist has newer version than we success = False return {'success': success}
def show(self, gist_id, revision='tip', format='html', f_path=None): c.gist = Gist.get_or_404(gist_id) if c.gist.is_expired: log.error('Gist expired at %s', time_to_datetime(c.gist.gist_expires)) raise HTTPNotFound() try: c.file_changeset, c.files = GistModel().get_gist_files(gist_id, revision=revision) except VCSError: log.error(traceback.format_exc()) raise HTTPNotFound() if format == 'raw': content = '\n\n'.join([f.content for f in c.files if (f_path is None or safe_unicode(f.path) == f_path)]) response.content_type = 'text/plain' return content return render('admin/gists/show.html')
def show(self, gist_id, revision='tip', format='html', f_path=None): c.gist = Gist.get_or_404(gist_id) if c.gist.is_expired: log.error('Gist expired at %s', time_to_datetime(c.gist.gist_expires)) raise HTTPNotFound() try: c.file_changeset, c.files = GistModel().get_gist_files( gist_id, revision=revision) except VCSError: log.error(traceback.format_exc()) raise HTTPNotFound() if format == 'raw': content = '\n\n'.join( safe_str(f.content) for f in c.files if (f_path is None or f.path == f_path)) response.content_type = 'text/plain' return content return render('admin/gists/show.html')
def show(self, gist_id, revision='tip', format='html', f_path=None): """GET /admin/gists/gist_id: Show a specific item""" # url('gist', gist_id=ID) c.gist = Gist.get_or_404(gist_id) #check if this gist is not expired if c.gist.gist_expires != -1: if time.time() > c.gist.gist_expires: log.error('Gist expired at %s', time_to_datetime(c.gist.gist_expires)) raise HTTPNotFound() try: c.file_changeset, c.files = GistModel().get_gist_files(gist_id, revision=revision) except VCSError: log.error(traceback.format_exc()) raise HTTPNotFound() if format == 'raw': content = '\n\n'.join([f.content for f in c.files if (f_path is None or safe_unicode(f.path) == f_path)]) response.content_type = 'text/plain' return content return render('admin/gists/show.html')
def show(self, gist_id, revision='tip', format='html', f_path=None): """GET /admin/gists/gist_id: Show a specific item""" # url('gist', gist_id=ID) c.gist = Gist.get_or_404(gist_id) #check if this gist is not expired if c.gist.gist_expires != -1: if time.time() > c.gist.gist_expires: log.error('Gist expired at %s' % (time_to_datetime(c.gist.gist_expires))) raise HTTPNotFound() try: c.file_changeset, c.files = GistModel().get_gist_files(gist_id, revision=revision) except VCSError: log.error(traceback.format_exc()) raise HTTPNotFound() if format == 'raw': content = '\n\n'.join([f.content for f in c.files if (f_path is None or f.path == f_path)]) response.content_type = 'text/plain' return content return render('admin/gists/show.html')
def tearDown(self): for g in Gist.get_all(): GistModel().delete(g) Session().commit()
def teardown_method(self, method): for g in Gist.query(): GistModel().delete(g) Session().commit()
def create(self, description, owner, gist_mapping, gist_type=Gist.GIST_PUBLIC, lifetime=-1): """ :param description: description of the gist :param owner: user who created this gist :param gist_mapping: mapping {filename:{'content':content},...} :param gist_type: type of gist private/public :param lifetime: in minutes, -1 == forever """ owner = self._get_user(owner) gist_id = safe_unicode(unique_id(20)) lifetime = safe_int(lifetime, -1) gist_expires = time.time() + (lifetime * 60) if lifetime != -1 else -1 log.debug('set GIST expiration date to: %s', time_to_datetime(gist_expires) if gist_expires != -1 else 'forever') #create the Database version gist = Gist() gist.gist_description = description gist.gist_access_id = gist_id gist.gist_owner = owner.user_id gist.gist_expires = gist_expires gist.gist_type = safe_unicode(gist_type) self.sa.add(gist) self.sa.flush() if gist_type == Gist.GIST_PUBLIC: # use DB ID for easy to use GIST ID gist_id = safe_unicode(gist.gist_id) gist.gist_access_id = gist_id self.sa.add(gist) gist_repo_path = os.path.join(GIST_STORE_LOC, gist_id) log.debug('Creating new %s GIST repo in %s', gist_type, gist_repo_path) repo = RepoModel()._create_filesystem_repo( repo_name=gist_id, repo_type='hg', repo_group=GIST_STORE_LOC) processed_mapping = {} for filename in gist_mapping: if filename != os.path.basename(filename): raise Exception('Filename cannot be inside a directory') content = gist_mapping[filename]['content'] #TODO: expand support for setting explicit lexers # if lexer is None: # try: # guess_lexer = pygments.lexers.guess_lexer_for_filename # lexer = guess_lexer(filename,content) # except pygments.util.ClassNotFound: # lexer = 'text' processed_mapping[filename] = {'content': content} # now create single multifile commit message = 'added file' message += 's: ' if len(processed_mapping) > 1 else ': ' message += ', '.join([x for x in processed_mapping]) #fake Kallithea Repository object fake_repo = AttributeDict(dict( repo_name=gist_repo_path, scm_instance_no_cache=lambda: repo, )) ScmModel().create_nodes( user=owner.user_id, repo=fake_repo, message=message, nodes=processed_mapping, trigger_push_hook=False ) self._store_metadata(repo, gist.gist_id, gist.gist_access_id, owner.user_id, gist.gist_type, gist.gist_expires) return gist
def get_gist(self, gist): return Gist.guess_instance(gist)
def create(self, description, owner, gist_mapping, gist_type=Gist.GIST_PUBLIC, lifetime=-1): """ :param description: description of the gist :param owner: user who created this gist :param gist_mapping: mapping {filename:{'content':content},...} :param gist_type: type of gist private/public :param lifetime: in minutes, -1 == forever """ owner = self._get_user(owner) gist_id = safe_unicode(unique_id(20)) lifetime = safe_int(lifetime, -1) gist_expires = time.time() + (lifetime * 60) if lifetime != -1 else -1 log.debug('set GIST expiration date to: %s' % (time_to_datetime(gist_expires) if gist_expires != -1 else 'forever')) #create the Database version gist = Gist() gist.gist_description = description gist.gist_access_id = gist_id gist.gist_owner = owner.user_id gist.gist_expires = gist_expires gist.gist_type = safe_unicode(gist_type) self.sa.add(gist) self.sa.flush() if gist_type == Gist.GIST_PUBLIC: # use DB ID for easy to use GIST ID gist_id = safe_unicode(gist.gist_id) gist.gist_access_id = gist_id self.sa.add(gist) gist_repo_path = os.path.join(GIST_STORE_LOC, gist_id) log.debug('Creating new %s GIST repo in %s' % (gist_type, gist_repo_path)) repo = RepoModel()._create_filesystem_repo( repo_name=gist_id, repo_type='hg', repo_group=GIST_STORE_LOC) processed_mapping = {} for filename in gist_mapping: if filename != os.path.basename(filename): raise Exception('Filename cannot be inside a directory') content = gist_mapping[filename]['content'] #TODO: expand support for setting explicit lexers # if lexer is None: # try: # guess_lexer = pygments.lexers.guess_lexer_for_filename # lexer = guess_lexer(filename,content) # except pygments.util.ClassNotFound: # lexer = 'text' processed_mapping[filename] = {'content': content} # now create single multifile commit message = 'added file' message += 's: ' if len(processed_mapping) > 1 else ': ' message += ', '.join([x for x in processed_mapping]) #fake Kallithea Repository object fake_repo = AttributeDict(dict( repo_name=gist_repo_path, scm_instance_no_cache=lambda: repo, )) ScmModel().create_nodes( user=owner.user_id, repo=fake_repo, message=message, nodes=processed_mapping, trigger_push_hook=False ) self._store_metadata(repo, gist.gist_id, gist.gist_access_id, owner.user_id, gist.gist_type, gist.gist_expires) return gist