def setUp(self): wiki = WikiPage(self.env) wiki.name = 'WikiStart' wiki.text = '--' wiki.save('joe', 'Entry page', '::1', datetime.now(utc)) if self._setup: self._setup(self)
def set_password(self, user, password): import re if len(user) < 3: raise TracError("user name must be at least 3 characters long") if not re.match(r"^\w+$", user): raise TracError("user name must consist only of alpha-numeric characters") if user not in self.get_users(): from trac.wiki.model import WikiPage db = self.env.get_db_cnx() page = WikiPage(self.env, user, db=db) # User creation with existing page if page.exists: raise TracError('wiki page "%s" already exists' % user) else: from tractags.api import TagEngine tagspace = TagEngine(self.env).tagspace.wiki tagspace.add_tags(None, user, ["user"]) page.text = """= %(user)s =\n\n[[ListTagged(%(user)s)]]\n\n[[TagIt(user)]]""" % {"user": user} page.save(user, "New user %s registered" % user, None) self.env.log.debug("New user %s registered" % user) HtPasswdStore.set_password(self, user, password)
def getPageInfo(self, req, pagename, version=None): """ Returns information about the given page. """ page = WikiPage(self.env, pagename, version) if page.exists: last_update = page.get_history().next() return self._page_info(page.name, last_update[1], last_update[2], page.version)
def getPageInfo(self, req, pagename, version=None): """ Returns information about the given page. """ page = WikiPage(self.env, pagename, version) req.perm(page.resource).require("WIKI_VIEW") if page.exists: last_update = page.get_history().next() return self._page_info(page.name, last_update[1], last_update[2], page.version, page.comment)
def _get_interwiki_map(self): from trac.wiki.model import WikiPage if self._interwiki_map is None: self._interwiki_lock.acquire() try: if self._interwiki_map is None: self._interwiki_map = {} content = WikiPage(self.env, InterWikiMap._page_name).text in_map = False for line in content.split('\n'): if in_map: if line.startswith('----'): in_map = False else: m = re.match(InterWikiMap._interwiki_re, line) if m: prefix, url, title = m.groups() url = url.strip() title = title and title.strip() or prefix self[prefix] = (prefix, url, title) elif line.startswith('----'): in_map = True finally: self._interwiki_lock.release() return self._interwiki_map
def add_pages(tc, names): now = datetime.now(utc) for name in names: w = WikiPage(tc.env) w.name = name w.text = '--' w.save('joe', 'the page ' + name, '::1', now)
def interwiki_map(self): """Map from upper-cased namespaces to (namespace, prefix, title) values. """ from trac.wiki.model import WikiPage map = {} content = WikiPage(self.env, InterWikiMap._page_name).text in_map = False for line in content.split('\n'): if in_map: if line.startswith('----'): in_map = False else: m = re.match(InterWikiMap._interwiki_re, line) if m: prefix, url, title = m.groups() url = url.strip() title = title.strip() if title else prefix map[prefix.upper()] = (prefix, url, title) elif line.startswith('----'): in_map = True for prefix, value in self.interwiki_section.options(): value = value.split(None, 1) if value: url = value[0].strip() title = value[1].strip() if len(value) > 1 else prefix map[prefix.upper()] = (prefix, url, title) return map
def main(): names = sorted(name for name in resource_listdir('trac.wiki', 'default-pages') if not name.startswith('.')) env = EnvironmentStub() load_components(env) with env.db_transaction: for name in names: wiki = WikiPage(env, name) wiki.text = resource_string('trac.wiki', 'default-pages/' + name).decode('utf-8') if wiki.text: wiki.save('trac', '') else: printout('%s: Skipped empty page' % name) req = Mock(href=Href('/'), abs_href=Href('http://trac.edgewall.org/'), perm=MockPerm(), chrome={}) for name in sys.argv[1:]: name = os.path.basename(name) wiki = WikiPage(env, name) if not wiki.exists: continue context = web_context(req, wiki.resource, absurls=True) rst = wiki2rest(env, context, wiki) sys.stdout.write(rst)
def initialize_agilo(self, project_name, db_url, svn_repo, demo=False): try: self.do_initenv('%s %s %s %s' % (project_name, db_url, 'svn', svn_repo or 'somewhere')) # Now add agilo and the template path env = Environment(self.envname) ac = AgiloConfig(env) if not svn_repo: # remove the fake from the config ac.change_option('repository_dir', '', 'trac') # sets the restric_owner option ac.change_option('restrict_owner', 'true', 'ticket') # this is also saving the config ac.enable_agilo() # update wiki wiki = WikiPage(env, name='WikiStart') wiki.text = agilo_wiki wiki.save('admin', 'Updated to Agilo', '127.0.0.1') # reset the env self.env_set(envname=self.envname, env=env) # Now initialize Agilo self.do_upgrade('upgrade --no-backup') # Now create the demo if needed if demo: try: from create_demo_data import _create_demo_data _create_demo_data(env) except ImportError, e: env.log.error(exception_to_unicode(e)) except: pass
def get_default_version(self, name): """Return default viewable version number for the named page. Called when the wiki UI is rendering a page with no 'version=' in the HTTP request arguments. In this method, you'd normally do db lookups and so on to determine what the default viewable version of the named page is, and then return it; for this example, we're just going to pick a random page version instead. """ db = self.env.get_db_cnx() page = WikiPage(self.env, name, 1) history = page.get_history(all_versions=1) try: # get highest version number (version,time,author,comment,ipnr) = history.next() # here's a twist; we can enable Wikipedia-style talk # pages which are *not* under workflow control if name.endswith("/Talk"): return version # make some debug noise import random, sys print >>sys.stderr, "highest version", version # randomize the version number version = random.randint(1,version) print >>sys.stderr, "random version", version return version except: # returning None means that the default wiki "last edit # wins" behavior will be used instead return None
def main(): options, args = parse_args() names = sorted(name for name in resource_listdir('trac.wiki', 'default-pages') if not name.startswith('.')) if args: args = sorted(set(names) & set(map(os.path.basename, args))) else: args = names if options.download: download_default_pages(args, options.prefix) env = EnvironmentStub() load_components(env) with env.db_transaction: for name in names: wiki = WikiPage(env, name) wiki.text = resource_string('trac.wiki', 'default-pages/' + name).decode('utf-8') if wiki.text: wiki.save('trac', '') else: printout('%s: Skipped empty page' % name) req = Mock(href=Href('/'), abs_href=Href('http://localhost/'), perm=MockPerm()) for name in args: wiki = WikiPage(env, name) if not wiki.exists: continue context = web_context(req, wiki.resource) out = DummyIO() DefaultWikiChecker(env, context, name).format(wiki.text, out)
def add_pages(tc, names): now = datetime.now(utc) for name in names: w = WikiPage(tc.env) w.name = name w.text = "--" w.save("joe", "the page " + name, "::1", now)
def copy_wiki_page(source_env, dest_env, name, dest_db=None): # In case a string gets passed in if not isinstance(source_env, Environment): source_env = _open_environment(source_env) if not isinstance(dest_env, Environment): dest_env = _open_environment(dest_env) # Log message source_env.log.info('DatamoverPlugin: Moving page %s to the environment at %s', name, dest_env.path) dest_env.log.info('DatamoverPlugin: Moving page %s from the environment at %s', name, source_env.path) # Open databases source_db = source_env.get_db_cnx() source_cursor = source_db.cursor() handle_commit = True if not dest_db: dest_db, handle_commit = dest_env.get_db_cnx(), False dest_cursor = dest_db.cursor() # Remove the page from the destination dest_page = WikiPage(dest_env, name, db=dest_db) if dest_page.exists: dest_page.delete(db=dest_db) # Copy each entry in the wiki table source_cursor.execute('SELECT * FROM wiki WHERE name=%s',(name,)) for row in source_cursor: wiki_data = dict(zip([d[0] for d in source_cursor.description], row)) q = make_query(wiki_data, 'wiki') dest_cursor.execute(*q) if handle_commit: dest_db.commit()
def save_wiki_data(self, req): page = WikiPage(self.env, self.name) if not page.exists: self.log.error('Wiki page "%s" doesn\'t exist' % self.name) return None lines = page.text.split('\n') first = -1 last = -1 new_lines = [] for index, line in enumerate(lines): if first < 0: new_lines.append(line) if self.data_start_regexp.match(line): first = index + 1 new_lines.append(self.get_json(False, True)) elif last < 0: if self.data_end_regexp.match(line): last = index - 1 new_lines.append(line) else: new_lines.append(line) if last > 0: page.text = '\n'.join(new_lines) try: page.save(req.authname, 'Kanban board data changed', req.remote_addr) except TracError as e: self.log.error('TracError: "%s"' % e.message)
def import_wiki_pages(self, template_path): """Creates wiki pages from wiki.xml template file. Creates wiki pages inside the project using data extracted from an wiki.ml file. We don't set the author or version as that wouldn't be applicable to a new project. """ # open the wiki XML file, parse the data and create wiki pages full_path = os.path.join(template_path, 'wiki.xml') try: tree = ET.ElementTree(file=full_path) for page in tree.getroot(): if page.text: wikipage = WikiPage(self.env, page.attrib['name']) wikipage.readonly = int(page.attrib['readonly']) # we store as a string in xml wikipage.text = page.text wikipage.save(None, None, None) self.log.info("Wiki page %s created", page.attrib['name']) else: self.log.debug("Cannot create wiki pages with no text. " "Unable to import %s", wikipage) except IOError as exception: if exception.errno == errno.ENOENT: self.log.info("Path to wiki.xml file %s does not exist. Unable " "to import wiki pages from template.", full_path)
def _do_wiki_upgrade(self): """Move all wiki pages starting with Trac prefix to unbranded user guide pages. """ wiki_admin = WikiAdmin(self.env) pages = wiki_admin.get_wiki_list() for old_name in pages: if old_name.startswith('Trac'): new_name = wiki.new_name(old_name) if not new_name: continue if new_name in pages: printout(_('Ignoring %(page)s : ' 'The page %(new_page)s already exists', page=old_name, new_page=new_name)) continue try: wiki_admin._do_rename(old_name, new_name) except AdminCommandError, exc: printout(_('Error moving %(page)s : %(message)s', page=old_name, message=unicode(exc))) else: # On success, rename links in other pages self._do_wiki_rename_links(old_name, new_name) # On success, insert redirection page redirection = WikiPage(self.env, old_name) redirection.text = _('See [wiki:"%(name)s"].', name=new_name) comment = 'Bloodhound guide update' redirection.save('bloodhound', comment, '0.0.0.0')
def do_upgrade_environment(db): for realm in self.SCHEMA: realm_schema = self.SCHEMA[realm] if need_db_create_for_realm(self.env, realm, realm_schema, db): create_db_for_realm(self.env, realm, realm_schema, db) elif need_db_upgrade_for_realm(self.env, realm, realm_schema, db): upgrade_db_for_realm(self.env, 'testmanager.upgrades', realm, realm_schema, db) # Create default values for configuration properties and initialize counters db_insert_or_ignore(self.env, 'testconfig', 'NEXT_CATALOG_ID', '0', db) db_insert_or_ignore(self.env, 'testconfig', 'NEXT_TESTCASE_ID', '0', db) db_insert_or_ignore(self.env, 'testconfig', 'NEXT_PLAN_ID', '0', db) db.commit() # Fix templates with a blank id if self._check_blank_id_templates(db): self._fix_blank_id_templates(db) db.commit() self.env.log.info(_(""" Test Manager templates with blank IDs have been fixed.\n Please go to the Administration panel, in the Test Manager Templates section, and check the associations between templates and Test Cases and Test Catalogs.\n You will have to manually fix any misconfiguration you should find. """)) # Create the basic "TC" Wiki page, used as the root test catalog tc_page = WikiPage(self.env, 'TC') if not tc_page.exists: tc_page.text = ' ' tc_page.save('System', '', '127.0.0.1') db.commit() if self._need_upgrade(db): # Set custom ticket field to hold related test case custom = self.config['ticket-custom'] config_dirty = False if 'testcaseid' not in custom: custom.set('testcaseid', 'text') custom.set('testcaseid.label', _("Test Case")) config_dirty = True if 'planid' not in custom: custom.set('planid', 'text') custom.set('planid.label', _("Test Plan")) config_dirty = True # Set config section for test case outcomes if 'test-outcomes' not in self.config: self.config.set('test-outcomes', 'green.SUCCESSFUL', _("Successful")) self.config.set('test-outcomes', 'yellow.TO_BE_TESTED', _("Untested")) self.config.set('test-outcomes', 'red.FAILED', _("Failed")) self.config.set('test-outcomes', 'default', 'TO_BE_TESTED') config_dirty = True if config_dirty: self.config.save()
def delete_wiki_page_in_trac(self, filename): page = WikiPage(self.env, filename) page.delete() conn = self.env.get_db_cnx() c = conn.cursor() c.execute("DELETE FROM wiki_local WHERE name = '%s'" % filename) conn.commit() conn.close()
def process_request(self, req): action = req.args.get("action", "view") pagename = req.args.get("page", "WikiStart") version = req.args.get("version") db = self.env.get_db_cnx() page = WikiPage(self.env, pagename, version, db) ########## # readonly hack. if user created page originally, user can edit readonly # page.readonly = 0 allows wiki.css to show edit buttons if page.readonly == 1 and action == "view" and not req.perm.has_permission("WIKI_ADMIN"): cursor = db.cursor() # cursor.execute("SELECT * FROM wiki WHERE author=%s AND name=%s ORDER BY version ASC LIMIT 1", (req.authname,pagename) ) cursor.execute("SELECT * FROM wiki WHERE author=%s AND name=%s AND version=1", (req.authname, pagename)) if cursor.fetchone(): page.readonly = 0 ########## add_stylesheet(req, "common/css/wiki.css") if req.method == "POST": if action == "edit": latest_version = WikiPage(self.env, pagename, None, db).version if req.args.has_key("cancel"): req.redirect(self.env.href.wiki(page.name)) elif int(version) != latest_version: action = "collision" self._render_editor(req, db, page) elif req.args.has_key("preview"): action = "preview" self._render_editor(req, db, page, preview=True) else: self._do_save(req, db, page) elif action == "delete": self._do_delete(req, db, page) elif action == "diff": get_diff_options(req) req.redirect(self.env.href.wiki(page.name, version=page.version, action="diff")) elif action == "delete": self._render_confirm(req, db, page) elif action == "edit": self._render_editor(req, db, page) elif action == "diff": self._render_diff(req, db, page) elif action == "history": self._render_history(req, db, page) else: if req.args.get("format") == "txt": req.send_response(200) req.send_header("Content-Type", "text/plain;charset=utf-8") req.end_headers() req.write(page.text) return self._render_view(req, db, page) req.hdf["wiki.action"] = action req.hdf["wiki.page_name"] = page.name req.hdf["wiki.current_href"] = self.env.href.wiki(page.name) return "wiki.cs", None
def _process_page(self, page, author = None, comment = None, ipnr = None): if self.boilerplate_start_re.search( page.text ) != None: # If the audit info isn't available, grab it from the boilerplate page. if author == None or comment == None: page = WikiPage( self.env, page.name ) if author == None: author = page.author if comment == None: comment = page.comment if ipnr == None: ipnr = '127.0.0.1' # I don't know what else to do here. # Extract the boilerplate text and the wanted pages. buf = StringIO() page_list = {} inboilerplate = False for line in page.text.splitlines(): if inboilerplate: if self.boilerplate_end_re.search( line ) != None: inboilerplate = False else: buf.write( line ) buf.write( '\n' ) else: if self.boilerplate_start_re.search( line ) != None: inboilerplate = True else: if line.startswith('||') and line.endswith('||') and line[3] != "'": try: descriptor = ([i.strip() for i in line.strip('||').split('||')]) name = descriptor[0] arguments = descriptor[1:] m = self.extractpagename_re.search( name ) if m != None: name = m.string[m.start(1):m.end(1)] self.env.log.warning("extracted name = " + name ) page_list[ name ] = arguments except Exception, e: self.env.log.warning("Invalid page line: %s (%s)", line, e) # Generate the derived pages as instructed. page_names = page_list.keys() page_names.sort() for name in page_names: text = buf.getvalue() args = page_list[ name ] text = text.replace( '{{0}}', name ) i = 0 for arg in args: text = text.replace('{{%d}}' % (i+1), args[i]) i += 1 newpage = WikiPage( self.env, name ) if newpage.text != text: newpage.text = text newpage.save( author, comment, ipnr )
def do_rename(db): page.rename(new_name) if redirect: redirection = WikiPage(self.env, old_name, db=db) redirection.text = _('See [wiki:"%(name)s"].', name=new_name) author = get_reporter_id(req) comment = u'[wiki:"%s@%d" %s] \u2192 [wiki:"%s"].' % ( new_name, old_version, old_name, new_name) redirection.save(author, comment, req.remote_addr)
def deletePage(self, req, name, version=None): """Delete a Wiki page (all versions) or a specific version by including an optional version number. Attachments will also be deleted if page no longer exists. Returns True for success.""" wp = WikiPage(self.env, name, version) req.perm(wp.resource).require("WIKI_DELETE") try: wp.delete(version) return True except: return False
def user_created(self, user, password): req = FakeRequest(self.env, user) resource = Resource('wiki', user) tag_system = TagSystem(self.env) tag_system.add_tags(req, resource, ['user',]) page = WikiPage(self.env, user) page.text = '''= %(user)s =\n\n[[ListTagged(%(user)s)]]\n''' % {'user' : user} page.save(user, 'New user %s registered' % user, None) self.env.log.debug("New user %s registered" % user)
def _render_editor(self, req, page, action='edit', has_collision=False): if has_collision: if action == 'merge': page = WikiPage(self.env, page.name, version=None) req.perm(page.resource).require('WIKI_VIEW') else: action = 'collision' if page.readonly: req.perm(page.resource).require('WIKI_ADMIN') else: req.perm(page.resource).require('WIKI_MODIFY') original_text = page.text if 'text' in req.args: page.text = req.args.get('text') elif 'template' in req.args: template = self.PAGE_TEMPLATES_PREFIX + req.args.get('template') template_page = WikiPage(self.env, template) if template_page and template_page.exists and \ 'WIKI_VIEW' in req.perm(template_page.resource): page.text = template_page.text if action == 'preview': page.readonly = 'readonly' in req.args author = get_reporter_id(req, 'author') 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') data = self._page_data(req, page, action) data.update({ 'author': author, 'comment': comment, 'edit_rows': editrows, 'scroll_bar_pos': req.args.get('scroll_bar_pos', ''), 'diff': None, }) if action in ('diff', 'merge'): old_text = original_text and original_text.splitlines() or [] new_text = page.text and page.text.splitlines() or [] diff_data, changes = self._prepare_diff( req, page, old_text, new_text, page.version, '') data.update({'diff': diff_data, 'changes': changes, 'action': 'preview', 'merge': action == 'merge', 'longcol': 'Version', 'shortcol': 'v'}) self._wiki_ctxtnav(req, page) return 'wiki_edit.html', data, None
def setUp(self): self.env = EnvironmentStub(enable=[AutoWikify]) self.req = Mock( authname='anonymous', perm=MockPerm(), tz=None, args={}, href=Href('/'), abs_href=Href('http://www.example.com/')) self.autowikify = AutoWikify(self.env) for name in (u'autowikify', u'あいうName', u'Nameあいう', u'かきくけこ'): page = WikiPage(self.env, name) page.text = name page.save('admin', '', '::1') self.context = Context.from_request(self.req, WikiPage(self.env, name))
def upgrade_environment(self, db): # Create or update db for realm in self.SCHEMA: realm_metadata = self.SCHEMA[realm] if need_db_create_for_realm(self.env, realm, realm_metadata, db): create_db_for_realm(self.env, realm, realm_metadata, db) elif need_db_upgrade_for_realm(self.env, realm, realm_metadata, db): upgrade_db_for_realm(self.env, 'testmanager.upgrades', realm, realm_metadata, db) # Create default values for configuration properties and initialize counters db_insert_or_ignore(self.env, 'testconfig', 'NEXT_CATALOG_ID', '0') db_insert_or_ignore(self.env, 'testconfig', 'NEXT_TESTCASE_ID', '0') db_insert_or_ignore(self.env, 'testconfig', 'NEXT_PLAN_ID', '0') # Create the basic "TC" Wiki page, used as the root test catalog tc_page = WikiPage(self.env, 'TC') if not tc_page.exists: tc_page.text = ' ' tc_page.save('System', '', '127.0.0.1') if self._need_upgrade(db): # Set custom ticket field to hold related test case custom = self.config['ticket-custom'] config_dirty = False if 'testcaseid' not in custom: custom.set('testcaseid', 'text') custom.set('testcaseid.label', _("Test Case")) config_dirty = True if 'planid' not in custom: custom.set('planid', 'text') custom.set('planid.label', _("Test Plan")) config_dirty = True # Set config section for test case outcomes if 'test-outcomes' not in self.config: self.config.set('test-outcomes', 'green.SUCCESSFUL', _("Successful")) self.config.set('test-outcomes', 'yellow.TO_BE_TESTED', _("Untested")) self.config.set('test-outcomes', 'red.FAILED', _("Failed")) self.config.set('test-outcomes', 'default', 'TO_BE_TESTED') config_dirty = True # Set config section for default visible columns in tabular view if self.config.get('testmanager', 'testcatalog.visible_description') == '': self.config.set('testmanager', 'testcatalog.visible_description', 'False') config_dirty = True if config_dirty: self.config.save()
def _controller_import(self, req, cat, page, component): """ Performs import. """ # Data to be passed to view data = {'operations': {}} # User selected pages selected_pages = req.args.get('wikiimport_selected_pages') # User has selected some pages if selected_pages: # Choose between preconfigured and raw instance if req.args.get('wikiimport_instance_path'): data['instance_path'] = req.args.get('wikiimport_instance_path') source_env = Environment(data['instance_path']) instance_identifier = data['instance_path'] else: data['instance_id'] = req.args.get('wikiimport_instance_id') source_env = self._get_instance_env(data['instance_id']) instance_identifier = data['instance_id'] # Get operations to be performed data['operations'] = self._get_page_operations(source_env, self.env) # This is required in order to display pages list alphabetically data['sorted_pages'] = data['operations'].keys() data['sorted_pages'].sort() # Discard operation for pages that were unchecked on the preview page for page in data['sorted_pages']: if page not in selected_pages: del data['operations'][page] # Update local wiki for page, operation in data['operations'].items(): source_page = WikiPage(source_env, page) local_page = WikiPage(self.env, page) local_page.text = source_page.text local_page.save( get_reporter_id(req, 'author'), 'Importing pages from "%s" using [http://trac-hacks.org/wiki/WikiImportPlugin WikiImport plugin].' % instance_identifier, req.remote_addr ) # Add stylesheet to view add_stylesheet(req, 'wikiimport/css/wikiimport.css'); return 'admin_wikiimport_import.html', data
def _do_rename(self, req, page): if page.readonly: req.perm(page.resource).require('WIKI_ADMIN') else: req.perm(page.resource).require('WIKI_RENAME') if 'cancel' in req.args: req.redirect(get_resource_url(self.env, page.resource, req.href)) old_name, old_version = page.name, page.version new_name = req.args.get('new_name', '') new_name = re.sub(r'/{2,}', '/', new_name.strip('/')) redirect = req.args.get('redirect') # verify input parameters warn = None if not new_name: warn = _("A new name is mandatory for a rename.") elif not validate_page_name(new_name): warn = _("The new name is invalid (a name which is separated " "with slashes cannot be '.' or '..').") elif new_name == old_name: warn = _("The new name must be different from the old name.") elif WikiPage(self.env, new_name).exists: warn = _("The page %(name)s already exists.", name=new_name) if warn: add_warning(req, warn) return self._render_confirm_rename(req, page, new_name) with self.env.db_transaction as db: page.rename(new_name) if redirect: redirection = WikiPage(self.env, old_name, db=db) redirection.text = _('See [wiki:"%(name)s"].', name=new_name) author = get_reporter_id(req) comment = u'[wiki:"%s@%d" %s] \u2192 [wiki:"%s"].' % ( new_name, old_version, old_name, new_name) redirection.save(author, comment, req.remote_addr) add_notice(req, _("The page %(old_name)s has been renamed to " "%(new_name)s.", old_name=old_name, new_name=new_name)) if redirect: add_notice(req, _("The page %(old_name)s has been recreated " "with a redirect to %(new_name)s.", old_name=old_name, new_name=new_name)) req.redirect(req.href.wiki(old_name if redirect else new_name))
def putPage(self, req, pagename, content, attributes): """ writes the content of the page. """ page = WikiPage(self.env, pagename) if page.readonly: req.perm(page.resource).require("WIKI_ADMIN") elif not page.exists: req.perm(page.resource).require("WIKI_CREATE") else: req.perm(page.resource).require("WIKI_MODIFY") page.text = content if req.perm(page.resource).has_permission("WIKI_ADMIN"): page.readonly = attributes.get("readonly") and 1 or 0 page.save(attributes.get("author", req.authname), attributes.get("comment"), req.remote_addr) return True
def Main(opts): """ Cross your fingers and pray """ env = Environment(opts.envpath) from tractags.api import TagSystem tlist = opts.tags or split_tags(env.config.get('blog', 'default_tag', 'blog')) tags = TagSystem(env) req = Mock(perm=MockPerm()) blog = tags.query(req, ' '.join(tlist + ['realm:wiki'])) cnx = env.get_db_cnx() for resource, page_tags in list(blog): try: page = WikiPage(env, version=1, name=resource.id) _, publish_time, author, _, _ = page.get_history().next() if opts.deleteonly: page.delete() continue categories = ' '.join([t for t in page_tags if t not in tlist]) page = WikiPage(env, name=resource.id) for version, version_time, version_author, version_comment, \ _ in page.get_history(): # Currently the basename of the post url is used due to # http://trac-hacks.org/ticket/2956 #name = resource.id.replace('/', '_') name = resource.id # extract title from text: fulltext = page.text match = _title_split_match(fulltext) if match: title = match.group(1) fulltext = match.group(2) else: title = name body = fulltext print "Adding post %s, v%s: %s" % (name, version, title) insert_blog_post(cnx, name, version, title, body, publish_time, version_time, version_comment, version_author, author, categories) reparent_blog_attachments(env, resource.id, name) continue cnx.commit() if opts.delete: page.delete() continue except: env.log.debug("Error loading wiki page %s" % resource.id, exc_info=True) print "Failed to add post %s, v%s: %s" % (name, version, title) cnx.rollback() cnx.close() return 1 cnx.close() return 0
def process_request(self, req): req.perm.assert_permission('PHPDOC_VIEW') # Get request arguments path = req.args.get('path') action = req.args.get('action') link = req.args.get('link') self.log.debug('Performing %s(%s,%s)"' % (action or 'default', path, link)) # Redirect search requests. if action == 'search': req.redirect(req.href.search(q=req.args.get('query'), phpdoc='on')) if action == 'redirect': if link: # we need to really redirect if there is a link if path: req.redirect(req.href.phpdoc(path=path) + link) else: req.redirect(req.href.phpdoc(link)) else: self.log.warn("redirect without link") if req.path_info == '/phpdoc': req.redirect(req.href.phpdoc('/')) # Handle /phpdoc request if action == 'index': wiki = self.wiki_index if wiki: if WikiSystem(self.env).has_page(wiki): text = WikiPage(self.env, wiki).text else: text = 'PHPDoc index page [wiki:%s] does not exist.' % \ wiki data = {'phpdoc_text': wiki_to_html(text, self.env, req)} add_ctxtnav(req, "View %s page" % wiki, req.href.wiki(wiki)) return 'phpdoc.html', data, 'text/html' # use configured PHPDoc index path = os.path.join(self.base_path, self.default_doc, self.html_output, self.index) self.log.debug('path: %s' % (path, )) # security check path = os.path.abspath(path) if not path.startswith(self.base_path): raise TracError("Can't access paths outside of " + self.base_path) # view mimetype = mimetypes.guess_type(path)[0] if mimetype == 'text/html': add_stylesheet(req, 'phpdoc/css/phpdoc.css') # Genshi can't include an unparsed file # data = {'phpdoc': path} try: charset = (self.encoding or self.env.config['trac'].get('default_charset')) content = Markup(to_unicode(file(path).read(), charset)) data = {'phpdoc_content': content} return 'phpdoc.html', data, 'text/html' except OSError, e: raise TracError("Can't read phpdoc content: %s" % e)
def setUp(self): ProductResourceTestCase.setUp(self) page = WikiPage(self.global_env) page.name = 'TestPage' page.text = 'Bla bla' t = datetime(2001, 1, 1, 1, 1, 1, 0, utc) page.save('joe', 'Testing global', '::1', t) page.text = 'Bla bla bla' t = datetime(2002, 2, 2, 2, 2, 2, 0, utc) page.save('joe', 'Testing global 2', '::1', t) page = WikiPage(self.env1) page.name = 'TestPage' page.text = 'alb alB' t = datetime(2011, 1, 1, 1, 1, 1, 0, utc) page.save('mary', 'Testing product', '::1', t) page.text = 'Bla bla bla' t = datetime(2012, 2, 2, 2, 2, 2, 0, utc) page.save('mary', 'Testing product 2', '::1', t)
def expand_macro(self, formatter, name, content): req = formatter.req args, kwargs = parse_args(content) args += [None, None] path, limit = args[:2] limit = kwargs.pop('limit', limit) package = kwargs.pop('package', None) if 'CHANGESET_VIEW' not in req.perm: return Markup('<i>Releases not available</i>') rm = RepositoryManager(self.env) reponame, repo, path = rm.get_repository_by_path(path) rev = repo.get_youngest_rev() rev = repo.normalize_rev(rev) path = repo.normalize_path(path) if limit is None: limit = 20 else: limit = int(limit) releases = self.get_releases(repo, path, rev) # limit the releases after they have been sorted releases = releases[:1 + limit] items = [] releases = [None] + releases + [None] # some extra checks to avoid using double-slashes if reponame == '': if path == '/': path = '' else: path = '/' + path elif path == '/': path = '/' + reponame.rstrip('/') else: path = '/' + reponame.rstrip('/') + '/' + path.lstrip('/') if not package: package = path.split("/")[-1] for i in xrange(len(releases) - 2): prev, cur, next = releases[i:i + 3] if prev == None and next == None: # no releases yet, just show trunk items.append(" * " " [/browser%(path)s/trunk trunk]" " @[changeset:%(rev)s/%(reponame)s %(rev)s]" " (" "[/log%(path)s/trunk changes]" " [/changeset?new_path=%(path)s/trunk diffs]" ")" % { 'reponame': reponame, 'path': path, 'rev': cur['rev'], }) elif prev == None: # first entry = trunk items.append( " * " " [/browser%(path)s/trunk trunk]" " @[changeset:%(rev)s/%(reponame)s %(rev)s]" " (" "[/log%(path)s/trunk?revs=%(stop_rev)s-%(rev)s changes]" " [/changeset?old_path=%(path)s/tags/%(old_tag)s&new_path=%(path)s/trunk diffs]" ")" % { 'reponame': reponame, 'path': path, 'rev': cur['rev'], 'old_tag': next['version'], 'stop_rev': next['rev'], }) elif next != None: # regular releases release_page = 'release/%s-%s' % (package, cur['version']) page = WikiPage(self.env, release_page) if page.exists: release_link = " [wiki:%s release notes]" % (release_page) else: release_link = "" items.append( " * '''%(date)s'''" " [/log%(path)s/tags/%(new_tag)s %(new_tag)s] " " @[changeset:%(rev)s/%(reponame)s %(rev)s]" " by %(author)s" " (" "[/log%(path)s/trunk?revs=%(stop_rev)s-%(rev)s changes]" " [/changeset?old_path=%(path)s/tags/%(old_tag)s&new_path=%(path)s/tags/%(new_tag)s diffs]" "%(release_link)s" ")" % { 'reponame': reponame, 'path': path, 'date': cur['time'].strftime('%Y-%m-%d'), 'rev': cur['rev'], 'stop_rev': next['rev'], 'old_tag': next['version'], 'new_tag': cur['version'], 'author': cur['author'], 'release_link': release_link, }) url = self.specurl_annotate(cur) if url != None: annotate = " spec: [%s annotate]" % url items.append(annotate) # check also diff link url = self.specurl_diff(cur, next) if url != None: annotate = " [%s diff]" % url items.append(annotate) else: # last release items.append( " * '''%(date)s'''" " [/log%(path)s/tags/%(new_tag)s?rev=%(rev)s&mode=follow_copy %(new_tag)s]" " @[changeset:%(rev)s/%(reponame)s %(rev)s]" " by %(author)s" % { 'reponame': reponame, 'path': path, 'date': cur['time'].strftime('%Y-%m-%d'), 'rev': cur['rev'], 'new_tag': cur['version'], 'author': cur['author'], }) return '<div class="releases">\n' + to_unicode( wiki_to_html("\n".join(items), self.env, req)) + '</div>\n'
def _render_diff(self, req, page): if not page.exists: raise TracError( _('Version %(num)s of page "%(name)s" does not ' 'exist', num=req.args.get('version'), name=page.name)) old_version = req.args.get('old_version') if old_version: old_version = int(old_version) if old_version == page.version: old_version = None elif old_version > page.version: # FIXME: what about reverse diffs? old_version = page.resource.version page = WikiPage(self.env, page.name, version=old_version) req.perm(page.resource).require('WIKI_VIEW') latest_page = WikiPage(self.env, page.name, version=None) req.perm(latest_page.resource).require('WIKI_VIEW') new_version = int(page.version) date = author = comment = ipnr = None num_changes = 0 prev_version = next_version = None for version, t, a, c, i in latest_page.get_history(): if version == new_version: date = t author = a or 'anonymous' comment = c or '--' ipnr = i or '' else: if version < new_version: num_changes += 1 if not prev_version: prev_version = version if old_version is None or version == old_version: old_version = version break else: next_version = version if not old_version: old_version = 0 old_page = WikiPage(self.env, page.name, old_version) req.perm(old_page.resource).require('WIKI_VIEW') # -- text diffs old_text = old_page.text.splitlines() new_text = page.text.splitlines() diff_data, changes = self._prepare_diff(req, page, old_text, new_text, old_version, new_version) # -- prev/up/next links if prev_version: add_link( req, 'prev', req.href.wiki(page.name, action='diff', version=prev_version), _('Version %(num)s', num=prev_version)) add_link(req, 'up', req.href.wiki(page.name, action='history'), _('Page history')) if next_version: add_link( req, 'next', req.href.wiki(page.name, action='diff', version=next_version), _('Version %(num)s', num=next_version)) data = self._page_data(req, page, 'diff') data.update({ 'change': { 'date': date, 'author': author, 'ipnr': ipnr, 'comment': comment }, 'new_version': new_version, 'old_version': old_version, 'latest_version': latest_page.version, 'num_changes': num_changes, 'longcol': 'Version', 'shortcol': 'v', 'changes': changes, 'diff': diff_data, }) prevnext_nav(req, _('Previous Change'), _('Next Change'), _('Wiki History')) return 'wiki_diff.html', data, None
def create_hack(self, req, data, vars): import fcntl messages = [] created = False have_lock = False lockfile = open(self.lockfile, "w") try: rv = fcntl.flock(lockfile, fcntl.LOCK_EX | fcntl.LOCK_NB) if rv: raise TracError('Failed to acquire lock, error: %i' % rv) have_lock = True except IOError: messages.append( 'A hack is currently being created by another user. ' 'Please wait a few seconds, then click the "Create hack" ' 'button again.' ) if have_lock: steps_done = [] try: # Step 1: create repository paths from os import popen svn_path = 'file://%s' % \ self.env.config.get('trac', 'repository_dir') svn_path = svn_path.rstrip('/') page_name = vars['WIKINAME'] hack_path = vars['LCNAME'] paths = [ '%s/%s' % (svn_path, hack_path) ] selected_releases = data['selected_releases'] if isinstance(selected_releases, (basestring, unicode)): selected_releases = [ selected_releases, ] for release in selected_releases: if release == 'anyrelease': continue paths.append("%s/%s/%s" % \ (svn_path, hack_path, release)) cmd = '/usr/bin/op create-hack %s ' % req.authname cmd += '"New hack %s, created by %s" ' % \ (page_name, req.authname) cmd += '%s 2>&1' % ' '.join(paths) output = popen(cmd).readlines() if output: raise Exception( "Failed to create Subversion paths:\n%s" % \ '\n'.join(output) ) steps_done.append('repository') # Step 2: Add permissions from svnauthz.model import User, Path, PathAcl authz_file = self.env.config.get('trac', 'authz_file') authz = AuthzFileReader().read(authz_file) svn_path_acl = PathAcl(User(req.authname), r=True, w=True) authz.add_path(Path("/%s" % hack_path, acls = [svn_path_acl,])) AuthzFileWriter().write(authz_file, authz) steps_done.append('permissions') # Step 3: Add component component = TicketComponent(self.env) component.name = page_name component.owner = req.authname component.insert() steps_done.append('component') # Step 4: Create wiki page template_page = WikiPage(self.env, self.template) page = WikiPage(self.env, page_name) page.text = Template(template_page.text).substitute(vars) page.save(req.authname, 'New hack %s, created by %s' % \ (page_name, req.authname), '0.0.0.0') steps_done.append('wiki') # Step 5: Tag the new wiki page res = Resource('wiki', page_name) tags = data['tags'].split() + selected_releases + [data['type']] TagSystem(self.env).set_tags(req, res, tags) steps_done.append('tags') rv = fcntl.flock(lockfile, fcntl.LOCK_UN) created = True except Exception, e: try: if 'tags' in steps_done: res = Resource('wiki', page_name) tags = data['tags'].split() + selected_releases TagSystem(self.env).delete_tags(req, res, tags) if 'wiki' in steps_done: WikiPage(self.env, page_name).delete() if 'component' in steps_done: TicketComponent(self.env, page_name).delete() if 'permissions' in steps_done: authz_file = self.env.config.get('trac', 'authz_file') authz = AuthzFileReader().read(authz_file) authz.del_path(Path("/%s" % hack_path)) AuthzFileWriter().write(authz_file, authz) # TODO: rollback subversion path creation rv = fcntl.flock(lockfile, fcntl.LOCK_UN) except: self.env.log.error("Rollback failed") rv = fcntl.flock(lockfile, fcntl.LOCK_UN) self.env.log.error(e, exc_info=True) raise TracError(str(e))
def wiki_setup(tc): tc.env.config.set('wiki', 'render_unsafe_content', True) # for #9712 now = datetime.now(utc) wiki0 = WikiPage(tc.env) wiki0.name = 'Main/Sub' wiki0.text = '--' wiki0.save('joe', 'subpage', '::1', now) wiki1 = WikiPage(tc.env) wiki1.name = 'TestPage' wiki1.text = '--' wiki1.save('joe', 'normal WikiPageNames', '::1', now) wiki2 = WikiPage(tc.env) wiki2.name = 'Space 1 23' wiki2.text = '--' wiki2.save('joe', 'not a WikiPageNames', '::1', now) wiki3 = WikiPage(tc.env) wiki3.name = u"C'est l'\xe9t\xe9" wiki3.text = '--' wiki3.save('joe', 'unicode WikiPageNames', '::1', now) imt = WikiPage(tc.env) imt.name = u"InterMapTxt" imt.text = """ This is the InterMapTxt ---- {{{ MeatBall http://www.usemod.com/cgi-bin/mb.pl? # $1 in MeatBall... tsvn tsvn: complex http://server/$1/page/$2?format=txt # resource $2 in $1 over http://unused/? # Overridden in trac.ini }}} ---- {{{ nolink http://noweb }}} """ imt.save('joe', 'test InterWiki links', '::1', now) tc.env.config.set('interwiki', 'inter', 'http://inter/$1/page/$2 Resource $2 in $1') tc.env.config.set('interwiki', 'over', 'http://over/$1/page/$2') w = WikiPage(tc.env) w.name = 'FirstLevel' w.text = '--' w.save('joe', 'first level of hierarchy', '::1', now) w = WikiPage(tc.env) w.name = 'FirstLevel/SecondLevel' w.text = '--' w.save('joe', 'second level of hierarchy', '::1', now) w = WikiPage(tc.env) w.name = 'FirstLevel/SecondLevel/ThirdLevel' w.text = '--' w.save('joe', 'third level of hierarchy', '::1', now) w = WikiPage(tc.env) w.name = 'FirstLevel/SecondLevel/OtherThirdLevel' w.text = '--' w.save('joe', 'other third level of hierarchy', '::1', now)
def fetch_hacks(self, req, data, types, releases): """Return a list of hacks in the form [votes, rank, resource, tags, title] """ tag_system = TagSystem(self.env) vote_system = VoteSystem(self.env) query = 'realm:wiki (%s) (%s)' % \ (' or '.join(releases), ' or '.join(types)) self.env.log.debug(query) tagged = tag_system.query(req, query) # Limit try: limit = int(req.args.get('limit', self.limit)) data['limit_message'] = 'top %s' % limit except ValueError: data['limit_message'] = 'all' limit = 9999 data['limit'] = limit # Query q = req.args.get('q', '') data['query'] = q query = Query(q.lower()) # Build hacks list hacks = [] for resource, tags in tagged: page = WikiPage(self.env, resource.id) if q: text = page.name.lower() + page.text.lower() + ' '.join(tags) if not query(text): continue _, count, _ = vote_system.get_vote_counts(resource) match = self.title_extract.search(page.text) count_string = pluralise(count, 'vote') if match: title = '%s (%s)' % (match.group(1).strip(), count_string) else: title = '%s' % count_string hacks.append([count, None, resource, tags, title]) # Rank total_hack_count = len(hacks) hacks = sorted(hacks, key=lambda i: -i[0]) remainder = hacks[limit:] hacks = hacks[:limit] + random.sample(remainder, min(limit, len(remainder))) # Navigation #if len(hacks) >= limit: # add_ctxtnav(req, builder.a('More', href='?action=more')) # limit = len(hacks) # data['limit'] = data['limit_message'] = limit #else: # add_ctxtnav(req, 'More') #if q or limit != self.limit: # add_ctxtnav(req, builder.a('Default', href='?action=default')) #else: # add_ctxtnav(req, 'Default') #if total_hack_count > limit: # add_ctxtnav(req, builder.a('All', href='?action=all')) #else: # add_ctxtnav(req, 'All') #if limit > 10: # limit = min(limit, len(hacks)) # add_ctxtnav(req, builder.a('Less', href='?action=less')) #else: # add_ctxtnav(req, 'Less') #for i, hack in enumerate(hacks): # hack[1] = i return hacks
def _render_view(self, req, page): version = page.resource.version # Add registered converters if page.exists: for conversion in Mimeview( self.env).get_supported_conversions('text/x-trac-wiki'): conversion_href = req.href.wiki(page.name, version=version, format=conversion[0]) # or... conversion_href = get_resource_url(self.env, page.resource, req.href, format=conversion[0]) add_link(req, 'alternate', conversion_href, conversion[1], conversion[3]) data = self._page_data(req, page) if page.name == 'WikiStart': data['title'] = '' ws = WikiSystem(self.env) context = web_context(req, page.resource) higher, related = [], [] if not page.exists: if 'WIKI_CREATE' not in req.perm(page.resource): raise ResourceNotFound( _('Page %(name)s not found', name=page.name)) formatter = OneLinerFormatter(self.env, context) if '/' in page.name: parts = page.name.split('/') for i in range(len(parts) - 2, -1, -1): name = '/'.join(parts[:i] + [parts[-1]]) if not ws.has_page(name): higher.append( ws._format_link(formatter, 'wiki', '/' + name, name, False)) else: name = page.name name = name.lower() related = [ each for each in ws.pages if name in each.lower() and 'WIKI_VIEW' in req.perm('wiki', each) ] related.sort() related = [ ws._format_link(formatter, 'wiki', '/' + each, each, False) for each in related ] latest_page = WikiPage(self.env, page.name, version=None) prev_version = next_version = None if version: try: version = int(version) for hist in latest_page.get_history(): v = hist[0] if v != version: if v < version: if not prev_version: prev_version = v break else: next_version = v except ValueError: version = None prefix = self.PAGE_TEMPLATES_PREFIX templates = [ template[len(prefix):] for template in ws.get_pages(prefix) if 'WIKI_VIEW' in req.perm('wiki', template) ] # -- prev/up/next links if prev_version: add_link(req, 'prev', req.href.wiki(page.name, version=prev_version), _('Version %(num)s', num=prev_version)) parent = None if version: add_link(req, 'up', req.href.wiki(page.name, version=None), _('View latest version')) elif '/' in page.name: parent = page.name[:page.name.rindex('/')] add_link(req, 'up', req.href.wiki(parent, version=None), _("View parent page")) if next_version: add_link(req, 'next', req.href.wiki(page.name, version=next_version), _('Version %(num)s', num=next_version)) # Add ctxtnav entries if version: prevnext_nav(req, _('Previous Version'), _('Next Version'), _('View Latest Version')) else: if parent: add_ctxtnav(req, _('Up'), req.href.wiki(parent)) self._wiki_ctxtnav(req, page) # Plugin content validation fields = {'text': page.text} for manipulator in self.page_manipulators: manipulator.prepare_wiki_page(req, page, fields) text = fields.get('text', '') data.update({ 'context': context, 'text': text, 'latest_version': latest_page.version, 'attachments': AttachmentModule(self.env).attachment_data(context), 'default_template': self.DEFAULT_PAGE_TEMPLATE, 'templates': templates, 'version': version, 'higher': higher, 'related': related, 'resourcepath_template': 'wiki_page_path.html', }) add_script(req, 'common/js/folding.js') return 'wiki_view.html', data, None
def process_request(self, req): req.perm.require('WIKIMETA_VIEW') data = {} self.log.debug(" +++ in process_request") self.log.debug(dir(req.args)) self.log.debug(req.args) # first process reordering: for key in req.args.keys(): if key.startswith('reorder_'): self.log.debug(" +++ found reorder: %s" % key) reorder_args = key.split('_') self._priority_reorder(int(reorder_args[1]), int(reorder_args[2])) # data for state filter data['state_label'] = 'State:' data['state_options'] = ['all (non-obsolete)'] + STATES data['selected_state'] = 'all (non-obsolete)' if req.args.get('state_name') is not None: data['selected_state'] = req.args.get('state_name') # data for owner filter data['owner_label'] = 'Owner:' owner_tuples = self.env.get_known_users() data['owner_options'] = ['all'] + [item[0] for item in owner_tuples] data['selected_owner'] = 'all' if req.args.get('owner_name') is not None: data['selected_owner'] = req.args.get('owner_name') # data for tag filters combined_title = "" categorized_tags = self._get_categorized_tags() tag_states = [] tag_list = [] for category in categorized_tags.keys(): tag_states.append([category, 'category']) for tag in categorized_tags[category]: if req.args.get('tagfilter_%s' % tag) is not None: tag_states.append([tag, 'checked']) tag_list.append(tag) combined_title = '%s %s' % (tag, combined_title) else: tag_states.append([tag, 'unchecked']) data['tags'] = tag_states data['tags_label'] = 'Tag Filter' if len(combined_title) == 0: data['combined_title'] = 'all' else: data['combined_title'] = combined_title # check if the user requested to add a new page: newpagename = req.args.get('newpagename') if newpagename is not None and len(newpagename) > 0: newpage = WikiPage(self.env, newpagename) currently_logged_in_user = get_reporter_id(req, 'author') if data['selected_owner'] == 'all': new_owner = currently_logged_in_user else: new_owner = data['selected_owner'] if newpage.exists == False: newpage.text = 'page content goes here' newpage.save(author=currently_logged_in_user, comment='', remote_addr='127.0.0.1') # add tags and meta if data['selected_state'] == 'all (non-obsolete)': new_state = 'planned' else: new_state = data['selected_state'] new_page_meta = PageMeta(newpagename, new_owner, new_state, 0, time.time(), currently_logged_in_user) new_page_meta.insert(self.env) tag_resource(self.env, newpage.resource, old_id=None, author=currently_logged_in_user, tags=tag_list) # get a top context to render the wiki data: context = Context.from_request(req, 'wiki') self.log.debug(" +++ context: ") self.log.debug(dir(context)) self.log.debug(" +++ child: ") self.log.debug(context.child) self.log.debug(" +++ href: ") self.log.debug(context.href) self.log.debug(" +++ parent: ") self.log.debug(context.parent) # get the wiki pages: wiki_data = self._get_wiki_data(context, data['selected_state'], data['selected_owner'], tag_list) #self.log.debug(" +++ wiki_data:") #self.log.debug(wiki_data) data['wiki_data'] = wiki_data add_stylesheet(req, 'wm/css/wikimeta.css') # This tuple is for Genshi (template_name, data, content_type) # Without data the trac layout will not appear. return 'wikimeta.html', data, None
def expand_macro(self, formatter, name, args): """ Return a list of translated pages with the native language names. The list of languages supported can be configured by adding new entries to TracLanguages page. Refer to ISO 639-1 for more information. """ args, kw = parse_args(args) # first handle special cases show = u"" lang = None silent = u'silent' in args outdated = u"" if u'lang' in kw: lang = kw[u'lang'] if u'outdated' in kw: outdated = self.outdated_tx % kw[u'outdated'] if u'showproblems' in args: show += self._get_problems(silent) if u'showstatus' in args: show += self._get_status(lang) if u'showoutdated' in args: label = None if u'label_outdated' in kw: label = kw[u'label_outdated'] show += self._get_outdated(lang, label) if u'showmissing' in args: show += self._get_missing(lang) if u'showuntranslated' in args: show += self._get_untranslated(silent) if len(show): outshow = StringIO() Formatter(self.env, formatter.context).format(show, outshow) val = outshow.getvalue() val = re.sub('>\$\$\$([a-z]+?)\$\$\$<a class=".*?"', \ ' style="background-color:\\1"><a style="color:#151B8D"', val) # try again more secure in case previous fails due to Wiki engine changes val = re.sub('>\$\$\$([a-z]+?)\$\$\$', \ ' style="background-color:\\1">', val) return val page_name = formatter.context.resource.id prefix, base_page_name, lang_code = self._get_page_info(page_name) lang_link_list = [] for translation in self._get_translations(prefix, base_page_name): if translation != lang_code: page_name = self._get_translated_page(prefix, base_page_name, translation) lang_link_list.append(u" * [[wiki:/%s|%s]]" % (page_name, \ self._get_language_name(translation))) else: lang_link_list.append(u" * '''%s'''" % self._get_language_name(translation)) baselink = "" if lang_code != self.base_lang and u'revision' in kw: basepage = self._get_translated_page(prefix, base_page_name, self.base_lang) newver = WikiPage(self.env, basepage).version oldver = abs(int(kw[u'revision'])) if oldver < newver: baselink = u"\n * [[wiki:/%s?action=diff&old_version=%s|@%s - @%s]]" \ % (basepage, oldver, oldver, newver) if len(lang_link_list) <= 1: return outdated out = StringIO() Formatter(self.env, formatter.context).format(u'\n'.join(lang_link_list) \ +baselink, out) desc = u"Languages" if self.description.has_key(lang_code): desc = self.description[lang_code] return outdated + u""" <div class="wiki-toc trac-nav" style="clear:both"> <h4>%s:</h4> %s </div>""" % (desc, out.getvalue())
def process_request(self, req): req.perm.require('TAGS_VIEW') match = re.match(r'/tags/?(.*)', req.path_info) tag_id = match.group(1) and match.group(1) or None query = req.args.get('q', '') # Consider only providers, that are permitted for display. tag_system = TagSystem(self.env) all_realms = tag_system.get_taggable_realms(req.perm) if not (tag_id or query) or [r for r in all_realms if r in req.args] == []: for realm in all_realms: if realm not in self.exclude_realms: req.args[realm] = 'on' checked_realms = [r for r in all_realms if r in req.args] if query: # Add permitted realms from query expression. checked_realms.extend(query_realms(query, all_realms)) realm_args = dict(zip([r for r in checked_realms], ['on' for r in checked_realms])) # Switch between single tag and tag query expression mode. if tag_id and not re.match(r"""(['"]?)(\S+)\1$""", tag_id, re.UNICODE): # Convert complex, invalid tag ID's --> query expression. req.redirect(req.href.tags(realm_args, q=tag_id)) elif query: single_page = re.match(r"""(['"]?)(\S+)\1$""", query, re.UNICODE) if single_page: # Convert simple query --> single tag. req.redirect(req.href.tags(single_page.group(2), realm_args)) data = dict(page_title=_("Tags"), checked_realms=checked_realms) # Populate the TagsQuery form field. data['tag_query'] = tag_id and tag_id or query data['tag_realms'] = list(dict(name=realm, checked=realm in checked_realms) for realm in all_realms) if tag_id: data['tag_page'] = WikiPage(self.env, tag_system.wiki_page_prefix + tag_id) if query or tag_id: macro = 'ListTagged' # TRANSLATOR: The meta-nav link label. add_ctxtnav(req, _("Back to Cloud"), req.href.tags()) args = "%s,format=%s,cols=%s" % \ (tag_id and tag_id or query, self.default_format, self.default_cols) data['mincount'] = 0 else: macro = 'TagCloud' mincount = as_int(req.args.get('mincount', 0), self.cloud_mincount) args = mincount and "mincount=%s" % mincount or None data['mincount'] = mincount # When using the given req the page isn't rendered properly. The call # to expand_macro() leads to Chrome().render_template(req, ...). # The function render_template() breaks something in the request handling. # That used to work with Genshi. # # With this mocked req everything is just fine. mock_req = MockRequest(self.env, path_info=req.path_info, authname=req.authname, script_name=req.href()) formatter = Formatter(self.env, web_context(mock_req, Resource('tag'))) self.env.log.debug("%s macro arguments: %s", macro, args and args or '(none)') macros = TagWikiMacros(self.env) try: # Query string without realm throws 'NotImplementedError'. data['tag_body'] = checked_realms and \ macros.expand_macro(formatter, macro, args, realms=checked_realms) \ or '' data['tag_body'] = Markup(to_unicode(data['tag_body'])) except InvalidQuery as e: data['tag_query_error'] = to_unicode(e) data['tag_body'] = macros.expand_macro(formatter, 'TagCloud', '') data['realm_args'] = realm_args add_stylesheet(req, 'tags/css/tractags.css') return 'tag_view.html', data, {'domain': 'tractags'}
def assertFileContentMatchesPage(self, names): for n in names: self.assertEqual( WikiPage(self.env, n).text, self._file_content(self.tempdir, n))
def process_request(self, req): """Process the request """ base = self.get_mypage_base(req.authname) tzinfo = getattr(req, 'tz', None) now = datetime.now(tzinfo or localtz) today = format_date(now, 'iso8601', tzinfo) today_page_name = base + today today_page = WikiPage(self.env, today_page_name) if today_page.exists: req.redirect(req.href.wiki(today_page_name, action='edit')) # create page of the day for today if 'WIKI_CREATE' not in req.perm(today_page.resource): raise ResourceNotFound(_("Can't create the page of the day.")) ws = WikiSystem(self.env) def get_page_text(pagename): if ws.has_page(pagename): page = WikiPage(self.env, pagename) if 'WIKI_VIEW' in req.perm(page.resource): self.log.debug("get_page_text(%s) -> %s", pagename, page.text) return page.text self.log.debug("get_page_text(%s) -> None", pagename) # retrieve page template template_name = 'PageTemplates/MyPage' mytemplate_name = '/'.join([template_name, req.authname]) template_text = get_page_text(mytemplate_name) if template_text is None: template_text = get_page_text(template_name) text = last_page_text = last_page_quoted = None if template_text is not None: # retrieve previous "page of the day", if any all_mypages = self.get_all_mypages(base) last = bisect(all_mypages, today_page_name) - 1 self.log.debug("Pos of today %s in %r is %d", today_page_name, all_mypages, last) last_page_name = all_mypages[last] if last >= 0 else None last_page_link = '' if last_page_name: last_page_link = '[[%s]]' % last_page_name last_page_text = get_page_text(last_page_name) if last_page_text is not None: last_page_quoted = '\n'.join( ['> ' + line for line in last_page_text.splitlines()]) today_user = user_time(req, format_date, now, tzinfo=tzinfo) author = req.session.get('name') or get_reporter_id(req) text = template_text \ .replace(self.tokens['date'][0], today_user) \ .replace(self.tokens['isodate'][0], today) \ .replace(self.tokens['user'][0], req.authname) \ .replace(self.tokens['author'][0], author) \ .replace(self.tokens['lp_link'][0], last_page_link) \ .replace(self.tokens['lp_name'][0], last_page_name or '') \ .replace(self.tokens['lp_text'][0], last_page_text or '') \ .replace(self.tokens['lp_quoted'][0], last_page_quoted or '') req.redirect(req.href.wiki(today_page_name, action='edit', text=text))
def _update_data(self, req): # Update narcissus_data table with info to be visualised db = self.env.get_db_cnx() cursor = db.cursor() cursor.execute('select max(dtime) from narcissus_data') start_rev = 1 last_update = cursor.fetchone()[0] if not last_update: # no data yet, update data from the beginning cursor.execute('select min(time) from wiki') last_update = cursor.fetchone()[0] else: # update data from this change cursor.execute( 'select eid from narcissus_data where resource = "svn"') for row in cursor: if int(row[0]) > start_rev: start_rev = int(row[0]) start_rev += 1 members = self._settings.members # populate table with wiki activity cursor.execute( '''select name, min(version), count(version), min(time) from wiki where time > %f group by name order by min(time)''' % last_update) for page, start_version, versions, _ in cursor: versions += start_version # page has been added if start_version == 1: new_page = WikiPage(self.env, page, 1) add = len(new_page.text.splitlines()) if (new_page.author in members) and (self._to_microseconds( new_page.time) > last_update): self._insert_data(new_page.author, new_page.time, new_page.name, 'wiki', 'add', add) start_version += 1 for i in xrange(start_version, versions): # page has been edited old_page, edit_page = WikiPage(self.env, page, i - 1), WikiPage( self.env, page, i) if (edit_page.author in members) and (self._to_microseconds( edit_page.time) > last_update): changes = self._my_diff(old_page.text, edit_page.text) edit = self._edit_newlines(changes) if edit: self._insert_data(edit_page.author, edit_page.time, edit_page.name, 'wiki', 'edit', edit) # populate table with ticket activity credits = self._settings.credits cursor.execute('select id from ticket') for row in cursor: ticket = Ticket(self.env, row[0]) # ticket has been opened if ticket['reporter'] in members and self._to_microseconds( ticket.time_created) > last_update: self._insert_data(ticket['reporter'], ticket.time_created, ticket.id, 'ticket', 'open', 1) # FIXME for dtime, author, field, _, newvalue, _ in ticket.get_changelog(): if author in members and self._to_microseconds( dtime) > last_update: if field == 'comment': # ticket has received comment self._insert_data(author, dtime, ticket.id, 'ticket', 'comment', credits['comment']) elif newvalue == 'assigned': # ticket has been accepted self._insert_data(author, dtime, ticket.id, 'ticket', 'accept', credits['accept']) elif field == 'resolution': # ticket has been closed, reopened closures only count as a change reopened = False for inner_time, _, _, _, _, _ in ticket.get_changelog( ): if inner_time > dtime and field == 'resolution': reopened = True if reopened: self._insert_data(author, dtime, ticket.id, 'ticket', 'update', credits['update']) else: if ticket['owner'] in members: self._insert_data(ticket['owner'], dtime, ticket.id, 'ticket', 'close', credits['close']) if author != ticket['owner']: self._insert_data(author, dtime, ticket.id, 'ticket', 'proxy close', credits['update']) else: # ticket has been changed self._insert_data(author, dtime, ticket.id, 'ticket', 'update', 1) # FIXME # populate table with svn activity repos = self.env.get_repository() youngest_rev = str(repos.youngest_rev or 0).split(':')[0] try: youngest_rev = int(youngest_rev) + 1 except: youngest_rev = 0 for rev in xrange(start_rev, youngest_rev): cs = repos.get_changeset(rev) add, edit = 0, 0 for path, _, change, base_path, base_rev in cs.get_changes(): if change == 'add': add += self._svn_add_newlines(repos, path, rev) elif change == 'edit': diff_args = { 'old_path': base_path, 'old_rev': base_rev, 'new_path': path or '/', 'new_rev': rev } changes = self._my_svn_diff(repos, diff_args) if changes: edit += self._edit_newlines(changes) valid_user = cs.author in members if not valid_user: for u, n, e in self.env.get_known_users(): if e != None and e in cs.author: valid_user = True if add and valid_user: self._insert_data(cs.author, cs.date, rev, 'svn', 'add', add) if edit and valid_user: self._insert_data(cs.author, cs.date, rev, 'svn', 'edit', edit) db.commit()
def expand_macro(self, formatter, name, args): req = formatter.req tag_system = TagSystem(self.env) all_releases = natural_sort([r.id for r, _ in tag_system.query(req, 'realm:wiki release')]) all_categories = sorted([r.id for r, _ in tag_system.query(req, 'realm:wiki type')]) hide_release_picker = False hide_fieldset_legend = False hide_fieldset_description = False other = [] if args: categories = [] releases = [] for arg in args.split(): if arg in all_releases: hide_release_picker = True releases.append(arg) elif arg in all_categories: categories.append(arg) else: other.append(arg) if len(categories) or len(releases): hide_fieldset_description = True if not len(categories): categories = all_categories elif len(categories) == 1: hide_fieldset_legend = True if not len(releases): releases = all_releases else: categories = all_categories releases = all_releases if 'update_th_filter' in req.args: show_releases = req.args.get('release', ['0.11']) if isinstance(show_releases, basestring): show_releases = [show_releases] req.session['th_release_filter'] = ','.join(show_releases) else: show_releases = req.session.get('th_release_filter', '0.11').split(',') output = "" if not hide_release_picker: style = "text-align:right; padding-top:1em; margin-right:5em;" form = builder.form('\n', style=style, method="get") style = "font-size:xx-small;" span = builder.span("Show hacks for releases:", style=style) for version in releases: inp = builder.input(version, type_="checkbox", name="release", value=version) if version in show_releases: inp(checked="checked") span(inp, '\n') style = "font-size:xx-small; padding:0; border:solid 1px black;" span(builder.input(name="update_th_filter", type_="submit", style=style, value="Update"), '\n') form('\n', span, '\n') output = "%s%s\n" % (output, form) def link(resource): return render_resource_link(self.env, formatter.context, resource, 'compact') for category in categories: page = WikiPage(self.env, category) match = self.title_extract.search(page.text) if match: cat_title = '%s' % match.group(1).strip() cat_body = self.title_extract.sub('', page.text, 1) else: cat_title = '%s' % category cat_body = page.text cat_body = self.self_extract.sub('', cat_body).strip() style = "padding:1em; margin:0em 5em 2em 5em; border:1px solid #999;" fieldset = builder.fieldset('\n', style=style) if not hide_fieldset_legend: legend = builder.legend(style="color: #999;") legend(builder.a(cat_title, href=self.env.href.wiki(category))) fieldset(legend, '\n') if not hide_fieldset_description: fieldset(builder.p(wiki_to_html(cat_body, self.env, req))) ul = builder.ul('\n', class_="listtagged") query = 'realm:wiki (%s) %s %s' % \ (' or '.join(show_releases), category, ' '.join(other)) lines = 0 for resource, tags in tag_system.query(req, query): # filter out the page used to make important tags # persistent if resource.id == "tags/persistent": continue lines += 1 li = builder.li(link(resource), ': ') page = WikiPage(self.env, resource) match = self.title_extract.search(page.text) description = "''no description available''" if match: if match.group(1): description = match.group(1).strip() li(wiki_to_oneliner(description, self.env, req=req)) if tags: if hide_fieldset_legend == False and category in tags: tags.remove(category) self.log.debug("hide %s: no legend" % category) for o in other: if o in tags: tags.remove(o) rendered_tags = [ link(resource('tag', tag)) for tag in natural_sort(tags) ] span = builder.span(style="font-size:xx-small;") span(' (tags: ', rendered_tags[0], [(', ', tag) for tag in rendered_tags[1:]], ')') li(span) ul(li, '\n') if lines: fieldset(ul, '\n') else: message = "No results for %s." % \ (hide_release_picker and "this version" or "your selection") fieldset(builder.p(builder.em(message)), '\n') output = "%s%s\n" % (output, fieldset) return output
def render_new(self, req, data, hacks): req.perm.require('HACK_CREATE') tag_system = TagSystem(self.env) hacks = list(hacks) hack_names = set(r[2].id for r in hacks) users = set(u.id for u, _ in tag_system.query(req, 'realm:wiki user')) exclude = hack_names.union(users).union(data['types']).union(data['releases']) cloud = {} for votes, rank, resource, tags, title in hacks: for tag in tags: if tag in exclude: continue try: cloud[tag] += 1 except KeyError: cloud[tag] = 1 # Pick the top 25 tags + a random sample of 10 from the rest. cloud = sorted(cloud.items(), key=lambda i: -i[1]) remainder = cloud[25:] cloud = dict(cloud[:25] + random.sample(remainder, min(10, len(remainder)))) # Render the cloud min_px = 8 max_px = 20 def cloud_renderer(tag, count, percent): self.env.log.debug("cloud: %s = %2.2f%%" % (tag, percent * 100)) return builder.a(tag, href='#', style='font-size: %ipx' % int(min_px + percent * (max_px - min_px))) data['cloud'] = render_cloud(self.env, req, cloud, cloud_renderer) add_script(req, 'common/js/wikitoolbar.js') add_script(req, 'common/js/folding.js') data['focus'] = 'name' # Populate data with form submission if req.method == 'POST' and 'create' in req.args or 'preview' in req.args: data.update(req.args) context = self.form.validate(data) data['form_context'] = context vars = {} vars['OWNER'] = req.authname vars['WIKINAME'] = get_page_name(data['name'], data['type']) vars['TYPE'] = data.setdefault('type', 'plugin') vars['TITLE'] = data.setdefault('title', 'No title available') vars['LCNAME'] = vars['WIKINAME'].lower() vars['SOURCEURL'] = '%s/%s' % (self.svnbase, vars['LCNAME']) vars['DESCRIPTION'] = data.setdefault('description', 'No description available') vars['EXAMPLE'] = data.setdefault('example', 'No example available') if 'create' in req.args and not context.errors: success, message = self.create_hack(req, data, vars) if success: target = '%s?%s' % \ (req.href.wiki(vars['WIKINAME']), 'hack=created') req.redirect(target) raise RequestDone else: add_warning(req, message) elif 'preview' in req.args and not context.errors: page = WikiPage(self.env, self.template) if not page.exists: raise TracError('New hack template %s does not exist.' % \ self.template) template = Template(page.text).substitute(vars) template = re.sub(r'\[\[ChangeLog[^\]]*\]\]', 'No changes yet', template) data['page_preview'] = wiki_to_html(template, self.env, req) else: data['form_context'] = None data['type'] = 'plugin' data['release'] = ['0.11'] self.env.log.debug('MUPPETS AHOY') return 'hacks_new.html', data, None
def test_tracguide_is_readonly(self): from trac.wiki.model import WikiPage for name in ('TracGuide', 'TracInstall', 'TracUpgrade'): self.assertTrue(WikiPage(self.env, name).readonly) for name in ('SandBox', 'WikiStart', 'InterMapTxt'): self.assertFalse(WikiPage(self.env, name).readonly)
def _insert_templates(self): page = WikiPage(self.env) page.name = 'PageTemplates/TheTemplate' page.text = 'The template below /PageTemplates' page.save('trac', 'create page') page = WikiPage(self.env) page.name = 'TheTemplate' page.text = 'The template below /' page.save('trac', 'create page')
def process_request(self, req): req.perm.require('TAGS_VIEW') match = re.match(r'/tags/?(.*)', req.path_info) tag_id = match.group(1) and match.group(1) or None query = req.args.get('q', '') # Consider only providers, that are permitted for display. realms = [p.get_taggable_realm() for p in self.tag_providers if (not hasattr(p, 'check_permission') or \ p.check_permission(req.perm, 'view'))] if not (tag_id or query) or [r for r in realms if r in req.args] == []: for realm in realms: if not realm in self.exclude_realms: req.args[realm] = 'on' checked_realms = [r for r in realms if r in req.args] if query: # Add permitted realms from query expression. checked_realms.extend(query_realms(query, realms)) realm_args = dict( zip([r for r in checked_realms], ['on' for r in checked_realms])) # Switch between single tag and tag query expression mode. if tag_id and not re.match(r"""(['"]?)(\S+)\1$""", tag_id, re.UNICODE): # Convert complex, invalid tag ID's --> query expression. req.redirect(req.href.tags(realm_args, q=tag_id)) elif query: single_page = re.match(r"""(['"]?)(\S+)\1$""", query, re.UNICODE) if single_page: # Convert simple query --> single tag. req.redirect(req.href.tags(single_page.group(2), realm_args)) data = dict(page_title=_("Tags"), checked_realms=checked_realms) # Populate the TagsQuery form field. data['tag_query'] = tag_id and tag_id or query data['tag_realms'] = list( dict(name=realm, checked=realm in checked_realms) for realm in realms) if tag_id: page_name = tag_id page = WikiPage(self.env, page_name) data['tag_page'] = page macros = TagWikiMacros(self.env) if query or tag_id: # TRANSLATOR: The meta-nav link label. add_ctxtnav(req, _("Back to Cloud"), req.href.tags()) macro = 'ListTagged' args = "%s,format=%s,cols=%s" % \ (tag_id and tag_id or query, self.default_format, self.default_cols) data['mincount'] = None else: macro = 'TagCloud' mincount = as_int(req.args.get('mincount', None), self.cloud_mincount) args = mincount and "mincount=%s" % mincount or None data['mincount'] = mincount formatter = Formatter(self.env, Context.from_request(req, Resource('tag'))) self.env.log.debug("Tag macro arguments: %s", args and args or '(none)') try: # Query string without realm throws 'NotImplementedError'. data['tag_body'] = checked_realms and \ macros.expand_macro(formatter, macro, args, realms=checked_realms) \ or '' except InvalidQuery, e: data['tag_query_error'] = to_unicode(e) data['tag_body'] = macros.expand_macro(formatter, 'TagCloud', '')
def process_request(self, req): page = req.args.get('page', None) location = req.args.get('location', None) theme = req.args.get('theme', 'default') if not page: raise TracError('Invalid S5 template') page = WikiPage(self.env, name=page) if not page.exists: raise TracError('Invalid S5 template "%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 = [] def htmlify(text): return wiki_to_html(text, self.env, req) for line in page_text.splitlines(): match = self.heading_re.match(line) if match: # Insert accumulated text into appropiate location if in_section == 1: title_page = htmlify(text) elif in_section == 2: text = self.fixup_re.sub(r'\1', text) slides.append({ 'body': htmlify(text), 'handout': htmlify(handout) }) if match.lastgroup == 'title': title = match.group(match.lastgroup) html_title = htmlify(title) title = html_title.plaintext() in_section = 1 else: in_section = 2 text = '' text += line + '\n' if in_section == 1: title_page = htmlify(text) elif in_section == 2: text = self.fixup_re.sub(r'\1', text) slides.append({'body': htmlify(text), 'handout': htmlify(handout)}) req.hdf['theme'] = theme req.hdf['title'] = title req.hdf['html_title'] = html_title req.hdf['location'] = location req.hdf['title_page'] = title_page req.hdf['slides'] = slides return 's5.cs', None
def _render_diff(self, req, db, page): req.perm.assert_permission('WIKI_VIEW') if not page.exists: raise TracError, "Version %s of page %s does not exist" \ % (req.args.get('version'), page.name) add_stylesheet(req, 'common/css/diff.css') req.hdf['title'] = escape(page.name) + ' (diff)' # Ask web spiders to not index old versions req.hdf['html.norobots'] = 1 old_version = req.args.get('old_version') if old_version: old_version = int(old_version) if old_version == page.version: old_version = None elif old_version > page.version: old_version, page = page.version, \ WikiPage(self.env, page.name, old_version) info = { 'version': page.version, 'history_href': escape(self.env.href.wiki(page.name, action='history')) } num_changes = 0 old_page = None for version, t, author, comment, ipnr in page.get_history(): if version == page.version: if t: info['time'] = format_datetime(t) info['time_delta'] = pretty_timedelta(t) info['author'] = escape(author or 'anonymous') info['comment'] = escape(comment or '--') info['ipnr'] = escape(ipnr or '') else: num_changes += 1 if version < page.version: if (old_version and version == old_version) or \ not old_version: old_page = WikiPage(self.env, page.name, version) info['num_changes'] = num_changes info['old_version'] = version break req.hdf['wiki'] = info diff_style, diff_options = get_diff_options(req) oldtext = old_page and old_page.text.splitlines() or [] newtext = page.text.splitlines() context = 3 for option in diff_options: if option.startswith('-U'): context = int(option[2:]) break if context < 0: context = None changes = hdf_diff(oldtext, newtext, context=context, ignore_blank_lines='-B' in diff_options, ignore_case='-i' in diff_options, ignore_space_changes='-b' in diff_options) req.hdf['wiki.diff'] = changes
def read_file(name): text[name] = file("wiki/" + name).read().decode('utf-8') page = WikiPage(env) page.name = name page.text = '--' page.save('', '', '::1', 0)
def _render_editor(self, req, page, action='edit', has_collision=False): if has_collision: if action == 'merge': page = WikiPage(self.env, page.name, version=None) req.perm(page.resource).require('WIKI_VIEW') else: action = 'collision' if not page.exists: req.perm(page.resource).require('WIKI_CREATE') else: req.perm(page.resource).require('WIKI_MODIFY') original_text = page.text comment = req.args.get('comment', '') if 'text' in req.args: page.text = req.args.get('text') elif 'template' in req.args: template = self.PAGE_TEMPLATES_PREFIX + req.args.get('template') template_page = WikiPage(self.env, template) if template_page and template_page.exists and \ 'WIKI_VIEW' in req.perm(template_page.resource): page.text = template_page.text elif 'version' in req.args: old_page = WikiPage(self.env, page.name, version=int(req.args['version'])) req.perm(page.resource).require('WIKI_VIEW') page.text = old_page.text comment = _("Reverted to version %(version)s.", version=req.args['version']) if action in ('preview', 'diff'): page.readonly = 'readonly' in req.args author = get_reporter_id(req, 'author') defaults = {'editrows': 20} prefs = dict((key, req.session.get('wiki_%s' % key, defaults.get(key))) for key in ('editrows', 'sidebyside')) if 'from_editor' in req.args: sidebyside = req.args.get('sidebyside') or None if sidebyside != prefs['sidebyside']: req.session.set('wiki_sidebyside', int(bool(sidebyside)), 0) else: sidebyside = prefs['sidebyside'] if sidebyside: editrows = max(int(prefs['editrows']), len(page.text.splitlines()) + 1) else: editrows = req.args.get('editrows') if editrows: if editrows != prefs['editrows']: req.session.set('wiki_editrows', editrows, defaults['editrows']) else: editrows = prefs['editrows'] data = self._page_data(req, page, action) context = web_context(req, page.resource) data.update({ 'context': context, 'author': author, 'comment': comment, 'edit_rows': editrows, 'sidebyside': sidebyside, 'scroll_bar_pos': req.args.get('scroll_bar_pos', ''), 'diff': None, 'attachments': AttachmentModule(self.env).attachment_data(context), 'show_readonly_checkbox': ReadonlyWikiPolicy.__name__ in self.config.get('trac', 'permission_policies') }) if action in ('diff', 'merge'): old_text = original_text.splitlines() if original_text else [] new_text = page.text.splitlines() if page.text else [] diff_data, changes = self._prepare_diff(req, page, old_text, new_text, page.version, '') data.update({ 'diff': diff_data, 'changes': changes, 'action': 'preview', 'merge': action == 'merge', 'longcol': 'Version', 'shortcol': 'v' }) elif sidebyside and action != 'collision': data['action'] = 'preview' self._wiki_ctxtnav(req, page) Chrome(self.env).add_wiki_toolbars(req) Chrome(self.env).add_auto_preview(req) add_script(req, 'common/js/folding.js') return 'wiki_edit.html', data, None
# 得到帮助文件名 # 不应该使用wiki-default,应该使用zhwiki-default目录的listdir() # 因为有可以没有一些页面的中文版本 help_zh = os.listdir(curdir + '/zhwiki-default') # \n 是后面安全去除添加内容的重要凭据 headString = '\n\n[Zh%s 中文版本][[BR]]%s\n\n\n' headStringCN = '\n\n%s\n\n\n' for docName in help_zh: # 防止.svn目录 if not os.path.isdir(curdir + '/zhwiki-default/' + docName): print 'editing %s' % docName # 取英文文件名 doc = docName[2:] # 英文文件 page = WikiPage(myEnv, doc) if page.version == 0: print '%s no exist!' continue seealso = seeAlso.get(doc, ['']) # %的两边要达到统一编码 addString = headString % (doc, seealso[0].encode('utf8')) addString = addString.decode('utf8') page.text = addString + page.text page.save('Trac', '', '') # 中文文件 page = WikiPage(myEnv, docName) if page.version == 0: print '%s no exist!' continue
def check_permission(self, action, username, resource, perm): if resource and resource.realm == 'wiki' and \ action in ('WIKI_DELETE', 'WIKI_MODIFY', 'WIKI_RENAME'): page = WikiPage(self.env, resource) if page.readonly and 'WIKI_ADMIN' not in perm(resource): return False
def get_resource_url(self, resource, href, **kwargs): page = WikiPage(self.env, resource.id) if page.exists: return get_resource_url(self.env, page.resource, href, **kwargs) return href("tags/'%s'" % unicode(resource.id).replace("'", "\\'"))
def setUp(self): self.env = EnvironmentStub(enable=[NewTitleIndexMacro]) page = WikiPage(self.env) page.name = 'NewTitleIndexMacroDefinitions' page.save('admin', 'NewTitleIndexMacro definitions')
def _generate_blog(self, req, args, kwargs): """Extract the blog pages and fill the HDF. *args is a list of tags to use to limit the blog scope **kwargs are any aditional keyword arguments that are needed """ tallies = {} parms = self._get_display_params(req, kwargs) tagged_pages, tlist = self._initialize_tags(args, kwargs) poststart, postend, default_times = self._get_time_range(parms, req, kwargs) # The blog can be displayed in various formats depending on the values # of the parameters. The two main methods/displays are: # * Fixed number of posts, ie. always show the last 5 posts. # * All posts in a given date range, ie. all posts for a given month. # Issues with the first method is that all posts have to be read, and # then sorted by date before the selection can be made, as we are not # guaranteed any specific order from the tag retrieval. # # Issues with the second are likewise. However, with the second, while # we still need to read in all of the posts, we can drop those that are # out of range in the process, so no extra sorting need be done. # # An option for parsing would be: # for each tagged post: # load post # save post_time and page name in list # sort the list # Formatting # # Create a dictionary of page names keyed by the post date. Create a # sorted (decending) list of post date timestamps. for p in tagged_pages: page = WikiPage(self.env, version=1, name=p) version, post_time, author, comment, ipnr = page.get_history( ).next() posts[post_time] = p # We also take time to update our tallies self._tally(tallies, post_time, p) continue post_times = posts.keys() post_times.sort() post_times.reverse() # Slice the list of post times down to those posts that fall in the # selected time frame and/or number of posts. if default_times and parms['num_posts']: post_times = post_times[:parms['num_posts']] else: i = 0 maxindex = len(post_times) while (i < maxindex) and (post_times[i] < poststart): i += 1 start_index = i while (i < maxindex) and (post_times[i] <= postend): i += 1 stop_index = i post_times = post_times[start_index:stop_index] if parms['num_posts'] and (parms['num_posts'] <= len(post_times)): post_times = post_times[:parms['num_posts']] # Now that we have the list of pages that we are going to use, what now? # We need the following information: #- * formatted post time #- * truncated(?) version of page to display # * list of tags to display in "tagged under" # * link name (tag) # * tag name (tag) # * last tag indicator #- * page name #- * link to wiki page (read_post) #- * author #- * comment (?) # * whether or not tags are present # * whether or not more tags are available #- * whether or not the post has been updated #- * update time entries = {} for post in post_times: page = WikiPage(self.env, name=posts[post]) version, modified, author, comment, ipnr = page.get_history().next() # Truncate the post text if necessary and format for display post_text = wiki_to_nofloat_html(self._trin_page(page.text), self.env, req, macro_blacklist=parms['macro_blacklist']) # Format the page time for display post_time = format_datetime(post_time, format=parms['date_format']) # Create the link to the full post text read_post_link = wiki_to_oneliner(parms['read_post'] % posts[post], self.env), # Set whether or not the page has been modified post_modified = ((modified != post) and parms['mark_updated']) # Create post modified string. If {{{post_modified}}} is false, # this string is simply ignored. modified_notice = format_datetime(modified, format=parms['date_format']) data = { 'name' : posts[post], 'wiki_text' : post_text, 'time' : post_time, 'author' : author, # need to make sure this is the orig. 'comment' : comment, 'modified' : post_modified, 'mod_time' : modified_notice, 'wiki_link' : read_post_link, 'tags' : { 'present' : tags_present, 'tags' : page_tags, 'more' : more_tags, }, } entries[post_time] = data for blog_entry in blog: pagetags = [x for x in self.tags.get_name_tags(blog_entry) if x not in tlist] tagtags = [] for i, t in enumerate(pagetags[:3]): d = { 'link' : t, 'name' : t, 'last' : i == 2, } tagtags.append(d) continue data = { 'tags' : { 'present' : len(pagetags), 'tags' : tagtags, 'more' : len(pagetags) > 3 or 0, }, } continue # mark the last post so that we don't display a line after the last post if post_times: entries[post_times[-1]]['last'] = 1 # fill the HDF with the blog entries req.hdf['blog.entries'] = [entries[x] for x in post_times] # set link name for blog posts bloglink = self.env.config.get('blog', 'new_blog_link', 'New Blog Post') req.hdf['blog.newblog'] = bloglink # generate calendar hidecal = self._choose_value('hidecal', req, kwargs) if not hidecal: self._generate_calendar(req, tallies) req.hdf['blog.hidecal'] = hidecal pass
def process_request(self, req): action = req.args.get('action', 'view') pagename = req.args.get('page', self.START_PAGE) version = None if req.args.get('version'): # Allow version to be empty version = req.args.getint('version') old_version = req.args.getint('old_version') if pagename.startswith('/') or pagename.endswith('/') or \ '//' in pagename: pagename = re.sub(r'/{2,}', '/', pagename.strip('/')) req.redirect(req.href.wiki(pagename)) if not validate_page_name(pagename): raise TracError(_("Invalid Wiki page name '%(name)s'", name=pagename)) page = WikiPage(self.env, pagename) versioned_page = WikiPage(self.env, pagename, version) req.perm(versioned_page.resource).require('WIKI_VIEW') if version and versioned_page.version != version: raise ResourceNotFound( _('No version "%(num)s" for Wiki page "%(name)s"', num=version, name=page.name)) add_stylesheet(req, 'common/css/wiki.css') if req.method == 'POST': if action == 'edit': if 'cancel' in req.args: req.redirect(req.href.wiki(page.name)) has_collision = version != page.version for a in ('preview', 'diff', 'merge'): if a in req.args: action = a break versioned_page.text = req.args.get('text') valid = self._validate(req, versioned_page) if action == 'edit' and not has_collision and valid: return self._do_save(req, versioned_page) else: return self._render_editor(req, page, action, has_collision) elif action == 'edit_comment': self._do_edit_comment(req, versioned_page) elif action == 'delete': self._do_delete(req, versioned_page) elif action == 'rename': return self._do_rename(req, page) elif action == 'diff': style, options, diff_data = get_diff_options(req) contextall = diff_data['options']['contextall'] req.redirect(req.href.wiki(versioned_page.name, action='diff', old_version=old_version, version=version, contextall=contextall or None)) else: raise HTTPBadRequest(_("Invalid request arguments.")) elif action == 'delete': return self._render_confirm_delete(req, page) elif action == 'rename': return self._render_confirm_rename(req, page) elif action == 'edit': return self._render_editor(req, page) elif action == 'edit_comment': return self._render_edit_comment(req, versioned_page) elif action == 'diff': return self._render_diff(req, versioned_page) elif action == 'history': return self._render_history(req, versioned_page) else: format = req.args.get('format') if format: Mimeview(self.env).send_converted(req, 'text/x-trac-wiki', versioned_page.text, format, versioned_page.name) return self._render_view(req, versioned_page)
def _change_page(self, name): page = WikiPage(self.env, name) page.text = random_paragraph() page.save('user2', 'Page changed.')