def get_content(self, wiki, version=None, all=False, translate=False): """For the Wiki page identified by `wiki`, which can be, `id` or `WikiPage` instance. Get the latest `wikipage` entry if version==None. else, get the entry wikipage.id==version. if all==True return all the versions of the wiki page. Return, WikiPage instance.""" wiki = self.get_wiki(wiki) WikiPage = self._map_wikipage(wiki.tablemap.table_pagenum) msession = meta.Session() if isinstance(version, (int, long)): wikipage = msession.query(WikiPage).filter_by(id=version).first() elif all: wikipage = msession.query(WikiPage).all() elif version == None: wikipage = msession.query(WikiPage).filter_by( id=wiki.latest_version).first() else: wikipage = None if translate and wikipage: with msession.begin(subtransactions=True): wikipage.translate(wiki=wiki, cache=True) return wikipage
def upgrade_0_8( defenv, appenv ) : """Upgrade Database version from 0.8 to 0.9""" from zeta.config.environment import syscomp print "Renaming static-wiki `p_frontpage` to `p_homepage` ..." sw = syscomp.get_staticwiki( u'p_frontpage' ) msession = meta.Session() with msession.begin( subtransactions=True ) : sw.path = u'p_homepage' paths = [ 'help/ColorValue', 'help/PasterAdmin', 'help/XmlRpcApi', 'help/ZWExtensions', 'help/ZWMacros', 'help/ZWTemplateTags', 'help/admin', 'help/features', 'help/pms', 'help/review', 'help/ticket', 'help/vcs', 'help/zwiki', ] [ upgradesw( join(defenv, 'staticfiles', path), path ) for path in paths ]
def remove_attach(self, attach=None, log=False, doclose=None, byuser=None): """Remove the attachment entry identified by, `attach` which can be `id` or `Attachment` instance. """ from zeta.config.environment import userscomp, tlcomp, srchcomp attach = self.get_attach(attach=attach) msession = meta.Session() attach and self._remove_content(attach) filename = attach.filename with msession.begin(subtransactions=True): attach and msession.delete(attach) msession.flush() log = log and 'deleted attachment, %s' % filename or '' # Post processing, optional deferred handling def onclose(tlcomp, srchcomp, attach, log, byuser): # TODO : Delete this attachment. #srchcomp.indexattach( [attach], replace=True ) log and tlcomp.log(byuser, log) doclose(h.hitchfn(onclose, tlcomp, srchcomp, attach, log, byuser)) return attach
def get_attach(self, attach=None, attrload=[], attrload_all=[]): """Get the attachment entry identified by, `attach` which can be `id` or `Attachment` instance. Return, Attachment Instance(s).""" if isinstance( attach, Attachment ) and attrload==[] and \ attrload_all==[] : return attach msession = meta.Session() # Compose query based on `attach` type if isinstance(attach, (int, long)): q = msession.query(Attachment).filter_by(id=attach) elif isinstance(attach, Attachment): q = msession.query(Attachment).filter_by(id=attach.id) else: q = None # Compose eager-loading options if q != None: q = q.options(*[eagerload_all(e) for e in attrload_all]) q = q.options(*[eagerload(e) for e in attrload]) attach = q.first() elif attach == None: q = msession.query(Attachment) q = q.options(*[eagerload_all(e) for e in attrload_all]) q = q.options(*[eagerload(e) for e in attrload]) attach = q.all() return attach
def delfavorites(self, wiki, favusers, doclose=None, byuser=None): """Delete the wiki as favorite for users identified by `favusers`, which can be (also can be an array of) `id` or `username` or `User` instance. to `wiki` which can be, `id` or `wikiurl` or `Wiki` instance.""" from zeta.config.environment import userscomp, tlcomp, srchcomp if not isinstance(favusers, list): favusers = [favusers] favusers = [userscomp.get_user(u) for u in favusers] wiki = self.get_wiki(wiki) msession = meta.Session() with msession.begin(subtransactions=True): [ wiki.favoriteof.remove(u) for u in favusers if u in wiki.favoriteof ] log = 'removed wiki page from favorite' # Post processing, optional deferred handling def onclose(tlcomp, wiki, byuser, log): tlcomp.log(byuser, log, wiki=wiki) doclose(h.hitchfn(onclose, tlcomp, wiki, byuser, log)) return None
def get_wikitype(self, wikitype=None): """Get the WikiType instance identified by, `wikitype`, which can be, `id` or `wiki_typename` or `WikiType` instance. if wikitype==None Return the list of all WikiType instances. Return, List of WikiType instances or WikiType instance.""" msession = meta.Session() if isinstance(wikitype, (int, long)): wikitype = msession.query(WikiType).filter_by(id=wikitype).first() elif isinstance(wikitype, (str, unicode)): wikitype = msession.query(WikiType).filter_by( wiki_typename=wikitype).first() elif wikitype == None: wikitype = msession.query(WikiType).all() elif isinstance(wikitype, WikiType): pass else: wikitype = None return wikitype
def latestattachs(self): """Fetch the latest attachment""" msession = meta.Session() q = msession.query(Attachment).order_by(Attachment.id.desc()).limit(1) attachs = q.all() attach = attachs and attachs[0] or None return attach
def create_attach(self, filename, fdfile=None, uploader=None, summary=None, log=False, doclose=None): """Create an attachment for `filename`, Return, Attachment instance.""" from zeta.config.environment import userscomp, tlcomp, srchcomp uploader = uploader and userscomp.get_user(uploader) content = fdfile and fdfile.read() or '' msession = meta.Session() with msession.begin(subtransactions=True): attach = Attachment(filename, 0) summary and setattr(attach, 'summary', summary) uploader and setattr(attach, 'uploader', uploader) attach.size = len(content) msession.add(attach) self._store_fileupload(content, attach) fdfile and fdfile.close() log = log and 'Uploaded attachment, %s' % filename or '' # Post processing, optional deferred handling def onclose(tlcomp, srchcomp, attach, uploader, log): srchcomp.indexattach([attach]) log and tlcomp.log(uploader, log, attach=attach) doclose(h.hitchfn(onclose, tlcomp, srchcomp, attach, uploader, log)) return attach
def recast_vote( self, vote, votedas='', medium='' ) : """Cast a vote for `voter`, which can be, `user_id`, `username` or User instance""" msession = meta.Session() with msession.begin( subtransactions=True ) : if vote and votedas : vote.votedas = votedas medium and setattr( vote, 'medium', medium )
def updatesize(self, attach): """Update the `size` field in the attachment table from disk-file having the attachment content""" attach = self.get_attach(attach=attach) msession = meta.Session() if attach: with msession.begin(subtransactions=True): attach.size = len(self.content(attach))
def config_wiki(self, wiki, wtype=None, summary=None, sourceurl=None, project=None, doclose=None, byuser=None): """For the wiki page identified by `wiki`, which can be, `id` or `wikiurl` or `Wiki` instance. Set the wiki wtype. `wtype`, can be `id` or `wiki_typename` or `WikiType` instance. Add the project to which the wiki belongs to. `project` can be, `id` or `projectname` or `Project` instance if project can also be a string.""" from zeta.config.environment import projcomp, tlcomp, srchcomp wiki = self.get_wiki(wiki) wtype = wtype and self.get_wikitype(wtype) project = project and projcomp.get_project(project) msession = meta.Session() summary = summary and summary.replace('\n', ' ').replace('\r', ' ') with msession.begin(subtransactions=True): # Construct log based on attributes that have changed loglines = [] wtype and loglines.append( ('type', wiki.type.wiki_typename, wtype.wiki_typename)) summary and loglines.append(('summary', wiki.summary, summary)) sourceurl and loglines.append( ('sourceurl', wiki.sourceurl, sourceurl)) log = h.logfor(loglines) if log: log = 'Changed,\n%s' % log # Logging ends here if wtype: wiki.type = wtype if summary != None: wiki.summary = unicode(summary) if sourceurl != None: wiki.sourceurl = unicode(sourceurl) if project != None: wiki.project = project # Post processing, optional deferred handling def onclose(tlcomp, srchcomp, wiki, byuser, log): log and tlcomp.log(byuser, log, wiki=wiki) srchcomp.indexwiki([wiki], replace=True) doclose(h.hitchfn(onclose, tlcomp, srchcomp, wiki, byuser, log)) return None
def model_add_attach(self, attach, modelobj, byuser=None): """Add attachment to the model instance `modelobj`. `attach` which can be `id` or `Attachment` instance.""" attach = self.get_attach(attach=attach) msession = meta.Session() with msession.begin(subtransactions=True): attach and modelobj.attachments.append(attach)
def get_users( field=None ) : """Return a list of all the entries in the user table. If the field keyword is passed, then return the list of field values """ msession = meta.Session() with msession.begin( subtransactions=True ) : users = msession.query( User ).all() if field : users = [ getattr(u, field) for u in users ] return users
def remove_wikicomment(self, wikicomment): """Remove the WikiComment identified by, `wikicomment` which can be, `id` or `WikiComment` instance""" wikicomment = self.get_wikicomment(wikicomment) msession = meta.Session() with msession.begin(subtransactions=True): wikicomment and msession.delete(wikicomment) return wikicomment
def test_duplicate_permname(self): msession = meta.Session() perm_obj1 = PermissionName('perm10_name1') perm_obj2 = PermissionName('PERM10_NAME1') with msession.begin(): msession.add(perm_obj1) self.assertRaises(IntegrityError, _add_obj, msession, perm_obj2) with msession.begin(): msession.delete(perm_obj1) self.assertRaises(InvalidRequestError, _del_obj, msession, perm_obj2)
def _latestversion(self, WikiPage): """Return the latest version of WikiPage.""" msession = meta.Session() latest = sorted([wp.id for wp in msession.query(WikiPage).all()]) latest = latest and latest[-1] if latest: wikipage = msession.query(WikiPage).filter_by(id=latest).first() else: wikipage = None return wikipage
def model_remove_attach(self, attach, modelobj, byuser=None): """Remove attachment from model instance `modelobj`. `attach` which can be `id` or `Attachment` instance.""" attach = self.get_attach(attach=attach) msession = meta.Session() with msession.begin(subtransactions=True): if attach: msession.delete(attach)
def test_duplicate_permgroup(self): msession = meta.Session() perm_obj1 = PermissionGroup('GROUP10') perm_obj2 = PermissionGroup('group10') with msession.begin(): msession.add(perm_obj1) self.assertRaises(IntegrityError, _add_obj, msession, perm_obj2) with msession.begin(): msession.delete(perm_obj1) self.assertRaises(InvalidRequestError, _del_obj, msession, perm_obj2)
def wikivotes( self, wiki, votedas='', medium='' ) : """count the votes for 'wiki' with specified `votedas` and `medium` values.""" msession = meta.Session() q = msession.query( Vote ).join( 'wiki').filter_by( id=wiki.id ) if votedas : q = q.filter( Vote.votedas==votedas ) if medium : q = q.filter( Vote.medium==medium ) return q.all()
def downloadattach(self, attach): """Get the attachment entry specified by, `attach`, which can be, `id` or `Attachment` instance. and send the file for downloading.""" attach = self.get_attach(attach=attach) msession = meta.Session() with msession.begin(subtransactions=True): attach.download_count += 1 content = self._read_content(attach) return (attach, content)
def get_vote( self, voter=None ) : """Get all the votes casted by the user""" from zeta.config.environment import userscomp voter = voter and userscomp.get_user( voter ) msession = meta.Session() if voter : vote = msession.query( Vote ).filter( Vote.user_id==voter.id ).all() else : vote = msession.query( Vote ).all() return vote
def remove_tag(self, tag, byuser=None): """Remove existing tag entry.""" from zeta.config.environment import tlcomp tag = self.get_tag(tag) tagname = tag and tag.tagname or '' msession = meta.Session() with msession.begin(subtransactions=True): tag and msession.delete(tag) # Database Post processing tlcomp.log(byuser, 'deleted tag, `%s`' % tagname)
def set_sysentry(self, entries, doclose=None, byuser=None): """`entries` is a dictionary of 'field': 'value' which should be populated into the database.""" from zeta.config.environment import tlcomp msession = meta.Session() # Sometimes, the caller might log the fact that sys-table is being # updated, so skip them here. #skiplog = [ 'projteamtypes', 'tickettypes', 'ticketstatus', # 'ticketseverity', 'reviewnatures', 'reviewactions', # 'wikitypes', 'vcstypes', 'specialtags' ] skiplog = [] with msession.begin(subtransactions=True): dbentries = dict( map(lambda e: (e.field, e), msession.query(System).all())) loglines = [] for k, v in entries.iteritems(): if not isinstance(entries[k], (str, unicode)): continue e = dbentries.get(k, None) if e == None: msession.add(System(k, v)) log = k not in skiplog elif k in csvfields and \ ( sorted(h.parse_csv(e.value)) != sorted(h.parse_csv(v)) ) : dbentries[k].value = v log = k not in skiplog elif (k not in csvfields) and (e.value != v): dbentries[k].value = v log = k not in skiplog else: log = False loglines.append('%s : %s' % (k, v)) if log else None log = loglines and 'system configuration,\n%s' % '\n'.join( loglines) or '' # Post processing, optional deferred handling cache.invalidate(self._sysentries) def onclose(tlcomp, byuser, log): log and tlcomp.log(byuser, log) doclose(h.hitchfn(onclose, tlcomp, byuser, log)) return None
def updatecreatedon(self, byuser=None): """If `created_on` field is empty for any of the static wiki, update it to utcnow()""" import datetime as dt updatedfor = [] msession = meta.Session() with msession.begin(subtransactions=True): for sw in self.get_staticwiki(): if sw.created_on: continue sw.created_on = dt.datetime.utcnow() updatedfor.append(sw) return updatedfor
def comment_reply(self, wikicomment, replytocomment): """Make `wikicomment` a reply to `replytocomment` where, `wikicomment` and `replytocomment` can be, `id` or `WikiComment` instance""" msession = meta.Session() wikicomment = wikicomment and \ self.get_wikicomment( wikicomment ) replytocomment = replytocomment and \ self.get_wikicomment( replytocomment, attrload=['replies'] ) if wikicomment and replytocomment: with msession.begin(subtransactions=True): replytocomment.replies.append(wikicomment)
def create_license(self, licensedetail, update=False, doclose=None, byuser=None): """Create an entry in the license table. licensedetail is, (licid, licensename, summary, text, source) if update=True, An exisiting license identified by `licensedetail[0]` will be updated with licensedetail. `licid` can be `id` ir `License` instance.""" from zeta.config.environment import tlcomp, srchcomp if filter(h.filter_badargs, licensedetail[1:]): raise ZetaLicenseError( "License Field empty while creating license entry ( %s ) !!" \ % licensedetail ) msession = meta.Session() license = (update and self.get_license(licensedetail[0])) or None with msession.begin(subtransactions=True): if (update and license) or license: licensedetail[1] and \ setattr( license, 'licensename', licensedetail[1] ) licensedetail[2] and \ setattr( license, 'summary', licensedetail[2] ) licensedetail[3] and \ setattr( license, 'text', licensedetail[3] ) licensedetail[4] and \ setattr( license, 'source', licensedetail[4] ) log = 'updated license' idxreplace = True else: license = License(*licensedetail[1:]) msession.add(license) msession.flush() log = 'created new license' idxreplace = False # Post processing, optional deferred handling def onclose(tlcomp, srchcomp, license, byuser, log, idxreplace): log and tlcomp.log(byuser, log, license=license) srchcomp.indexlicense([license], replace=idxreplace) doclose( h.hitchfn(onclose, tlcomp, srchcomp, license, byuser, log, idxreplace)) return license
def upgradewiki(self, byuser=None): """Upgrade the database fields supporting wiki markup to the latest zwiki version""" from zeta.config.environment import tlcomp, srchcomp msession = meta.Session() staticwikis = self.get_staticwiki() with msession.begin(subtransactions=True): for sw in staticwikis: sw.texthtml = sw.translate(wiki=sw) # To HTML # Database Post processing tlcomp.log(byuser, "Upgraded static wiki pages") return len(staticwikis)
def get_ticketvote( self, voter=None, ticket=None ) : """Get the vote with specific attribute""" from zeta.config.environment import userscomp voter = voter and userscomp.get_user( voter ) msession = meta.Session() if voter and ticket : vote = msession.query( Vote ).join( 'ticket' ).filter_by( id=ticket.id ).filter( Vote.user_id==voter.id ).first() elif ticket : vote = msession.query( Vote ).join( 'ticket' ).filter_by( id=ticket.id ).all() else : vote = msession.query( Vote ).all() return vote
def cast_vote( self, voter, modelobj=None, votedas='', medium='' ) : """Cast a vote for `voter`, which can be, `user_id`, `username` or User instance""" from zeta.config.environment import userscomp voter = userscomp.get_user( voter ) msession = meta.Session() with msession.begin( subtransactions=True ) : vote = Vote() votedas and setattr( vote, 'votedas', votedas ) medium and setattr( vote, 'medium', medium ) vote.voter = voter msession.add( vote ) voter.votes.append( vote ) modelobj and modelobj.votes.append( vote )
def log(self, user, log, **kwargs): """Make an entry and all the timeline as logs to models, specified by kwargs, which can be, permgroup, tag, attach, license, project, ticket, review, wiki""" config = self.compmgr.config cntlr = BaseController() tl = None userscomp = h.fromconfig('userscomp') c = config.get('c', None) if not config['zeta.enabletline']: return None user = user or (c and c.authuser) user = isinstance(user, User) and user.id or user user = userscomp.get_user(user) log = user and (u'%s' % log.decode('utf8')) or log.decode('utf8') userhtml = '<a href="%s">%s</a>' % \ ( cntlr.url_user(user.username), user.username ) itemhtml = url_formodels(**kwargs) msession = meta.Session() with msession.begin(subtransactions=True): # Insert the timeline log stmt = t_timeline.insert().values( log=unicode(log[:LEN_1K]), userhtml=unicode(userhtml), itemhtml=unicode(itemhtml), ) res = msession.connection().execute(stmt) tl_id = res.inserted_primary_key[0] # User log stmt = at_user_logs.insert().values(timelineid=tl_id, userid=user.id) msession.connection().execute(stmt) # Object logs kwargs.pop('staticwiki', None) for k in kwargs: kw = {'timelineid': tl_id, k + 'id': kwargs[k].id} stmt = obj2assctable[k].insert().values(**kw) msession.connection().execute(stmt) return None