summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--packages/models.py7
-rw-r--r--packages/templatetags/jinja2.py72
-rw-r--r--packages/templatetags/package_extras.py94
-rw-r--r--requirements.txt2
-rw-r--r--requirements_prod.txt2
-rw-r--r--settings.py10
-rw-r--r--templates/packages/details.html225
-rw-r--r--templates/packages/details.html.jinja223
-rw-r--r--templates/packages/details_depend.html.jinja (renamed from templates/packages/details_depend.html)10
-rw-r--r--templates/packages/details_link.html.jinja1
-rw-r--r--templates/packages/details_relatedto.html2
-rw-r--r--templates/packages/details_relatedto.html.jinja3
-rw-r--r--templates/packages/details_requiredby.html.jinja (renamed from templates/packages/details_requiredby.html)2
13 files changed, 326 insertions, 327 deletions
diff --git a/packages/models.py b/packages/models.py
index dd69e7d3..03f03422 100644
--- a/packages/models.py
+++ b/packages/models.py
@@ -379,6 +379,13 @@ class RelatedToBase(models.Model):
given criteria. It will not search provisions, but will find packages
named and matching repo characteristics if possible.'''
pkgs = Package.objects.normal().filter(pkgname=self.name)
+ # TODO: this may in fact be faster- select only the fields we know will
+ # actually get used, saving us some bandwidth and hopefully query
+ # construction time. However, reality hasn't quite proved it out yet.
+ #pkgs = Package.objects.select_related('repo', 'arch').only(
+ # 'id', 'pkgname', 'epoch', 'pkgver', 'pkgrel',
+ # 'repo__id', 'repo__name', 'repo__testing', 'repo__staging',
+ # 'arch__id', 'arch__name').filter(pkgname=self.name)
if not self.pkg.arch.agnostic:
# make sure we match architectures if possible
arches = self.pkg.applicable_arches()
diff --git a/packages/templatetags/jinja2.py b/packages/templatetags/jinja2.py
new file mode 100644
index 00000000..22f9914b
--- /dev/null
+++ b/packages/templatetags/jinja2.py
@@ -0,0 +1,72 @@
+from urllib import urlencode, quote as urlquote, unquote
+from django.utils.html import escape
+from django_jinja import library
+from main.templatetags import pgp
+
+
+@library.filter
+def url_unquote(original_url):
+ try:
+ url = original_url
+ if isinstance(url, unicode):
+ url = url.encode('ascii')
+ url = unquote(url).decode('utf-8')
+ return url
+ except UnicodeError:
+ return original_url
+
+
+def link_encode(url, query):
+ # massage the data into all utf-8 encoded strings first, so urlencode
+ # doesn't barf at the data we pass it
+ query = {k: unicode(v).encode('utf-8') for k, v in query.items()}
+ data = urlencode(query)
+ return "%s?%s" % (url, data)
+
+
+@library.global_function
+def pgp_key_link(key_id, link_text=None):
+ return pgp.pgp_key_link(key_id, link_text)
+
+
+@library.global_function
+def scm_link(package, operation):
+ parts = (package.repo.svn_root, operation, package.pkgbase)
+ linkbase = (
+ "https://projects.archlinux.org/svntogit/%s.git/%s/trunk?"
+ "h=packages/%s")
+ return linkbase % tuple(urlquote(part.encode('utf-8')) for part in parts)
+
+
+@library.global_function
+def wiki_link(package):
+ url = "https://wiki.archlinux.org/index.php/Special:Search"
+ data = {
+ 'search': package.pkgname,
+ }
+ return link_encode(url, data)
+
+
+@library.global_function
+def bugs_list(package):
+ url = "https://bugs.archlinux.org/"
+ data = {
+ 'project': package.repo.bugs_project,
+ 'cat[]': package.repo.bugs_category,
+ 'string': package.pkgname,
+ }
+ return link_encode(url, data)
+
+
+@library.global_function
+def bug_report(package):
+ url = "https://bugs.archlinux.org/newtask"
+ data = {
+ 'project': package.repo.bugs_project,
+ 'product_category': package.repo.bugs_category,
+ 'item_summary': '[%s] PLEASE ENTER SUMMARY' % package.pkgname,
+ }
+ return link_encode(url, data)
+
+
+# vim: set ts=4 sw=4 et:
diff --git a/packages/templatetags/package_extras.py b/packages/templatetags/package_extras.py
index 3ce64748..73a39092 100644
--- a/packages/templatetags/package_extras.py
+++ b/packages/templatetags/package_extras.py
@@ -1,33 +1,13 @@
-from urllib import urlencode, quote as urlquote, unquote
+from urllib import urlencode
try:
from urlparse import parse_qs
except ImportError:
from cgi import parse_qs
from django import template
-from django.utils.html import escape
-
-register = template.Library()
-
-
-def link_encode(url, query):
- # massage the data into all utf-8 encoded strings first, so urlencode
- # doesn't barf at the data we pass it
- query = {k: unicode(v).encode('utf-8') for k, v in query.items()}
- data = urlencode(query).replace('&', '&')
- return "%s?%s" % (url, data)
-@register.filter
-def url_unquote(original_url):
- try:
- url = original_url
- if isinstance(url, unicode):
- url = url.encode('ascii')
- url = unquote(url).decode('utf-8')
- return url
- except UnicodeError:
- return original_url
+register = template.Library()
class BuildQueryStringNode(template.Node):
@@ -79,74 +59,4 @@ def pkg_details_link(pkg, link_title=None, honor_flagged=False):
return link % (pkg.get_absolute_url(), pkg.pkgname, link_content)
-@register.simple_tag
-def multi_pkg_details(pkgs):
- return ', '.join([pkg_details_link(pkg) for pkg in pkgs])
-
-
-@register.simple_tag
-def maintainer_link(user):
- if user:
- # TODO don't hardcode
- title = escape('View packages maintained by ' + user.get_full_name())
- return '<a href="/packages/?maintainer=%s" title="%s">%s</a>' % (
- user.username,
- title,
- user.get_full_name(),
- )
- return ''
-
-
-@register.simple_tag
-def packager_link(user):
- if user:
- # TODO don't hardcode
- title = escape('View packages packaged by ' + user.get_full_name())
- return '<a href="/packages/?packager=%s" title="%s">%s</a>' % (
- user.username,
- title,
- user.get_full_name(),
- )
- return ''
-
-
-@register.simple_tag
-def scm_link(package, operation):
- parts = (package.repo.svn_root, operation, package.pkgbase)
- linkbase = (
- "https://projects.archlinux.org/svntogit/%s.git/%s/trunk?"
- "h=packages/%s")
- return linkbase % tuple(urlquote(part.encode('utf-8')) for part in parts)
-
-
-@register.simple_tag
-def get_wiki_link(package):
- url = "https://wiki.archlinux.org/index.php/Special:Search"
- data = {
- 'search': package.pkgname,
- }
- return link_encode(url, data)
-
-
-@register.simple_tag
-def bugs_list(package):
- url = "https://bugs.archlinux.org/"
- data = {
- 'project': package.repo.bugs_project,
- 'cat[]': package.repo.bugs_category,
- 'string': package.pkgname,
- }
- return link_encode(url, data)
-
-
-@register.simple_tag
-def bug_report(package):
- url = "https://bugs.archlinux.org/newtask"
- data = {
- 'project': package.repo.bugs_project,
- 'product_category': package.repo.bugs_category,
- 'item_summary': '[%s] PLEASE ENTER SUMMARY' % package.pkgname,
- }
- return link_encode(url, data)
-
# vim: set ts=4 sw=4 et:
diff --git a/requirements.txt b/requirements.txt
index eff75bad..e2b49aba 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -2,8 +2,10 @@
-e git+git://github.com/SmileyChris/django-countries.git@a2c924074dbe2f0b9b3059bf70064aeadf5643ed#egg=django-countries
Django==1.7
IPy==0.81
+Jinja2==2.7.3
Markdown==2.4.1
bencode==1.0
+django-jinja==1.0.4
jsmin==2.0.11
pgpdump==1.5
pytz>=2014.7
diff --git a/requirements_prod.txt b/requirements_prod.txt
index c181c3af..020a5ac4 100644
--- a/requirements_prod.txt
+++ b/requirements_prod.txt
@@ -2,8 +2,10 @@
-e git+git://github.com/SmileyChris/django-countries.git@a2c924074dbe2f0b9b3059bf70064aeadf5643ed#egg=django-countries
Django==1.7
IPy==0.81
+Jinja2==2.7.3
Markdown==2.4.1
bencode==1.0
+django-jinja==1.0.4
jsmin==2.0.11
pgpdump==1.5
psycopg2==2.5.4
diff --git a/settings.py b/settings.py
index 368dcb73..ba6c68ee 100644
--- a/settings.py
+++ b/settings.py
@@ -60,11 +60,13 @@ TEMPLATE_DIRS = (
)
TEMPLATE_LOADERS = (
- 'django.template.loaders.filesystem.Loader',
- 'django.template.loaders.eggs.Loader',
- 'django.template.loaders.app_directories.Loader',
+ 'django_jinja.loaders.FileSystemLoader',
+ 'django_jinja.loaders.AppLoader',
)
+# Send templates matching the following to the Jinja2 engine
+DEFAULT_JINJA2_TEMPLATE_EXTENSION = '.jinja'
+
MIDDLEWARE_CLASSES = (
'django.middleware.common.CommonMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
@@ -115,6 +117,7 @@ INSTALLED_APPS = (
'django.contrib.admin',
'django.contrib.staticfiles',
'django_countries',
+ 'django_jinja',
'main',
'mirrors',
@@ -180,6 +183,7 @@ if not TEMPLATE_DEBUG:
TEMPLATE_LOADERS = (
('django.template.loaders.cached.Loader', TEMPLATE_LOADERS),
)
+ JINJA2_BYTECODE_CACHE_ENABLE = True
# Enable the debug toolbar if requested
if DEBUG_TOOLBAR:
diff --git a/templates/packages/details.html b/templates/packages/details.html
index bfa2de16..7a0f8e88 100644
--- a/templates/packages/details.html
+++ b/templates/packages/details.html
@@ -1,234 +1,11 @@
{% extends "base.html" %}
{% load static from staticfiles %}
-{% load package_extras %}
-{% load pgp %}
{% block title %}Arch Linux - {{ pkg.pkgname }} {{ pkg.full_version }} ({{ pkg.arch.name }}){% endblock %}
{% block navbarclass %}anb-packages{% endblock %}
-{% load package_extras %}
{% block content %}
-<div id="pkgdetails" class="box">
-
- <h2>{{ pkg.pkgname }} {{ pkg.full_version }}</h2>
-
- <div id="detailslinks" class="listing">
- <div id="actionlist">
- <h4>Package Actions</h4>
- <ul class="small">
- <li>
- <a href="{% scm_link pkg 'tree' %}" title="View source files for {{ pkg.pkgname }}">Source Files</a> /
- <a href="{% scm_link pkg 'log' %}" title="View changes for {{ pkg.pkgname }}">View Changes</a>
- </li>
- <li>
- <a href="{% bugs_list pkg %}" title="View existing bug tickets for {{ pkg.pkgname }}">Bug Reports</a> /
- <a href="{% bug_report pkg %}" title="Report new bug for {{ pkg.pkgname }}">Add New Bug</a>
- </li>
- <li><a href="{% get_wiki_link pkg %}" title="Search wiki for {{ pkg.pkgname }}">Search Wiki</a></li>
- {% if pkg.flag_date %}
- <li><span class="flagged">Flagged out-of-date on {{ pkg.flag_date|date }}</span></li>
- {% with pkg.in_testing as tp %}{% if tp %}
- <li><span class="flagged">Version
- <a href="{{ tp.get_absolute_url }}"
- title="Testing package details for {{ tp.pkgname }}">{{ tp.full_version }}</a>
- in testing</span></li>
- {% endif %}{% endwith %}
- {% if perms.main.change_package %}
- <li><a href="unflag/" title="Unflag this package">Click here to unflag</a></li>
- <li><a href="unflag/all/" title="Unflag all matching pkgbase">Click here to unflag all split packages</a></li>
- {% endif %}
- {% else %}
- <li><a href="flag/" title="Flag {{ pkg.pkgname }} as out-of-date">Flag Package Out-of-Date</a>
- <a href="/packages/flaghelp/"
- title="Get help on package flagging"
- onclick="return !window.open('/packages/flaghelp/','FlagHelp',
- 'height=350,width=450,location=no,scrollbars=yes,menubars=no,toolbars=no,resizable=no');">(?)</a></li>
- {% endif %}
- <li><a href="download/" rel="nofollow" title="Download {{ pkg.pkgname }} from mirror">Download From Mirror</a></li>
- </ul>
-
- {% if perms.main.change_package %}
- <form id="pkg-action" method="post" action="/packages/update/">{% csrf_token %}
- <div><input type="hidden" name="pkgid" value="{{ pkg.id }}" /></div>
- <p>{% if user in pkg.maintainers %}
- <input title="Orphan this package" type="submit" name="disown" value="Disown"/>
- {% else %}
- <input title="Adopt this package" type="submit" name="adopt" value="Adopt"/>
- {% endif %}</p>
- </form>
- {% endif %}
- </div>
-
- {% with pkg.elsewhere as others %}{% if others %}
- <div id="elsewhere" class="widget">
- <h4>Versions Elsewhere</h4>
- <ul>
- {% for o in others %}
- <li><a href="{{ o.get_absolute_url }}"
- title="Package details for {{ o.pkgname }}">{{ o.pkgname }} {{ o.full_version }} [{{ o.repo.name|lower }}] ({{ o.arch.name }})</a></li>
- {% endfor %}
- </ul>
- </div>
- {% endif %}{% endwith %}
- </div>
-
- <div itemscope itemtype="http://schema.org/SoftwareApplication">
- <meta itemprop="name" content="{{ pkg.pkgname|escape }}"/>
- <meta itemprop="version" content="{{ pkg.full_version|escape }}"/>
- <meta itemprop="softwareVersion" content="{{ pkg.full_version|escape }}"/>
- <meta itemprop="fileSize" content="{{ pkg.compressed_size }}"/>
- <meta itemprop="dateCreated" content="{{ pkg.build_date|date:"Y-m-d" }}"/>
- <meta itemprop="datePublished" content="{{ pkg.last_update|date:"Y-m-d" }}"/>
- <meta itemprop="operatingSystem" content="Linux"/>
- <div style="display:none" itemprop="provider" itemscope itemtype="http://schema.org/Person">
- <meta itemprop="name" content="{{ pkg.packager.get_full_name|escape }}"/>
- </div>
- <table id="pkginfo">
- <tr>
- <th>Architecture:</th>
- <td><a href="/packages/?arch={{ pkg.arch.name }}"
- title="Browse packages for {{ pkg.arch.name }} architecture">{{ pkg.arch.name }}</a></td>
- </tr><tr>
- <th>Repository:</th>
- <td><a href="/packages/?repo={{ pkg.repo.name|capfirst }}"
- title="Browse the {{ pkg.repo.name|capfirst }} repository">{{ pkg.repo.name|capfirst }}</a></td>
- </tr>
- {% ifequal pkg.pkgname pkg.pkgbase %}
- {% with pkg.split_packages as splits %}{% if splits %}
- <tr>
- <th>Split Packages:</th>
- <td class="wrap relatedto">{% for s in splits %}<span class="related">{% pkg_details_link s %}{% if not forloop.last %}, {% endif %}</span>{% endfor %}</td>
- </tr>
- {% endif %}{% endwith %}
- {% else %}
- <tr>
- <th>Base Package:</th>
- {% with pkg.base_package as base %}{% if base %}
- <td>{% pkg_details_link base %}</td>
- {% else %}
- <td><a href="../{{ pkg.pkgbase }}/"
- title="Split package details for {{ pkg.pkgbase }}">{{ pkg.pkgbase }}</a></td>
- {% endif %}{% endwith %}
- </tr>
- {% endifequal %}
- <tr>
- <th>Description:</th>
- <td class="wrap" itemprop="description">{{ pkg.pkgdesc|default:"" }}</td>
- </tr><tr>
- <th>Upstream URL:</th>
- <td>{% if pkg.url %}<a itemprop="url" href="{{ pkg.url }}"
- title="Visit the website for {{ pkg.pkgname }}">{{ pkg.url|url_unquote }}</a>{% endif %}</td>
- </tr><tr>
- <th>License(s):</th>
- <td class="wrap">{{ pkg.licenses.all|join:", " }}</td>
- </tr>
- {% with pkg.groups.all as groups %}{% if groups %}
- <tr>
- <th>Groups:</th>
- <td class="wrap">{% for g in groups %}
- <a href="/groups/{{ pkg.arch.name }}/{{ g.name }}/"
- title="Group details for {{ g.name }}">{{ g.name }}</a>{% if not forloop.last %}, {% endif %}{% endfor %}
- </td>
- </tr>
- {% endif %}{% endwith %}
- {% with pkg.provides.all as all_related %}{% if all_related %}
- <tr>
- <th>Provides:</th>
- <td class="wrap relatedto">{% include "packages/details_relatedto.html" %}</td>
- </tr>
- {% endif %}{% endwith %}
- {% with pkg.replaces.all as all_related %}{% if all_related %}
- <tr>
- <th>Replaces:</th>
- <td class="wrap relatedto">{% include "packages/details_relatedto.html" %}</td>
- </tr>
- {% endif %}{% endwith %}
- {% with pkg.conflicts.all as all_related %}{% if all_related %}
- <tr>
- <th>Conflicts:</th>
- <td class="wrap relatedto">{% include "packages/details_relatedto.html" %}</td>
- </tr>
- {% endif %}{% endwith %}
- {% with pkg.reverse_conflicts as rev_conflicts %}{% if rev_conflicts %}
- <tr>
- <th>Reverse Conflicts:</th>
- <td class="wrap relatedto">{% for conflict in rev_conflicts %}
- <span class="related">{% pkg_details_link conflict %}{% if not forloop.last %}, {% endif %}</span>{% endfor %}</td>
- </tr>
- {% endif %}{% endwith %}
- <tr>
- <th>Maintainers:</th>
- {% with pkg.maintainers as maints %}
- <td>{% if maints %}
- {% for m in maints %}
- {% maintainer_link m %}<br/>
- {% endfor %}
- {% else %}Orphan{% endif %}
- </td>
- {% endwith %}
- </tr><tr>
- <th>Package Size:</th>
- <td>{{ pkg.compressed_size|filesizeformat }}</td>
- </tr><tr>
- <th>Installed Size:</th>
- <td>{{ pkg.installed_size|filesizeformat }}</td>
- </tr><tr>
- <th>Last Packager:</th>
- <td>{% with pkg.packager as pkgr %}{% if pkgr %}{% packager_link pkgr %}{% else %}{{ pkg.packager_str }}{% endif %}{% endwith %}</td>
- </tr><tr>
- <th>Build Date:</th>
- <td>{{ pkg.build_date|date:"DATETIME_FORMAT" }} UTC</td>
- </tr>{% if pkg.signature %}<tr>
- <th>Signed By:</th>
- <td>{% with pkg.signer as signer %}{% if signer %}{% pgp_key_link pkg.signature.key_id signer.get_full_name %}{% else %}Unknown ({% pgp_key_link pkg.signature.key_id %}){% endif %}{% endwith %}</td>
- </tr><tr>
- <th>Signature Date:</th>
- <td>{{ pkg.signature.creation_time|date:"DATETIME_FORMAT" }} UTC</td>
- </tr>{% else %}<tr>
- <th>Signed By:</th>
- <td>Unsigned</td>
- </tr>{% endif %}<tr>
- <th>Last Updated:</th>
- <td>{{ pkg.last_update|date:"DATETIME_FORMAT" }} UTC</td>
- </tr>
- {% if user.is_authenticated %}{% with pkg.flag_request as flag_request %}{% if flag_request %}<tr>
- <th>Last Flag Request:</th>
- <td class="wrap">From {{ flag_request.who }} on {{ flag_request.created|date }}:<br/>
- <div class="userdata">{{ flag_request.message|linebreaksbr|default:"{no message}" }}</div></td>
- </tr>{% endif %}{% endwith %}{% endif %}
- </table>
- </div>
-
- <div id="metadata">
- {% with pkg.get_depends as deps %}
- <div id="pkgdeps" class="listing">
- <h3 title="{{ pkg.pkgname }} has the following dependencies">
- Dependencies ({{deps|length}})</h3>
- {% if deps %}<ul id="pkgdepslist">
- {% for depend in deps %}{% include "packages/details_depend.html" %}{% endfor %}
- </ul>{% endif %}
- </div>
- {% endwith %}
- {% with pkg.get_requiredby as rqdby %}
- <div id="pkgreqs" class="listing">
- <h3 title="Packages that require {{ pkg.pkgname }}">
- Required By ({{rqdby|length}})</h3>
- {% if rqdby %}<ul id="pkgreqslist">
- {% for req in rqdby %}{% include "packages/details_requiredby.html" %}{% endfor %}
- </ul>{% endif %}
- </div>
- {% endwith %}
- <div id="pkgfiles" class="listing">
- <h3 title="Complete list of files contained within this package">
- Package Contents</h3>
- <div id="pkgfilelist">
- <p><a id="filelink" href="files/"
- title="Click to view the complete file list for {{ pkg.pkgname }}">
- View the file list for {{ pkg.pkgname }}</a></p>
- </div>
- </div>
- </div>
-</div>
+{% include "packages/details.html.jinja" %}
{% endblock %}
{% block script_block %}
diff --git a/templates/packages/details.html.jinja b/templates/packages/details.html.jinja
new file mode 100644
index 00000000..52d13f14
--- /dev/null
+++ b/templates/packages/details.html.jinja
@@ -0,0 +1,223 @@
+{% import 'packages/details_link.html.jinja' as details %}
+<div id="pkgdetails" class="box">
+ <h2>{{ pkg.pkgname }} {{ pkg.full_version }}</h2>
+
+ <div id="detailslinks" class="listing">
+ <div id="actionlist">
+ <h4>Package Actions</h4>
+ <ul class="small">
+ <li>
+ <a href="{{ scm_link(pkg, 'tree') }}" title="View source files for {{ pkg.pkgname }}">Source Files</a> /
+ <a href="{{ scm_link(pkg, 'log') }}" title="View changes for {{ pkg.pkgname }}">View Changes</a>
+ </li>
+ <li>
+ <a href="{{ bugs_list(pkg) }}" title="View existing bug tickets for {{ pkg.pkgname }}">Bug Reports</a> /
+ <a href="{{ bug_report(pkg) }}" title="Report new bug for {{ pkg.pkgname }}">Add New Bug</a>
+ </li>
+ <li><a href="{{ wiki_link(pkg) }}" title="Search wiki for {{ pkg.pkgname }}">Search Wiki</a></li>
+ {% if pkg.flag_date %}
+ <li><span class="flagged">Flagged out-of-date on {{ pkg.flag_date|date }}</span></li>
+ {% with tp = pkg.in_testing() %}{% if tp %}
+ <li><span class="flagged">Version
+ <a href="{{ tp.get_absolute_url() }}"
+ title="Testing package details for {{ tp.pkgname }}">{{ tp.full_version }}</a>
+ in testing</span></li>
+ {% endif %}{% endwith %}
+ {% if perms.main.change_package %}
+ <li><a href="unflag/" title="Unflag this package">Click here to unflag</a></li>
+ <li><a href="unflag/all/" title="Unflag all matching pkgbase">Click here to unflag all split packages</a></li>
+ {% endif %}
+ {% else %}
+ <li><a href="flag/" title="Flag {{ pkg.pkgname }} as out-of-date">Flag Package Out-of-Date</a>
+ <a href="/packages/flaghelp/"
+ title="Get help on package flagging"
+ onclick="return !window.open('/packages/flaghelp/','FlagHelp',
+ 'height=350,width=450,location=no,scrollbars=yes,menubars=no,toolbars=no,resizable=no');">(?)</a></li>
+ {% endif %}
+ <li><a href="download/" rel="nofollow" title="Download {{ pkg.pkgname }} from mirror">Download From Mirror</a></li>
+ </ul>
+
+ {% if perms.main.change_package %}
+ <form id="pkg-action" method="post" action="/packages/update/">{% csrf_token %}
+ <div><input type="hidden" name="pkgid" value="{{ pkg.id }}" /></div>
+ <p>{% if user in pkg.maintainers %}
+ <input title="Orphan this package" type="submit" name="disown" value="Disown"/>
+ {% else %}
+ <input title="Adopt this package" type="submit" name="adopt" value="Adopt"/>
+ {% endif %}</p>
+ </form>
+ {% endif %}
+ </div>
+
+ {% with others = pkg.elsewhere() %}{% if others %}
+ <div id="elsewhere" class="widget">
+ <h4>Versions Elsewhere</h4>
+ <ul>
+ {% for o in others %}
+ <li><a href="{{ o.get_absolute_url() }}"
+ title="Package details for {{ o.pkgname }}">{{ o.pkgname }} {{ o.full_version }} [{{ o.repo.name|lower }}] ({{ o.arch.name }})</a></li>
+ {% endfor %}
+ </ul>
+ </div>
+ {% endif %}{% endwith %}
+ </div>
+
+ <div itemscope itemtype="http://schema.org/SoftwareApplication">
+ <meta itemprop="name" content="{{ pkg.pkgname|escape }}"/>
+ <meta itemprop="version" content="{{ pkg.full_version|escape }}"/>
+ <meta itemprop="softwareVersion" content="{{ pkg.full_version|escape }}"/>
+ <meta itemprop="fileSize" content="{{ pkg.compressed_size }}"/>
+ <meta itemprop="dateCreated" content="{{ pkg.build_date|date("Y-m-d") }}"/>
+ <meta itemprop="datePublished" content="{{ pkg.last_update|date("Y-m-d") }}"/>
+ <meta itemprop="operatingSystem" content="Linux"/>
+ <div style="display:none" itemprop="provider" itemscope itemtype="http://schema.org/Person">
+ <meta itemprop="name" content="{{ pkg.packager.get_full_name()|escape }}"/>
+ </div>
+ <table id="pkginfo">
+ <tr>
+ <th>Architecture:</th>
+ <td><a href="/packages/?arch={{ pkg.arch.name }}"
+ title="Browse packages for {{ pkg.arch.name }} architecture">{{ pkg.arch.name }}</a></td>
+ </tr><tr>
+ <th>Repository:</th>
+ <td><a href="/packages/?repo={{ pkg.repo.name|capfirst }}"
+ title="Browse the {{ pkg.repo.name|capfirst }} repository">{{ pkg.repo.name|capfirst }}</a></td>
+ </tr>
+ {% if pkg.pkgname == pkg.pkgbase %}
+ {% with splits = pkg.split_packages() %}{% if splits %}
+ <tr>
+ <th>Split Packages:</th>
+ <td class="wrap relatedto">{% for s in splits %}<span class="related">{{ details.details_link(s) }}{% if not loop.last %}, {% endif %}</span>{% endfor %}</td>
+ </tr>
+ {% endif %}{% endwith %}
+ {% else %}
+ <tr>
+ <th>Base Package:</th>
+ {% with base = pkg.base_package %}{% if base %}
+ <td>{{ details.details_link(base) }}</td>
+ {% else %}
+ <td><a href="../{{ pkg.pkgbase }}/"
+ title="Split package details for {{ pkg.pkgbase }}">{{ pkg.pkgbase }}</a></td>
+ {% endif %}{% endwith %}
+ </tr>
+ {% endif %}
+ <tr>
+ <th>Description:</th>
+ <td class="wrap" itemprop="description">{{ pkg.pkgdesc|default("") }}</td>
+ </tr><tr>
+ <th>Upstream URL:</th>
+ <td>{% if pkg.url %}<a itemprop="url" href="{{ pkg.url }}"
+ title="Visit the website for {{ pkg.pkgname }}">{{ pkg.url|url_unquote }}</a>{% endif %}</td>
+ </tr><tr>
+ <th>License(s):</th>
+ <td class="wrap">{{ pkg.licenses.all()|join(", ") }}</td>
+ </tr>
+ {% with groups = pkg.groups.all() %}{% if groups %}
+ <tr>
+ <th>Groups:</th>
+ <td class="wrap">{% for g in groups %}
+ <a href="/groups/{{ pkg.arch.name }}/{{ g.name }}/"
+ title="Group details for {{ g.name }}">{{ g.name }}</a>{% if not loop.last %}, {% endif %}{% endfor %}
+ </td>
+ </tr>
+ {% endif %}{% endwith %}
+ {% with all_related = pkg.provides.all() %}{% if all_related %}
+ <tr>
+ <th>Provides:</th>
+ <td class="wrap relatedto">{% include "packages/details_relatedto.html.jinja" %}</td>
+ </tr>
+ {% endif %}{% endwith %}
+ {% with all_related = pkg.replaces.all() %}{% if all_related %}
+ <tr>
+ <th>Replaces:</th>
+ <td class="wrap relatedto">{% include "packages/details_relatedto.html.jinja" %}</td>
+ </tr>
+ {% endif %}{% endwith %}
+ {% with all_related = pkg.conflicts.all() %}{% if all_related %}
+ <tr>
+ <th>Conflicts:</th>
+ <td class="wrap relatedto">{% include "packages/details_relatedto.html.jinja" %}</td>
+ </tr>
+ {% endif %}{% endwith %}
+ {% with rev_conflicts = pkg.reverse_conflicts() %}{% if rev_conflicts %}
+ <tr>
+ <th>Reverse Conflicts:</th>
+ <td class="wrap relatedto">{% for conflict in rev_conflicts %}
+ <span class="related">{{ details.details_link(conflict) }}{% if not loop.last %}, {% endif %}</span>{% endfor %}</td>
+ </tr>
+ {% endif %}{% endwith %}
+ <tr>
+ <th>Maintainers:</th>
+ {% with maints = pkg.maintainers %}
+ <td>{% if maints %}{% for m in maints %}
+ <a href="/packages/?maintainer={{ m.username }}"
+ title="View packages maintained by {{ m.get_full_name() }}">{{ m.get_full_name() }}</a><br/>
+ {% endfor %}{% else %}Orphan{% endif %}
+ </td>
+ {% endwith %}
+ </tr><tr>
+ <th>Package Size:</th>
+ <td>{{ pkg.compressed_size|filesizeformat }}</td>
+ </tr><tr>
+ <th>Installed Size:</th>
+ <td>{{ pkg.installed_size|filesizeformat }}</td>
+ </tr><tr>
+ <th>Last Packager:</th>
+ <td>{% with pkgr = pkg.packager %}{% if pkgr %}
+ <a href="/packages/?packager={{ pkgr.username }}"
+ title="View packages packaged by {{ pkgr.get_full_name() }}">{{ pkgr.get_full_name() }}</a>
+ {% else %}{{ pkg.packager_str }}{% endif %}{% endwith %}</td>
+ </tr><tr>
+ <th>Build Date:</th>
+ <td>{{ pkg.build_date|date("DATETIME_FORMAT") }} UTC</td>
+ </tr>{% if pkg.signature %}<tr>
+ <th>Signed By:</th>
+ <td>{% with signer = pkg.signer %}{% if signer %}{{ pgp_key_link(pkg.signature.key_id, signer.get_full_name())|safe }}{% else %}Unknown ({{ pgp_key_link(pkg.signature.key_id)|safe }}){% endif %}{% endwith %}</td>
+ </tr><tr>
+ <th>Signature Date:</th>
+ <td>{{ pkg.signature.creation_time|date("DATETIME_FORMAT") }} UTC</td>
+ </tr>{% else %}<tr>
+ <th>Signed By:</th>
+ <td>Unsigned</td>
+ </tr>{% endif %}<tr>
+ <th>Last Updated:</th>
+ <td>{{ pkg.last_update|date("DATETIME_FORMAT") }} UTC</td>
+ </tr>
+ {% if user.is_authenticated %}{% with flag_request = pkg.flag_request() %}{% if flag_request %}<tr>
+ <th>Last Flag Request:</th>
+ <td class="wrap">From {{ flag_request.who() }} on {{ flag_request.created|date }}:<br/>
+ <div class="userdata">{{ flag_request.message|linebreaksbr|default("{no message}") }}</div></td>
+ </tr>{% endif %}{% endwith %}{% endif %}
+ </table>
+ </div>
+
+ <div id="metadata">
+ {% with deps = pkg.get_depends() %}
+ <div id="pkgdeps" class="listing">
+ <h3 title="{{ pkg.pkgname }} has the following dependencies">
+ Dependencies ({{deps|length}})</h3>
+ {% if deps %}<ul id="pkgdepslist">
+ {% for depend in deps %}{% include "packages/details_depend.html.jinja" %}{% endfor %}
+ </ul>{% endif %}
+ </div>
+ {% endwith %}
+ {% with rqdby = pkg.get_requiredby() %}
+ <div id="pkgreqs" class="listing">
+ <h3 title="Packages that require {{ pkg.pkgname }}">
+ Required By ({{rqdby|length}})</h3>
+ {% if rqdby %}<ul id="pkgreqslist">
+ {% for req in rqdby %}{% include "packages/details_requiredby.html.jinja" %}{% endfor %}
+ </ul>{% endif %}
+ </div>
+ {% endwith %}
+ <div id="pkgfiles" class="listing">
+ <h3 title="Complete list of files contained within this package">
+ Package Contents</h3>
+ <div id="pkgfilelist">
+ <p><a id="filelink" href="files/"
+ title="Click to view the complete file list for {{ pkg.pkgname }}">
+ View the file list for {{ pkg.pkgname }}</a></p>
+ </div>
+ </div>
+ </div>
+</div>
diff --git a/templates/packages/details_depend.html b/templates/packages/details_depend.html.jinja
index b89ffbfa..404793b6 100644
--- a/templates/packages/details_depend.html
+++ b/templates/packages/details_depend.html.jinja
@@ -1,11 +1,11 @@
-{% load package_extras %}<li>{% ifequal depend.pkg None %}
-{% if depend.providers %}{{ depend.dep.name }}{{ depend.dep.comparison|default:"" }}{{ depend.dep.version|default:"" }} <span class="virtual-dep">({% multi_pkg_details depend.providers %})</span>
-{% else %}{{ depend.dep.name }}{{ depend.dep.comparison|default:"" }}{{ depend.dep.version|default:"" }} <span class="virtual-dep">(virtual)</span>
+{% import 'packages/details_link.html.jinja' as details %}<li>{% if depend.pkg == None %}
+{% if depend.providers %}{{ depend.dep.name }}{{ depend.dep.comparison|default("") }}{{ depend.dep.version|default("") }} <span class="virtual-dep">({% for pkg in depend.providers %}{{ details.details_link(pkg) }}{% if not loop.last %}, {% endif %}{% endfor %})</span>
+{% else %}{{ depend.dep.name }}{{ depend.dep.comparison|default("") }}{{ depend.dep.version|default("") }} <span class="virtual-dep">(virtual)</span>
{% endif %}{% else %}
-{% pkg_details_link depend.pkg %}{{ depend.dep.comparison|default:"" }}{{ depend.dep.version|default:"" }}
+{{ details.details_link(depend.pkg) }}{{ depend.dep.comparison|default("") }}{{ depend.dep.version|default("") }}
{% if depend.pkg.repo.testing %} <span class="testing-dep"> (testing)</span>
{% endif %}{% if depend.pkg.repo.staging %} <span class="staging-dep"> (staging)</span>
-{% endif %}{% endifequal %}
+{% endif %}{% endif %}
{% if depend.dep.deptype == 'O' %} <span class="opt-dep"> (optional)</span>
{% endif %}{% if depend.dep.deptype == 'M' %} <span class="make-dep"> (make)</span>
{% endif %}{% if depend.dep.deptype == 'C' %} <span class="check-dep"> (check)</span>
diff --git a/templates/packages/details_link.html.jinja b/templates/packages/details_link.html.jinja
new file mode 100644
index 00000000..b7e75fe5
--- /dev/null
+++ b/templates/packages/details_link.html.jinja
@@ -0,0 +1 @@
+{% macro details_link(pkg) %}<a href="{{ pkg.get_absolute_url() }}" title="View package details for {{ pkg.pkgname }}">{{ pkg.pkgname }}</a>{% endmacro %}
diff --git a/templates/packages/details_relatedto.html b/templates/packages/details_relatedto.html
deleted file mode 100644
index e14375d3..00000000
--- a/templates/packages/details_relatedto.html
+++ /dev/null
@@ -1,2 +0,0 @@
-{% load package_extras %}{% for related in all_related %}{% with related.get_best_satisfier as best_satisfier %}<span class="related">{% ifequal best_satisfier None %}{{ related.name }}{% else %}{% pkg_details_link best_satisfier %}{% endifequal %}{{ related.comparison|default:"" }}{{ related.version|default:"" }}{% if not forloop.last %}, {% endif %}</span>
-{% endwith %}{% endfor %}
diff --git a/templates/packages/details_relatedto.html.jinja b/templates/packages/details_relatedto.html.jinja
new file mode 100644
index 00000000..955fdd37
--- /dev/null
+++ b/templates/packages/details_relatedto.html.jinja
@@ -0,0 +1,3 @@
+{% import 'packages/details_link.html.jinja' as details %}{% for related in all_related %}{% with best_satisfier = related.get_best_satisfier() %}
+<span class="related">{% if best_satisfier == None %}{{ related.name }}{% else %}{{ details.details_link(best_satisfier) }}{% endif %}{{ related.comparison|default("") }}{{ related.version|default("") }}{% if not loop.last %}, {% endif %}</span>
+{% endwith %}{% endfor %}
diff --git a/templates/packages/details_requiredby.html b/templates/packages/details_requiredby.html.jinja
index 504a322f..b083a7fc 100644
--- a/templates/packages/details_requiredby.html
+++ b/templates/packages/details_requiredby.html.jinja
@@ -1,4 +1,4 @@
-{% load package_extras %}<li>{% pkg_details_link req.pkg %}
+{% import 'packages/details_link.html.jinja' as details %}<li>{{ details.details_link(req.pkg) }}
{% if req.name != pkg.pkgname %}<span class="virtual-dep"> (requires {{ req.name }})</span>
{% endif %}{% if req.pkg.repo.testing %}<span class="testing-dep"> (testing)</span>
{% endif %}{% if req.pkg.repo.staging %}<span class="staging-dep"> (staging)</span>