def get_navigation_items(self, req): if req.authname and req.authname != 'anonymous': # Use the same names as LoginModule to avoid duplicates. yield ('metanav', 'login', _('logged in as %(user)s', user=req.authname)) logout_href = req.href('%s/logout' % self.auth_path_prefix) from pkg_resources import parse_version if parse_version(trac.__version__) < parse_version('1.0.2'): yield ('metanav', 'logout', tag.a(_('Logout'), logout_href)) else: yield ('metanav', 'logout', tag.form(tag.div( tag.button(_('Logout'), name='logout', type='submit')), action=logout_href, method='post', id='logout', class_='trac-logout')) else: text = _('GitHub Login') if self.fontawesome_url: add_script(req, self.fontawesome_url) text = tag(tag.i(class_='fab fa-github-alt'), ' ', text) yield ('metanav', 'github_login', tag.a(text, href=req.href('%s/login' % self.auth_path_prefix)))
def _subscription_button(self, path): """ Generates a (disabled) button to connect JavaScript to. """ return tag.button('Subscribe', id_='subscribe', disabled=True, title=('Code comment subscriptions require ' 'JavaScript to be enabled'), data_base_url=self.env.project_url or self.env.abs_href(), data_path=path)
def get_navigation_items(self, req): if req.authname and req.authname != 'anonymous': yield ('metanav', 'login', _('logged in as %(user)s', user=req.authname)) yield ('metanav', 'logout', tag.form(tag.div(tag.button(_('Logout'), name='logout', type='submit')), action=req.href.logout(), method='post', id='logout', class_='trac-logout')) else: yield ('metanav', 'login', tag.a(_('Login'), href=req.href.login()))
def get_navigation_items(self, req): if req.authname and req.authname != 'anonymous': yield ('metanav', 'login', tag_("logged in as %(user)s", user=Chrome(self.env).authorinfo(req, req.authname))) yield ('metanav', 'logout', tag.form(tag.div(tag.button(_("Logout"), name='logout', type='submit')), action=req.href.logout(), method='post', id='logout', class_='trac-logout')) else: yield ('metanav', 'login', tag.a(_("Login"), href=req.href.login()))
def _logout_form(href, **kwargs): '''Return "Logout" "link" This version returns a form — styled to look like a link — as used by trac >= 1.0.2 (for CSRF protection.) Unfortunately, this does not render nicely in older tracs, since ``trac.css`` does not include the proper styling for ``form.trac-logout``. ''' fields = [tag.button(_('Logout'), name='logout', type='submit')] for name, value in kwargs.items(): fields.append(tag.input(type='hidden', name=name, value=value)) return tag.form(tag.div(*fields), action=href('logout'), id='logout', class_='trac-logout')
def get_navigation_items(self, req): if req.authname and req.authname != 'anonymous': # Use the same names as LoginModule to avoid duplicates. yield ('metanav', 'login', _('logged in as %(user)s', user=req.authname)) from pkg_resources import parse_version if parse_version(trac.__version__) < parse_version('1.0.2'): yield ('metanav', 'logout', tag.a(_('Logout'), href=req.href.github('logout'))) else: yield ('metanav', 'logout', tag.form(tag.div(tag.button(_('Logout'), name='logout', type='submit')), action=req.href.github('logout'), method='post', id='logout', class_='trac-logout')) else: # Use a different name from LoginModule to allow both in parallel. yield ('metanav', 'github_login', tag.a(_('GitHub Login'), href=req.href.github('login')))
def AddComment(macro, environ, data, *args, **kwargs): """Display an add comment form allowing users to post comments. This macro allows you to display an add comment form on the current page allowing users to post comments. The comments are added to the page's content itself. **Arguments:** //No Arguments// **Example(s):** {{{ <<AddComment>> }}} <<AddComment>> """ # Setup info and defaults parser = environ.parser request = environ.request page = data["page"] page_name = page["name"] page_text = page["text"] # Get the data from the POST comment = request.kwargs.get("comment", "") action = request.kwargs.get("action", "") author = request.kwargs.get("author", environ._user()) # Ensure <<AddComment>> is not present in comment, so that infinite # recursion does not occur. comment = re.sub("(^|[^!])(\<\<AddComment)", "\\1!\\2", comment) the_preview = None the_comment = None # If we are submitting or previewing, inject comment as it should look if action == "preview": the_preview = tag.div(tag.h1("Preview"), id="preview") the_preview += tag.div(parser.generate(comment, environ=(environ, data)), class_="article") # When submitting, inject comment before macro if comment and action == "save": new_text = "" comment_text = "\n==== Comment by %s on %s ====\n\n%s\n\n" % ( author, time.strftime('%c', time.localtime()), comment) for line in page_text.split("\n"): if line.find("<<AddComment") == 0: new_text += comment_text new_text += line + "\n" search = environ.search storage = environ.storage storage.reopen() search.update(environ) storage.save_text(page_name, new_text, author, "Comment added by %s" % author) search.update_page(environ.get_page(page_name), page_name, text=new_text) the_comment = tag.div(parser.generate(comment_text, environ=(environ, data)), class_="article") the_form = tag.form( tag.input(type="hidden", name="parent", value=page["node"]), tag.fieldset( tag.legend("Add Comment"), tag.p(tag.textarea( (not action in ("cancel", "save") and comment or ""), id="comment", name="comment", cols=80, rows=5), class_="text"), tag.h4(tag.label("Your email or username:"******"author")), tag.p(tag.input(id="author", name="author", type="text", value=(not action in ("cancel", "save")) and author or ""), class_="input"), tag.p(tag.button("Preview", type="submit", name="action", value="preview"), tag.button("Save", type="submit", name="action", value="save"), tag.button("Cancel", type="submit", name="action", value="cancel"), class_="button"), ), method="post", action="") return tag(the_preview, the_comment, the_form)
def AddComment(macro, environ, data, *args, **kwargs): """Display an add comment form allowing users to post comments. This macro allows you to display an add comment form on the current page allowing users to post comments. The comments are added to the page's content itself. **Arguments:** //No Arguments// **Example(s):** {{{ <<AddComment>> }}} <<AddComment>> """ # Setup info and defaults parser = environ.parser request = environ.request page = data["page"] page_name = page["name"] page_text = page["text"] # Get the data from the POST comment = request.kwargs.get("comment", "") action = request.kwargs.get("action", "") author = request.kwargs.get("author", environ._user()) # Ensure <<AddComment>> is not present in comment, so that infinite # recursion does not occur. comment = re.sub("(^|[^!])(\<\<AddComment)", "\\1!\\2", comment) the_preview = None the_comment = None # If we are submitting or previewing, inject comment as it should look if action == "preview": the_preview = tag.div(tag.h1("Preview"), id="preview") the_preview += tag.div(parser.generate(comment, environ=(environ, data)), class_="article") # When submitting, inject comment before macro if comment and action == "save": new_text = "" comment_text = "\n==== Comment by %s on %s ====\n\n%s\n\n" % ( author, time.strftime('%c', time.localtime()), comment) for line in page_text.split("\n"): if line.find("<<AddComment") == 0: new_text += comment_text new_text += line + "\n" search = environ.search storage = environ.storage storage.reopen() search.update(environ) storage.save_text(page_name, new_text, author, "Comment added by %s" % author) search.update_page(environ.get_page(page_name), page_name, text=new_text) the_comment = tag.div(parser.generate(comment_text, environ=(environ, data)), class_="article") the_form = tag.form( tag.input(type="hidden", name="parent", value=page["node"]), tag.fieldset( tag.legend("Add Comment"), tag.p( tag.textarea( (not action in ("cancel", "save") and comment or ""), id="comment", name="comment", cols=80, rows=5 ), class_="text" ), tag.h4(tag.label("Your email or username:"******"author")), tag.p( tag.input(id="author", name="author", type="text", value=(not action in ("cancel", "save")) and author or "" ), class_="input" ), tag.p( tag.button("Preview", type="submit", name="action", value="preview"), tag.button("Save", type="submit", name="action", value="save"), tag.button("Cancel", type="submit", name="action", value="cancel"), class_="button" ), ), method="post", action="" ) return tag(the_preview, the_comment, the_form)
def filter_stream(self, req, method, filename, stream, data): """ Check for alert messages to show authenticated user. If there are any project messages that the authenticated user has not seen, which are selected to be viewed as alert based notifications, we add the necessary mark-up and javscript. """ if req.authname != 'anonymous': timeout_exceeded = self._timeout_limit_exceeded(req) if timeout_exceeded or timeout_exceeded is None: # we can check for alert notifications unagreed = ProjectMessage.get_unagreed_messages(self.env, req.authname, 'Alert') if unagreed: # we only shown one notification at a time currently msg = unagreed[0] msg['message'] = format_to_html(self.env, Context.from_request(req), msg['message']) alert_markup = tag( tag.div( tag.i( class_="alert-icon fa fa-info-circle" ), tag.ul( tag.li(msg['message'], class_="alert-message" ), ), tag.button(msg['button'], class_="close btn btn-mini", type="button", data_dismiss="alert" ), class_="project-message cf alert alert-info alert-dismissable individual" ), tag.form( tag.input( name="name", value=msg['name'], type="text", ), tag.input( name="agree", value=True, type="text", ), class_="hidden", method="post", action="", ), ) stream |= Transformer("//*[@id='main']/*[1]").before(alert_markup) add_script(req, 'projectmessage/js/project_message.js') # if the timeout has been exceeded or does not exist yet, # and there are no notifications to show, we update the # session attribute table if not ProjectMessage.get_unagreed_messages(self.env, req.authname): stamp = str(to_utimestamp(datetime.now(pytz.utc))) req.session['project_message_timeout'] = stamp req.session.save() return stream