Пример #1
0
def open(id, redirect_after=True):
    """
    Open an issue.

    :param id: issue id
    :param redirect_after: return a redirect. This happens by default, but turning
                           it off may be desirable for async requests.
    """
    tracker, config = setup()
    issue = tracker.issue(id)
    if issue:
        issue.status = 'open'
        comment = Comment(issue)
        comment.event = True
        comment.event_data = 'opened'
        comment.author = config.user
        comment.save()
        issue.save()
        tracker.autocommit('Re-opened issue %s/%s' % (issue.id[:6], comment.id[:6]),
                           config.user)
        if redirect_after:
            return redirect(url_for('issues.view', id=issue.id))
        else:
            return True
    return False
Пример #2
0
def view(id):
    """
    Render the issue view to display information about a single issue.

    :param id: id of the issue to view.
    """
    tracker, config = setup()
    issue = tracker.issue(id)
    if request.method == 'POST':
        comment = Comment(issue)
        comment.content = request.form['content']
        comment.author['name'] = config.user['name']
        comment.author['email'] = config.user['email']
        comment.save()
        if issue.save(): # ping the issue (updated = now)
            tracker.autocommit(message='Commented on issue %s/%s' % \
                                        (issue.id[:6], comment.id[:6]),
                               author=config.user)
        else:
            flash('There was an error saving your comment.')
        return redirect(url_for('issues.view', id=issue.id))
    else:
        issue.updated = relative_time(issue.updated)
        issue.created = relative_time(issue.created)
        issue.content = markdown_to_html(issue.content)
        comments = issue.comments()
        header = 'Viewing Issue &nbsp;<span class="fancy-monospace">%s</span>' \
                % issue.id[:6]
        if comments:
            map_attr(comments, 'timestamp', relative_time)
            map_attr(comments, 'content', markdown_to_html)
        return render_template('issue.html', issue=issue,
                               comments=comments, selected='issues',
                               config=config, header=header, tracker=tracker)
Пример #3
0
def new():
    """Render the new issue view."""
    tracker, config = setup()
    header = 'Create a new issue'
    if request.method == 'POST':
        issue = Issue(tracker)
        issue.content = request.form['content']
        issue.title = request.form['title']
        labels = request.form['labels']
        if labels:
            issue.labels = labels.split(',')
        else:
            issue.labels = []
        issue.author['name'] = config.user['name']
        issue.author['email'] = config.user['email']
        if issue.save():
            tracker.autocommit(message='Created a new issue %s' % issue.id[:6], 
                               author=config.user)
            return redirect(url_for('issues.view', id=issue.id)) 
        else:
            flash('There was an error saving your issue.')
            return render_template('new.html', selected='issues', 
                                   header=header, tracker=tracker)
    else:
        return render_template('new.html', selected='issues', 
                               header=header, tracker=tracker)
Пример #4
0
def members():
    tracker, config = setup()
    header = "Everyone who's altered the %s time continuum." % tracker.config.name
    raw_history = tracker.history(all=True)
    # get the unique set of authors (in this history segment)
    users = set(strip_email(c.author) for c in raw_history)
    return render_template('members.html', header=header, 
                           tracker=tracker, users=users)
Пример #5
0
def doc_raw(doc):
    """
    Returns the given doc in raw form.

    :param doc: name of the doc.
    """
    tracker, config = setup()
    doc = tracker.doc(doc)
    return to_json({'content': doc.read()})
Пример #6
0
def doc(doc):
    """
    Returns the given doc as html.

    :param doc: name of the doc.
    """
    tracker, config = setup()
    doc = tracker.doc(doc)
    return to_json({'content': doc.read(convert=True)})
Пример #7
0
def main():
    tracker, config = setup()
    if request.method == 'POST':
        tracker.config.name = request.form['name']
        tracker.config.save()
    header = 'Settings for %s' % tracker.config.name
    return render_template('settings.html', tracker=tracker, 
                           name=tracker.config.name, selected='settings', 
                           header=header)
Пример #8
0
def doc(doc):
    """
    Returns the given doc as html.

    :param doc: name of the doc.
    """
    tracker, config = setup()
    doc = tracker.doc(doc)
    return to_json({'content': doc.read(convert=True)})
Пример #9
0
def doc_raw(doc):
    """
    Returns the given doc in raw form.

    :param doc: name of the doc.
    """
    tracker, config = setup()
    doc = tracker.doc(doc)
    return to_json({'content': doc.read()})
Пример #10
0
def label(label, status=None):
    """
    Returns issues that have a given label.

    :param label: label to filter by.
    :param status: status to filter by, in addition to the label.
    """
    tracker, config = setup()
    issues = [i.fields for i in tracker.issues(label=label, status=status)]
    return to_json(issues)
Пример #11
0
def label(label, status=None):
    """
    Returns issues that have a given label.

    :param label: label to filter by.
    :param status: status to filter by, in addition to the label.
    """
    tracker, config = setup()
    issues = [i.fields for i in tracker.issues(label=label, status=status)]
    return to_json(issues)
Пример #12
0
def issue(id):
    """
    Return the issue with the given id.

    :param id: id of the issue. Only the number of characters necessary to
               uniquely identify it are required, but using more is a good
               idea.
    """
    tracker, config = setup()
    return to_json(tracker.issue(id).fields)
Пример #13
0
def issue(id):
    """
    Return the issue with the given id.

    :param id: id of the issue. Only the number of characters necessary to
               uniquely identify it are required, but using more is a good
               idea.
    """
    tracker, config = setup()
    return to_json(tracker.issue(id).fields)
Пример #14
0
def members():
    tracker, config = setup()
    header = "Everyone who's altered the %s time continuum." % tracker.config.name
    raw_history = tracker.history(all=True)
    # get the unique set of authors (in this history segment)
    users = set(strip_email(c.author) for c in raw_history)
    return render_template('members.html',
                           header=header,
                           tracker=tracker,
                           users=users)
Пример #15
0
def search(query, status=None):
    """
    Returns issues that match the search query.

    :param query: string to search issues for.
    :param status: status to filter by, in addition to the search query.
    """
    tracker, config = setup()
    issues = [i.fields for i in 
              tracker.query().search(sstr=query, status=status)]
    return to_json(issues)
Пример #16
0
def index(status='open'):
    """
    Render the issue index view.

    :param status: 'open' or 'closed'
    """
    tracker, config = setup()

    # get the url params
    order = request.args.get('order', 'updated')
    direc = request.args.get('dir', 'asc')
    page = int(request.args.get('page', 1))
    label = request.args.get('label', None)

    # verify the params
    order = order if order in ['id', 'title', 'author'] else 'updated'
    reverse = True if direc == 'asc' else False
    per_page = 15 
    offset = (page - 1) * per_page if page > 1 else 0

    # run our query
    issues_ = tracker.query().select(limit=per_page, offset=offset, 
                                     status=status, order_by=order, 
                                     reverse=reverse, label=label)
    # humanize the timestamps
    map_attr(issues_, 'updated', relative_time)
    map_attr(issues_, 'created', relative_time)

    # get the number of issues by status
    n = tracker.query().count(status)

    # get the number of pages
    n_pages = n / per_page
    if n % per_page > 1:
        n_pages += 1

    # get pages to link to
    pages = pager(page, n_pages) if n > per_page else None

    # set the header
    header = 'Viewing %s issues for %s' % (status, tracker.config.name)
    if label:
        header += ' with label &nbsp; <span class="fancy-monospace">'
        header += '%s</span>' % label

    if request.json is not None:
        return to_json(request.json)
    else:
        return render_template('issues.html', issues_=issues_, 
                               selected='issues', status=status, 
                               order=order, page=page, pages=pages,
                               num_pages=n_pages, asc=reverse,
                               header=header, n=n, tracker=tracker)
Пример #17
0
def search(query, status=None):
    """
    Returns issues that match the search query.

    :param query: string to search issues for.
    :param status: status to filter by, in addition to the search query.
    """
    tracker, config = setup()
    issues = [
        i.fields for i in tracker.query().search(sstr=query, status=status)
    ]
    return to_json(issues)
Пример #18
0
def doc_edit(doc):
    """
    Given a POST request that contains an 'edited' field, the given
    doc's raw content is replaced.

    :param doc: name of the doc to edit.
    :returns: {'success': True} if there were no errors.
    """
    tracker, config = setup()
    success = False
    if request.form:
        doc = tracker.doc(doc)
        doc.write(request.form['edited'])
        success = True
    return to_json({'success': success})
Пример #19
0
def doc_edit(doc):
    """
    Given a POST request that contains an 'edited' field, the given
    doc's raw content is replaced.

    :param doc: name of the doc to edit.
    :returns: {'success': True} if there were no errors.
    """
    tracker, config = setup()
    success = False
    if request.form:
        doc = tracker.doc(doc)
        doc.write(request.form['edited'])
        success = True
    return to_json({'success': success})
Пример #20
0
def search(query=None):
    tracker, config = setup()
    if query is None:
        query = request.args.get('query', 'test')
    header = "Search results for '%s'" % query
    issues_ = tracker.query().search(query)
    for i in issues_:
        blurb = i.content
        if i.comments():
            blurb += ' ... ' + ' ... '.join(c.content for c in i.comments() if 
                                            type(c.content) is str)
        blurb = highlight(blurb, query)
        i.content = blurb
        i.title = highlight(i.title, query, False)
    return render_template('search.html', issues_=issues_, 
                           selected='issues', tracker=tracker,
                           header=header)
Пример #21
0
def main(name=None):
    tracker, config = setup()
    header = 'Documentation for %s' % tracker.config.name
    docs = tracker.docs()
    if name:
        try:
            doc = tracker.doc(name)
            converted = doc.read(convert=True)
            markdown = doc.read()
        except OSError:
            abort(404)
    else:
        doc = docs[0]
        converted = doc.read(convert=True)
        markdown = doc.read()
    return render_template('docs.html', tracker=tracker, docs=docs,
                           doc=doc, markdown=markdown, converted=converted, 
                           selected='docs', header=header)
Пример #22
0
def main(name=None):
    tracker, config = setup()
    header = 'Documentation for %s' % tracker.config.name
    docs = tracker.docs()
    if name:
        try:
            doc = tracker.doc(name)
            converted = doc.read(convert=True)
            markdown = doc.read()
        except OSError:
            abort(404)
    else:
        doc = docs[0]
        converted = doc.read(convert=True)
        markdown = doc.read()
    return render_template('docs.html',
                           tracker=tracker,
                           docs=docs,
                           doc=doc,
                           markdown=markdown,
                           converted=converted,
                           selected='docs',
                           header=header)
Пример #23
0
def open_issues():
    """Returns open issues."""
    tracker, config = setup()
    issues = [i.fields for i in tracker.issues(status='open')]
    return to_json(issues)
Пример #24
0
def settings():
    """Settings"""
    tracker, config = setup()
    return render_template('/settings.html')
Пример #25
0
def main():
    tracker, config = setup()

    # get the offset param (intended for javascript requests)
    offset = int(request.args.get('offset', 0))

    # Get up to 20 commits starting at whatever offset.
    raw_history = tracker.history(n=offset+20, offset=offset)

    # Don't want the performance hit of checking how many commits there are.
    # Instead, we're guessing that there's more if we get a full 20 in the 
    # first batch. 
    more_history = False if len(raw_history) < 20 else True

    # get the unique set of authors (in this history segment)
    users = set(strip_email(c.author) for c in raw_history)
    docs = tracker.docs()
    history = []
    for c in raw_history:
        split = c.author.index('<')
        name = c.author[:split]
        email = c.author[(split + 1):-1]
        time = relative_time(c.commit_time)
        message, obj = interpret(c.message, tracker)

        snippet = title = link = button = None

        if type(obj) is Comment:
            snippet = cut(obj.content, 190)
            link = url_for('issues.view', id=obj.issue.id[:6]) + '#comment-' + obj.id[:6]
            button = obj.issue.id[:6]
        if type(obj) is Issue:
            title = obj.title
            snippet = cut(obj.content, 190)
            link = url_for('issues.view', id=obj.id[:6])
            button = obj.id[:6]

        history.append({'user': {'name': name, 'email': email},
                        'message': message.strip(),
                        'time': time,
                        'link': link,
                        'button': button,
                        'title': title,
                        'snippet': snippet
                        }
                       )
    # If the request is async, we're all set.
    if request.is_xhr:
        return to_json(history)

    # Otherwise, we have to get some more info.

    header = 'Recent Activity for %s' % tracker.config.name
    # Issue counts
    n_open = tracker.query().count('open')
    n_closed = tracker.query().count('closed')
    n_total = n_open + n_closed
    # Graph percentages
    # the subtraction is spacing for the CSS.
    g_open = (float(n_open) / n_total) * 100 - 2 if n_total > 0 else 0
    g_closed = (float(n_closed) / n_total) * 100 - 2 if n_total > 0 else 0
    g_open = 1 if g_open < 1 else g_open
    g_closed = 1 if g_closed < 1 else g_closed

    return render_template('feed.html', history=history,
                           selected='feed', header=header, 
                           tracker=tracker, users=users,
                           docs=docs, n_open=n_open, 
                           n_closed=n_closed, n_total=n_total,
                           g_open=g_open, g_closed=g_closed,
                           more_history=more_history)
Пример #26
0
def open_issues():
    """Returns open issues."""
    tracker, config = setup()
    issues = [i.fields for i in tracker.issues(status='open')]
    return to_json(issues)
Пример #27
0
def main():
    tracker, config = setup()

    # get the offset param (intended for javascript requests)
    offset = int(request.args.get('offset', 0))

    # Get up to 20 commits starting at whatever offset.
    raw_history = tracker.history(n=offset + 20, offset=offset)

    # Don't want the performance hit of checking how many commits there are.
    # Instead, we're guessing that there's more if we get a full 20 in the
    # first batch.
    more_history = False if len(raw_history) < 20 else True

    # get the unique set of authors (in this history segment)
    users = set(strip_email(c.author) for c in raw_history)
    docs = tracker.docs()
    history = []
    for c in raw_history:
        split = c.author.index('<')
        name = c.author[:split]
        email = c.author[(split + 1):-1]
        time = relative_time(c.commit_time)
        message, obj = interpret(c.message, tracker)

        snippet = title = link = button = None

        if type(obj) is Comment:
            snippet = cut(obj.content, 190)
            link = url_for('issues.view',
                           id=obj.issue.id[:6]) + '#comment-' + obj.id[:6]
            button = obj.issue.id[:6]
        if type(obj) is Issue:
            title = obj.title
            snippet = cut(obj.content, 190)
            link = url_for('issues.view', id=obj.id[:6])
            button = obj.id[:6]

        history.append({
            'user': {
                'name': name,
                'email': email
            },
            'message': message.strip(),
            'time': time,
            'link': link,
            'button': button,
            'title': title,
            'snippet': snippet
        })
    # If the request is async, we're all set.
    if request.is_xhr:
        return to_json(history)

    # Otherwise, we have to get some more info.

    header = 'Recent Activity for %s' % tracker.config.name
    # Issue counts
    n_open = tracker.query().count('open')
    n_closed = tracker.query().count('closed')
    n_total = n_open + n_closed
    # Graph percentages
    # the subtraction is spacing for the CSS.
    g_open = (float(n_open) / n_total) * 100 - 2 if n_total > 0 else 0
    g_closed = (float(n_closed) / n_total) * 100 - 2 if n_total > 0 else 0
    g_open = 1 if g_open < 1 else g_open
    g_closed = 1 if g_closed < 1 else g_closed

    return render_template('feed.html',
                           history=history,
                           selected='feed',
                           header=header,
                           tracker=tracker,
                           users=users,
                           docs=docs,
                           n_open=n_open,
                           n_closed=n_closed,
                           n_total=n_total,
                           g_open=g_open,
                           g_closed=g_closed,
                           more_history=more_history)
Пример #28
0
def closed_issues():
    """Returns closed issues."""
    tracker, config = setup()
    issues = [i.fields for i in tracker.issues(status='closed')]
    return to_json(issues)
Пример #29
0
def closed_issues():
    """Returns closed issues."""
    tracker, config = setup()
    issues = [i.fields for i in tracker.issues(status='closed')]
    return to_json(issues)