def render_voter(self, req): resource = self.normalise_resource(req.path_info) count = self.get_vote_counts(resource) add_stylesheet(req, 'fivestarvote/css/fivestarvote.css') names = ['', 'one', 'two', 'three', 'four', 'five'] els = [] percent = 0 if count[2] > 0: percent = count[2] * 20 str = "Currently %s/5 stars." % count[2] sign = '%' style = "width: %s%s" % (percent, sign) li = tag.li(str, class_='current-rating', style=style) els.append(li) for i in range(1, 6): className = "item %s-star" % names[i] href = "#" if 'VOTE_MODIFY' in req.perm and get_reporter_id(req) != 'anonymous': href = req.href.fivestarvote(i, resource) add_script(req, 'fivestarvote/js/fivestarvote.js', mimetype='text/javascript') a = tag.a(i, href=href, class_=className) li = tag.li(a) els.append(li) ul = tag.ul(els, class_='star-rating') className = '' if 'VOTE_MODIFY' in req.perm and get_reporter_id(req) != 'anonymous': className = 'active' title = "Current Vote: %s users voted for a total of %s" % (count[1], count[0]) add_ctxtnav(req, tag.span(tag.object(ul), id='fivestarvotes', title=title, class_=className))
def set_vote(self, req, resource, vote): """Vote for a resource.""" now_ts = to_utimestamp(datetime.now(utc)) args = list((now_ts, resource.version, vote, get_reporter_id(req), resource.realm, to_unicode(resource.id))) if not resource.version: args.pop(1) db = self.env.get_db_cnx() cursor = db.cursor() cursor.execute( """ UPDATE votes SET changetime=%%s%s,vote=%%s WHERE username=%%s AND realm=%%s AND resource_id=%%s """ % (resource.version and ',version=%s' or ''), args) if self.get_vote(req, resource) is None: cursor.execute( """ INSERT INTO votes (realm,resource_id,version,username,vote,time,changetime) VALUES (%s,%s,%s,%s,%s,%s,%s) """, (resource.realm, to_unicode(resource.id), resource.version, get_reporter_id(req), vote, now_ts, now_ts)) db.commit()
def set_vote(self, req, resource, vote): """Vote for a resource.""" resource = self.normalise_resource(resource) db = self.env.get_db_cnx() cursor = db.cursor() cursor.execute('DELETE FROM votes WHERE username=%s ' 'AND resource = %s', (get_reporter_id(req), resource)) if vote: cursor.execute('INSERT INTO votes (resource, username, vote) ' 'VALUES (%s, %s, %s)', (resource, get_reporter_id(req), vote)) db.commit()
def set_vote(self, req, resource, vote): """Vote for a resource.""" resource = self.normalise_resource(resource) db = self.env.get_db_cnx() cursor = db.cursor() cursor.execute( 'DELETE FROM votes WHERE username=%s ' 'AND resource = %s', (get_reporter_id(req), resource)) if vote: cursor.execute( 'INSERT INTO votes (resource, username, vote) ' 'VALUES (%s, %s, %s)', (resource, get_reporter_id(req), vote)) db.commit()
def _do_save(self, req, db, page): if page.readonly: req.perm.assert_permission('WIKI_ADMIN') elif not page.exists: req.perm.assert_permission('WIKI_CREATE') else: req.perm.assert_permission('WIKI_MODIFY') page.text = req.args.get('text') if req.perm.has_permission('WIKI_ADMIN'): # Modify the read-only flag if it has been changed and the user is # WIKI_ADMIN page.readonly = int(req.args.has_key('readonly')) # Give the manipulators a pass at post-processing the page for manipulator in self.page_manipulators: for field, message in manipulator.validate_wiki_page(req, page): if field: raise InvalidWikiPage( "The Wiki page field %s is invalid: %s" % (field, message)) else: raise InvalidWikiPage("Invalid Wiki page: %s" % message) page.save(get_reporter_id(req, 'author'), req.args.get('comment'), req.remote_addr) req.redirect(req.href.wiki(page.name))
def _do_preview(self, uploadedfile, sheet, req): filereader = get_reader(uploadedfile, sheet) try: return self._process(filereader, get_reporter_id(req), PreviewProcessor(self.env, req)) finally: filereader.close()
def post_edit_spec(request, dbp, obj, resource): require_permission(request.req, resource, dbp.env, operation="MODIFY") assert (obj is Instance or isinstance(obj, Entity)) attributes = [ Attribute(n, m, t) for n, t, m in _group_spec_attributes(request.req) ] base = None base_name = request.req.args['parent'] if base_name: dbp.load_spec(base_name) base = dbp.pool.get_item(request.req.args['parent']) obj.replace_state(name=request.req.args['name'], base=base, attributes=attributes) dbp.save(get_reporter_id(request.req), 'comment', request.req.remote_addr) add_notice(request.req, 'Your changes have been saved.') url = request.req.href.customartifacts('spec', obj.get_name(), action='view') request.req.redirect(url)
def post_new_spec(request, dbp, obj, resource): require_permission(request.req, resource, dbp.env, operation="CREATE") if obj is Entity: # instantiating Entity (i.e., creating a spec) pass elif obj is Instance or isinstance( obj, Entity): # instantiating an existing spec return post_new_artifact(request.req, dbp, obj, resource) else: raise Exception( "Trying to instantiate something that can't be instantiated '%s'" % (obj, )) name = request.req.args.get('name') parent_name = request.req.args.get('parent') attributes = [ Attribute(n, m, t) for n, t, m in _group_spec_attributes(request.req) ] if parent_name: dbp.load_spec(parent_name) bases = (dbp.pool.get_item(parent_name), ) else: bases = tuple() brand_new_inst = Entity(name=name, attributes=attributes, bases=bases) dbp.pool.add(brand_new_inst) dbp.save(get_reporter_id(request.req), 'comment', request.req.remote_addr) add_notice(request.req, 'Your changes have been saved.') url = request.req.href.customartifacts('spec', brand_new_inst.get_name(), action='view') request.req.redirect(url)
def _do_save(self, req, page): if not page.exists: req.perm(page.resource).require('WIKI_CREATE') else: req.perm(page.resource).require('WIKI_MODIFY') if 'WIKI_ADMIN' in req.perm(page.resource): # Modify the read-only flag if it has been changed and the user is # WIKI_ADMIN page.readonly = int('readonly' in req.args) try: page.save(get_reporter_id(req, 'author'), req.args.get('comment'), req.remote_addr) href = req.href.wiki(page.name, action='diff', version=page.version) add_notice(req, tag_("Your changes have been saved in version " "%(version)s (%(diff)s).", version=page.version, diff=tag.a(_("diff"), href=href))) req.redirect(get_resource_url(self.env, page.resource, req.href, version=None)) except TracError: add_warning(req, _("Page not modified, showing latest version.")) return self._render_view(req, page)
def _create_attachment(self, req, tid, upload, description): attachment = Attachment(self.env, "ticket", tid) if hasattr(upload.file, "fileno"): size = os.fstat(upload.file.fileno())[6] else: upload.file.seek(0, 2) size = upload.file.tell() upload.file.seek(0) if size == 0: raise TracError(_("Can't upload empty file")) max_size = self.env.config.get("attachment", "max_size") if 0 <= max_size < size: raise TracError(_("Maximum attachment size: %(num)s bytes", num=max_size), _("Upload failed")) filename = _normalized_filename(upload.filename) if not filename: raise TracError(_("No file uploaded")) attachment.description = description attachment.author = get_reporter_id(req, "author") attachment.ipnr = req.remote_addr attachment.insert(filename, upload.file, size)
def _do_uploadPicture(self, req, userProfile, teamRosterData, req_arg_picture = 'tr_userProfile_picture' ): upload = req.args.get(req_arg_picture, None) if upload == None or not hasattr(upload, 'filename') or not upload.filename: return userProfile.picture_href if hasattr(upload.file, 'fileno'): size = os.fstat(upload.file.fileno())[6] else: upload.file.seek(0, 2) # seek to end of file size = upload.file.tell() upload.file.seek(0) if size == 0: raise TracError(_("Can't upload empty file")) filename = upload.filename filename = filename.replace('\\', '/').replace(':', '/') filename = os.path.basename(filename) if not filename: raise TracError(_('No file uploaded')) page = WikiPage(self.env, self.teamRoster_wikiPage) if not page.exists: page.text="= Team Roster Pictures =" page.save( 'trac', 'Page created by tracteamroster component', req.remote_addr) attachment = Attachment(self.env, 'wiki', self.teamRoster_wikiPage) attachment.author = get_reporter_id(req, 'author') attachment.ipnr = req.remote_addr attachment.insert('_'.join([userProfile.id, filename]), upload.file, size) return req.href('/'.join(['raw-attachment', 'wiki',self.teamRoster_wikiPage,attachment.filename]))
def end_process_row(self): try: # 'when' is a datetime in 0.11, and an int in 0.10. # if we have trac.util.datefmt.to_datetime, we're likely with 0.11 from trac.util.datefmt import to_datetime tickettime = to_datetime(self.tickettime) except ImportError: tickettime = self.tickettime if self.ticket.id == None: for f in self.missingemptyfields: if self.ticket.values.has_key(f) and self.ticket[f] == None: self.ticket[f] = '' for f in self.computedfields: if self.computedfields[f] != None and self.computedfields[f]['set']: self.ticket[f] = self.computedfields[f]['value'] self.added += 1 self.ticket.insert(when=tickettime, db=self.db) else: message = "Batch update from file " + self.filename if self.ticket.is_modified(): self.modifiedcount += 1 self.ticket.save_changes(get_reporter_id(self.req), message, when=tickettime, db=self.db) # TODO: handle cnum, cnum = ticket.values['cnum'] + 1) else: self.notmodifiedcount += 1 self.ticket = None
def _handle_ripe_save(self, req): """ hander for save """ # TODO: workflow # get ticket id ticket_id = req.args.get("ticket_id") value = req.args.get("value", "").strip() field = req.args.get("field") old_value = req.args.get("old_value") # ticket ticket = Ticket(self.env, ticket_id) current_value = ticket.values.get(field) # validation if current_value != old_value and (old_value or current_value): self.log.info("Field value should be %s, got %s" % (repr(current_value), repr(old_value))) raise TracError("field value inconsistant.") # set params params = {} params[field] = value ticket.populate(params) # save ticket comment = "Updated from report" author = get_reporter_id(req, 'author') ticket.save_changes(author, comment) return value
def _render_editor(self, req, db, page, preview=False): req.perm.assert_permission("WIKI_MODIFY") if req.args.has_key("text"): page.text = req.args.get("text") if preview: page.readonly = req.args.has_key("readonly") author = req.args.get("author", get_reporter_id(req)) comment = req.args.get("comment", "") editrows = req.args.get("editrows") if editrows: pref = req.session.get("wiki_editrows", "20") if editrows != pref: req.session["wiki_editrows"] = editrows else: editrows = req.session.get("wiki_editrows", "20") req.hdf["title"] = page.name + " (edit)" info = { "page_name": page.name, "page_source": page.text, "version": page.version, "author": author, "comment": comment, "readonly": page.readonly, "edit_rows": editrows, "scroll_bar_pos": req.args.get("scroll_bar_pos", ""), } if page.exists: info["history_href"] = self.env.href.wiki(page.name, action="history") if preview: info["page_html"] = wiki_to_html(page.text, self.env, req, db) info["readonly"] = int(req.args.has_key("readonly")) req.hdf["wiki"] = info
def end_process_row(self): try: # 'when' is a datetime in 0.11, and an int in 0.10. # if we have trac.util.datefmt.to_datetime, we're likely with 0.11 from trac.util.datefmt import to_datetime tickettime = to_datetime(self.tickettime) except ImportError: tickettime = self.tickettime if self.ticket.id == None: for f in self.missingemptyfields: if self.ticket.values.has_key(f) and self.ticket[f] == None: self.ticket[f] = '' for f in self.computedfields: if self.computedfields[f] != None and self.computedfields[f][ 'set']: self.ticket[f] = self.computedfields[f]['value'] self.added += 1 self.ticket.insert(when=tickettime, db=self.db) else: message = "Batch update from file " + self.filename if self.ticket.is_modified(): self.modifiedcount += 1 self.ticket.save_changes( get_reporter_id(self.req), message, when=tickettime, db=self.db ) # TODO: handle cnum, cnum = ticket.values['cnum'] + 1) else: self.notmodifiedcount += 1 self.ticket = None
def _process_add(self, req, ticket): if req.method == "POST" and self._validate_add(req): if req.args.get('reminder_type') == 'interval': time = clear_time(to_datetime(None)) delta = _time_intervals[req.args.get('unit')](req.args.get('interval')) time += delta time = to_utimestamp(time) else: time = to_utimestamp(parse_date(req.args.get('date'))) origin = to_utimestamp(to_datetime(None)) self.env.db_transaction(""" INSERT INTO ticketreminder (ticket, time, author, origin, reminded, description) VALUES (%s, %s, %s, %s, 0, %s) """, (ticket.id, time, get_reporter_id(req, 'author'), origin, req.args.get('description'))) add_notice(req, "Reminder has been added.") req.redirect(get_resource_url(self.env, ticket.resource, req.href) + "#reminders") add_script(req, 'ticketreminder/js/ticketreminder.js') data = { 'ticket': ticket, 'date_hint': get_date_format_hint(), } return ("ticket_reminder_add.html", data, None)
def createTestPlan(self, req, catalog_id, name): """ Creates a new test plan, on the catalog specified, with the specified name. Returns the generated object ID, or '-1' if an error occurs. """ result = "-1" try: # Check catalog really exists, and get its page_name tcat = TestCatalog(self.env, catalog_id) if not tcat.exists: self.env.log.error("Input test catalog with ID %s not found." % catalog_id) return result author = get_reporter_id(req, "author") id = self.testmanagersys.get_next_id("testplan") pagename = tcat["page_name"] new_tp = TestPlan(self.env, id, catalog_id, pagename, name, author) new_tp.insert() result = id except: self.env.log.error("Error adding test plan with name '%s' for catalog with ID %s!" % (name, catalog_id)) self.env.log.error(formatExceptionInfo()) return result
def createTestCase(self, req, catalog_id, title, description): """ Creates a new test case, in the catalog specified, with the specified title and description. Returns the generated object ID, or '-1' if an error occurs. """ result = '-1' try: if catalog_id is None or catalog_id == '': self.env.log.error("Cannot create a test plan on the root catalog container.") return result # Check catalog really exists, and get its page_name tcat = TestCatalog(self.env, catalog_id) if not tcat.exists: self.env.log.error("Input test catalog with ID %s not found." % catalog_id) return result author = get_reporter_id(req, 'author') id = self.testmanagersys.get_next_id('testcase') pagename = tcat['page_name'] + '_TC' + id new_tc = TestCase(self.env, id, pagename, title, description) new_tc.author = author new_tc.remote_addr = req.remote_addr # This also creates the Wiki page new_tc.insert() result = id except: self.env.log.error("Error adding test case with title '%s' in catalog with ID %s!" % (title, catalog_id)) self.env.log.error(formatExceptionInfo()) return id
def process_request(self, req): req.perm.assert_permission('TICKET_VIEW') action = req.args.get('action', 'view') if not req.args.has_key('id'): req.redirect(self.env.href.wiki()) db = self.env.get_db_cnx() id = int(req.args.get('id')) ticket = Ticket(self.env, id, db=db) reporter_id = util.get_reporter_id(req) if req.method == 'POST': if not req.args.has_key('preview'): self._do_save(req, db, ticket) else: # Use user supplied values ticket.populate(req.args) req.hdf['ticket.action'] = action req.hdf['ticket.ts'] = req.args.get('ts') req.hdf['ticket.reassign_owner'] = req.args.get('reassign_owner') \ or req.authname req.hdf['ticket.resolve_resolution'] = req.args.get('resolve_resolution') reporter_id = req.args.get('author') comment = req.args.get('comment') if comment: req.hdf['ticket.comment'] = util.escape(comment) # Wiki format a preview of comment req.hdf['ticket.comment_preview'] = wiki_to_html(comment, self.env, req, db) else: req.hdf['ticket.reassign_owner'] = req.authname # Store a timestamp in order to detect "mid air collisions" req.hdf['ticket.ts'] = ticket.time_changed self._insert_ticket_data(req, db, ticket, reporter_id) # If the ticket is being shown in the context of a query, add # links to help navigate in the query result set if 'query_tickets' in req.session: tickets = req.session['query_tickets'].split() if str(id) in tickets: idx = tickets.index(str(ticket.id)) if idx > 0: add_link(req, 'first', self.env.href.ticket(tickets[0]), 'Ticket #%s' % tickets[0]) add_link(req, 'prev', self.env.href.ticket(tickets[idx - 1]), 'Ticket #%s' % tickets[idx - 1]) if idx < len(tickets) - 1: add_link(req, 'next', self.env.href.ticket(tickets[idx + 1]), 'Ticket #%s' % tickets[idx + 1]) add_link(req, 'last', self.env.href.ticket(tickets[-1]), 'Ticket #%s' % tickets[-1]) add_link(req, 'up', req.session['query_href']) add_stylesheet(req, 'common/css/ticket.css') return 'ticket.cs', None
def _process_import(self, req): req.perm.assert_permission('TICKET_ADMIN') added = 0 modified = 0 if req.session.has_key('importexportxls.tempfile'): tempfile = req.session['importexportxls.tempfile'] del req.session['importexportxls.tempfile'] tickets, importFields, warnings = self._get_tickets(tempfile) try: # some times tempfile leave opened os.remove(tempfile) except: exc = sys.exc_info() for i, t in enumerate(tickets): if bool(req.args.get('ticket.' + unicode(i), False)): if t.exists: if t.save_changes(author=util.get_reporter_id(req)): modified += 1 else: t.insert() added += 1 return {'added': added, 'modified': modified}
def _process_import(self, req): req.perm.assert_permission('TICKET_ADMIN') added = 0 modified = 0; if req.session.has_key('importexportxls.tempfile'): tempfile = req.session['importexportxls.tempfile'] del req.session['importexportxls.tempfile'] tickets, importFields, warnings = self._get_tickets(tempfile) try: # some times tempfile leave opened os.remove( tempfile ) except: exc = sys.exc_info() for i, t in enumerate(tickets): if bool( req.args.get('ticket.'+unicode(i), False) ): if t.exists: if t.save_changes(author=util.get_reporter_id(req)): modified += 1 else: t.insert() added += 1 return {'added':added,'modified':modified}
def update(self, req, name, comment, attributes=None): """ Updates a structure milestone object.""" milestone = StructuredMilestone(self.env, name) if not milestone.exists: raise TracError('Milestone with name %s does not exist' % name) req.perm.require('MILESTONE_MODIFY', Resource(milestone.resource.realm)) if attributes is not None: milestone.name = attributes.get('summary') milestone.description = attributes.get('description') milestone.ticket.populate(attributes) def set_date(name, attr_name=None): val = attributes.get(name) if val is None: return val = val and parse_date(val, tzinfo=req.tz) or None if attr_name is not None: setattr(milestone, attr_name, val) milestone.ticket[name] = val and str(to_timestamp(val)) set_date('duedate', 'due') set_date('completedate', 'completed') set_date('started') milestone.save_changes(get_reporter_id(req, 'author'), comment) return self._milestone_as_dict(milestone)
def create(self, req, attributes): """ Create a structure milestone object.""" name = attributes.get('summary') try: if StructuredMilestone(self.env, name).exists: raise TracError('Milestone with name %s already exists' % name) except ResourceNotFound: pass milestone = StructuredMilestone(self.env) milestone.name = name req.perm.require('MILESTONE_CREATE', Resource(milestone.resource.realm)) milestone.description = attributes.get('description') milestone.ticket.populate(attributes) def set_date(name, attr_name=None): val = attributes.get(name) if val is None: return val = val and parse_date(val, tzinfo=req.tz) or None if attr_name is not None: setattr(milestone, attr_name, val) milestone.ticket[name] = val and str(to_timestamp(val)) set_date('duedate', 'due') set_date('completedate', 'completed') set_date('started') milestone.ticket.values['reporter'] = attributes.get( 'author') or get_reporter_id(req) milestone.insert() return self._milestone_as_dict(milestone)
def createTestPlan(self, req, catalog_id, name): """ Creates a new test plan, on the catalog specified, with the specified name. Returns the generated object ID, or '-1' if an error occurs. """ result = '-1' try: # Check catalog really exists, and get its page_name tcat = TestCatalog(self.env, catalog_id) if not tcat.exists: self.env.log.error("Input test catalog with ID %s not found." % catalog_id) return result author = get_reporter_id(req, 'author') id = self.testmanagersys.get_next_id('testplan') pagename = tcat['page_name'] new_tp = TestPlan(self.env, id, catalog_id, pagename, name, author) new_tp.insert() result = id except: self.env.log.error("Error adding test plan with name '%s' for catalog with ID %s!" % (name, catalog_id)) self.env.log.error(formatExceptionInfo()) return result
def post_new_spec(request, dbp, obj, resource): require_permission(request.req, resource, dbp.env, operation="CREATE") if obj is Entity: # instantiating Entity (i.e., creating a spec) pass elif obj is Instance or isinstance(obj, Entity): # instantiating an existing spec return post_new_artifact(request.req, dbp, obj, resource) else: raise Exception("Trying to instantiate something that can't be instantiated '%s'" % (obj,)) name = request.req.args.get('name') parent_name = request.req.args.get('parent') attributes = [Attribute(n,m,t) for n,t,m in _group_spec_attributes(request.req)] if parent_name: dbp.load_spec(parent_name) bases = (dbp.pool.get_item(parent_name),) else: bases = tuple() brand_new_inst = Entity(name=name, attributes=attributes, bases=bases) dbp.pool.add(brand_new_inst) dbp.save(get_reporter_id(request.req), 'comment', request.req.remote_addr) add_notice(request.req, 'Your changes have been saved.') url = request.req.href.customartifacts('spec', brand_new_inst.get_name(), action='view') request.req.redirect(url)
def _do_save(self, req, page): if not page.exists: req.perm(page.resource).require('WIKI_CREATE') else: req.perm(page.resource).require('WIKI_MODIFY') if 'WIKI_ADMIN' in req.perm(page.resource): # Modify the read-only flag if it has been changed and the user is # WIKI_ADMIN page.readonly = int('readonly' in req.args) try: page.save(get_reporter_id(req, 'author'), req.args.get('comment'), req.remote_addr) add_notice( req, _("Your changes have been saved in version " "%(version)s.", version=page.version)) req.redirect( get_resource_url(self.env, page.resource, req.href, version=None)) except TracError: add_warning(req, _("Page not modified, showing latest version.")) return self._render_view(req, page)
def create(self, req, attributes): """ Create a structure milestone object.""" name = attributes.get('summary') try: if StructuredMilestone(self.env, name).exists: raise TracError('Milestone with name %s already exists' % name) except ResourceNotFound: pass milestone = StructuredMilestone(self.env) milestone.name = name req.perm.require('MILESTONE_CREATE', Resource(milestone.resource.realm)) milestone.description = attributes.get('description') milestone.ticket.populate(attributes) def set_date(name, attr_name = None): val = attributes.get(name) if val is None: return val = val and parse_date(val, tzinfo=req.tz) or None if attr_name is not None: setattr(milestone, attr_name, val) milestone.ticket[name] = val and str(to_timestamp(val)) set_date('duedate', 'due') set_date('completedate', 'completed') set_date('started') milestone.ticket.values['reporter'] = attributes.get('author') or get_reporter_id(req) milestone.insert() return self._milestone_as_dict(milestone)
def _render_editor(self, req, db, milestone): data = { 'milestone': milestone, 'ticket': milestone.ticket, 'datefields' : self.date_fields, 'date_hint': get_date_format_hint(), 'datetime_hint': get_datetime_format_hint(), 'milestone_groups': [], 'jump_to' : req.args.get('jump_to') or referer_module(req) } if milestone.exists: req.perm(milestone.resource).require('MILESTONE_VIEW') milestones = [m for m in StructuredMilestone.select(self.env, db=db) if m.name != milestone.name and 'MILESTONE_VIEW' in req.perm(m.resource)] data['milestone_groups'] = group_milestones(milestones, 'TICKET_ADMIN' in req.perm) else: req.perm(milestone.resource).require('MILESTONE_CREATE') TicketModule(self.env)._insert_ticket_data(req, milestone.ticket, data, get_reporter_id(req, 'author'), {}) self._add_tickets_report_data(milestone, req, data) context = Context.from_request(req, milestone.resource) data['attachments']=AttachmentModule(self.env).attachment_data(context) return 'itteco_milestone_edit.html', data, None
def render_voter(self, req): resource = self.normalise_resource(req.path_info) vote = self.get_vote(req, resource) up = tag.img(src=req.href.chrome('vote/' + self.image_map[vote][0]), alt='Up-vote') down = tag.img(src=req.href.chrome('vote/' + self.image_map[vote][1]), alt='Down-vote') if 'VOTE_MODIFY' in req.perm and get_reporter_id(req) != 'anonymous': down = tag.a(down, id='downvote', href=req.href.vote('down', resource), title='Down-vote') up = tag.a(up, id='upvote', href=req.href.vote('up', resource), title='Up-vote') add_script(req, 'vote/js/tracvote.js') shown = req.session.get('shown_vote_message') if not shown: add_notice(req, 'You can vote for resources on this Trac ' 'install by clicking the up-vote/down-vote arrows ' 'in the context navigation bar.') req.session['shown_vote_message'] = '1' body, title = self.format_votes(resource) votes = tag.span(body, id='votes') add_stylesheet(req, 'vote/css/tracvote.css') elm = tag.span(up, votes, down, id='vote', title=title) req.chrome.setdefault('ctxtnav', []).insert(0, elm)
def _render_editor(self, req, db, page, preview=False): req.perm.assert_permission('WIKI_MODIFY') if req.args.has_key('text'): page.text = req.args.get('text') if preview: page.readonly = req.args.has_key('readonly') author = req.args.get('author', get_reporter_id(req)) comment = req.args.get('comment', '') editrows = req.args.get('editrows') if editrows: pref = req.session.get('wiki_editrows', '20') if editrows != pref: req.session['wiki_editrows'] = editrows else: editrows = req.session.get('wiki_editrows', '20') req.hdf['title'] = escape(page.name) + ' (edit)' info = { 'page_source': escape(page.text), 'version': page.version, 'author': escape(author), 'comment': escape(comment), 'readonly': page.readonly, 'edit_rows': editrows, 'scroll_bar_pos': req.args.get('scroll_bar_pos', '') } if page.exists: info['history_href'] = escape( self.env.href.wiki(page.name, action='history')) if preview: info['page_html'] = wiki_to_html(page.text, self.env, req, db) info['readonly'] = int(req.args.has_key('readonly')) req.hdf['wiki'] = info
def update(self, req, name, comment, attributes=None): """ Updates a structure milestone object.""" milestone = StructuredMilestone(self.env, name) if not milestone.exists: raise TracError('Milestone with name %s does not exist' % name) req.perm.require('MILESTONE_MODIFY', Resource(milestone.resource.realm)) if attributes is not None: milestone.name = attributes.get('summary') milestone.description = attributes.get('description') milestone.ticket.populate(attributes) def set_date(name, attr_name = None): val = attributes.get(name) if val is None: return val = val and parse_date(val, tzinfo=req.tz) or None if attr_name is not None: setattr(milestone, attr_name, val) milestone.ticket[name] = val and str(to_timestamp(val)) set_date('duedate', 'due') set_date('completedate', 'completed') set_date('started') milestone.save_changes(get_reporter_id(req, 'author'), comment) return self._milestone_as_dict(milestone)
def _create_attachment(self, req, ticket, upload, description): if hasattr(upload, 'filename'): attachment = Attachment(self.env, 'ticket', ticket.id) if hasattr(upload.file, 'fileno'): size = os.fstat(upload.file.fileno())[6] else: upload.file.seek(0, 2) size = upload.file.tell() upload.file.seek(0) if size == 0: raise TracError(_("Can't upload empty file")) max_size = self.env.config.get('attachment', 'max_size') if max_size >= 0 and size > max_size: raise TracError( _('Maximum attachment size: %(num)s bytes', num=max_size), _('Upload failed')) filename = unicodedata.normalize('NFC', unicode(upload.filename, 'utf-8')) filename = filename.replace('\\', '/').replace(':', '/') filename = os.path.basename(filename) if not filename: raise TracError(_('No file uploaded')) attachment.description = description if 'author' in req.args: attachment.author = get_reporter_id(req, 'author') attachment.ipnr = req.remote_addr attachment.insert(filename, upload.file, size)
def set_resource_tags(self, req, ticket_or_resource, tags, comment=u'', when=None): try: resource = ticket_or_resource.resource except AttributeError: resource = ticket_or_resource assert resource.realm == self.realm if not self._check_permission(req, resource, 'modify'): raise PermissionError(resource=resource, env=self.env) tag_set = set(tags) # Processing a call from TracTags, try to alter the ticket. tkt = Ticket(self.env, resource.id) all = self._ticket_tags(tkt) # Avoid unnecessary ticket changes, considering comments below. if tag_set != all: # Will only alter tags in 'keywords' ticket field. keywords = split_into_tags(tkt['keywords']) # Assume, that duplication is depreciated and consolitation # wanted to primarily affect 'keywords' ticket field. # Consequently updating ticket tags and reducing (tag) # 'ticket_fields' afterwards may result in undesired tag loss. tag_set.difference_update(all.difference(keywords)) tkt['keywords'] = u' '.join(sorted(map(to_unicode, tag_set))) tkt.save_changes(get_reporter_id(req), comment) else: # Processing a change listener event. tags = self._ticket_tags(ticket_or_resource) super(TicketTagProvider, self).set_resource_tags(req, resource, tags)
def process_request(self, req): req.perm.assert_permission('TICKET_VIEW') action = req.args.get('action', 'view') if not req.args.has_key('id'): req.redirect(self.env.href.wiki()) db = self.env.get_db_cnx() id = int(req.args.get('id')) ticket = Ticket(self.env, id, db=db) reporter_id = util.get_reporter_id(req) if req.method == 'POST': if not req.args.has_key('preview'): self._do_save(req, db, ticket) else: # Use user supplied values ticket.populate(req.args) req.hdf['ticket.action'] = action req.hdf['ticket.ts'] = req.args.get('ts') req.hdf['ticket.reassign_owner'] = req.args.get('reassign_owner') \ or req.authname req.hdf['ticket.resolve_resolution'] = req.args.get('resolve_resolution') reporter_id = req.args.get('author') comment = req.args.get('comment') if comment: req.hdf['ticket.comment'] = comment # Wiki format a preview of comment req.hdf['ticket.comment_preview'] = wiki_to_html(comment, self.env, req, db) else: req.hdf['ticket.reassign_owner'] = req.authname # Store a timestamp in order to detect "mid air collisions" req.hdf['ticket.ts'] = ticket.time_changed self._insert_ticket_data(req, db, ticket, reporter_id) # If the ticket is being shown in the context of a query, add # links to help navigate in the query result set if 'query_tickets' in req.session: tickets = req.session['query_tickets'].split() if str(id) in tickets: idx = tickets.index(str(ticket.id)) if idx > 0: add_link(req, 'first', self.env.href.ticket(tickets[0]), 'Ticket #%s' % tickets[0]) add_link(req, 'prev', self.env.href.ticket(tickets[idx - 1]), 'Ticket #%s' % tickets[idx - 1]) if idx < len(tickets) - 1: add_link(req, 'next', self.env.href.ticket(tickets[idx + 1]), 'Ticket #%s' % tickets[idx + 1]) add_link(req, 'last', self.env.href.ticket(tickets[-1]), 'Ticket #%s' % tickets[-1]) add_link(req, 'up', req.session['query_href']) add_stylesheet(req, 'common/css/ticket.css') return 'ticket.cs', None
def _do_save(self, req, page): if not page.exists: req.perm(page.resource).require('WIKI_CREATE') else: req.perm(page.resource).require('WIKI_MODIFY') if 'WIKI_CHANGE_READONLY' in req.perm(page.resource): # Modify the read-only flag if it has been changed and the user is # WIKI_ADMIN page.readonly = int('readonly' in req.args) try: page.save(get_reporter_id(req, 'author'), req.args.get('comment')) except TracError: add_warning(req, _("Page not modified, showing latest version.")) return self._render_view(req, page) href = req.href.wiki(page.name, action='diff', version=page.version) add_notice( req, tag_( "Your changes have been saved in version " "%(version)s (%(diff)s).", version=page.version, diff=tag.a(_("diff"), href=href))) req.redirect( get_resource_url(self.env, page.resource, req.href, version=None))
def _do_save(self, req, db, page): if page.readonly: req.perm.assert_permission('WIKI_ADMIN') elif not page.exists: req.perm.assert_permission('WIKI_CREATE') else: req.perm.assert_permission('WIKI_MODIFY') page.text = req.args.get('text') if req.perm.has_permission('WIKI_ADMIN'): # Modify the read-only flag if it has been changed and the user is # WIKI_ADMIN page.readonly = int(req.args.has_key('readonly')) # Give the manipulators a pass at post-processing the page for manipulator in self.page_manipulators: for field, message in manipulator.validate_wiki_page(req, page): if field: raise InvalidWikiPage("The Wiki page field %s is invalid: %s" % (field, message)) else: raise InvalidWikiPage("Invalid Wiki page: %s" % message) page.save(get_reporter_id(req, 'author'), req.args.get('comment'), req.remote_addr) req.redirect(req.href.wiki(page.name))
def _create_attachment(self, req, ticket, upload, description): if hasattr(upload, 'filename'): attachment = Attachment(self.env, 'ticket', ticket.id) if hasattr(upload.file, 'fileno'): size = os.fstat(upload.file.fileno())[6] else: upload.file.seek(0, 2) size = upload.file.tell() upload.file.seek(0) if size == 0: raise TracError(_("Can't upload empty file")) max_size = self.env.config.get('attachment', 'max_size') if max_size >= 0 and size > max_size: raise TracError(_('Maximum attachment size: %(num)s bytes', num=max_size), _('Upload failed')) filename = unicodedata.normalize('NFC', unicode(upload.filename, 'utf-8')) filename = filename.replace('\\', '/').replace(':', '/') filename = os.path.basename(filename) if not filename: raise TracError(_('No file uploaded')) attachment.description = description if 'author' in req.args: attachment.author = get_reporter_id(req, 'author') attachment.ipnr = req.remote_addr attachment.insert(filename, upload.file, size)
def _process_add(self, req, ticket): if req.method == "POST" and self._validate_add(req): if req.args.get('reminder_type') == 'interval': time = clear_time(to_datetime(None)) delta = _time_intervals[req.args.get('unit')]( req.args.get('interval')) time += delta time = to_utimestamp(time) else: time = to_utimestamp(parse_date(req.args.get('date'))) origin = to_utimestamp(to_datetime(None)) self.env.db_transaction( """ INSERT INTO ticketreminder (ticket, time, author, origin, reminded, description) VALUES (%s, %s, %s, %s, 0, %s) """, (ticket.id, time, get_reporter_id( req, 'author'), origin, req.args.get('description'))) add_notice(req, "Reminder has been added.") req.redirect( get_resource_url(self.env, ticket.resource, req.href) + "#reminders") add_script(req, 'ticketreminder/js/ticketreminder.js') data = { 'ticket': ticket, 'date_hint': get_date_format_hint(), } return ("ticket_reminder_add.html", data, None)
def setTestCaseStatus(self, req, testcase_id, plan_id, status): """ Sets the test case status. Returns True if successful, False otherwise. """ try: author = get_reporter_id(req, "author") tcip = TestCaseInPlan(self.env, testcase_id, plan_id) if tcip.exists: tcip.set_status(status, author) tcip.save_changes(author, "Status changed") else: tc = TestCase(self.env, testcase_id) tcip["page_name"] = tc["page_name"] tcip.set_status(status, author) tcip.insert() except: self.env.log.error( "Error setting the test case status with ID %s on plan %s to %s!" % (testcase_id, plan_id, status) ) self.env.log.error(formatExceptionInfo()) return False return True
def _render_editor(self, req, page, data, preview=False): req.perm.assert_permission('WIKI_MODIFY') if page.node.isdir: raise TracError("Cannot edit a directory.") if req.args.has_key('text'): page.mime_type = 'text/x-rst; charset=utf8' page.chunk = req.args.get('text') else: page.get_raw() author = get_reporter_id(req, 'author') comment = req.args.get('comment', '') # FIXME: self._set_title(req, page, 'edit') if preview: data['content'] = page.get_html(req) data['page_name'] = page.base data['page_source'] = page.chunk data['version'] = page.version data['author'] = author data['comment'] = comment
def _render_editor(self, req, db, milestone): data = { 'milestone': milestone, 'ticket': milestone.ticket, 'datefields': self.date_fields, 'date_hint': get_date_format_hint(), 'datetime_hint': get_datetime_format_hint(), 'milestone_groups': [], 'jump_to': req.args.get('jump_to') or referer_module(req) } if milestone.exists: req.perm(milestone.resource).require('MILESTONE_VIEW') milestones = [ m for m in StructuredMilestone.select(self.env, db=db) if m.name != milestone.name and 'MILESTONE_VIEW' in req.perm(m.resource) ] data['milestone_groups'] = group_milestones( milestones, 'TICKET_ADMIN' in req.perm) else: req.perm(milestone.resource).require('MILESTONE_CREATE') TicketModule(self.env)._insert_ticket_data( req, milestone.ticket, data, get_reporter_id(req, 'author'), {}) self._add_tickets_report_data(milestone, req, data) context = Context.from_request(req, milestone.resource) data['attachments'] = AttachmentModule( self.env).attachment_data(context) return 'itteco_milestone_edit.html', data, None
def post_new_artifact(request, dbp, obj, resource): require_permission(request.req, resource, dbp.env, operation="CREATE") assert(obj is Instance or isinstance(obj, Entity)) # otherwise, we're trying to instantiate something that is not an artifact spec_name = request.req.args['spec'] if spec_name: try: dbp.load_spec(spec_name) spec = dbp.pool.get_item(spec_name) except ValueError: add_warning(request.req, "Spec '%s' not found, assumed an empty spec instead." % spec_name) spec = Instance else: spec = Instance values, str_attr = _group_artifact_values(request.req) brand_new_inst = spec(str_attr=str_attr, values=values) dbp.pool.add(brand_new_inst) dbp.save(get_reporter_id(request.req), 'comment', request.req.remote_addr) if request.get_format() == 'page': add_notice(request.req, 'Your changes have been saved.') url = request.req.href.customartifacts('artifact/%d' % (brand_new_inst.get_id(),), action='view', format=request.get_format()) request.req.redirect(url) else: import json url = request.req.href.customartifacts('artifact/%d' % (brand_new_inst.get_id(),), action='view') msg = json.dumps([{'result': 'success', 'resource_id': brand_new_inst.get_id(), 'resource_url': url}]) request.req.send_response(200) request.req.send_header('Content-Type', 'application/json') request.req.send_header('Content-Length', len(msg)) request.req.end_headers() request.req.write(msg)
def process_request(self, req): """ Handles Ajax requests to change an object's property. """ author = get_reporter_id(req, 'author') if req.path_info.startswith('/propertyupdate'): realm = req.args.get('realm') key_str = req.args.get('key') name = req.args.get('name') value = req.args.get('value') result = 'ERROR' key = get_dictionary_from_string(key_str) try: self.env.log.debug("Setting property %s to %s, in %s with key %s" % (name, value, realm, key)) gclass_modelprovider = GenericClassModelProvider(self.env) gclass_modelprovider.check_permission(req, realm, key_str, name, value) obj = gclass_modelprovider.get_object(realm, key) # Set the required property obj[name] = value obj.author = author obj.remote_addr = req.remote_addr if obj is not None and obj.exists: comment = "Property changed" obj.save_changes(author, comment) # Call listeners self.object_changed(obj, comment, author) else: self.env.log.debug("Object to update not found. Creating it.") props_str = req.args.get('props') if props_str is not None and not props_str == '': # In order to create an object, additional properties may be required props = get_dictionary_from_string(props_str) obj.set_values(props) obj.insert() # Call listeners self.object_created(obj) result = 'OK' except: self.env.log.debug(formatExceptionInfo()) req.send_header("Content-Length", len(result)) req.write(result) return return 'empty.html', {}, None
def _display_edit(self, req): req.perm.assert_permission('CODE_REVIEW_EDIT') cs_id = req.args.get('id') cr = CodeReview(self.env, int(cs_id)) if not cr.is_existent_rev(): return pretty_err(req, 'Review ID error', 'No ChangeSet %s, it cannot ' \ 'CodeReview for a Non-existent ChangeSet' % cs_id) item = cr.get_item() if cr.is_existent(): item['reviewers'] = ', '.join(item['reviewers']) #ver, ctime, status, text, priority = record ver = item['version'] status = item['status'] priority = item['priority'] ctime = time.ctime(item['time']) text = item['text'] or '' else: authors = '' ver = 0 status = str_status["UndergoingReview"] text = '' ctime = '' priority = 'normal' sourcelists = [{'i':i, 'v': '[[CodeSegment(%s, 1, 2, %s)]]'%(v, cs_id)} \ for i, v in enumerate(cr.get_all_pathes())] if len(sourcelists) > 0: req.hdf['source_count'] = len(sourcelists) req.hdf['sourcelists'] = sourcelists if req.args.get('action') == 'preview' and req.args.has_key('text'): req.hdf['preview'] = wiki_to_html(req.args.get('text'), self.env, req) req.hdf['text'] = req.args.get('text') else: req.hdf['text'] = text author = util.get_reporter_id(req) if req.args.has_key('req_version'): if ver != int(req.args.get('req_version')): if req.args.has_key('oldtext'): req.hdf['oldtext'] = req.args.get('oldtext') else: req.hdf['oldtext'] = req.args.get('text') req.hdf['version'] = req.args.get('req_version') else: req.hdf['version'] = ver else: req.hdf['version'] = ver self._render_attachment(req, cs_id, True) req.hdf['page_class'] = 'edit' req.hdf['time'] = ctime req.hdf['status'] = status req.hdf['reviewers'] = item['reviewers'] req.hdf['author'] = author req.hdf['id'] = cs_id req.hdf['priority'] = priority req.hdf['cs_href'] = '%s/changeset/%s' % (self.env.href.base, cs_id) req.hdf['save_href'] = '%s/CodeReview/%s' % (self.env.href.base, cs_id) req.hdf['title'] = "Edit CodeReview r%s" % cs_id return 'codereviewpage.cs', None
def _render_form(self, req, attachment): req.perm(attachment.resource).require('ATTACHMENT_CREATE') return { 'mode': 'new', 'author': get_reporter_id(req), 'attachment': attachment, 'max_size': self.max_size }
def delete_bookmark(self, req, resource): """Bookmark a resource.""" # resource = self.normalise_resource(resource) db = self.env.get_db_cnx() cursor = db.cursor() cursor.execute('DELETE FROM bookmarks WHERE resource = %s AND username = %s', (resource, get_reporter_id(req))) db.commit()
def _do_save(self, req, db, ticket): if req.perm.has_permission('TICKET_CHGPROP'): # TICKET_CHGPROP gives permission to edit the ticket if not req.args.get('summary'): raise TracError(u'Les tickets doivent contenir un intitulé.') if req.args.has_key('description') or req.args.has_key('reporter'): req.perm.assert_permission('TICKET_ADMIN') ticket.populate(req.args) else: req.perm.assert_permission('TICKET_APPEND') # Mid air collision? if int(req.args.get('ts')) != ticket.time_changed: raise TracError(u"Désolé, impossible d'enregistrer vos modifications. " u"Ce ticket a été modifié par quelqu'un d'autre " u"depuis que vous avez commencé", u'Collision en plein vol') # Do any action on the ticket? action = req.args.get('action') actions = TicketSystem(self.env).get_available_actions(ticket, req.perm) if action not in actions: raise TracError(u'Action invalide') # TODO: this should not be hard-coded like this if action == 'accept': ticket['status'] = 'assigned' ticket['owner'] = req.authname if action == 'resolve': ticket['status'] = 'closed' ticket['resolution'] = req.args.get('resolve_resolution') elif action == 'reassign': ticket['owner'] = req.args.get('reassign_owner') ticket['status'] = 'new' elif action == 'reopen': ticket['status'] = 'reopened' ticket['resolution'] = '' self._validate_ticket(req, ticket) now = int(time.time()) cnum = req.args.get('cnum') replyto = req.args.get('replyto') internal_cnum = cnum if cnum and replyto: # record parent.child relationship internal_cnum = '%s.%s' % (replyto, cnum) if ticket.save_changes(get_reporter_id(req, 'author'), req.args.get('comment'), when=now, db=db, cnum=internal_cnum): db.commit() try: tn = TicketNotifyEmail(self.env) tn.notify(ticket, newticket=False, modtime=now) except Exception, e: self.log.exception("Failure sending notification on change to " "ticket #%s: %s" % (ticket.id, e))
def _do_save(self, req, db, ticket): if req.perm.has_permission('TICKET_CHGPROP'): # TICKET_CHGPROP gives permission to edit the ticket if not req.args.get('summary'): raise TracError('Tickets must contain summary.') if req.args.has_key('description') or req.args.has_key('reporter'): req.perm.assert_permission('TICKET_ADMIN') ticket.populate(req.args) else: req.perm.assert_permission('TICKET_APPEND') # Mid air collision? if int(req.args.get('ts')) != ticket.time_changed: raise TracError("Sorry, can not save your changes. " "This ticket has been modified by someone else " "since you started", 'Mid Air Collision') # Do any action on the ticket? action = req.args.get('action') actions = TicketSystem(self.env).get_available_actions(ticket, req.perm) if action not in actions: raise TracError('Invalid action') # TODO: this should not be hard-coded like this if action == 'accept': ticket['status'] = 'assigned' ticket['owner'] = req.authname if action == 'resolve': ticket['status'] = 'closed' ticket['resolution'] = req.args.get('resolve_resolution') elif action == 'reassign': ticket['owner'] = req.args.get('reassign_owner') ticket['status'] = 'new' elif action == 'reopen': ticket['status'] = 'reopened' ticket['resolution'] = '' self._validate_ticket(req, ticket) now = int(time.time()) cnum = req.args.get('cnum') replyto = req.args.get('replyto') internal_cnum = cnum if cnum and replyto: # record parent.child relationship internal_cnum = '%s.%s' % (replyto, cnum) if ticket.save_changes(get_reporter_id(req, 'author'), req.args.get('comment'), when=now, db=db, cnum=internal_cnum): db.commit() try: tn = TicketNotifyEmail(self.env) tn.notify(ticket, newticket=False, modtime=now) except Exception, e: self.log.exception("Failure sending notification on change to " "ticket #%s: %s" % (ticket.id, e))
def submit_for_inclusion(self, number, req): db = self.env.get_db_cnx() dbBack = dbBackend(db) review = dbBack.getCodeReviewsByID(number) if review.Author == util.get_reporter_id(req): if review.Status == "Reviewed": review.Status = "Ready for inclusion" review.save(db) req.redirect(req.hdf['trac.href.peerReviewView'] + "?Review=" + number)
def close_review(self, number, req): db = self.env.get_db_cnx() dbBack = dbBackend(db) review = dbBack.getCodeReviewsByID(number) # this option available if you are the author or manager of this code review if review.Author == util.get_reporter_id(req) or req.hdf('Manager') == '1': review.Status = "Closed" review.save(db) req.redirect(req.hdf['trac.href.peerReviewView'] + "?Review=" + number)
def get_bookmarks(self, req): """Return the current users bookmarks.""" db = self.env.get_db_cnx() cursor = db.cursor() cursor.execute( "SELECT resource, name, username FROM bookmarks WHERE username=%s", (get_reporter_id(req), )) for row in cursor: yield row