Ejemplo n.º 1
0
def execute(hdf, args, env):
    authname = hdf.getValue("trac.authname", "anonymous")
    db = env.get_db_cnx()
    perm = trac.perm.PermissionCache(db, authname)
    pagename = hdf.getValue("args.page", "WikiStart")
    page = WikiPage(pagename, None, perm, db)
    wikipreview = hdf.getValue("args.preview", "")
    appendonly = (args == 'appendonly')
    readonlypage = int(hdf.getValue("wiki.readonly", "0"))
    # Can this user add a comment to this page?
    cancomment = not readonlypage
    # Is this an "append-only" comment or are we an administrator?
    if perm.has_permission(trac.perm.WIKI_ADMIN) or appendonly:
        cancomment = True

    if not cancomment:
        raise TracError('Error: Insufficient privileges to AddComment')

    disabled = ''
    comment = hdf.getValue("args.addcomment", "")
    preview = hdf.getValue("args.previewaddcomment", "")
    cancel = hdf.getValue("args.canceladdcomment", "")
    submit = hdf.getValue("args.submitaddcomment", "")
    if not cancel:
        authname = hdf.getValue("args.authoraddcomment", authname)

    # Ensure [[AddComment]] is not present in comment, so that infinite
    # recursion does not occur.
    comment = re.sub('(^|[^!])(\[\[AddComment)', '\\1!\\2', comment)

    out = StringIO()
    if wikipreview or not (perm.has_permission(trac.perm.WIKI_MODIFY) or appendonly):
        disabled = ' disabled="disabled"'

    # If we are submitting or previewing, inject comment as it should look
    if cancomment and comment and (preview or submit):
        if preview:
            out.write("<div class='wikipage' id='preview'>\n")
        out.write("<h4 id='commentpreview'>Comment by %s on %s</h4>\n<p>\n%s\n</p>\n" % (authname, time.strftime('%c', time.localtime()), wiki_to_html(comment, hdf, env, db)))
        if preview:
            out.write("</div>\n")

    # When submitting, inject comment before macro
    if comment and submit:
        submitted = False
        newtext = StringIO()
        for line in page.text.splitlines():
            if line.find('[[AddComment') == 0:
                newtext.write("==== Comment by %s on %s ====\n%s\n\n" % (authname, time.strftime('%c', time.localtime()), comment))
                submitted = True
            newtext.write(line + "\n")
        if submitted:
            # XXX Is this the dodigest hack ever? This is needed in 
            # "appendonly" mode when the page is readonly. XXX
            if appendonly:
                perm.expand_meta_permission('WIKI_ADMIN');
            page.set_content(newtext.getvalue())
            # TODO: How do we get remote_addr from a macro?
            page.commit(authname, 'Comment added', None)
            comment = ""
        else:
            out.write("<div class='system-message'><strong>ERROR: [[AddComment]] macro call must be the only content on its line. Could not add comment.</strong></div>\n")

    out.write("<form action='%s#commentpreview' method='post'>\n" % env.href.wiki(pagename))
    out.write("<fieldset>\n<legend>Add comment</legend>\n")
    out.write("<div class='field'>\n<textarea id='addcomment' name='addcomment' cols='80' rows='5'%s>" % disabled)
    if wikipreview:
        out.write("Page preview...")
    elif not cancel:
        out.write(comment)
    out.write("</textarea>\n")
    out.write("</div>\n")
    out.write('<div class="field">\n<label for="authoraddcomment">Your email or username:</label>\n<br/><input id="authoraddcomment" type="text" name="authoraddcomment" size="30" value="%s" />\n</div>' % authname)
    out.write("<div class='field'>\n<input size='30' type='submit' name='submitaddcomment' value='Add comment'%s/>\n" % disabled)
    out.write("<input type='submit' name='previewaddcomment' value='Preview comment'%s/>\n" % disabled)
    out.write("<input type='submit' name='canceladdcomment' value='Cancel'%s/>\n</div>\n" % disabled)
    out.write("<script type='text/javascript'>\naddWikiFormattingToolbar(document.getElementById('addcomment'));\n</script>\n")
    out.write("</fieldset>\n</form>\n")
    return out.getvalue()# + "<pre>" + hdf.dump() + "</pre>"
Ejemplo n.º 2
0
def execute(hdf, template, env):
    out = StringIO()
    errors = []
    authname = hdf.getValue("trac.authname", "anonymous")
    if not template:
        raise TracError("No template page supplied")
    if authname == "anonymous":
        errors.append(
            'You need to <a href="%s">register</a> then <a href="%s">login</a> in order to create a new hack.'
            % (hdf.getValue("trac.href.registration",
                            ""), hdf.getValue("trac.href.login", "")))
    db = env.get_db_cnx()
    cursor = db.cursor()

    # Fetch meta-data from tags
    META_TAGS = []
    cursor.execute("SELECT name FROM wiki_namespace WHERE namespace=%s",
                   'metatag')
    for tag in cursor.fetchall():
        tag = tag[0]
        cursor.execute("SELECT name FROM wiki_namespace WHERE namespace=%s",
                       tag)
        META_TAGS += [x[0] for x in cursor.fetchall()]
    cursor.execute("SELECT name FROM wiki_namespace WHERE namespace=%s",
                   'type')
    TYPES = [x[0] for x in cursor.fetchall()]
    cursor.execute("SELECT name FROM wiki_namespace WHERE namespace=%s",
                   'release')
    RELEASES = [x[0] for x in cursor.fetchall()]

    page_name = hdf.getValue('args.name', '')
    if not page_name.lower().endswith(hdf.getValue('args.type', '')):
        page_name += hdf.getValue('args.type', '').title()
    page_title = hdf.getValue('args.title', '')
    page_description = hdf.getValue('args.description', '')
    page_example = hdf.getValue('args.example', '')
    page_type = hdf.getValue('args.type', 'macro')
    page_tags = get_branch_values(hdf, 'args.tags')
    page_releases = get_branch_values(hdf, 'args.releases')
    page_preview = hdf.getValue('args.previewhack', '')
    page_create = hdf.getValue('args.createhack', '')

    def write_tags(out, tags, checked=(), name="tags", type="checkbox"):
        count = 0
        for tag in sorted(tags):
            if tag[0].isupper():
                continue
            (linktext, title, desc) = getInfo(db, tag)
            link = env.href.wiki(tag)
            check = ""
            if tag in checked:
                check = " checked"
            out.write(
                '<input type="%s" name="%s" value="%s"%s/> <a href="%s" title="%s">%s</a>&nbsp;&nbsp;\n'
                % (type, name, tag, check, link, title, tag))
            count += 1
            if count % 8 == 0:
                out.write("<br/>\n")
        return count

    # Validation
    if page_preview or page_create:
        try:
            fetch_page(cursor, page_name)
        except:
            pass
        else:
            errors.append("Page name %s already exists" % page_name)
        if not re.match('^([A-Z][a-z]+){2,}$', page_name):
            errors.append(
                'Invalid WikiName, only alpha characters are accepted and must be CamelCase'
            )
        if not page_name: errors.append("No WikiName provided")
        if not page_title: errors.append("No page title provided")
        if not page_type: errors.append('No page type selected')
        if not page_description: errors.append("No description provided")
        if not page_example: errors.append("No example provided")
        if not page_releases: errors.append("No releases selected")

    if page_create and not errors:
        repos_dir = env.get_config('trac', 'repository_dir')
        pool, rep, fs_ptr = open_svn_repos(repos_dir)
        rev = svn.fs.youngest_rev(fs_ptr, pool)
        root = svn.fs.revision_root(fs_ptr, rev, pool)
        node_type = svn.fs.check_path(root, page_name.lower(), pool)
        cursor.execute("SELECT name FROM component WHERE name='%s'" %
                       page_name)
        row = cursor.fetchone()
        if row:
            errors.append("Component '%s' already exists" % page_name)
        if node_type:
            errors.append("Repository path '%s' already exists" %
                          page_name.lower())
        if not os.access(SVN_PERMISSIONS, os.W_OK):
            errors.append("Can't write to Subversion permissions file")

        lockfile = open("/var/tmp/newhack.lock", "w")
        try:
            rv = fcntl.flock(lockfile, fcntl.LOCK_EX | fcntl.LOCK_NB)
            if rv:
                errors.append(
                    'Failed to acquire lock, received error code %i' % rv)
        except IOError:
            errors.append(
                'A hack is currently being created by another user. Try again later.'
            )

        if not errors:
            try:
                # Insert component
                cursor.execute(
                    'INSERT INTO component (name, owner) VALUES (%s, %s)',
                    page_name, authname)
                # Create page
                perm = trac.perm.PermissionCache(db, authname)
                page = WikiPage(page_name, None, perm, db)
                page.set_content(
                    expand_vars(fetch_page(cursor, template),
                                generate_vars(hdf)))
                out.write('Created wiki page.<br>\n')
                # Creating SVN paths
                paths = ['%s%s' % (SVN_LOCAL_PATH, page_name.lower())]
                for release in page_releases:
                    paths.append("%s%s/%s" %
                                 (SVN_LOCAL_PATH, page_name.lower(), release))
                output = os.popen(
                    'umask 775; /usr/bin/op create-hack %s "New hack %s, created by %s" %s 2>&1'
                    % (authname, page_name, authname,
                       ' '.join(paths))).readlines()
                if output:
                    raise Exception(
                        "Failed to create Subversion paths:\n<blockquote>%s</blockquote>"
                        % ''.join(output))
                out.write("Created SVN layout.<br>\n")
                # Add SVN permissions
                perms = open(SVN_PERMISSIONS, "a")
                perms.write("\n[/%s]\n%s = rw\n" %
                            (page_name.lower(), authname))
                out.write('Added SVN write permission.<br>\n')
                out.write('\nFinished.<p><h1>Hack Details</h1>\n')
                for release in page_releases:
                    svnpath = "%s%s/%s" % (SVN_URL, page_name.lower(), release)
                    out.write(
                        'The Subversion repository path for %s is <a href="%s">%s</a>.<br>\n'
                        % (release, svnpath, svnpath))
                out.write(
                    'The page for your hack is <a href="%s">%s</a>.<br>\n' %
                    (env.href.wiki(page_name), page_name))
                page.commit(
                    authname,
                    'New hack %s, created by %s' % (page_name, authname), None)
                rv = fcntl.flock(lockfile, fcntl.LOCK_UN)
                return out.getvalue()
            except Exception, e:
                # TODO Roll back changes to SVN_PERMISSIONS file
                cursor.execute("ROLLBACK")
                rv = fcntl.flock(lockfile, fcntl.LOCK_UN)
                raise TracError(e)
Ejemplo n.º 3
0
def execute(hdf, template, env):
    out = StringIO()
    errors = []
    authname = hdf.getValue("trac.authname", "anonymous")
    if not template:
        raise TracError("No template page supplied")
    if authname == "anonymous":
        errors.append('You need to <a href="%s">register</a> then <a href="%s">login</a> in order to create a new hack.' % (hdf.getValue("trac.href.registration", ""), hdf.getValue("trac.href.login", "")))
    db = env.get_db_cnx()
    cursor = db.cursor()

    # Fetch meta-data from tags
    META_TAGS = []
    cursor.execute("SELECT name FROM wiki_namespace WHERE namespace=%s", 'metatag')
    for tag in cursor.fetchall():
        tag = tag[0]
        cursor.execute("SELECT name FROM wiki_namespace WHERE namespace=%s", tag)
        META_TAGS += [x[0] for x in cursor.fetchall()]
    cursor.execute("SELECT name FROM wiki_namespace WHERE namespace=%s", 'type')
    TYPES = [x[0] for x in cursor.fetchall()]
    cursor.execute("SELECT name FROM wiki_namespace WHERE namespace=%s", 'release')
    RELEASES = [x[0] for x in cursor.fetchall()]

    page_name = hdf.getValue('args.name', '')
    if not page_name.lower().endswith(hdf.getValue('args.type', '')):
        page_name += hdf.getValue('args.type', '').title()
    page_title = hdf.getValue('args.title', '')
    page_description = hdf.getValue('args.description', '')
    page_example = hdf.getValue('args.example', '')
    page_type = hdf.getValue('args.type', 'macro')
    page_tags = get_branch_values(hdf, 'args.tags')
    page_releases = get_branch_values(hdf, 'args.releases')
    page_preview = hdf.getValue('args.previewhack', '')
    page_create = hdf.getValue('args.createhack', '')

    def write_tags(out, tags, checked = (), name = "tags", type="checkbox"):
        count = 0
        for tag in sorted(tags):
            if tag[0].isupper():
                continue
            (linktext,title,desc) = getInfo(db,tag)
            link = env.href.wiki(tag)
            check = ""
            if tag in checked:
                check = " checked"
            out.write('<input type="%s" name="%s" value="%s"%s/> <a href="%s" title="%s">%s</a>&nbsp;&nbsp;\n' % (type, name, tag, check, link, title, tag))
            count += 1
            if count % 8 == 0:
                out.write("<br/>\n")
        return count

    # Validation
    if page_preview or page_create:
        try:
            fetch_page(cursor, page_name)
        except:
            pass
        else:
            errors.append("Page name %s already exists" % page_name)
        if not re.match('^([A-Z][a-z]+){2,}$', page_name): errors.append('Invalid WikiName, only alpha characters are accepted and must be CamelCase')
        if not page_name: errors.append("No WikiName provided")
        if not page_title: errors.append("No page title provided")
        if not page_type: errors.append('No page type selected')
        if not page_description: errors.append("No description provided")
        if not page_example: errors.append("No example provided")
        if not page_releases: errors.append("No releases selected")

    if page_create and not errors:
        repos_dir = env.get_config('trac', 'repository_dir')
        pool, rep, fs_ptr = open_svn_repos(repos_dir)
        rev = svn.fs.youngest_rev(fs_ptr, pool)
        root = svn.fs.revision_root(fs_ptr, rev, pool)
        node_type = svn.fs.check_path(root, page_name.lower(), pool)
        cursor.execute("SELECT name FROM component WHERE name='%s'" % page_name)
        row = cursor.fetchone()
        if row:
            errors.append("Component '%s' already exists" % page_name)
        if node_type:
            errors.append("Repository path '%s' already exists" % page_name.lower())
        if not os.access(SVN_PERMISSIONS, os.W_OK):
            errors.append("Can't write to Subversion permissions file")

        lockfile = open("/var/tmp/newhack.lock", "w")
        try:
            rv = fcntl.flock(lockfile, fcntl.LOCK_EX | fcntl.LOCK_NB)
            if rv:
                errors.append('Failed to acquire lock, received error code %i' % rv)
        except IOError:
            errors.append('A hack is currently being created by another user. Try again later.')

        if not errors:
            try:
                # Insert component
                cursor.execute('INSERT INTO component (name, owner) VALUES (%s, %s)', page_name, authname)
                # Create page
                perm = trac.perm.PermissionCache(db, authname)
                page = WikiPage(page_name, None, perm, db)
                page.set_content(expand_vars(fetch_page(cursor, template), generate_vars(hdf)))
                out.write('Created wiki page.<br>\n')
                # Creating SVN paths
                paths = ['%s%s' % (SVN_LOCAL_PATH, page_name.lower())]
                for release in page_releases:
                    paths.append("%s%s/%s" % (SVN_LOCAL_PATH, page_name.lower(), release))
                output = os.popen('umask 775; /usr/bin/op create-hack %s "New hack %s, created by %s" %s 2>&1' % (authname, page_name, authname, ' '.join(paths))).readlines()
                if output:
                    raise Exception("Failed to create Subversion paths:\n<blockquote>%s</blockquote>" % ''.join(output))
                out.write("Created SVN layout.<br>\n")
                # Add SVN permissions
                perms = open(SVN_PERMISSIONS, "a")
                perms.write("\n[/%s]\n%s = rw\n" % (page_name.lower(), authname))
                out.write('Added SVN write permission.<br>\n')
                out.write('\nFinished.<p><h1>Hack Details</h1>\n')
                for release in page_releases:
                    svnpath = "%s%s/%s" % (SVN_URL, page_name.lower(), release)
                    out.write('The Subversion repository path for %s is <a href="%s">%s</a>.<br>\n' % (release, svnpath, svnpath))
                out.write('The page for your hack is <a href="%s">%s</a>.<br>\n' % (env.href.wiki(page_name), page_name))
                page.commit(authname, 'New hack %s, created by %s' % (page_name, authname), None)
                rv = fcntl.flock(lockfile, fcntl.LOCK_UN)
                return out.getvalue()
            except Exception, e:
                # TODO Roll back changes to SVN_PERMISSIONS file
                cursor.execute("ROLLBACK");
                rv = fcntl.flock(lockfile, fcntl.LOCK_UN)
                raise TracError(e)