def _format_timeline(self, d, format, dateonly): data = Chrome(self.env).populate_data(self.req, {}) TimelineModule(self.env) \ .post_process_request(self.req, 'timeline.html', data, None) return plaintext(data['pretty_dateinfo'](d, format=format, dateonly=dateonly))
def _format_message(self, user, project, events): """ Create the text body for email """ url_home = self.env.config.get('multiproject', 'url_home').rstrip('/') url_service = self.env.config.get('multiproject', 'url_service').rstrip('/') # TODO: Move into template msg = "Hi %s,\nhere are the latest updates for the project %s that you are following.\n" % ( user.username, project.project_name) for project, event, context in events: event_title = plaintext(event['render']('title', context), keeplinebreaks=False) description = self._get_event_description(event, context) date = to_web_time(event['date']) author = event['author'] event_url = url_service + str(event['render']('url', context)) msg += "\n%s\n" % event_title if description: msg += "%s\n" % description msg += "%s by %s\n" % (date, author) msg += "Read more about this at %s\n" % event_url prefs = url_home + "/prefs/following" msg += "\nYou are receiving this e-mail because you subscribed to this project. " msg += "You may edit the frequency or stop following this project at %s.\n" % prefs return msg
def _get_event_description(self, event, context): if event['kind'] == 'wiki': return None description = plaintext(event['render']('description', context), keeplinebreaks=False) if len(description) > 70: description = description[:70] + "..." return description
def pre_process_request(self, req, handler): """ Pre-process the request by adding 'Zip Archive' link into alternative format links The link is constructed from first and latest revision number, taken from the default repository. :param Request req: Trac request :param object handler: existing handler :returns: Handler, modified or not """ # Add link only in /browser or /browser/?rev= pages if (self.browser_regx.match(req.path_info) and 'BROWSER_VIEW' in req.perm and 'FILE_VIEW' in req.perm): # Get default repository and its type rm = RepositoryManager(self.env) repo = rm.get_repository('') repo_type = rm.repository_type # Construct the export urls for each format and based on revision info latest_rev = plaintext(str(req.args.get('rev', repo.get_youngest_rev()))) # Use Trac's internal implementation if repo_type == 'svn': return handler # For other types, iterate supported formats for format, info in self.formats.items(): add_link(req, 'alternate', req.href('export/archive', rev=latest_rev, format=format), _(info['desc']), info['mime'], info['ext']) return handler
def _parse_heading(self, match, fullmatch, shorten): match = match.strip() depth = min(len(fullmatch.group('hdepth')), 5) anchor = fullmatch.group('hanchor') or '' heading_text = match[depth + 1:-depth - 1 - len(anchor)] heading = wiki_to_oneliner(self.env, heading_text, self.path, self.basepath, self.db, False, self.absurls) if anchor: anchor = anchor[1:] else: sans_markup = plaintext(heading, keeplinebreaks=False) anchor = WikiParser._anchor_re.sub('', sans_markup) if not anchor or anchor[0].isdigit() or anchor[0] in '.-': # an ID must start with a Name-start character in XHTML anchor = 'a' + anchor # keeping 'a' for backward compat i = 1 anchor_base = anchor while anchor in self._anchors: anchor = anchor_base + str(i) i += 1 self._anchors[anchor] = True if shorten: heading = wiki_to_oneliner(self.env, heading_text, self.db, True, self.absurls) return (depth, heading, anchor)
def pre_process_request(self, req, handler): """ Pre-process the request by adding 'Zip Archive' link into alternative format links The link is constructed from first and latest revision number, taken from the default repository. :param Request req: Trac request :param object handler: existing handler :returns: Handler, modified or not """ # Add link only in /browser or /browser/?rev= pages if (self.browser_regx.match(req.path_info) and 'BROWSER_VIEW' in req.perm and 'FILE_VIEW' in req.perm): # Get default repository and its type rm = RepositoryManager(self.env) repo = rm.get_repository('') repo_type = rm.repository_type # Construct the export urls for each format and based on revision info try: latest_rev = plaintext( str(req.args.get('rev', repo.get_youngest_rev()))) except: pass # Use Trac's internal implementation if repo_type == 'svn': return handler # For other types, iterate supported formats for format, info in self.formats.items(): add_link( req, 'alternate', req.href('export/archive', rev=latest_rev, format=format), _(info['desc']), info['mime'], info['ext']) return handler
def _format_chrome(self, d, format, dateonly): data = Chrome(self.env).populate_data(self.req) return plaintext(data['pretty_dateinfo'](d, format=format, dateonly=dateonly))
def _format_timeline(self, d, format, dateonly): data = Chrome(self.env).populate_data(self.req, {}) TimelineModule(self.env).post_process_request(self.req, "timeline.html", data, None) return plaintext(data["pretty_dateinfo"](d, format=format, dateonly=dateonly))
def _format_chrome(self, d, format, dateonly): data = Chrome(self.env).populate_data(self.req, {}) return plaintext(data["pretty_dateinfo"](d, format=format, dateonly=dateonly))
def _do_process(self, req): """Handle the redirect from the OpenID server. """ db = self.env.get_db_cnx() oidconsumer, session = self._get_consumer(req, db) # Ask the library to check the response that the server sent # us. Status is a code indicating the response type. info is # either None or a string containing more information about # the return type. info = oidconsumer.complete(req.args,req.args['openid.return_to']) css_class = 'error' if info.status == consumer.FAILURE and info.identity_url: # In the case of failure, if info is non-None, it is the # URL that we were verifying. We include it in the error # message to help the user figure out what happened. fmt = "Verification of %s failed: %s" message = fmt % (cgi.escape(info.identity_url), info.message) elif info.status == consumer.SUCCESS: # Success means that the transaction completed without # error. If info is None, it means that the user cancelled # the verification. css_class = 'alert' # This is a successful verification attempt. If this # was a real application, we would do our login, # comment posting, etc. here. fmt = "You have successfully verified %s as your identity." message = fmt % (cgi.escape(info.identity_url),) remote_user = info.identity_url reg_info = None ax_response = ax.FetchResponse.fromSuccessResponse(info) if ax_response: ax_data = ax_response.getExtensionArgs() email = ax_data.get('value.ext0.1', '') if email: reg_info = {'email': email, 'fullname': email.split('@', 1)[0].replace('.', ' ').title()} if not reg_info: response = sreg.SRegResponse.fromSuccessResponse(info) if response: reg_info = response.getExtensionArgs() if self.strip_protocol: remote_user = remote_user[remote_user.find('://')+3:] if self.strip_trailing_slash and remote_user[-1] == '/': remote_user = remote_user[:-1] if info.endpoint.canonicalID: # You should authorize i-name users by their canonicalID, # rather than their more human-friendly identifiers. That # way their account with you is not compromised if their # i-name registration expires and is bought by someone else. message += (" This is an i-name, and its persistent ID is %s" % (cgi.escape(info.endpoint.canonicalID),)) remote_user = info.endpoint.canonicalID allowed = True if self.re_white_list: self.env.log.debug("Filtering REMOTE_USER '%s' through white-list." % remote_user) allowed = False for item in self.re_white_list: if not allowed and item.match(remote_user): allowed = True self.env.log.debug("User white-listed.") if allowed and self.re_black_list: self.env.log.debug("Filtering REMOTE_USER '%s' through black-list." % remote_user) for item in self.re_black_list: if item.match(remote_user): allowed = False self.env.log.debug("User black-listed.") if allowed and self.check_list: params = {self.check_list_key: remote_user} if reg_info and reg_info.has_key('email') and len(reg_info['email']) > 0: params['email'] = reg_info['email'] url = self.check_list + '?' + urllib.urlencode(params) self.env.log.debug('OpenID check list URL: %s' % url) result = simplejson.load(urllib.urlopen(url)) if not result[self.check_list_key]: allowed = False elif self.check_list_username: new_user = result[self.check_list_username] if new_user: remote_user = new_user if allowed: cookie = hex_entropy() req.outcookie['trac_auth_openid'] = cookie req.outcookie['trac_auth_openid']['path'] = req.href() req.outcookie['trac_auth_openid']['expires'] = self.trac_auth_expires req.session[self.openid_session_identity_url] = info.identity_url if reg_info and reg_info.has_key('fullname') and len(reg_info['fullname']) > 0: req.session['name'] = plaintext(reg_info['fullname'], keeplinebreaks=False) if reg_info and reg_info.has_key('email') and len(reg_info['email']) > 0: req.session['email'] = plaintext(reg_info['email'], keeplinebreaks=False) self._commit_session(session, req) if req.session.has_key('name'): remote_user = req.session['name'] elif req.session.has_key('email'): remote_user = req.session['email'] remote_user = plaintext("openid:%s" % (remote_user,), keeplinebreaks=False) if self.combined_username and req.session['name']: remote_user = plaintext('%s <%s>' % (req.session['name'], remote_user), keeplinebreaks=False) # Check if we generated a colliding remote_user and make the user unique collisions = 0 cremote_user = remote_user while True: ds = DetachedSession(self.env, remote_user) if not ds.last_visit: # New session break if not ds.has_key(self.openid_session_identity_url): # Old session, without the iurl set # Save the iurl then (bascially adopt the session) ds[self.openid_session_identity_url] = info.identity_url ds.save() break if ds[self.openid_session_identity_url] == info.identity_url: # No collision break # We got us a collision # Make the thing unique collisions += 1 remote_user = "******" % (cremote_user, collisions) req.authname = remote_user db = self.env.get_db_cnx() cursor = db.cursor() cursor.execute("INSERT INTO auth_cookie (cookie,name,ipnr,time) " "VALUES (%s, %s, %s, %s)", (cookie, remote_user, self._get_masked_address(req.remote_addr), int(time.time()))) db.commit() req.redirect(req.session.get('oid.referer') or self.env.abs_href()) else: message = 'You are not allowed here.' elif info.status == consumer.CANCEL: # cancelled message = 'Verification cancelled' elif info.status == consumer.SETUP_NEEDED: if info.setup_url: message = '<a href=%s>Setup needed</a>' % ( quoteattr(info.setup_url),) else: # This means auth didn't succeed, but you're welcome to try # non-immediate mode. message = 'Setup needed' else: # Either we don't understand the code or there is no # openid_url included with the error. Give a generic # failure message. The library should supply debug # information in a log. message = 'Verification failed.' self._commit_session(session, req) add_stylesheet(req, 'authopenid/css/openid.css') add_script(req, 'authopenid/js/openid-jquery.js') return 'openidlogin.html', { 'images': req.href.chrome('authopenid/images') + '/', 'action': req.href.openidverify(), 'message': message, 'signup': self.signup_link, 'whatis': self.whatis_link, 'css_class': css_class, 'custom_provider_name': self.custom_provider_name, 'custom_provider_label': self.custom_provider_label, 'custom_provider_url': self.custom_provider_url, 'custom_provider_image': self.custom_provider_image, }, None
def process_request(self, req): """ Handle the export requests :raises: TracError in case of failure """ req.perm.require('BROWSER_VIEW') req.perm.require('FILE_VIEW') # Get default repository and its type rm = RepositoryManager(self.env) repo = rm.get_repository('') repo_type = rm.repository_type svn_path = 'trunk' format = plaintext(req.args.get('format', 'zip')) # Get revision info. For svn it's in format: <revnum>/<path> revision = plaintext(str(req.args.get('rev', repo.get_youngest_rev()))) if repo_type == 'svn': revision = repo.get_youngest_rev() svn_path = req.args.get('rev', svn_path) # Validate if given revision really exists try: revision = repo.normalize_rev(revision) except NoSuchChangeset: raise HTTPNotFound('No such changeset') # Validate format if format not in self.formats: raise TracError('Format is not supported') # Load project object based on current environment env_name = conf.resolveProjectName(self.env) repo_type = self.env.config.get('trac', 'repository_type') repo_dir = conf.getEnvironmentVcsPath(env_name) project = Project.get(env_name=env_name) if repo_type not in conf.supported_scm_systems: raise TracError('Non-supported VCS type') # Create temporary directory with appropriate subdirectory where to export repository tempfd = tempfile.NamedTemporaryFile(delete=False) # Dump the repository per type, into defined location try: if repo_type == 'git': # Use short revision format revision = revision[:6] prefix = '%s-%s' % (env_name, revision[:6]) self._archive_git(repo_dir, revision, format, tempfd.name, prefix) elif repo_type == 'hg': # In case of both local:global revision format, use only global if ':' in revision: revision = revision.split(':', 1)[1] prefix = '%s-%s' % (env_name, revision[:6]) self._archive_hg(repo_dir, revision, format, tempfd.name, prefix) elif repo_type == 'svn': assert format == 'zip', 'Only zip format is supported for subversion' # Redirect to Trac's internal changeset functionality # Example: https://localhost/svnproject/changeset/4/trunk?old_path=%2F&format=zip changeset_href = Href('/%s/changeset' % env_name) return req.redirect(changeset_href(revision, svn_path, old_path='/', format='zip')) # Redirect raises RequestDone: re-raise it except RequestDone: raise except Exception, err: self.env.log.exception('Repository dump failed: %s' % err) raise TracError('Repository archive failed - please try again later')
def process_request(self, req): page_name = req.args.get('page') location = req.args.get('location') theme = req.args.get('theme', self.default_theme) page = WikiPage(self.env, page_name) if not page.exists: raise TracError('Invalid wiki page "%s"' % page.name) page_text = self.fixup_images_re.sub(r'[[Image(wiki:%s:\1)]]' % page.name, page.text) in_section = -1 text = title = html_title = title_page = handout = '' slides = [] context = Context.from_request(req, page.resource) for line in page_text.splitlines(): match = self.heading_re.match(line) if match: # Insert accumulated text into appropriate location if in_section == 1: title_page = format_to_html(self.env, context, text) elif in_section == 2: text = self.fixup_re.sub(r'\1', text) slides.append({'body': format_to_html(self.env, context, text), 'handout': format_to_html(self.env, context, handout)}) if match.lastgroup == 'title': title = match.group(match.lastgroup) html_title = format_to_html(self.env, context, title) title = plaintext(html_title) in_section = 1 else: in_section = 2 text = '' text += line + '\n' if in_section == 1: title_page = format_to_html(self.env, context, text) elif in_section == 2: text = self.fixup_re.sub(r'\1', text) slides.append({'body': format_to_html(self.env, context, text), 'handout': format_to_html(self.env, context, handout)}) add_stylesheet(req, 'common/css/code.css') add_stylesheet(req, 'common/css/diff.css') data = { 'html_title': html_title, 'location': location, 'slides': slides, 'theme': theme, 'title': title, 'title_page': title_page } return 'slideshow.html', data, 'text/html'
def process_request(self, req): """ Handle the export requests :raises: TracError in case of failure """ req.perm.require('BROWSER_VIEW') req.perm.require('FILE_VIEW') repository_name = req.path_info.split("/")[-1] # Get default repository and its type rm = RepositoryManager(self.env) list_repos = rm.get_real_repositories() repo = None repo_type = None for r in list_repos: if r.get_base().split("/")[-1].lower() == repository_name: repo = r break repo_type = repo.get_base().split(":")[0] svn_path = 'trunk' format = plaintext(req.args.get('format', 'zip')) conf.log.exception("Repotype at beginning: %s" % repo_type) # Get revision info. For svn it's in format: <revnum>/<path> revision = plaintext(str(req.args.get('rev', repo.get_youngest_rev()))) # Validate if given revision really exists try: revision = repo.normalize_rev(revision) except NoSuchChangeset: raise HTTPNotFound('No such changeset') # Validate format if format not in self.formats: raise TracError('Format is not supported') # Load project object based on current environment env_name = conf.resolveProjectName(self.env) #repo_type = self.env.config.get('trac', 'repository_type') repo_dir = conf.getEnvironmentVcsPath(env_name, repo_type, repository_name) project = Project.get(env_name=env_name) if repo_type not in conf.supported_scm_systems: raise TracError('Non-supported VCS type') # Create temporary directory with appropriate subdirectory where to export repository tempfd = tempfile.NamedTemporaryFile(delete=False) # Dump the repository per type, into defined location conf.log.exception("Repotype: %s, repo_dir: %s" % (repo_type, repo_dir)) try: if repo_type == 'git': # Use short revision format revision = revision[:6] prefix = '%s-%s' % (env_name, revision[:6]) self._archive_git(repo_dir, revision, format, tempfd.name, prefix) elif repo_type == 'hg': # In case of both local:global revision format, use only global if ':' in revision: revision = revision.split(':', 1)[1] prefix = '%s-%s' % (env_name, revision[:6]) self._archive_hg(repo_dir, revision, format, tempfd.name, prefix) elif repo_type == 'svn': assert format == 'zip', 'Only zip format is supported for subversion' # Redirect to Trac's internal changeset functionality # Example: https://localhost/svnproject/changeset/4/trunk?old_path=%2F&format=zip changeset_href = Href('/%s/changeset' % env_name) return req.redirect( changeset_href(revision, repository_name + "/", format='zip')) # Redirect raises RequestDone: re-raise it except RequestDone: raise except Exception, err: self.env.log.exception('Repository dump failed: %s' % err) raise TracError( 'Repository archive failed - please try again later')