code:
{% extends "repo_master.html" %}
{% from "_formhelper.html" import render_field_in_row, show_comment, render_bootstrap_field %}

{% block title %}
  {%- if pull_request -%}
    PR#{{ requestid }}: {{ pull_request.title | noJS(ignore="img")}} - {{ repo.name }}
  {% elif form and (repo_admin or remote_git) %}
    Create new Pull Request for {{ branch_to }} - {{ repo.name }}
  {%- elif origin == 'compare_commits' -%}
    Diff from {{ commit1 }} to {{ commit2 }} - {{ repo.name }}
  {%- else -%}
    Diff from {{ branch_from }} to {{ branch_to }} - {{ repo.name }}
  {%- endif -%}
{% endblock %}

{% set tag = "home" %}

{% block header %}
<link href="{{ url_for('static', filename='emoji/emojione.sprites.css') }}"
  rel="stylesheet" />
<link href="{{ url_for('static', filename='selectize.bootstrap3.css') }}"
  rel="stylesheet" />
<link href="{{ url_for('static', filename='atwho/jquery.atwho.min.css') }}"
  rel="stylesheet" />
{% endblock %}

{% block repo %}

{% if pull_request %}

PR#{{requestid}}
  {% if pull_request.status != 'Open'%}
  {{pull_request.status}}
  {% endif %}
  {{ pull_request.title | noJS(ignore="img") | safe}}
  {% if authenticated and (g.fas_user.username == pull_request.user.username
    or repo_admin) and pull_request.status == 'Open'%}

     {% if pull_request.status == 'Open' and authenticated and
        (repo_admin or g.fas_user.username == pull_request.user.username) %}
        <form style="display:inline;" action="{{ url_for('cancel_request_pull', username=username,
            repo=repo.name, requestid=requestid) }}" method="POST">
     {% endif %}

     {% if pull_request.status == 'Open' and authenticated and
        (repo_admin or g.fas_user.username == pull_request.user.username) %}
        {{ mergeform.csrf_token }}
            <button type="submit" value="Close" id="cancel_pr"
                    class="btn btn-danger btn-sm" title="Close PR without merging it">

            </button>
    {% endif %}

    {% if pull_request.status == 'Open' and authenticated and
        (repo_admin or g.fas_user.username == pull_request.user.username) %}
      </form>
    {% endif %}

  {% endif %}

    Proposed {{ pull_request.date_created |humanize }}
    by {{ pull_request.user.default_email | avatar(16) | safe
      }} {{ pull_request.user.user }}

  From
    {{
        pull_request.project_from.fullname or pull_request.remote_git
    }}

    {{ pull_request.branch_from }}

   into
    {{ pull_request.project.fullname }}

    {{ pull_request.branch }}

{%if pull_request and pull_request.initial_comment %}

{{ pull_request.initial_comment | markdown | noJS | safe }}

{%endif%}
{% elif form and (repo_admin or remote_git) %}

Create pull request

{% else %}

Diff
      (tree)

    {% if origin == 'compare_commits' %}

{{ commit1 }} .. {{ commit2 }}

    {% endif %}

{% endif %}

{% if form and (repo_admin or remote_git) %}

  {% if remote_git %}
  <form action="{{ url_for('.new_remote_request_pull', username=username,
    repo=repo.name, confirm=True) }}" method="post">
    <input type="hidden" value="{{ branch_from }}" name="branch_from" />
    <input type="hidden" value="{{ remote_git }}" name="git_repo" />
  {% else %}
  <form action="{{ url_for('.new_request_pull', username=username,
    repo=repo.name, commitid=commitid, branch_from=branch_from,
    branch_to=branch_to) }}" method="post">
  {% endif %}

    Pull from
      {%
        if remote_git -%}{{ remote_git }}{%-
        else -%}
           {{ repo.fullname }} {%-
        endif -%}

        {{ branch_from }}

      into

        {% if repo.is_fork -%}{{ repo.parent.fullname }}{%
           else %}{{ repo.fullname }}{% endif %}

      <select class="pr-toplabel-select" id="branch_select" name="branch_to">
          <option value="{{ branch_to }}">{{ branch_to }}</option>
        {% for branch in branches |reverse %}
          {% if branch != branch_to %}
          <option value="{{ branch }}">{{ branch }}</option>
          {% endif %}
        {% endfor %}
      </select>

    {% if contributing %}

      {{ contributing | markdown | noJS | safe}}

    {% endif %}
    {{ render_bootstrap_field(form.title) }}
    <fieldset class="form-group">
      Inital Comment

        Preview

      {{ form.initial_comment(class_="form-control")|safe }}

        {% if form.initial_comment.errors %}

          {% for error in form.initial_comment.errors %}
            {{ error }}
          {% endfor %}

        {% endif %}

    </fieldset>

      <input type="submit" class="btn btn-primary" value="Create">
      {{ form.csrf_token }}

        Cancel

  </form>

{% endif %}

  {% if pull_request %}

        Comments

  {%endif%}

      Files Changed

        {{ diff|length if diff else 0}}

      Commits

        {{ diff_commits|length }}

  {% if pull_request %}

      Patch

  {% endif %}

        {% for commit in diff_commits %}

            {% if pull_request and pull_request.status and pull_request.project_from.is_fork %}

            {% elif pull_request and pull_request.remote %}

            {% else %}

            {% endif %}

              {{ commit.message.strip().split('\n')[0] }}

                  {{ commit.commit_time|humanize }}

            {{ commit.author | author2avatar(20) | safe }} {{ commit.author.name }}

              {{ commit.hex|short }}

        {% else %}

 No commits found

        {% endfor %}

    {% if authenticated and pull_request %}
    <form action="{{ url_for('.pull_request_drop_comment', username=username,
        repo=repo.name, requestid=requestid) }}" method="post" class="icon"
        onsubmit="return try_async_comment(this, null)" >
    {% endif %}

    {% if diff %}
      {% set count = 0 %}
      {% for patch in diff %}
        {% set count = count+1 %}
        {% if patch |hasattr('new_id') %}
          {% set patch_new_id = patch.new_id %}
        {% elif patch |hasattr('delta') %}
          {% set patch_new_id = patch.delta.new_file.id %}
        {% else %}
          {% set patch_new_id = patch.new_oid %}
        {% endif %}

        {% if patch |hasattr('old_id') %}
          {% set patch_old_id = patch.old_id %}
        {% elif patch |hasattr('delta') %}
          {% set patch_old_id = patch.delta.old_file.id %}
        {% else %}
          {% set patch_old_id = patch.old_oid %}
        {% endif %}

        {% if patch | hasattr('new_file_path') %}
          {% set patch_new_file_path = patch.new_file_path -%}
          {% if patch.new_file_path != patch.old_file_path %}
            {% set patch_old_file_path = patch.old_file_path %}
          {%- endif -%}
        {%- elif patch | hasattr('delta') -%}
          {% set patch_new_file_path = patch.delta.new_file.path -%}
          {%- if patch.delta.new_file.path != patch.delta.old_file.path -%}
            {% set patch_old_file_path = patch.delta.old_file.path %}
          {%- endif -%}
        {%- endif -%}

              {% if patch | hasattr('additions') %}
              {# Version of pygit2 -0.21.4 -- F21/EL7 #}
                  {% set linesadded = patch.additions %}
                  {% set linesremoved = patch.deletions %}
              {% else %}
              {# Version of pygit2 -0.23.0 -- F23 #}
                  {% set linesadded = patch.line_stats[1] %}
                  {% set linesremoved = patch.line_stats[2] %}
              {% endif %}

              {% macro lineschanged(added, removed) -%}
                {%if added%}
                  +{{linesadded}}
                {%endif%}
                {%if removed%}
                  -{{linesremoved}}
                {%endif%}
              {%endmacro%}

              {% macro viewfilelink(filepath, identifier=False)%}
              {% if pull_request %}
              {% if not identifier %}
                {% set identifier = pull_request.branch_from %}
              {% endif %}
              <a href="{{
                  url_for(
                      'view_file',
                      username=pull_request.project_from.user.username
                          if pull_request.project_from.is_fork else None,
                      repo=pull_request.project_from.name,
                      identifier=identifier,
                      filename=filepath) }}"
              {% else %}
              {% if identifier == False %}
                {% set identifier = branch_from %}
              {% endif %}
              {{filepath | unicode}}
              {% endmacro %}

              {% if patch | hasattr('new_file_path') %}
                {%- if patch.new_file_path == patch.old_file_path -%}
                  {%- if patch.status == 'D' -%}
                    {% set patchtype = "removed"%}

                      {{ viewfilelink(patch.new_file_path) }} {{ lineschanged(False, True) }}

file removed

                  {%-elif patch.status == 'A' -%}
                    {% set patchtype = "added"%}

                      {{ viewfilelink(patch.new_file_path) }} {{ lineschanged(True, False) }}

file added

                  {%-elif patch.status == 'M' -%}
                    {% set patchtype = "changed"%}

                      {{ viewfilelink(patch.new_file_path) }} {{ lineschanged(True, True) }}

file changed

                  {%-endif-%}
                {%- else -%}
                  {% set patchtype = "moved"%}
                  {{lineschanged(True, True)}}

                    {{patch.old_file_path}}

                    {{viewfilelink(patch.new_file_path)}}

file moved

                {%- endif -%}
              {%- elif patch | hasattr('delta') -%}
                {%- if patch.delta.new_file.path == patch.delta.old_file.path -%}
                  {%- if patch.delta.new_file.mode == 0 and patch.delta.old_file.mode == 33188 -%}
                    {% set patchtype = "removed"%}

{{viewfilelink(patch.delta.new_file.path)}} {{lineschanged(False, True)}}

file removed

                  {%-elif patch.delta.new_file.mode == 33188 and patch.delta.old_file.mode == 0 -%}
                    {% set patchtype = "added"%}

{{viewfilelink(patch.delta.new_file.path)}} {{lineschanged(True, False)}}

file added

                  {%-elif patch.delta.new_file.mode == 33188 and patch.delta.old_file.mode == 33188 -%}
                    {% set patchtype = "changed"%}

                      {{ viewfilelink(patch.delta.new_file.path)}} {{lineschanged(True, True)}}

file changed

                  {%-endif-%}
                {%- else -%}
                  {% set patchtype = "moved"%}
                  {{lineschanged(True, True)}}

                    {{patch.delta.old_file.path}}

                    {{viewfilelink(patch.delta.new_file.path)}}

file moved

                {%- endif -%}
              {%- endif -%}

      {% if patchtype == "moved" and linesadded == 0 and linesremoved == 0%}

file was moved with no change to the file

      {% elif patchtype == "added" and linesadded == 0 %}

empty file added

      {% else %}
        {% if patchtype == "added" and linesadded > 1000 %}

                The added file is too large to be shown here, see it at:
                {{ viewfilelink(patch_new_file_path) }}

        {% elif patchtype == "removed" %}

                The removed file is too large to be shown here, see it at:
                {{ viewfilelink(patch_new_file_path, patch_old_id) }}

        {% else %}
          {% autoescape false %}
              {{ patch | patch_to_diff | html_diff | format_loc(
                      filename=patch_new_file_path,
                      commit=patch_new_id,
                      prequest=pull_request,
                      index=loop.index,
                      tree_id=diff_commits[0].tree.id)}}
          {% endautoescape %}
        {% endif %}
      {% endif %}

      {% endfor %}
      {% endif %}

    {% if authenticated and pull_request %}
    {{ mergeform.csrf_token }}
    </form>
    {% endif %}

  {% if pull_request %}

    {% if pull_request.comments %}
      <form action="{{ url_for('.pull_request_drop_comment', username=username,
          repo=repo.name, requestid=requestid) }}" method="post"
          onsubmit="return try_async_comment(this, null)">

      {% for comment in pull_request.comments %}
        {% if comment.commit_id %}

                {{ comment.user.user }} commented on line
                    {{
                        comment.line }} of {{ comment.filename }}.

                    {{
                        comment.date_created | humanize }}

                (Show)

                  {{ comment.comment }}

        {% elif comment.notification %}

                    {{
                        comment.date_created | humanize }}

                {{ comment.comment | markdown | noJS | safe }}

        {% else %}
          {{ show_comment(comment, comment.id, repo, username,
                          requestid, form, repo_admin) }}
        {% endif %}
      {% endfor %}
      {{ mergeform.csrf_token }}
      </form>
    {% endif %}

    {% if authenticated and mergeform and pull_request %}

          {% if authenticated %}
            <form action="{{ url_for(
                'pull_request_add_comment', username=username, repo=repo.name,
                requestid=requestid) }}"
                method="post" onsubmit="return try_async_comment(this, false)">
              {{ mergeform.csrf_token }}

              <fieldset class="form-group">
                Add new comment

                  Preview

                <textarea class="form-control" rows=8 id="comment" name="comment"
                placeholder="Enter your comment here" tabindex=1></textarea>

              </fieldset>

              Markdown Syntax

                <input type="submit" class="btn btn-primary"
                  value="Update Issue" tabindex=2 />
                <input type="button" class="btn btn-secondary" value="Clear"
                  id="clear_comment" tabindex=3 />

            </form>
          {% else %}

                Login
               to comment on this ticket.

          {% endif %}

    {% endif %}

  {% endif %}

  {% if pull_request %}

      {% if pull_request.status == 'Open' and repo_admin %}

        <form action="{{ url_for('merge_request_pull', username=username,
            repo=repo.name, requestid=requestid) }}" method="POST">
          {{ mergeform.csrf_token }}
          <button id="merge_btn" type="submit" class="btn btn-block">Merge</button>
        </form>

      {% endif %}

      {% if pull_request.status != 'Open'%}

{{ pull_request.status }} by

            {{ pull_request.closed_by.user if pull_request.closed_by else ''}}
           {{pull_request.closed_at|humanize}}

      {% endif %}

    {% if pull_request.flags %}

            {% for flag in pull_request.flags %}

                  {{ flag.username }}

<span class="label {%if flag.percent <= 10%}label-danger{%elif flag.percent <= 90%}label-warning{%else%}label-success{%endif%}">{{ flag.percent }}%

                    {{ flag.comment }}

                    {{ flag.date_created | humanize }}

            {% endfor %}

    {% endif %}

        {% if authenticated and mergeform and pull_request.status == 'Open' and repo_admin %}
          <form method="POST" action="{{ url_for('.set_assignee_requests',
              username=username, repo=repo.name, requestid=requestid) }}">
            <fieldset class="form-group issue-metadata-form">
              Assignee

                <input value="{{ pull_request.assignee.username or '' }}"
                    name="user" id="assignee" placeholder="username" >
                {{ mergeform.csrf_token }}

              </fieldset>
        {% endif %}
              <fieldset class="form-group issue-metadata-display">
                Assignee

                  {{ pull_request.assignee.username or 'Unassigned' }}

              </fieldset>
        {% if authenticated and mergeform and pull_request.status == 'Open' and repo_admin %}
              <input type="submit" class="btn btn-primary issue-metadata-form" value="Update">
              cancel
            </form>
            Edit Metadata
        {% endif %}

  {% endif %}
  {% if diff and pull_request%}

Changes summary

    {% macro changeschangedfile(filepath, added, removed, diffanchor) -%}

            +{{added}}
            -{{removed}}

            file changed

          {{filepath}}

    {%- endmacro %}
    {% macro changesrenamedfile(oldfilepath, newfilepath, added, removed, diffanchor) -%}

+{{added}} -{{removed}}

file renamed

          {{oldfilepath}}

          {{newfilepath}}

    {%- endmacro %}
    {% macro changesdeletedfile(filepath, added, removed, diffanchor) -%}

-{{removed}}

file removed

          {{filepath}}

    {%- endmacro %}
    {% macro changesaddedfile(filepath, added, removed, diffanchor) -%}

+{{added}}

file added

          {{filepath}}

    {%- endmacro %}

    {% set count = 0 %}
    {% for patch in diff %}
        {% set count = count+1 %}

          {% if patch | hasattr('additions') %}
          {# Version of pygit2 -0.21.4 -- F21/EL7 #}
              {% set linesadded = patch.additions %}
              {% set linesremoved = patch.deletions %}
          {% else %}
          {# Version of pygit2 -0.23.0 -- F23 #}
              {% set linesadded = patch.line_stats[1] %}
              {% set linesremoved = patch.line_stats[2] %}
          {% endif %}
          {% if patch | hasattr('new_file_path') %}
            {%- if patch.new_file_path == patch.old_file_path -%}
              {%- if patch.status == 'D' -%}
                {{ changesdeletedfile(patch.new_file_path, linesadded, linesremoved, count) }}
              {%-elif patch.status == 'A' -%}
                {{ changesaddedfile(patch.new_file_path, linesadded, linesremoved, count) }}
              {%-elif patch.status == 'M' -%}
                {{ changeschangedfile(patch.new_file_path, linesadded, linesremoved, count) }}
              {%-endif-%}
            {%- else -%}
              {{changesrenamedfile(patch.old_file_path, patch.new_file_path, linesadded, linesremoved, count)}}
            {%- endif -%}
          {%- elif patch | hasattr('delta') -%}
            {%- if patch.delta.new_file.path == patch.delta.old_file.path -%}
              {%- if patch.delta.new_file.mode == 0 and patch.delta.old_file.mode == 33188 -%}
                {{ changesdeletedfile(patch.delta.new_file.path, linesadded, linesremoved, count) }}
              {%-elif patch.delta.new_file.mode == 33188 and patch.delta.old_file.mode == 0 -%}
                {{ changesaddedfile(patch.delta.new_file.path, linesadded, linesremoved, count) }}
              {%-elif patch.delta.new_file.mode == 33188 and patch.delta.old_file.mode == 33188 -%}
                {{ changeschangedfile(patch.delta.new_file.path, linesadded, linesremoved, count) }}
              {%-endif-%}
            {%- else -%}
              {{changesrenamedfile(patch.delta.old_file.path, patch.delta.new_file.path, linesadded, linesremoved, count)}}
            {%- endif -%}
          {%- endif -%}

    {% endfor %}

  {% endif %}

{% endblock %}

{% block jscripts %}
{{ super() }}

{% if config['EVENTSOURCE_SOURCE'] and pull_request %}

{% endif %}

{% endblock %}


code:
{% if authenticated %}

  <form action="{{ url_for(
    'pull_request_add_comment', username=username, repo=repo.name,
    requestid=requestid, commit=commit, tree_id=tree_id, filename=filename,
    row=row) }}"
    method="post" onsubmit="return try_async_comment(this, true)">

        <textarea class="form-control" id="comment" name="comment"
            title="comment" style="width:100%;">
          {{- form.comment.data if form.comment.data else '' -}}
        </textarea>

  {{ form.csrf_token }}

      <input type="submit" class="btn btn-primary" value="Comment" />
      <input type="button" class="btn btn-secondary cancel" value="Cancel"/>

  </form>

{% else %}

Login to comment on this ticket.

{% endif %}

repo_name: bill/auger

license: mit


code:
{% extends "repo_master.html" %}
{% from "_formhelper.html" import render_bootstrap_field %}

{% block title %}Edit PR#{{ request.id }}: {{ request.title }} - {{ repo.name }}{% endblock %}
{% set tag = "home" %}

{% block header %}
<link href="{{ url_for('static', filename='emoji/emojione.sprites.css') }}"
  rel="stylesheet" />
  <link href="{{ url_for('static', filename='selectize.bootstrap3.css') }}"
  rel="stylesheet" />
{% endblock %}

{% block repo %}

        Edit PR#{{ request.id }}: {{ request.title }} - {{ repo.name }}

        <form action="{{ url_for('.request_pull_edit',
                           username=username, repo=repo.name, requestid=request.id)
                         }}" method="post">

            {{ render_bootstrap_field(
                form.title,
                field_description="the new title of your pull-request") }}
            {{ render_bootstrap_field(
                form.initial_comment,
                field_description="description of your pull-request") }}

            <input type="submit" class="btn btn-primary" value="Edit">
            {{ form.csrf_token }}

              <input type="button" class="btn btn-secondary" value="Cancel" />

            {{ form.csrf_token }}

        </form>

{% endblock %}


code:
{% extends "repo_master.html" %}

{% block title %}Releases - {{ repo.name }}{% endblock %}
{% set tag = "home" %}

{% block repo %}

  Releases
{% if config.get('UPLOAD_FOLDER_PATH') and config.get('UPLOAD_FOLDER') %}
  {% if repo_admin %}

    <button class="btn btn-primary" type="submit" title="Upload a tarball">

      Upload a new release
    </button>

  {% endif %}
{% endif %}

{% if config.get('UPLOAD_FOLDER_PATH') and config.get('UPLOAD_FOLDER') %}

  If the developers have upload one or more tarball(s), you will be able to
  find them in the
    release folder.

{% endif %}

  {% if tags %}

    {% for tag in tags %}

{{tag['date'] | humanize}}

            {{ tag['object'].oid | short }}

        {% if tag['objecttype'] == "tag" and tag['object'].message.strip() %}
            {{tag['tagname']}}
            {{ tag['head_msg'] }}
            {% if tag['body_msg'] %}

              {{ tag['body_msg'] }}

            {% endif %}
        {% else %}
            {{tag['tagname']}}
        {% endif %}

    {% endfor %}

  {% else %}

    This project has not been tagged.

  {% endif %}

{% endblock %}


code:
{% extends "repo_master.html" %}
{% from "_formhelper.html" import render_field_in_row %}

{% block title %}Remote Pull request {{ repo.name }}{% endblock %}
{% set tag = "home" %}

{% block repo %}

New remote pull-request

  Remote pull-requests are pull-requests made from a project *not* hosted
  on pagure or not hosted on the same pagure instance than the target project,
  hosted on pagure.

  If you wish to create a pull-request from a fork to a project on pagure,
  visit your fork, go to the branch where you pushed your changes, it will
  show the commits that can be merged with a red asterisk and click on the
  "Pull-Request" button.

{% if form %}

  <form action="{{ url_for('.new_remote_request_pull', username=username,
    repo=repo.name) }}" method="post">

      {{ render_field_in_row(form.title, size=80) }}
      {{ render_field_in_row(form.git_repo, size=80) }}
      {{ render_field_in_row(form.branch_from, size=80) }}

        To branch

          <select id="branch_select" name="branch_to">
            {% if branch_to %}<option>{{ branch_to }}</option>{% endif %}
            {% for branch in branches |reverse %}
              {% if not branch_to or branch != branch_to %}
              <option>{{ branch }}</option>
              {% endif %}
            {% endfor %}
          </select>

      <input type="submit" class="submit positive button" value="Preview">
      {{ form.csrf_token }}

        <input type="button" value="Cancel" />

  </form>

{% endif %}

{% endblock %}


code:
{% extends "repo_master.html" %}

{% block title %}{{ select.capitalize() }} - {{ repo.name }}{% endblock %}
{% set tag = "home" %}

{% block repo %}

    {% if repo_obj and repo_obj.is_empty %}

This repo is brand new!

            {% if authenticated and repo_admin %}

If you already have a git repo:

git remote add origin {{ config.get('GIT_URL_SSH') }}{% if repo.parent %}forks/{% endif %}{{ repo.fullname }}.git
git push -u origin master

If you have not created your git repo yet:

git clone {{ config.get('GIT_URL_SSH') }}{% if repo.parent %}forks/{% endif %}{{ repo.fullname }}.git
cd {{ repo.name }}
touch README.rst
git add README.rst
git commit -m "Add README file"
git push -u origin master

            {% else %}

The Project Creator has not pushed any code yet

            {% endif %}

    {% else %}

            {% if readme %}

              {% if safe %}
                {{ readme | noJS |safe }}
              {% else %}
                {{ readme | noJS }}
              {% endif %}

            {% else %}

                  The {{repo.name}} project has not checked in a README file yet

            {% endif %}

    {% endif %}

Owners

                  {{ repo.user.default_email | avatar(20) | safe }}
                  {{ repo.user.fullname }} ({{ repo.user.user }})  -  creator

              {% for user in repo.users %}

                  {{ user.default_email | avatar(20) | safe }}
                  {{ user.fullname }} ({{ user.user }})

              {% endfor %}
              {% for group in repo.groups %}

                  @{{ group.group_name }}

              {% endfor %}

Branches

              {% if head %}

                  {% if branchname == head %}

                  {{ head }}
                  {% else  %}

                    {{ head }}

                  {% endif %}

              {% endif %}

            {% for branch in branches if branch != head%}

                  {% if branchname != branch %}
                  {{ branch }}

                  {% else %}
                  {{ branch }}
                  {% endif %}

                  {% if repo_admin and branch != head %}
                  <form id="delete_branch_form-{{ branch | replace('/', '_') }}" action="{{
                    url_for('.delete_branch',
                            username=username, repo=repo.name, branchname=branch)
                    }}" method="post" class="inline icon del_icon"
                    onsubmit="return confirm('Are you sure you want to remove the branch: {{ branch }}?\nThis cannot be un-done!');">
                    {{ form.csrf_token }}

                  </form>
                  {% endif %}

              {% endfor %}

Source GIT URLs{% if
              (authenticated and repo_admin) or
              (config['DOC_APP_URL'] and repo and
                      repo.settings.get('project_documentation', True))
              %}
                  more{%endif%}

SSH

                  <input class="form-control" type="text" value="{{
                    config.get('GIT_URL_SSH') }}{{ repo.fullname }}.git" readonly>

GIT

                  <input class="form-control" type="text" value="{{
                    config.get('GIT_URL_GIT') }}{{ repo.fullname }}.git" readonly>

                {% if config['DOC_APP_URL']
                    and repo
                    and repo.settings.get('project_documentation', True) %}

Docs GIT URLs

                  {% if authenticated and repo_admin %}

SSH

                        <input class="form-control" type="text" value="{{
                          config.get('GIT_URL_SSH') }}docs/{{ repo.fullname }}.git" readonly>

                  {% endif %}

GIT

                      <input class="form-control" type="text" value="{{
                        config.get('GIT_URL_GIT') }}docs/{{ repo.fullname }}.git" readonly>

                {% endif %}
                {% if authenticated and repo_admin %}
                  {% if config.get('ENABLE_TICKETS', True)
                     and repo.settings.get('issue_tracker', True) %}

Issues GIT URLs

SSH

                        <input class="form-control" type="text" value="{{
                          config.get('GIT_URL_SSH') }}tickets/{{ repo.fullname }}.git" readonly>

                  {% endif %}

Pull Requests GIT URLs

SSH

                      <input class="form-control" type="text" value="{{
                        config.get('GIT_URL_SSH') }}requests/{{ repo.fullname }}.git" readonly>

                {% endif %}

              created {{repo.date_created|humanize}}

        {% if last_commits %}

              Recent Commits in

                  {{branchname}}

                {% for commit in last_commits %}

                          {{ commit.author | author2avatar(20) | safe }}
                          {{ commit.author.name }}

                        commited {{ commit.commit_time|humanize }}

                      {{ commit.message.split('\n')[0] }}
                      {% if diff_commits and commit.oid.hex in diff_commits %}
                        *
                      {% endif %}

                {% endfor %}

        {% endif %}

{% endblock %}

{% block jscripts %}
{{ super() }}

{% endblock %}


code:
{% extends "master.html" %}

{% block title %}{{ repo.name }}{% endblock %}
{% set tag = "home" %}

{% block content %}

              {% if repo.is_fork -%}

                {{ repo.user.user }}/{{ repo.name}}
              {%- else -%}
                {{ repo.name }}
              {%- endif -%}

            {% if authenticated %}

              {% if repo.settings.get('issue_tracker', True)
                    and config.get('ENABLE_TICKETS', True)%}
              New Issue
              {% endif %}

              {% if not repo.is_fork %}
                <form method="POST" name="fork_project" id="fork_project"
                  action="{{ url_for(
                    '.fork_project', repo=repo.name, username=username) }}">
                  {{ forkbuttonform.csrf_token }}
                </form>
                <button class="btn btn-sm btn-secondary"
                  onclick="$('#fork_project').submit();">
                   Fork</button>
              {% endif %}
                <button title="{%- if is_watching(repo.name, repo.user.user if repo.is_fork else None)
                %}You are watching this project{% else %}
                You are not watching this project{% endif -%}"
                type="button" class="btn btn-sm dropdown-toggle
                {%- if is_watching(repo.name, repo.user.user if repo.is_fork else None)
                %} btn-primary{% else %} btn-secondary{% endif -%}"
                data-toggle="dropdown" id="watch-button">

                </button>

                  <form method="POST" id="watch_project" name="watch_project"
                      action="{{ url_for('.watch_repo', user=repo.user.user if repo.is_fork else None,
                                         repo=repo.name, watch=0) }}">
                   {%- if is_watching(repo.name, repo.user.user if repo.is_fork else None)
                   %}
                   Stop watching {{repo.name}}
                   {% else %}
                   Watch {{repo.name}}
                   {% endif -%}

                    {{ forkbuttonform.csrf_token }}
                  </form>

            {% endif %}

          {% if authenticated %}

          {% endif %}

        {% if repo.is_fork %}

            Forked from
            {% if repo.parent.is_fork %}

            {% else %}

            {% endif %}
                {{ repo.parent.fullname }}

        {% endif %}

        {% if repo.description %}{{ repo.description | safe }}{% else %}-{% endif -%}
        {%- if repo.url %}  |  {{ repo.url }}{% endif %}

            Overview

        {% if config['DOC_APP_URL'] and repo and repo.settings.get('project_documentation', True) %}

              Docs

        {% endif %}

              Commits

              Files

              Releases

        {% if config.get('ENABLE_TICKETS', True) and repo
              and repo.settings.get('issue_tracker', True) %}

                Issues

                  {{ repo.open_tickets if repo_admin else repo.open_tickets_public }}

        {% endif %}

        {% if repo and repo.settings.get('pull_requests', True) %}

              Pull Requests

                {{ repo.open_requests }}

        {% endif %}

        {% if repo and repo.forks %}

              Forks

                {{ repo.forks |length }}

        {% endif %}

      {% if authenticated %}
        {% if repo_admin %}

        {% endif %}
      {% endif %}
      {% if endpoint == 'view_docs' %}

      {% endif %}

{% block repo %}
{% endblock %}

{% endblock %}

{% block jscripts %}
{{ super() }}

{% endblock %}


code:
{% extends "repo_master.html" %}

{% block title %}Pull requests - {{ repo.name }}{% endblock %}
{% set tag = "home" %}

{% block repo %}

    {% if status|lower != 'open' and status|lower != 'false' %}
    {{ status }} {% elif status|lower != 'open' -%}
    Closed/Merged {% endif -%}
    Pull Requests {{ requests|count }}
    {% if authenticated and repo.settings.get('pull_requests', True) %}

      <button class="btn btn-primary btn-sm dropdown-toggle"
        type="button" id="dropdownMenu1" data-toggle="dropdown"
        aria-haspopup="true" aria-expanded="false">
        File Pull Request
      </button>

          Remote pull-request

    {%endif%}

      Open
      Closed

  Reset Filters

            Pull Request
            Opened
            {% if status|lower != 'open' %}
            Closed
            {% endif %}

              Reporter(reset)

            {% if status|lower == 'open' %}

              Assignee(reset)

            {% endif %}

    {% for request in requests %}

                PR#{{ request.id }}
                {% if status|lower not in ['open', 'true'] %}{{request.status}}{%
                  endif %} {{ request.title | noJS("img") | safe }}

              {% if request.user_comments|count > 0 %}

                  {{ request.user_comments|count }}

              {% endif %}

              {{
                request.date_created | humanize}}

            {% if status|lower not in ['open', 'true'] %}

              {{
                request.closed_at | humanize
                if request.closed_at }}

            {% endif %}

                {{ request.user.default_email | avatar(16) | safe }}
                {{ request.user.user }}

            {% if status|lower in ['open', 'true'] %}

              {% if request.assignee %}

                {{ request.assignee.default_email | avatar(16) | safe }}
                {{ request.assignee.user }}

              {% else %}
              unassigned
              {% endif %}

            {% endif %}

    {% else %}

            No Pull Requests found

    {% endfor %}

{% endblock %}

{% block jscripts %}
{{ super() }}
{% if authenticated %}

{% endif %}
{% endblock %}


code:
{% extends "repo_master.html" %}

{% block title %}Roadmap - {{ repo.name }}{% endblock %}
{% set tag = "home"%}

{% block repo %}

    {{ issues|count }} Milestones

        List

        New Issue

    {% if oth_issues %}

      {% if (issues | length + oth_issues) %}

            {{ (100.0 * (1 - issues | length / (issues | length + oth_issues)))|round|int }}%

      {% endif %}

    {% endif %}

    {% if not status %}
      Open
      All
    {% else %}
      Open
      All
    {% endif %}

    {% for tag in tag_list %}
      {% if tag.tag in tags %}

      {% else %}

      {% endif %}

        {{ tag.tag }}
    {% endfor %}

{% for milestone in milestones %}

      Milestone: {{ milestone }}
      {% if repo.milestones[milestone] %}

        Due: {{ repo.milestones[milestone] }}

      {% endif %}

        {% for issue in issues[milestone] |sort(attribute='priority') %}

              #{{ issue.id }}
              {% if status and status != 'Open' %}
              {{issue.status}}
              {% endif %}
              {% if issue.private %}

              {% endif %}

                {{ issue.title | noJS("img") | safe }}

              {% if issue.comments|count > 0 %}

                  {{issue.comments|count}}

              {% endif %}
              {% for tag in issue.tags%}
                {{tag.tag}}
              {% endfor%}

                {{
                        issue.date_created | humanize}}

              {% if issue.priority %}
                {{repo.priorities[issue.priority | string] }}
              {% endif %}

              {% if issue.status != 'Open' %}
              {{ issue.status }}
              {% else %}
                {% if issue.assignee %}
                  {{ issue.assignee.default_email | avatar(16) | safe }}
                  {{ issue.assignee.user }}
                {% else %}
                  unassigned
                {% endif %}
              {% endif %}

        {% else %}

            No issues found

        {% endfor %}

{% endfor %}
{% endblock %}
{% block jscripts %}
{{ super() }}

{% endblock %}


code:
{% extends "repo_master.html" %}
{% from "_formhelper.html" import render_field_in_row %}

{% block title %}{{ select.capitalize() }} - {{ repo.name }}{% endblock %}
{% set tag = "home" %}

{% block repo %}

Settings for {{repo.name}}

          Project Details

          <form action="{{ url_for('.update_project',
                          username=username, repo=repo.name) }}" method="post">
            <fieldset class="form-group">
              Description
              <input class="form-control" name="description" value="{{
                repo.description if repo.description }}" required/>
              Short description of the project
            </fieldset>
            <fieldset class="form-group">
                Project's url
                <input class="form-control" name="url" value="{{ repo.url if repo.url else '' }}" />
                Website URL of the project
            </fieldset>
            <fieldset class="form-group">
              Avatar email
              <input class="form-control" name="avatar_email" value="{{ repo.avatar_email if repo.avatar_email else '' }}" />
              Email address linked to avatar to display for the project
            </fieldset>
            <fieldset class="form-group">
              Project tags
              <input class="form-control" name="tags" value="{{ repo.tags_text |join(', ') if repo.tags else '' }}" />
              tags for project
            </fieldset>
            <button class="btn btn-primary" type="submit" title="Update description">
              Update
            </button>
            {{ form.csrf_token }}
          </form>

          Default Branch

          <form action="{{ url_for('change_ref_head',
                 username=username, repo=repo.name) }}" method="post">
            {{ branches_form.csrf_token }}
            {{ branches_form.branches(class_="c-select") }}
            <input class="btn btn-primary" type="submit" value="Make Default"/>
          </form>

    {% if config.get('WEBHOOK', False) %}

          Private web-hook key

            Each message sent to the web-hook are signed via hmac and SHA1 using
            this private key.

            This key is private to your project, make sure to store in a safe place
            and do not share it.

              <input class="form-control" type="text" value="{{ repo.hook_token }}" readonly>

          <form action="{{ url_for('.new_repo_hook_token',
                        username=username, repo=repo.name) }}"
              method="post" class="icon">
          <button class="btn btn-primary" type="submit"
            onclick="return confirm('Are you sure to generate a new token for '
              + 'this project/fork? \nThis will break all web hook in place and '
              + 'cannot be un-done.');"
            title="Generate a new hook token">
              Re-generate
          </button>
          {{ form.csrf_token }}
        </form>

    {% endif %}

          API Keys

            API keys are tokens used to authenticate you on pagure. They can also
            be used to grant access to 3rd party application to behave on this
            project on your name.

            These are your personal tokens; they are not visible to other owners
            of this repository.

            These keys are valid for 60 days.

            These keys are private to your project, make sure to store in a safe
            place and do not share it.

        {% if repo.tokens %}

        {% for token in repo.tokens %}
          {% if token.user.username == g.fas_user.username %}

                  <input class="form-control" type="text" value="{{ token.id }}" readonly>

            {% if token.expired %}
              Expired since {{ token.expiration.date() }}
            {% else %}
              Valid until: {{ token.expiration.date() }}
              <form class="pull-xs-right" action="{{ url_for('.revoke_api_token',
                    username=username, repo=repo.name, token_id=token.id) }}"
                method="post" class="icon">
                <button class="btn btn-danger" type="submit"
                    onclick="return confirm('Are you sure to revoke this token ?'
                        + '\nThis will break all application using it and '
                        + 'cannot be un-done.');"
                    title="Revoke token">
                    Revoke
                </button>
                {{ form.csrf_token }}
              </form>
            {% endif %}
              <button type="button" class="btn btn-link"
                data-toggle="modal" data-target="#acls{{ token.id }}">
                ACLs
              </button>

                      <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                        ×
                        Close
                      </button>

ACLs

                        {% for acl in token.acls_list_pretty %}

{{ acl }}

                        {% endfor %}

          {% endif %}
        {% endfor %}

        {% endif %}

          <button class="btn btn-primary" type="submit"
            title="Generate a new API token">
            Create new key
          </button>

          Project options

          <form action="{{ url_for('.view_settings',
                          username=username, repo=repo.name) }}" method="post">
            {% for key in repo.settings | sort %}
            {% if not config.get('ENABLE_TICKETS', True) and key in ['issue_tracker'] %}
            {% elif not config.get('DOC_APP_URL') and key in ['project_documentation'] %}
            {% elif not config.get('WEBHOOK') and key in ['Web-hooks'] %}
            {% else %}
              {% if repo.settings[key] in [True, False, 'y'] %}

                    <input id="{{ key }}" type="checkbox" value="y" name="{{ key }}" {%
                            if repo.settings[key] -%}checked=""{%- endif -%}/>

                    Activate {{ key | replace('_', ' ') }}

              {% else %}

                  Activate {{ key | replace('_', ' ') }} :
                  <input width="4em" class="form-control" id="{{ key }}" type="text" {% if repo.settings[key]
                        %}value="{{ repo.settings[key] }}"{% endif %} name="{{ key }}" />

              {% endif %}
            {% endif %}
            {% endfor %}

              <input type="submit" class="btn btn-primary" value="Update">
              {{ form.csrf_token }}

          </form>

          Re-generate git repos

          <form action="{{ url_for('.regenerate_git',
                          username=username, repo=repo.name) }}" method="post"
                class="icon">
            <input name="regenerate" value="tickets" type="hidden"/>
            <button class="btn btn-primary" type="submit"
              title="Regenerate tickets git repo">
                Regenerate the git repo for issues
            </button>
            {{ form.csrf_token }}
          </form>
          <form class="m-t-2" action="{{ url_for('.regenerate_git',
                          username=username, repo=repo.name) }}" method="post"
                class="icon">
            <input name="regenerate" value="requests" type="hidden"/>
            <button class="btn btn-primary" type="submit"
              title="Regenerate requests git repo">
                Regenerate the git repo for requests
            </button>
            {{ form.csrf_token }}
          </form>

    {% if config.get('ENABLE_USER_MNGT', True) %}

          Users and Groups

Below is the list of user having commit rights to this repo.

                add user

                add group

                  {{ repo.user.user }}

              (owner)

          {% for user in repo.users %}

                  {{ user.user }}

              <form class="pull-xs-right" method="POST"
                action="{{ url_for('.remove_user', username=username, repo=repo.name, userid=user.id) }}">
                <button
                  onclick="return confirm('You sure you want to remove this user from this project?');"
                  title="Remove user" class="btn btn-danger btn-sm">

                </button>
                {{ form.csrf_token }}
              </form>

          {% endfor %}
          {% for group in repo.groups %}

                  {{ group.group_name }}

              <form class="pull-xs-right" method="POST"
                action="{{ url_for('.remove_group_project', username=username, repo=repo.name, groupid=group.id) }}">
                <button
                  onclick="return confirm('You sure you want to remove this group from this project?');"
                  title="Remove group" class="btn btn-danger btn-sm pull-xs-right">

                </button>
                {{ form.csrf_token }}
              </form>

          {% endfor %}

    {% endif %}

    {% if plugins %}

          Hooks

            {% set idcount = 1 %}
            {% for plugin in plugins %}

                     {{ plugin }}

            {% set idcount = idcount+1 %}
            {% endfor %}

    {% endif %}

    {% if config.get('ENABLE_TICKETS', True)
        and repo.settings.get('issue_tracker', True) %}

          Priorities

            Below are the priorities you may assign to a ticket, allowing you
            to sort them with it. The Weight determines the ordering. Higher
            priority should correspond to higher weight.

              To remove an entry, simply clean the Weight and Title

        <form action="{{ url_for('.update_priorities',
                          username=username, repo=repo.name) }}"
            method="post" class="icon">
          {{ tag_form.csrf_token }}

                Weight

                Title

          {% for priority in repo.priorities | sort %}

                  <input type="text" name="priority_weigth"
                    value="{{ priority }}" size="3" class="form-control"/>

                  <input type="text" name="priority_title"
                    value="{{ repo.priorities[priority] }}" class="form-control"/>

          {% endfor %}

                  Add new priority

            {% if not repo.priorities %}

                  Default priority set

            {% endif %}

              <button class="btn btn-primary" type="submit"
                  title="Update the priorities">
                Update
              </button>

        </form>

          Roadmap

            Below are the milestones you may assign to a ticket, allowing
            you to build a roadmap using the `roadmap` tag and a tag
            corresponding to one of the milestones defined here.

        <form action="{{ url_for('.update_milestones',
                          username=username, repo=repo.name) }}"
            method="post" class="icon">
          {{ tag_form.csrf_token }}

                Milestone

                Date (optional)

          {% for milestone in repo.milestones | sort %}

                  <input type="text" name="milestones"
                    value="{{ milestone }}" size="3" class="form-control"/>

                  <input type="text" name="milestone_dates"
                    value="{{ repo.milestones[milestone] }}" class="form-control"/>

          {% endfor %}

                  Add new milestone

              <button class="btn btn-primary" type="submit"
                  title="Update the milestones">
                Update
              </button>

        </form>

          Issue Tags

            Here below is the list of tags associated with one or more issue of
            the project.

        {% for tag in tags %}

                {{ tag.tag }}

            <form class="icon del_icon pull-xs-right" method="POST"
              action="{{ url_for('remove_tag', username=username, repo=repo.name) }}">
              <input type="hidden" value="{{ tag.tag }}" name="tag" />
              {{ tag_form.csrf_token }}
              <button
                onclick="return confirm('Do you really want to remove the tag: {{ tag.tag }}?');"
                title="Remove tag" class="btn btn-danger btn-sm">

              </button>
            </form>

              <button class="btn btn-default btn-sm" title="Edit tag">

              </button>

        {% endfor %}

    {% endif %}

    {% if config.get('ENABLE_DEL_PROJECTS', True) %}

          Delete Project

        <form action="{{ url_for('.delete_repo',
                        username=username, repo=repo.name) }}"
              method="post" class="icon">
          <button class="btn btn-danger" type="submit"
            onclick="return confirm('Are you sure to delete {{repo.name}}? \nThis is final and cannot be un-done.');"
            title="Delete the project/fork">
                Delete the {{repo.name}} project
          </button>
        </form>

    {% endif %}

{% endblock %}

{% block jscripts %}
{{ super() }}

{% endblock %}


code:
{% extends "master.html" %}

{% block title %}Unauthorized :'({% endblock %}
{% set tag = "error" %}

{% block content %}

Unauthorized (401)

You are not authorized to display the requested page.

If you're not logged in, try to login; if you're already done,
      that probably means you do not have sufficient access.

{% endblock %}


code:
{% extends "master.html" %}
{% from "_formhelper.html" import render_bootstrap_field %}

{% block title %}Add email{% endblock %}
{% set tag = "home" %}

{% block content %}

      Add new email

        <form action="{{ url_for('.add_user_email') }}" method="post">
            {{ render_bootstrap_field(form.email) }}
            <input type="submit" class="btn btn-primary" value="Add">
            <input type="button" value="Cancel" class="btn btn-secondary" onclick="history.back();">
            {{ form.csrf_token }}
        </form>

{% endblock %}


code:
{% extends "master.html" %}

{% block title %}User {{username}}{% endblock %}
{% set tag = "users" %}
{% from "_browseheader.html" import browse_header %}

{% block header %}
  <link href="{{ url_for('static', filename='selectize.bootstrap3.css') }}"
  rel="stylesheet" />
{% endblock %}

{% from "_render_repo.html" import render_repos_as_card, render_contributions_graph %}

{% block content %}

    {{browse_header(select=tag)}}

        {{ user.default_email | avatar(36) | safe }} {{ username }}

      Joined {{ user.created | humanize }}

        {{ render_repos_as_card(repos, repos_length, 'Projects', 'repopage', repopage, total_page_repos) }}
        {{ render_repos_as_card(forks, forks_length,'Forks', 'forkpage', forkpage, total_page_forks) }}
        {{ render_contributions_graph(username) }}

                Groups {{ user.groups | length }}

            {% for group in user.groups %}

                      {{ group }}

            {% else %}

No group found

            {% endfor %}

{% endblock %}

{% block jscripts %}
    {{ super() }}

{% endblock %}


code:
{% extends "master.html" %}
{% block title %}Users{% endblock %}
{% set tag = "users" %}
{% from "_browseheader.html" import browse_header %}

{% block header %}
<link href="{{ url_for('static', filename='selectize.bootstrap3.css') }}"
  rel="stylesheet" />
{% endblock %}

{% block content %}

    {{browse_header(select=select)}}

  {% if total_page and total_page > 1 %}

      <li {% if page <= 1%} class="disabled" {% endif %}>

          «
          Newer

page {{ page }} of {{total_page}}

= total_page %}class="disabled"{%endif%}>

          »
          Older

  {% endif %}

      Users {{ users_length }}
      {%- if authenticated and config.get('PAGURE_AUTH') == 'local' %}

      <button type="button" class="btn btn-success pull-xs-right">
          New User
      </button>

      {% endif -%}

    {% for user in users %}

{{ user.fullname }}

            {{ user.user }} joined {{
            user.created | humanize }}

                {{- user.repos_length}}

                {{- user.forks_length}}

                {{- user.groups|count}}

    {% endfor %}

  {% if total_page and total_page > 1 %}

      <li {% if page <= 1%} class="disabled" {% endif %}>

          «
          Newer

page {{ page }} of {{total_page}}

= total_page %}class="disabled"{%endif%}>

          »
          Older

  {% endif %}

{% endblock %}

{% block jscripts %}
    {{ super() }}

{% endblock %}


code:
{% extends "master.html" %}
{% from "_formhelper.html" import render_field_in_row %}
{% from "_browseheader.html" import browse_header %}

{% block title %}Pull-requests of {{ username }}{% endblock %}
{% set tag = "users"%}

{% block content %}

    {{browse_header(select=tag)}}

        Pull Requests opened by {{ username | avatar(20) | safe }} {{ username }}

          Open
          Merged
          Closed
          All

                #
                Status
                Title
                Opened
                Project
                Assigned to

        {% for request in requests %}

                PR#{{ request.id }}
                {{request.status}}

                    {{ request.title | noJS("img") | safe }}

                    {{
                        request.date_created | humanize}}

                    {{ request.project.username + '/' if request.project.is_fork }}
                    {{ request.project.name }}

                  {% if request.assignee %}
                  {{ request.assignee.default_email | avatar(16) | safe }}
                  {{ request.assignee.user }}
                  {% else %}
                  unassigned
                  {% endif %}

        {% else %}

                No pull-request found

        {% endfor %}

{% endblock %}

{% block jscripts %}
    {{ super() }}

{% endblock %}


code:
{% extends "master.html" %}
{% from "_formhelper.html" import render_bootstrap_field %}

{% block title %}{{ user.user }}'s settings{% endblock %}
{% set tag = "users"%}

{% macro render_email(email, form, validated=True) %}

    {{ email.email }}
  {% if validated %}
    <form class="pull-xs-right" method="POST"
        action="{{ url_for('remove_user_email') }}">
      <input type="hidden" value="{{ email.email }}" name="email" />
      {{ form.csrf_token }}
      <button
        onclick="return confirm('Do you really want to remove the email: {{ email.email }}?');"
        title="Remove email" class="btn btn-sm btn-danger">

      </button>
    </form>
    {% if email.email == user.default_email %}

    {% else %}
    <form style="display:inline;" method="POST"
      action="{{ url_for('set_default_email') }}" id="default_mail">
      <input type="hidden" value="{{ email.email }}" name="email" />
      {{ form.csrf_token }}

        set as default

    </form>
    {% endif %}
  {% else %}

      pending verification via email
      <form style="display:inline;" method="POST"
        action="{{ url_for('reconfirm_email') }}" id="reconfirm_mail">
        <input type="hidden" value="{{ email.email }}" name="email" />
        {{ form.csrf_token }}
        <button
          onclick="$(this).closest('form').submit();"
          title="Resend validation email" class="btn btn-sm btn-warning">

        </button>
      </form>

  {% endif %}

{% endmacro %}

{% block content %}

          Basic Information

        <fieldset class="form-group">
          Username

{{ user.user }}

        </fieldset>
        <fieldset class="form-group">
          Full Name

{{ user.fullname }}

        </fieldset>
        <fieldset class="form-group">
          Avatar

               {{ g.fas_user.username | avatar(80) | safe }}

                 Change Avatar

        </fieldset>

        Email Addresses

                  Add Email

        {% for email in user.emails %}
          {{ render_email(email, form) }}
        {% endfor %}
        {% for email in user.emails_pending %}
          {{ render_email(email, form, validated=False) }}
        {% endfor %}

          Authentication

        <form action="{{ url_for('user_settings') }}" method="post">
          {{ render_bootstrap_field(form.ssh_key) }}

            <input type="submit" class="btn btn-primary" value="Update">
            <input type="button" class="btn btn-secondary" value="Cancel" class="button" onclick="history.back();">
            {{ form.csrf_token }}

        </form>

        {% if config.get('PAGURE_AUTH')=='local' %}
            Change password
        {% endif %}

{% endblock %}


code:
# -*- coding: utf-8 -*-

"""
 (c) 2014 - Copyright Red Hat Inc

 Authors:
   Pierre-Yves Chibon <pingou@pingoured.fr>

"""


code:
# -*- coding: utf-8 -*-

"""
 (c) 2014-2015 - Copyright Red Hat Inc

 Authors:
   Pierre-Yves Chibon <pingou@pingoured.fr>

"""

from functools import wraps

import flask
from sqlalchemy.exc import SQLAlchemyError

import pagure.exceptions
import pagure.forms
import pagure.lib
import pagure.lib.git
from pagure import (APP, SESSION, generate_user_key_files,
                    is_admin, admin_session_timedout)

# pylint: disable=E1101

def admin_required(function):
    """ Flask decorator to retrict access to admins of pagure.
    """
    @wraps(function)
    def decorated_function(*args, **kwargs):
        """ Decorated function, actually does the work. """
        if admin_session_timedout():
            return flask.redirect(
                flask.url_for('auth_login', next=flask.request.url))
        elif not is_admin():
            flask.flash('Access restricted', 'error')
            return flask.redirect(flask.url_for('.index'))

        return function(*args, **kwargs)
    return decorated_function

# Application

@APP.route('/admin/')
@APP.route('/admin')
@admin_required
def admin_index():
    """ Front page of the admin section of the application.
    """
    form = pagure.forms.ConfirmationForm()

    return flask.render_template(
        'admin_index.html', form=form,
    )

@APP.route('/admin/gitolite', methods=['POST'])
@admin_required
def admin_generate_acl():
    """ Regenerate the gitolite ACL file. """
    form = pagure.forms.ConfirmationForm()
    if form.validate_on_submit():
        try:
            pagure.lib.git.generate_gitolite_acls()
            flask.flash('Gitolite ACLs updated')
        except pagure.exceptions.PagureException as err:
            flask.flash(str(err), 'error')
    return flask.redirect(flask.url_for('admin_index'))

@APP.route('/admin/ssh', methods=['POST'])
@admin_required
def admin_refresh_ssh():
    """ Regenerate the user key files. """
    form = pagure.forms.ConfirmationForm()
    if form.validate_on_submit():
        try:
            generate_user_key_files()
            pagure.lib.git.generate_gitolite_acls()
            flask.flash('User key files regenerated')
        except pagure.exceptions.PagureException as err:
            flask.flash(str(err), 'error')
    return flask.redirect(flask.url_for('admin_index'))

@APP.route('/admin/hook_token', methods=['POST'])
@admin_required
def admin_generate_hook_token():
    """ Regenerate the hook_token for each projects in the DB. """
    form = pagure.forms.ConfirmationForm()
    if form.validate_on_submit():
        pagure.lib.generate_hook_token(SESSION)
        flask.flash('Hook token all re-generated')
    return flask.redirect(flask.url_for('admin_index'))


code:
# -*- coding: utf-8 -*-

"""
 (c) 2014-2015 - Copyright Red Hat Inc

 Authors:
   Pierre-Yves Chibon <pingou@pingoured.fr>

"""

import flask
from math import ceil

from sqlalchemy.exc import SQLAlchemyError

import pagure.exceptions
import pagure.lib
import pagure.lib.git
import pagure.forms
import pagure.ui.filters
from pagure import (APP, SESSION, login_required,
                    authenticated,
                    admin_session_timedout)

# Application
# pylint: disable=E1101

@APP.route('/browse/projects', endpoint='browse_projects')
@APP.route('/browse/projects/', endpoint='browse_projects')
@APP.route('/')
def index():
    """ Front page of the application.
    """
    sorting = flask.request.args.get('sorting') or None
    page = flask.request.args.get('page', 1)
    try:
        page = int(page)
        if page < 1:
            page = 1
    except ValueError:
        page = 1

    limit = APP.config['ITEM_PER_PAGE']
    start = limit * (page - 1)

    repos = pagure.lib.search_projects(
        SESSION,
        fork=False,
        start=start,
        limit=limit,
        sort=sorting)

    num_repos = pagure.lib.search_projects(
        SESSION,
        fork=False,
        count=True)
    total_page = int(ceil(num_repos / float(limit)))

    if authenticated() and flask.request.path == '/':
        return index_auth()

    return flask.render_template(
        'index.html',
        select="projects",
        repos=repos,
        repos_length=num_repos,
        total_page=total_page,
        page=page,
        sorting=sorting,
    )

def index_auth():
    """ Front page for authenticated user.
    """
    user = pagure.lib.search_user(SESSION, username=flask.g.fas_user.username)
    if not user:
        flask.abort(404, 'No user `%s` found, re-login maybe?' % (
            flask.g.fas_user.username))

    repopage = flask.request.args.get('repopage', 1)
    try:
        repopage = int(repopage)
        if repopage < 1:
            page = 1
    except ValueError:
        repopage = 1

    forkpage = flask.request.args.get('forkpage', 1)
    try:
        forkpage = int(forkpage)
        if forkpage < 1:
            page = 1
    except ValueError:
        forkpage = 1

    repos = pagure.lib.search_projects(
        SESSION,
        username=flask.g.fas_user.username,
        fork=False)
    repos_length = pagure.lib.search_projects(
        SESSION,
        username=flask.g.fas_user.username,
        fork=False,
        count=True)

    forks = pagure.lib.search_projects(
        SESSION,
        username=flask.g.fas_user.username,
        fork=True)
    forks_length = pagure.lib.search_projects(
        SESSION,
        username=flask.g.fas_user.username,
        fork=True,
        count=True)

    return flask.render_template(
        'index_auth.html',
        username=flask.g.fas_user.username,
        user=user,
        forks=forks,
        repos=repos,
        repopage=repopage,
        forkpage=forkpage,
        repos_length=repos_length,
        forks_length=forks_length,
    )

@APP.route('/search/')
@APP.route('/search')
def search():
    """ Search this pagure instance for projects or users.
    """
    stype = flask.request.args.get('type', 'projects')
    term = flask.request.args.get('term')
    page = flask.request.args.get('page', 1)
    try:
        page = int(page)
        if page < 1:
            page = 1
    except ValueError:
        page = 1

    if stype == 'projects':
        return flask.redirect(flask.url_for('view_projects', pattern=term))
    elif stype == 'projects_forks':
        return flask.redirect(flask.url_for(
            'view_projects', pattern=term, forks=True))
    else:
        return flask.redirect(flask.url_for('view_users', username=term))

@APP.route('/users/')
@APP.route('/users')
@APP.route('/users/<username>')
def view_users(username=None):
    """ Present the list of users.
    """
    page = flask.request.args.get('page', 1)
    try:
        page = int(page)
        if page < 1:
            page = 1
    except ValueError:
        page = 1

    users = pagure.lib.search_user(SESSION, pattern=username)

    if len(users) == 1:
        flask.flash('Only one result found, redirecting you to it')
        return flask.redirect(
            flask.url_for('view_user', username=users[0].username))

    limit = APP.config['ITEM_PER_PAGE']
    start = limit * (page - 1)
    end = limit * page
    users_length = len(users)
    users = users[start:end]

    total_page = int(ceil(users_length / float(limit)))

    for user in users:
        repos_length = pagure.lib.search_projects(
            SESSION,
            username=user.user,
            fork=False,
            count=True)

        forks_length = pagure.lib.search_projects(
            SESSION,
            username=user.user,
            fork=True,
            count=True)
        user.repos_length = repos_length
        user.forks_length = forks_length

    return flask.render_template(
        'user_list.html',
        users=users,
        users_length=users_length,
        total_page=total_page,
        page=page,
        select='users',
    )

@APP.route('/projects/')
@APP.route('/projects')
@APP.route('/projects/<pattern>')
def view_projects(pattern=None):
    """ Present the list of projects.
    """
    forks = flask.request.args.get('forks')
    page = flask.request.args.get('page', 1)

    try:
        page = int(page)
        if page < 1:
            page = 1
    except ValueError:
        page = 1

    select = 'projects'
    # If forks is specified, we want both forks and projects
    if str(forks).lower() in ['true', '1']:
        forks = None
        select = 'projects_forks'
    else:
        forks = False

    limit = APP.config['ITEM_PER_PAGE']
    start = limit * (page - 1)

    projects = pagure.lib.search_projects(
        SESSION, pattern=pattern, fork=forks, start=start, limit=limit)

    if len(projects) == 1:
        flask.flash('Only one result found, redirecting you to it')
        return flask.redirect(flask.url_for(
            'view_repo', repo=projects[0].name,
            username=projects[0].user.username if projects[0].is_fork else None
        ))

    limit = APP.config['ITEM_PER_PAGE']
    start = limit * (page - 1)
    end = limit * page
    projects_length = len(projects)
    projects = projects[start:end]

    total_page = int(ceil(projects_length / float(limit)))

    return flask.render_template(
        'index.html',
        repos=projects,
        repos_length=projects_length,
        total_page=total_page,
        page=page,
        select=select,
    )

@APP.route('/user/<username>/')
@APP.route('/user/<username>')
def view_user(username):
    """ Front page of a specific user.
    """
    user = pagure.lib.search_user(SESSION, username=username)
    if not user:
        flask.abort(404, 'No user `%s` found' % username)

    repopage = flask.request.args.get('repopage', 1)
    try:
        repopage = int(repopage)
        if repopage < 1:
            repopage = 1
    except ValueError:
        repopage = 1

    forkpage = flask.request.args.get('forkpage', 1)
    try:
        forkpage = int(forkpage)
        if forkpage < 1:
            forkpage = 1
    except ValueError:
        forkpage = 1

    limit = APP.config['ITEM_PER_PAGE']
    repo_start = limit * (repopage - 1)
    fork_start = limit * (forkpage - 1)

    repos = pagure.lib.search_projects(
        SESSION,
        username=username,
        fork=False,
        start=repo_start,
        limit=limit)
    repos_length = pagure.lib.search_projects(
        SESSION,
        username=username,
        fork=False,
        count=True)

    forks = pagure.lib.search_projects(
        SESSION,
        username=username,
        fork=True,
        start=fork_start,
        limit=limit)
    forks_length = pagure.lib.search_projects(
        SESSION,
        username=username,
        fork=True,
        count=True)

    total_page_repos = int(ceil(repos_length / float(limit)))
    total_page_forks = int(ceil(forks_length / float(limit)))

    return flask.render_template(
        'user_info.html',
        username=username,
        user=user,
        repos=repos,
        total_page_repos=total_page_repos,
        forks=forks,
        total_page_forks=total_page_forks,
        repopage=repopage,
        forkpage=forkpage,
        repos_length=repos_length,
        forks_length=forks_length,
    )

@APP.route('/user/<username>/requests/')
@APP.route('/user/<username>/requests')
def view_user_requests(username):
    """ Shows the pull-requests for the specified user.
    """
    user = pagure.lib.search_user(SESSION, username=username)
    if not user:
        flask.abort(404, 'No user `%s` found' % username)

    requests = pagure.lib.get_pull_request_of_user(
        SESSION,
        username=username
    )

    return flask.render_template(
        'user_requests.html',
        username=username,
        user=user,
        requests=requests,
    )

@APP.route('/new/', methods=('GET', 'POST'))
@APP.route('/new', methods=('GET', 'POST'))
@login_required
def new_project():
    """ Form to create a new project.
    """
    user = pagure.lib.search_user(SESSION, username=flask.g.fas_user.username)

    if not pagure.APP.config.get('ENABLE_NEW_PROJECTS', True):
        flask.abort(404, 'Creation of new project is not allowed on this \
                pagure instance')

    form = pagure.forms.ProjectForm()
    if form.validate_on_submit():
        name = form.name.data
        description = form.description.data
        url = form.url.data
        avatar_email = form.avatar_email.data
        create_readme = form.create_readme.data

        try:
            message = pagure.lib.new_project(
                SESSION,
                name=name,
                description=description,
                url=url,
                avatar_email=avatar_email,
                user=flask.g.fas_user.username,
                blacklist=APP.config['BLACKLISTED_PROJECTS'],
                allowed_prefix=APP.config['ALLOWED_PREFIX'],
                gitfolder=APP.config['GIT_FOLDER'],
                docfolder=APP.config['DOCS_FOLDER'],
                ticketfolder=APP.config['TICKETS_FOLDER'],
                requestfolder=APP.config['REQUESTS_FOLDER'],
                add_readme=create_readme,
                userobj=user,
                prevent_40_chars=APP.config.get(
                    'OLD_VIEW_COMMIT_ENABLED', False),
            )
            SESSION.commit()
            pagure.lib.git.generate_gitolite_acls()
            return flask.redirect(flask.url_for('view_repo', repo=name))
        except pagure.exceptions.PagureException as err:
            flask.flash(str(err), 'error')
        except SQLAlchemyError as err:  # pragma: no cover
            SESSION.rollback()
            flask.flash(str(err), 'error')

    return flask.render_template(
        'new_project.html',
        form=form,
    )

@APP.route('/settings/', methods=('GET', 'POST'))
@APP.route('/settings', methods=('GET', 'POST'))
@login_required
def user_settings():
    """ Update the user settings.
    """
    if admin_session_timedout():
        return flask.redirect(
            flask.url_for('auth_login', next=flask.request.url))

    user = pagure.lib.search_user(
        SESSION, username=flask.g.fas_user.username)
    if not user:
        flask.abort(404, 'User not found')

    form = pagure.forms.UserSettingsForm()
    if form.validate_on_submit():
        ssh_key = form.ssh_key.data

        try:
            message = 'Nothing to update'
            if user.public_ssh_key != ssh_key:
                pagure.lib.update_user_ssh(
                    SESSION,
                    user=user,
                    ssh_key=ssh_key,
                    keydir=APP.config.get('GITOLITE_KEYDIR', None),
                )
                SESSION.commit()
                message = 'Public ssh key updated'
            flask.flash(message)
            return flask.redirect(
                flask.url_for('.user_settings'))
        except SQLAlchemyError as err:  # pragma: no cover
            SESSION.rollback()
            flask.flash(str(err), 'error')
    elif flask.request.method == 'GET':
        form.ssh_key.data = user.public_ssh_key

    return flask.render_template(
        'user_settings.html',
        user=user,
        form=form,
    )

@APP.route('/markdown/', methods=['POST'])
def markdown_preview():
    """ Return the provided markdown text in html.

    The text has to be provided via the parameter 'content' of a POST query.
    """
    form = pagure.forms.ConfirmationForm()
    if form.validate_on_submit():
        return pagure.ui.filters.markdown_filter(flask.request.form['content'])
    else:
        flask.abort(400, 'Invalid request')

@APP.route('/settings/email/drop', methods=['POST'])
@login_required
def remove_user_email():
    """ Remove the specified email from the logged in user.
    """
    if admin_session_timedout():
        return flask.redirect(
            flask.url_for('auth_login', next=flask.request.url))

    user = pagure.lib.search_user(
        SESSION, username=flask.g.fas_user.username)
    if not user:
        flask.abort(404, 'User not found')

    if len(user.emails) == 1:
        flask.flash(
            'You must always have at least one email', 'error')
        return flask.redirect(
            flask.url_for('.user_settings')
        )

    form = pagure.forms.UserEmailForm()

    if form.validate_on_submit():
        email = form.email.data
        useremails = [mail.email for mail in user.emails]

        if email not in useremails:
            flask.flash(
                'You do not have the email: %s, nothing to remove' % email,
                'error')
            return flask.redirect(
                flask.url_for('.user_settings')
            )

        for mail in user.emails:
            if mail.email == email:
                user.emails.remove(mail)
                break
        try:
            SESSION.commit()
            flask.flash('Email removed')
        except SQLAlchemyError as err:  # pragma: no cover
            SESSION.rollback()
            APP.logger.exception(err)
            flask.flash('Email could not be removed', 'error')

    return flask.redirect(flask.url_for('.user_settings'))

@APP.route('/settings/email/add/', methods=['GET', 'POST'])
@APP.route('/settings/email/add', methods=['GET', 'POST'])
@login_required
def add_user_email():
    """ Add a new email for the logged in user.
    """
    if admin_session_timedout():
        return flask.redirect(
            flask.url_for('auth_login', next=flask.request.url))

    user = pagure.lib.search_user(
        SESSION, username=flask.g.fas_user.username)
    if not user:
        flask.abort(404, 'User not found')

    form = pagure.forms.UserEmailForm(
        emails=[mail.email for mail in user.emails])
    if form.validate_on_submit():
        email = form.email.data

        try:
            pagure.lib.add_user_pending_email(SESSION, user, email)
            SESSION.commit()
            flask.flash('Email pending validation')
            return flask.redirect(flask.url_for('.user_settings'))
        except pagure.exceptions.PagureException as err:
            flask.flash(str(err), 'error')
        except SQLAlchemyError as err:  # pragma: no cover
            SESSION.rollback()
            APP.logger.exception(err)
            flask.flash('Email could not be added', 'error')

    return flask.render_template(
        'user_emails.html',
        user=user,
        form=form,
    )

@APP.route('/settings/email/default', methods=['POST'])
@login_required
def set_default_email():
    """ Set the default email address of the user.
    """
    if admin_session_timedout():
        return flask.redirect(
            flask.url_for('auth_login', next=flask.request.url))

    user = pagure.lib.search_user(
        SESSION, username=flask.g.fas_user.username)
    if not user:
        flask.abort(404, 'User not found')

    form = pagure.forms.UserEmailForm()
    if form.validate_on_submit():
        email = form.email.data
        useremails = [mail.email for mail in user.emails]

        if email not in useremails:
            flask.flash(
                'You do not have the email: %s, nothing to set' % email,
                'error')

            return flask.redirect(
                flask.url_for('.user_settings')
            )

        user.default_email = email

        try:
            SESSION.commit()
            flask.flash('Default email set to: %s' % email)
        except SQLAlchemyError as err:  # pragma: no cover
            SESSION.rollback()
            APP.logger.exception(err)
            flask.flash('Default email could not be set', 'error')

    return flask.redirect(flask.url_for('.user_settings'))

@APP.route('/settings/email/resend', methods=['POST'])
@login_required
def reconfirm_email():
    """ Re-send the email address of the user.
    """
    if admin_session_timedout():
        return flask.redirect(
            flask.url_for('auth_login', next=flask.request.url))

    user = pagure.lib.search_user(
        SESSION, username=flask.g.fas_user.username)
    if not user:
        flask.abort(404, 'User not found')

    form = pagure.forms.UserEmailForm()
    if form.validate_on_submit():
        email = form.email.data

        try:
            pagure.lib.resend_pending_email(SESSION, user, email)
            SESSION.commit()
            flask.flash('Confirmation email re-sent')
        except pagure.exceptions.PagureException as err:
            flask.flash(str(err), 'error')
        except SQLAlchemyError as err:  # pragma: no cover
            SESSION.rollback()
            APP.logger.exception(err)
            flask.flash('Confirmation email could not be re-sent', 'error')

    return flask.redirect(flask.url_for('.user_settings'))

@APP.route('/settings/email/confirm/<token>/')
@APP.route('/settings/email/confirm/<token>')
def confirm_email(token):
    """ Confirm a new email.
    """
    if admin_session_timedout():
        return flask.redirect(
            flask.url_for('auth_login', next=flask.request.url))

    email = pagure.lib.search_pending_email(SESSION, token=token)
    if not email:
        flask.flash('No email associated with this token.', 'error')
    else:
        try:
            pagure.lib.add_email_to_user(SESSION, email.user, email.email)
            SESSION.delete(email)
            SESSION.commit()
            flask.flash('Email validated')
        except SQLAlchemyError as err:  # pragma: no cover
            SESSION.rollback()
            flask.flash(
                'Could not set the account as active in the db, '
                'please report this error to an admin', 'error')
            APP.logger.exception(err)

    return flask.redirect(flask.url_for('.user_settings'))

@APP.route('/ssh_info/')
@APP.route('/ssh_info')
def ssh_hostkey():
    """ Endpoint returning information about the SSH hostkey and fingerprint
    of the current pagure instance.
    """
    return flask.render_template(
        'doc_ssh_keys.html',
    )


code:
# -*- coding: utf-8 -*-

"""
 (c) 2014 - Copyright Red Hat Inc

 Authors:
   Pierre-Yves Chibon <pingou@pingoured.fr>

"""

import datetime
import textwrap

import arrow
import flask
import md5

from pygments import highlight
from pygments.lexers.text import DiffLexer
from pygments.formatters import HtmlFormatter

import pagure.exceptions
import pagure.lib
import pagure.forms
from pagure import (APP, SESSION, authenticated, is_repo_admin)

# Jinja filters

@APP.template_filter('hasattr')
def jinja_hasattr(obj, string):
    """ Template filter checking if the provided object at the provided
    string as attribute
    """
    return hasattr(obj, string)

@APP.template_filter('humanize')
def humanize_date(date):
    """ Template filter returning the last commit date of the provided repo.
    """
    return arrow.get(date).humanize()

@APP.template_filter('format_ts')
def format_ts(string):
    """ Template filter transforming a timestamp to a date
    """
    dattime = datetime.datetime.fromtimestamp(int(string))
    return dattime.strftime('%b %d %Y %H:%M:%S')

@APP.template_filter('format_loc')
def format_loc(loc, commit=None, filename=None, tree_id=None, prequest=None,
               index=None):
    """ Template filter putting the provided lines of code into a table
    """
    if loc is None:
        return

    output = [
        '
',
        '
'
    ]

    comments = {}
    if prequest and not isinstance(prequest, flask.wrappers.Request):
        for com in prequest.comments:
            if commit and unicode(com.commit_id) == unicode(commit) \
                    and unicode(com.filename) == unicode(filename):
                if com.line in comments:
                    comments[com.line].append(com)
                else:
                    comments[com.line] = [com]
    for key in comments:
        comments[key] = sorted(
            comments[key], key=lambda obj: obj.date_created)

    if not index:
        index = ''

    cnt = 1
    for line in loc.split('\n'):
        if line == '

':
            break
        if filename and commit:
            output.append(
                '
'
                '	'
                ''
                '
'
                ''
                '
'
                '	' % (
                    {
                        'cnt': '%s_%s' % (index, cnt),
                        'cnt_lbl': cnt,
                        'img': flask.url_for('static', filename='users.png'),
                        'filename': filename.decode('UTF-8'),
                        'commit': commit,
                        'tree_id': tree_id,
                    }
                )
            )
        else:
            output.append(
                '
'
                '	'
                % (
                    {
                        'cnt': '%s_%s' % (index, cnt),
                        'cnt_lbl': cnt,
                    }
                )
            )

        cnt += 1
        if not line:
            output.append(line)
            continue
        if line.startswith('<div'):
            line = line.split('
')[1]
        output.append('
%s
	' % line)
        output.append('
')

        tpl_edit = '' \
            '' \
            ''
        tpl_edited = ' ' \
            'Edited %(human_edit_date)s by %(user)s '

        tpl_delete = '<button class="btn btn-secondary btn-sm" '\
            'title="Remove comment" '\
            'name="drop_comment" value="%(commentid)s" type="submit" ' \
            'onclick="return confirm(\'Do you really want to remove this comment?\');" '\
            '>' \
            '</button>'

        if cnt - 1 in comments:
            for comment in comments[cnt - 1]:

                templ_delete = ''
                templ_edit = ''
                templ_edited = ''
                if authenticated() and (
                        (str(comment.parent.status).lower() in ['true', 'open']
                         and comment.user.user == flask.g.fas_user.username)
                         or is_repo_admin(comment.parent.project)):
                    templ_delete = tpl_delete % ({'commentid': comment.id})
                    templ_edit = tpl_edit %({
                        'edit_url': flask.url_for(
                            'pull_request_edit_comment',
                            repo=comment.parent.project.name,
                            requestid=comment.parent.id,
                            commentid=comment.id,
                            username=comment.parent.user.user \
                                if comment.parent.project.is_fork else None
                        ),
                        'requestid': comment.parent.id,
                        'commentid': comment.id,
                    })

                if comment.edited_on:
                    templ_edited = tpl_edited %({
                        'edit_date':comment.edited_on.strftime(
                            '%b %d %Y %H:%M:%S'),
                        'human_edit_date': humanize_date(comment.edited_on),
                        'user': comment.editor.user,
                    })

                output.append(
                    '
	'
                    ''
                    '
'
                    '
'
                    '
'
                    ''
                    ' %(user)s commented '
                    ''
                    '%(human_date)s'
                    '
'
                    '
'
                    '
'
                    '%(comment)s'
                    '
'
                    '
'
                    '
'
                    '%(templ_edited)s'
                    ''
                    '%(templ_edit)s'
                    '%(templ_delete)s'
                    ''
                    '

'
                    '
' % (
                        {
                            'url': flask.url_for(
                                'view_user', username=comment.user.user),
                            'templ_delete': templ_delete,
                            'templ_edit': templ_edit,
                            'templ_edited': templ_edited,
                            'user': comment.user.user,
                            'avatar_url': avatar_url(
                                comment.user.default_email, 16),
                            'date': comment.date_created.strftime(
                                '%b %d %Y %H:%M:%S'),
                            'human_date': humanize_date(comment.date_created),
                            'comment': markdown_filter(comment.comment),
                            'commentid': comment.id,
                            'anchor': u'¶',
                        }
                    )
                )

    output.append('

')

    return '\n'.join(output)

@APP.template_filter('wraps')
def text_wraps(text, size=10):
    """ Template filter to wrap text at a specified size
    """
    if text:
        parts = textwrap.wrap(text, size)
        if len(parts) > 1:
            parts = '%s...' % parts[0]
        else:
            parts = parts[0]
        return parts

@APP.template_filter('avatar')
def avatar(packager, size=64, default="retro"):
    """ Template filter sorting the given branches, Fedora first then EPEL,
    then whatever is left.
    """
    if not '@' in packager:
        user = pagure.lib.search_user(SESSION, username=packager)
        if user:
            packager = user.default_email

    output = '' % (
        avatar_url(packager, size)
    )

    return output

@APP.template_filter('avatar_url')
def avatar_url(email, size=64):
    """ Template filter sorting the given branches, Fedora first then EPEL,
    then whatever is left.
    """
    return pagure.lib.avatar_url_from_openid(email, size)

@APP.template_filter('short')
def shorted_commit(cid):
    """Gets short version of the commit id"""
    return str(cid)[:APP.config['SHORT_LENGTH']]

@APP.template_filter('markdown')
def markdown_filter(text):
    """ Template filter converting a string into html content using the
    markdown library.
    """
    return pagure.lib.text2markdown(text)

@APP.template_filter('html_diff')
def html_diff(diff):
    """Display diff as HTML"""
    if diff is None:
        return
    return highlight(
        diff,
        DiffLexer(),
        HtmlFormatter(
            noclasses=True,
            style="tango",)
    )

@APP.template_filter('patch_to_diff')
def patch_to_diff(patch):
    """Render a hunk as a diff"""
    content = ""
    for hunk in patch.hunks:
        content = content + "@@ -%i,%i +%i,%i @@\n" % (
            hunk.old_start, hunk.old_lines, hunk.new_start, hunk.new_lines)
        for line in hunk.lines:
            if hasattr(line, 'content'):
                origin = line.origin
                if line.origin in ['<', '>', '=']:
                    origin = ''
                content = content + origin + ' '+ line.content
            else:
                # Avoid situation where at the end of a file we get:
                # + foo<
                # \ No newline at end of file
                if line[0] in ['<', '>', '=']:
                    line = ('', line[1])
                content = content + ' '.join(line)

    return content

@APP.template_filter('author2user')
def author_to_user(author, size=16):
    """ Template filter transforming a pygit2 Author object into a text
    either with just the username or linking to the user in pagure.
    """
    output = author.name
    if not author.email:
        return output
    user = pagure.lib.search_user(SESSION, email=author.email)
    if user:
        output = "%s %s" % (
            avatar(user.default_email, size),
            flask.url_for('view_user', username=user.username),
            author.name,
        )
    return output

@APP.template_filter('author2avatar')
def author_to_avatar(author, size=32):
    """ Template filter transforming a pygit2 Author object into an avatar.
    """
    user = pagure.lib.search_user(SESSION, email=author.email)
    output = user.default_email if user else author.email
    return avatar(output.encode('utf-8'), size)

@APP.template_filter('InsertDiv')
def insert_div(content):
    """ Template filter inserting an opening
 and closing

    after the first title and then at the end of the content.
    """
    # This is quite a hack but simpler solution using .replace() didn't work
    # for some reasons...
    content = content.split('\n')
    output = []
    for row in content:
        if row.startswith('<div class="document" id='):
            continue
        if '
' in row:
            row = str(row).replace(
                '
',
                '
'
                '  '
            )
        output.append(row)
    output = "\n".join(output)
    output = output.replace('
', '
\n
', 1)
    output = output.replace('h1', 'h3')

    return output

@APP.template_filter('noJS')
def no_js(content, ignore=None):
    """ Template filter replacing  by
    </script>
    """
    return pagure.lib.clean_input(content, ignore=ignore)

@APP.template_filter('toRGB')
def int_to_rgb(percent):
    """ Template filter converting a given percentage to a css RGB value.
    """
    output = "rgb(255, 0, 0);"
    try:
        percent = int(percent)
        if percent < 50:
            red = 255
            green = (255.0/50) * percent
        else:
            green = 255
            red = (255.0/50) * (100 - percent)
        output = "rgb(%s, %s, 0);" % (int(red), int(green))
    except ValueError:
        pass
    return output

@APP.template_filter('return_md5')
def return_md5(text):
    """ Template filter to return an MD5 for a string
    """
    m = md5.new()
    m.update(text)
    return pagure.lib.clean_input(m.hexdigest())

@APP.template_filter('increment_largest_priority')
def text_wraps(dictionary):
    """ Template filter to return the largest priority +1
    """
    if dictionary:
        return max([int(k) for k in dictionary if k]) + 1
    else:
        return 1

@APP.template_filter('unicode')
def convert_unicode(text):
    if isinstance(text, str):
        return text.decode("utf8")
    else:
        return text