mirror of
https://github.com/pretix/pretix.git
synced 2026-08-11 10:57:00 +00:00
Merge branch 'master' of github.com:pretix/pretix
This commit is contained in:
@@ -0,0 +1,28 @@
|
||||
before_script:
|
||||
tests:
|
||||
script:
|
||||
- git submodule init
|
||||
- git submodule update
|
||||
- pyvenv-3.4 --without-pip env
|
||||
- source env/bin/activate
|
||||
- curl https://bootstrap.pypa.io/get-pip.py | python
|
||||
- cd src
|
||||
- pip3 install -q -r requirements.txt
|
||||
- flake8 --ignore=E123,F403,F401,N802,C901,W503 .
|
||||
- python3 manage.py check
|
||||
- make
|
||||
- make compress
|
||||
- coverage run -m py.test tests
|
||||
tags:
|
||||
- python3
|
||||
- selenium
|
||||
build:
|
||||
type: deploy
|
||||
script:
|
||||
- cd deployment/docker/standalone/
|
||||
- docker login -u ciuser -p $DOCKERPW -e admin@rami.io docker.rami.io
|
||||
- docker build -t pretix/standalone .
|
||||
- docker tag pretix/standalone docker.rami.io/pretix/standalone
|
||||
- docker push docker.rami.io/pretix/standalone
|
||||
tags:
|
||||
- docker
|
||||
@@ -27,6 +27,7 @@ RUN pip3 install -r requirements.txt
|
||||
RUN pip3 install -r requirements/mysql.txt
|
||||
RUN pip3 install -r requirements/postgres.txt
|
||||
RUN pip3 install -r requirements/memcached.txt
|
||||
RUN pip3 install -r requirements/redis.txt
|
||||
RUN pip3 install gunicorn
|
||||
|
||||
RUN make
|
||||
|
||||
@@ -177,4 +177,25 @@ You can use an existing memcached server as pretix's caching backend::
|
||||
|
||||
If no memcached is configures, pretix will use Django's built-in local-memory caching method.
|
||||
|
||||
|
||||
Redis
|
||||
-----
|
||||
|
||||
If a redis server is configured, pretix can use it for locking, caching and session storage
|
||||
to speed up various operations::
|
||||
|
||||
[redis]
|
||||
location=redis://127.0.0.1:6379/1
|
||||
sessions=false
|
||||
|
||||
``location``
|
||||
The location of memcached, as an URL of the form ``redis://[:password]@localhost:6379/0``
|
||||
or ``unix://[:password]@/path/to/socket.sock?db=0``
|
||||
|
||||
``session``
|
||||
When this is set to true, redis will be used as the session storage.
|
||||
|
||||
If no redis is configured, pretix will store sessions and locks in the database. If memcached
|
||||
is configured, memcached will be used for caching instead of redis.
|
||||
|
||||
.. _Python documentation: https://docs.python.org/3/library/configparser.html?highlight=configparser#supported-ini-file-structure
|
||||
@@ -0,0 +1,13 @@
|
||||
include LICENSE
|
||||
include README.rst
|
||||
recursive-include base/static *
|
||||
recursive-include base/templates *
|
||||
recursive-include control/static *
|
||||
recursive-include control/templates *
|
||||
recursive-include presale/static *
|
||||
recursive-include presale/templates *
|
||||
recursive-include plugins/banktransfer/templates *
|
||||
recursive-include plugins/paypal/templates *
|
||||
recursive-include plugins/stripe/templates *
|
||||
recursive-include plugins/stripe/static *
|
||||
|
||||
@@ -1408,22 +1408,8 @@ class Quota(Versionable):
|
||||
:raises Quota.LockTimeoutException: if the quota is locked every time we try
|
||||
to obtain the lock
|
||||
"""
|
||||
retries = 5
|
||||
for i in range(retries):
|
||||
dt = now()
|
||||
updated = Quota.objects.current.filter(
|
||||
Q(identity=self.identity)
|
||||
& Q(Q(locked__lt=dt - timedelta(seconds=120)) | Q(locked__isnull=True))
|
||||
& Q(version_end_date__isnull=True)
|
||||
).update(
|
||||
locked=dt
|
||||
)
|
||||
if updated:
|
||||
self.locked_here = dt
|
||||
self.locked = dt
|
||||
return True
|
||||
time.sleep(2 ** i / 100)
|
||||
raise Quota.LockTimeoutException()
|
||||
from .services import locking
|
||||
return locking.lock_quota(self)
|
||||
|
||||
def release(self, force=False):
|
||||
"""
|
||||
@@ -1431,17 +1417,8 @@ class Quota(Versionable):
|
||||
the lock will only be released if it was issued in _this_ python
|
||||
representation of the database object.
|
||||
"""
|
||||
if not self.locked_here and not force:
|
||||
return False
|
||||
updated = Quota.objects.current.filter(
|
||||
identity=self.identity,
|
||||
version_end_date__isnull=True
|
||||
).update(
|
||||
locked=None
|
||||
)
|
||||
self.locked_here = None
|
||||
self.locked = None
|
||||
return updated
|
||||
from .services import locking
|
||||
return locking.release_quota(self, force)
|
||||
|
||||
|
||||
class Order(Versionable):
|
||||
|
||||
@@ -0,0 +1,111 @@
|
||||
from datetime import timedelta
|
||||
import logging
|
||||
import time
|
||||
from django.db.models import Q
|
||||
from django.utils.timezone import now
|
||||
from pretix import settings
|
||||
|
||||
from pretix.base.models import Quota
|
||||
|
||||
logger = logging.getLogger('pretix.base.locking')
|
||||
|
||||
|
||||
def lock_quota(quota):
|
||||
"""
|
||||
Issue a lock on this quota so nobody can take tickets from this quota until
|
||||
you release the lock. Will retry 5 times on failure.
|
||||
|
||||
:raises Quota.LockTimeoutException: if the quota is locked every time we try
|
||||
to obtain the lock
|
||||
"""
|
||||
if settings.HAS_REDIS:
|
||||
return lock_quota_redis(quota)
|
||||
else:
|
||||
return lock_quota_db(quota)
|
||||
|
||||
|
||||
def lock_quota_db(quota):
|
||||
retries = 5
|
||||
for i in range(retries):
|
||||
dt = now()
|
||||
|
||||
updated = Quota.objects.current.filter(
|
||||
Q(identity=quota.identity)
|
||||
& Q(Q(locked__lt=dt - timedelta(seconds=120)) | Q(locked__isnull=True))
|
||||
& Q(version_end_date__isnull=True)
|
||||
).update(
|
||||
locked=dt
|
||||
)
|
||||
if updated:
|
||||
quota.locked_here = dt
|
||||
quota.locked = dt
|
||||
return True
|
||||
time.sleep(2 ** i / 100)
|
||||
raise Quota.LockTimeoutException()
|
||||
|
||||
|
||||
def release_quota(quota, force=False):
|
||||
"""
|
||||
Release a lock placed by :py:meth:`lock()`. If the parameter force is not set to ``True``,
|
||||
the lock will only be released if it was issued in _this_ python
|
||||
representation of the database object.
|
||||
"""
|
||||
if not quota.locked_here and not force:
|
||||
return False
|
||||
if settings.HAS_REDIS:
|
||||
return release_quota_redis(quota)
|
||||
else:
|
||||
return release_quota_db(quota)
|
||||
|
||||
|
||||
def release_quota_db(quota):
|
||||
updated = Quota.objects.current.filter(
|
||||
identity=quota.identity,
|
||||
version_end_date__isnull=True
|
||||
).update(
|
||||
locked=None
|
||||
)
|
||||
quota.locked_here = None
|
||||
quota.locked = None
|
||||
return updated
|
||||
|
||||
|
||||
def redis_lock_from_quota(quota):
|
||||
from django_redis import get_redis_connection
|
||||
from redis.lock import Lock
|
||||
|
||||
if not hasattr(quota, '_redis_lock'):
|
||||
rc = get_redis_connection("redis")
|
||||
quota._redis_lock = Lock(redis=rc, name='pretix_quota_%s' % quota.identity, timeout=120)
|
||||
return quota._redis_lock
|
||||
|
||||
|
||||
def lock_quota_redis(quota):
|
||||
from redis.exceptions import RedisError
|
||||
lock = redis_lock_from_quota(quota)
|
||||
retries = 5
|
||||
for i in range(retries):
|
||||
dt = now()
|
||||
try:
|
||||
if lock.acquire(False):
|
||||
quota.locked_here = dt
|
||||
quota.locked = dt
|
||||
return True
|
||||
except RedisError:
|
||||
logger.exception('Error locking a quota')
|
||||
raise Quota.LockTimeoutException()
|
||||
time.sleep(2 ** i / 100)
|
||||
raise Quota.LockTimeoutException()
|
||||
|
||||
|
||||
def release_quota_redis(quota):
|
||||
from redis import RedisError
|
||||
lock = redis_lock_from_quota(quota)
|
||||
try:
|
||||
lock.release()
|
||||
except RedisError:
|
||||
logger.exception('Error releasing a quota lock')
|
||||
raise Quota.LockTimeoutException()
|
||||
quota.locked_here = None
|
||||
quota.locked = None
|
||||
return True
|
||||
@@ -18,6 +18,11 @@ nav.navbar {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.navbar-header .navbar-events {
|
||||
color: white;
|
||||
padding-top: 6px;
|
||||
padding-bottom: 6px;
|
||||
}
|
||||
.nav-pills {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
@@ -66,4 +71,9 @@ nav.navbar {
|
||||
transform: rotateX(180deg);
|
||||
-ms-transform: rotateX(180deg); /* IE 9 */
|
||||
-webkit-transform: rotateX(180deg); /* Safari and Chrome */
|
||||
}
|
||||
}
|
||||
@media (max-width: @screen-sm-max) {
|
||||
.navbar-nav {
|
||||
margin-left: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
{% compress css %}
|
||||
<link rel="stylesheet" type="text/less" href="{% static "pretixcontrol/less/auth.less" %}" />
|
||||
{% endcompress %}
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
|
||||
@@ -18,20 +18,26 @@
|
||||
<script type="text/javascript" src="{% static "pretixcontrol/js/ui/main.js" %}"></script>
|
||||
{% endcompress %}
|
||||
{{ html_head|safe }}
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
</head>
|
||||
<body>
|
||||
<div id="#wrapper">
|
||||
<nav class="navbar navbar-inverse navbar-static-top" role="navigation">
|
||||
<div class="navbar-header">
|
||||
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
|
||||
<button type="button" class="navbar-toggle"
|
||||
data-toggle="collapse" data-target=".navbar-nav-collapse">
|
||||
<span class="sr-only">{% trans "Toggle navigation" %}</span>
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
</button>
|
||||
<button type="button" class="navbar-toggle navbar-events"
|
||||
data-toggle="collapse" data-target=".navbar-events-collapse">
|
||||
<i class="fa fa-calendar"></i><span class="caret"></span>
|
||||
</button>
|
||||
<a class="navbar-brand" href="{% url "control:index" %}">{{ settings.PRETIX_INSTANCE_NAME }}</a>
|
||||
</div>
|
||||
<ul class="nav navbar-nav navbar-top-links navbar-left">
|
||||
<ul class="nav navbar-nav navbar-top-links navbar-left hidden-xs">
|
||||
<li class="dropdown">
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown"><i class="fa fa-calendar"></i>
|
||||
{{ request.event }} <span class="caret"></span></a>
|
||||
@@ -61,7 +67,19 @@
|
||||
</li>
|
||||
</ul>
|
||||
<div class="navbar-default sidebar" role="navigation">
|
||||
<div class="sidebar-nav navbar-collapse">
|
||||
<div class="sidebar-nav navbar-events-collapse navbar-collapse hidden-md hidden-lg">
|
||||
<ul class="nav">
|
||||
<li><a href="{% url "control:events" %}">{% trans "Event overview" %}</a></li>
|
||||
{% for e in request.user.events_cache %}
|
||||
<li>
|
||||
<a href="{% url "control:event.index" organizer=e.organizer.slug event=e.slug %}">
|
||||
{{ e.name }}
|
||||
</a>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
<div class="sidebar-nav navbar-nav-collapse navbar-collapse">
|
||||
<ul class="nav" id="side-menu">
|
||||
{% block nav %}
|
||||
<li>
|
||||
|
||||
@@ -7,46 +7,48 @@
|
||||
<fieldset>
|
||||
<legend>{% trans "Permissions" %}</legend>
|
||||
{{ formset.management_form }}
|
||||
<table class="table table-striped table-condensed">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{% trans "User" %}</th>
|
||||
<th>{% trans "Change settings" %}</th>
|
||||
<th>{% trans "Change products" %}</th>
|
||||
<th>{% trans "View orders" %}</th>
|
||||
<th>{% trans "Change orders" %}</th>
|
||||
<th>{% trans "Change permissions" %}</th>
|
||||
<th>{% trans "Delete" %}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for form in formset %}
|
||||
<div class="table-responsive">
|
||||
<table class="table table-striped table-condensed">
|
||||
<thead>
|
||||
<tr>
|
||||
<td>{{ form.id }}{{ form.instance.user }}</td>
|
||||
<td>{{ form.can_change_settings }}</td>
|
||||
<td>{{ form.can_change_items }}</td>
|
||||
<td>{{ form.can_view_orders }}</td>
|
||||
<td>{{ form.can_change_orders }}</td>
|
||||
<td>{{ form.can_change_permissions }}</td>
|
||||
<td>{{ form.DELETE }}</td>
|
||||
<th>{% trans "User" %}</th>
|
||||
<th>{% trans "Change settings" %}</th>
|
||||
<th>{% trans "Change products" %}</th>
|
||||
<th>{% trans "View orders" %}</th>
|
||||
<th>{% trans "Change orders" %}</th>
|
||||
<th>{% trans "Change permissions" %}</th>
|
||||
<th>{% trans "Delete" %}</th>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
<tr>
|
||||
<td>
|
||||
<div class="row-fluid">
|
||||
<div class="col-sm-12">
|
||||
{% bootstrap_field add_form.user layout='inline' %}
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for form in formset %}
|
||||
<tr>
|
||||
<td>{{ form.id }}{{ form.instance.user }}</td>
|
||||
<td>{{ form.can_change_settings }}</td>
|
||||
<td>{{ form.can_change_items }}</td>
|
||||
<td>{{ form.can_view_orders }}</td>
|
||||
<td>{{ form.can_change_orders }}</td>
|
||||
<td>{{ form.can_change_permissions }}</td>
|
||||
<td>{{ form.DELETE }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
<tr>
|
||||
<td>
|
||||
<div class="row-fluid">
|
||||
<div class="col-sm-12">
|
||||
{% bootstrap_field add_form.user layout='inline' %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td>{{ add_form.can_change_settings }}</td>
|
||||
<td>{{ add_form.can_change_items }}</td>
|
||||
<td>{{ add_form.can_view_orders }}</td>
|
||||
<td>{{ add_form.can_change_orders }}</td>
|
||||
<td>{{ add_form.can_change_permissions }}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</td>
|
||||
<td>{{ add_form.can_change_settings }}</td>
|
||||
<td>{{ add_form.can_change_items }}</td>
|
||||
<td>{{ add_form.can_view_orders }}</td>
|
||||
<td>{{ add_form.can_change_orders }}</td>
|
||||
<td>{{ add_form.can_change_permissions }}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</fieldset>
|
||||
<div class="form-group submit-group">
|
||||
<button type="submit" class="btn btn-primary btn-save">
|
||||
|
||||
@@ -4,25 +4,27 @@
|
||||
{% block inside %}
|
||||
<form action="" method="post">
|
||||
{% csrf_token %}
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{{ properties.0 }}</th>
|
||||
<th>{% trans "Active" %}</th>
|
||||
<th>{% trans "Price" %}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for form in forms %}
|
||||
{% bootstrap_form_errors form type='all' layout='inline' %}
|
||||
<tr>
|
||||
<td>{{ form.values.0 }}</td>
|
||||
<td>{% bootstrap_field form.active layout='inline' %}</td>
|
||||
<td>{% bootstrap_field form.default_price layout='inline' %} {{ form.default_price.errors }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="table-responsive">
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{{ properties.0 }}</th>
|
||||
<th>{% trans "Active" %}</th>
|
||||
<th>{% trans "Price" %}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for form in forms %}
|
||||
{% bootstrap_form_errors form type='all' layout='inline' %}
|
||||
<tr>
|
||||
<td>{{ form.values.0 }}</td>
|
||||
<td>{% bootstrap_field form.active layout='inline' %}</td>
|
||||
<td>{% bootstrap_field form.default_price layout='inline' %} {{ form.default_price.errors }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="form-group submit-group">
|
||||
<button type="submit" class="btn btn-primary btn-save">
|
||||
{% trans "Save" %}
|
||||
|
||||
@@ -8,36 +8,38 @@
|
||||
{% if major.row %}
|
||||
<h3>{{ major.row }}</h3>
|
||||
{% endif %}
|
||||
<table class="table variation-matrix">
|
||||
<thead>
|
||||
<tr>
|
||||
<th></th>
|
||||
{% for val in properties.1.values.all %}
|
||||
<th>{{ val.value }}</th>
|
||||
{% endfor %}
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for sub in major.forms %}
|
||||
<div class="table-responsive">
|
||||
<table class="table variation-matrix">
|
||||
<thead>
|
||||
<tr>
|
||||
<td>{{ sub.row.value }}</td>
|
||||
{% for form in sub.forms %}
|
||||
<td>
|
||||
<div class="row">
|
||||
<div class="col-sm-5">
|
||||
{% bootstrap_field form.active layout='inline' %}
|
||||
</div>
|
||||
<div class="col-sm-7">
|
||||
{% bootstrap_field form.default_price layout='inline' %}
|
||||
</div>
|
||||
</div>
|
||||
{{ form.default_price.errors }}
|
||||
</td>
|
||||
<th></th>
|
||||
{% for val in properties.1.values.all %}
|
||||
<th>{{ val.value }}</th>
|
||||
{% endfor %}
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for sub in major.forms %}
|
||||
<tr>
|
||||
<td>{{ sub.row.value }}</td>
|
||||
{% for form in sub.forms %}
|
||||
<td>
|
||||
<div class="row">
|
||||
<div class="col-sm-5">
|
||||
{% bootstrap_field form.active layout='inline' %}
|
||||
</div>
|
||||
<div class="col-sm-7">
|
||||
{% bootstrap_field form.default_price layout='inline' %}
|
||||
</div>
|
||||
</div>
|
||||
{{ form.default_price.errors }}
|
||||
</td>
|
||||
{% endfor %}
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{% endfor %}
|
||||
<div class="form-group submit-group">
|
||||
<button type="submit" class="btn btn-primary btn-save">
|
||||
|
||||
@@ -6,26 +6,28 @@
|
||||
<p>
|
||||
<a href="{% url "control:event.items.categories.add" organizer=request.event.organizer.slug event=request.event.slug %}" class="btn btn-default"><i class="fa fa-plus"></i> {% trans "Create new category" %}</a>
|
||||
</p>
|
||||
<table class="table table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{% trans "Product categories" %}</th>
|
||||
<th></th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for c in categories %}
|
||||
<tr>
|
||||
<td><strong><a href="{% url "control:event.items.categories.edit" organizer=request.event.organizer.slug event=request.event.slug category=c.identity %}">{{ c.name }}</a></strong></td>
|
||||
<td>
|
||||
<a href="{% url "control:event.items.categories.up" organizer=request.event.organizer.slug event=request.event.slug category=c.identity %}" class="btn btn-default btn-sm {% if forloop.counter0 == 0 %}disabled{% endif %}"><i class="fa fa-arrow-up"></i></a>
|
||||
<a href="{% url "control:event.items.categories.down" organizer=request.event.organizer.slug event=request.event.slug category=c.identity %}" class="btn btn-default btn-sm {% if forloop.revcounter0 == 0 %}disabled{% endif %}"><i class="fa fa-arrow-down"></i></a>
|
||||
</td>
|
||||
<td class="text-right"><a href="{% url "control:event.items.categories.delete" organizer=request.event.organizer.slug event=request.event.slug category=c.identity %}" class="btn btn-danger btn-sm"><i class="fa fa-trash"></i></a></td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="table-responsive">
|
||||
<table class="table table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{% trans "Product categories" %}</th>
|
||||
<th></th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for c in categories %}
|
||||
<tr>
|
||||
<td><strong><a href="{% url "control:event.items.categories.edit" organizer=request.event.organizer.slug event=request.event.slug category=c.identity %}">{{ c.name }}</a></strong></td>
|
||||
<td>
|
||||
<a href="{% url "control:event.items.categories.up" organizer=request.event.organizer.slug event=request.event.slug category=c.identity %}" class="btn btn-default btn-sm {% if forloop.counter0 == 0 %}disabled{% endif %}"><i class="fa fa-arrow-up"></i></a>
|
||||
<a href="{% url "control:event.items.categories.down" organizer=request.event.organizer.slug event=request.event.slug category=c.identity %}" class="btn btn-default btn-sm {% if forloop.revcounter0 == 0 %}disabled{% endif %}"><i class="fa fa-arrow-down"></i></a>
|
||||
</td>
|
||||
<td class="text-right"><a href="{% url "control:event.items.categories.delete" organizer=request.event.organizer.slug event=request.event.slug category=c.identity %}" class="btn btn-danger btn-sm"><i class="fa fa-trash"></i></a></td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{% include "pretixcontrol/pagination.html" %}
|
||||
{% endblock %}
|
||||
|
||||
@@ -14,30 +14,32 @@
|
||||
<a href="{% url "control:event.items.add" organizer=request.event.organizer.slug event=request.event.slug %}"
|
||||
class="btn btn-default"><i class="fa fa-plus"></i> {% trans "Create new product" %}</a>
|
||||
</p>
|
||||
<table class="table table-condensed table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{% trans "Product name" %}</th>
|
||||
<th>{% trans "Category" %}</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% regroup items by category as cat_list %}
|
||||
{% for c in cat_list %}
|
||||
{% for i in c.list %}
|
||||
<div class="table-responsive">
|
||||
<table class="table table-condensed table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<td><strong><a href="
|
||||
{% url "control:event.item" organizer=request.event.organizer.slug event=request.event.slug item=i.identity %}">{{ i.name }}</a></strong></td>
|
||||
<td>{% if i.category %}{{ i.category.name }}{% endif %}</td>
|
||||
<td>
|
||||
<a href="{% url "control:event.items.up" organizer=request.event.organizer.slug event=request.event.slug item=i.identity %}" class="btn btn-default btn-sm {% if forloop.counter0 == 0 %}disabled{% endif %}"><i class="fa fa-arrow-up"></i></a>
|
||||
<a href="{% url "control:event.items.down" organizer=request.event.organizer.slug event=request.event.slug item=i.identity %}" class="btn btn-default btn-sm {% if forloop.revcounter0 == 0 %}disabled{% endif %}"><i class="fa fa-arrow-down"></i></a>
|
||||
</td>
|
||||
<th>{% trans "Product name" %}</th>
|
||||
<th>{% trans "Category" %}</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% regroup items by category as cat_list %}
|
||||
{% for c in cat_list %}
|
||||
{% for i in c.list %}
|
||||
<tr>
|
||||
<td><strong><a href="
|
||||
{% url "control:event.item" organizer=request.event.organizer.slug event=request.event.slug item=i.identity %}">{{ i.name }}</a></strong></td>
|
||||
<td>{% if i.category %}{{ i.category.name }}{% endif %}</td>
|
||||
<td>
|
||||
<a href="{% url "control:event.items.up" organizer=request.event.organizer.slug event=request.event.slug item=i.identity %}" class="btn btn-default btn-sm {% if forloop.counter0 == 0 %}disabled{% endif %}"><i class="fa fa-arrow-up"></i></a>
|
||||
<a href="{% url "control:event.items.down" organizer=request.event.organizer.slug event=request.event.slug item=i.identity %}" class="btn btn-default btn-sm {% if forloop.revcounter0 == 0 %}disabled{% endif %}"><i class="fa fa-arrow-down"></i></a>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
{% endfor %}
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{% include "pretixcontrol/pagination.html" %}
|
||||
{% endblock %}
|
||||
|
||||
@@ -6,23 +6,25 @@
|
||||
<p>
|
||||
<a href="{% url "control:event.items.properties.add" organizer=request.event.organizer.slug event=request.event.slug %}" class="btn btn-default"><i class="fa fa-plus"></i> {% trans "Create new property" %}</a>
|
||||
</p>
|
||||
<table class="table table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{% trans "Product properties" %}</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for p in properties %}
|
||||
<tr>
|
||||
<td><strong><a href="
|
||||
{% url "control:event.items.properties.edit" organizer=request.event.organizer.slug event=request.event.slug property=p.identity %}">{{ p.name }}</a></strong></td>
|
||||
<td class="text-right"><a href="
|
||||
{% url "control:event.items.properties.delete" organizer=request.event.organizer.slug event=request.event.slug property=p.identity %}" class="btn btn-danger btn-sm"><i class="fa fa-trash"></i></a></td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="table-responsive">
|
||||
<table class="table table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{% trans "Product properties" %}</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for p in properties %}
|
||||
<tr>
|
||||
<td><strong><a href="
|
||||
{% url "control:event.items.properties.edit" organizer=request.event.organizer.slug event=request.event.slug property=p.identity %}">{{ p.name }}</a></strong></td>
|
||||
<td class="text-right"><a href="
|
||||
{% url "control:event.items.properties.delete" organizer=request.event.organizer.slug event=request.event.slug property=p.identity %}" class="btn btn-danger btn-sm"><i class="fa fa-trash"></i></a></td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{% include "pretixcontrol/pagination.html" %}
|
||||
{% endblock %}
|
||||
|
||||
@@ -6,25 +6,27 @@
|
||||
<p>
|
||||
<a href="{% url "control:event.items.questions.add" organizer=request.event.organizer.slug event=request.event.slug %}" class="btn btn-default"><i class="fa fa-plus"></i> {% trans "Create new question" %}</a>
|
||||
</p>
|
||||
<table class="table table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{% trans "Question" %}</th>
|
||||
<th>{% trans "Type" %}</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for q in questions %}
|
||||
<tr>
|
||||
<td><strong><a href="
|
||||
{% url "control:event.items.questions.edit" organizer=request.event.organizer.slug event=request.event.slug question=q.identity %}">{{ q.question }}</a></strong></td>
|
||||
<td>{{ q.get_type_display }}</td>
|
||||
<td class="text-right"><a href="
|
||||
{% url "control:event.items.questions.delete" organizer=request.event.organizer.slug event=request.event.slug question=q.identity %}" class="btn btn-danger btn-sm"><i class="fa fa-trash"></i></a></td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="table-responsive">
|
||||
<table class="table table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{% trans "Question" %}</th>
|
||||
<th>{% trans "Type" %}</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for q in questions %}
|
||||
<tr>
|
||||
<td><strong><a href="
|
||||
{% url "control:event.items.questions.edit" organizer=request.event.organizer.slug event=request.event.slug question=q.identity %}">{{ q.question }}</a></strong></td>
|
||||
<td>{{ q.get_type_display }}</td>
|
||||
<td class="text-right"><a href="
|
||||
{% url "control:event.items.questions.delete" organizer=request.event.organizer.slug event=request.event.slug question=q.identity %}" class="btn btn-danger btn-sm"><i class="fa fa-trash"></i></a></td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{% include "pretixcontrol/pagination.html" %}
|
||||
{% endblock %}
|
||||
|
||||
@@ -6,35 +6,37 @@
|
||||
<p>
|
||||
<a href="{% url "control:event.items.quotas.add" organizer=request.event.organizer.slug event=request.event.slug %}" class="btn btn-default"><i class="fa fa-plus"></i> {% trans "Create a new quota" %}</a>
|
||||
</p>
|
||||
<table class="table table-hover table-quotas">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{% trans "Quota name" %}</th>
|
||||
<th>{% trans "Products" %}</th>
|
||||
<th>{% trans "Total capacity" %}</th>
|
||||
<th>{% trans "Capacity left" %}</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for q in quotas %}
|
||||
<tr>
|
||||
<td><strong><a href="{% url "control:event.items.quotas.edit" organizer=request.event.organizer.slug event=request.event.slug quota=q.identity %}">{{ q.name }}</a></strong></td>
|
||||
<td>
|
||||
<ul>
|
||||
{% for item in q.items.all %}
|
||||
<li><a href="
|
||||
{% url "control:event.item" organizer=request.event.organizer.slug event=request.event.slug item=item.identity %}"
|
||||
>{{ item.name }}</a></li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</td>
|
||||
<td>{{ q.size }}</td>
|
||||
<td></td>
|
||||
<td class="text-right"><a href="{% url "control:event.items.quotas.delete" organizer=request.event.organizer.slug event=request.event.slug quota=q.identity %}" class="btn btn-danger btn-sm"><i class="fa fa-trash"></i></a></td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="table-responsive">
|
||||
<table class="table table-hover table-quotas">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{% trans "Quota name" %}</th>
|
||||
<th>{% trans "Products" %}</th>
|
||||
<th>{% trans "Total capacity" %}</th>
|
||||
<th>{% trans "Capacity left" %}</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for q in quotas %}
|
||||
<tr>
|
||||
<td><strong><a href="{% url "control:event.items.quotas.edit" organizer=request.event.organizer.slug event=request.event.slug quota=q.identity %}">{{ q.name }}</a></strong></td>
|
||||
<td>
|
||||
<ul>
|
||||
{% for item in q.items.all %}
|
||||
<li><a href="
|
||||
{% url "control:event.item" organizer=request.event.organizer.slug event=request.event.slug item=item.identity %}"
|
||||
>{{ item.name }}</a></li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</td>
|
||||
<td>{{ q.size }}</td>
|
||||
<td></td>
|
||||
<td class="text-right"><a href="{% url "control:event.items.quotas.delete" organizer=request.event.organizer.slug event=request.event.slug quota=q.identity %}" class="btn btn-danger btn-sm"><i class="fa fa-trash"></i></a></td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{% include "pretixcontrol/pagination.html" %}
|
||||
{% endblock %}
|
||||
|
||||
@@ -26,29 +26,31 @@
|
||||
<button class="btn btn-primary" type="submit">{% trans "Filter" %}</button>
|
||||
</form>
|
||||
</p>
|
||||
<table class="table table-condensed table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{% trans "Order code" %}</th>
|
||||
<th>{% trans "User" %}</th>
|
||||
<th>{% trans "Order total" %}</th>
|
||||
<th>{% trans "Order date" %}</th>
|
||||
<th>{% trans "Status" %}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for o in orders %}
|
||||
<tr>
|
||||
<td><strong><a
|
||||
href="{% url "control:event.order" event=request.event.slug organizer=request.event.organizer.slug code=o.code%}"
|
||||
>{{ o.code }}</a></strong></td>
|
||||
<td>{{ o.user.get_short_name }}</td>
|
||||
<td>{{ o.total|floatformat:2 }} {{ request.event.currency }}</td>
|
||||
<td>{{ o.datetime|date:"SHORT_DATETIME_FORMAT" }}</td>
|
||||
<td>{% include "pretixcontrol/orders/fragment_order_status.html" with order=o %}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="table-responsive">
|
||||
<table class="table table-condensed table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{% trans "Order code" %}</th>
|
||||
<th>{% trans "User" %}</th>
|
||||
<th>{% trans "Order total" %}</th>
|
||||
<th>{% trans "Order date" %}</th>
|
||||
<th>{% trans "Status" %}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for o in orders %}
|
||||
<tr>
|
||||
<td><strong><a
|
||||
href="{% url "control:event.order" event=request.event.slug organizer=request.event.organizer.slug code=o.code%}"
|
||||
>{{ o.code }}</a></strong></td>
|
||||
<td>{{ o.user.get_short_name }}</td>
|
||||
<td>{{ o.total|floatformat:2 }} {{ request.event.currency }}</td>
|
||||
<td>{{ o.datetime|date:"SHORT_DATETIME_FORMAT" }}</td>
|
||||
<td>{% include "pretixcontrol/orders/fragment_order_status.html" with order=o %}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{% include "pretixcontrol/pagination.html" %}
|
||||
{% endblock %}
|
||||
|
||||
@@ -3,62 +3,64 @@
|
||||
{% block title %}{% trans "Order overview" %}{% endblock %}
|
||||
{% block content %}
|
||||
<h1>{% trans "Order overview" %}</h1>
|
||||
<table class="table table-condensed table-hover table-product-overview">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{% trans "Product" %}</th>
|
||||
<th>{% trans "Total orders" %}</th>
|
||||
<th>{% trans "Payment pending" %}</th>
|
||||
<th>{% trans "Cancelled" %}</th>
|
||||
<th>{% trans "Refunded" %}</th>
|
||||
<th>{% trans "Paid" %}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for tup in items_by_category %}
|
||||
{% if tup.0 %}
|
||||
<tr class="category">
|
||||
<th>{{ tup.0.name }}</th>
|
||||
<th>{{ tup.0.num_total }}</th>
|
||||
<th>{{ tup.0.num_pending }}</th>
|
||||
<th>{{ tup.0.num_cancelled }}</th>
|
||||
<th>{{ tup.0.num_refunded }}</th>
|
||||
<th>{{ tup.0.num_paid }}</th>
|
||||
</tr>
|
||||
{% endif %}
|
||||
{% for item in tup.1 %}
|
||||
<tr class="item {% if tup.0 %}categorized{% endif %}">
|
||||
<td>{{ item.name }}</td>
|
||||
<td>{{ item.num_total }}</td>
|
||||
<td>{{ item.num_pending }}</td>
|
||||
<td>{{ item.num_cancelled }}</td>
|
||||
<td>{{ item.num_refunded }}</td>
|
||||
<td>{{ item.num_paid }}</td>
|
||||
</tr>
|
||||
{% if item.has_variations %}
|
||||
{% for var in item.all_variations %}
|
||||
<tr class="variation {% if tup.0 %}categorized{% endif %}">
|
||||
<td>{{ var }}</td>
|
||||
<td>{{ var.num_total }}</td>
|
||||
<td>{{ var.num_pending }}</td>
|
||||
<td>{{ var.num_cancelled }}</td>
|
||||
<td>{{ var.num_refunded }}</td>
|
||||
<td>{{ var.num_paid }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
<div class="table-responsive">
|
||||
<table class="table table-condensed table-hover table-product-overview">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{% trans "Product" %}</th>
|
||||
<th>{% trans "Total orders" %}</th>
|
||||
<th>{% trans "Payment pending" %}</th>
|
||||
<th>{% trans "Cancelled" %}</th>
|
||||
<th>{% trans "Refunded" %}</th>
|
||||
<th>{% trans "Paid" %}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for tup in items_by_category %}
|
||||
{% if tup.0 %}
|
||||
<tr class="category">
|
||||
<th>{{ tup.0.name }}</th>
|
||||
<th>{{ tup.0.num_total }}</th>
|
||||
<th>{{ tup.0.num_pending }}</th>
|
||||
<th>{{ tup.0.num_cancelled }}</th>
|
||||
<th>{{ tup.0.num_refunded }}</th>
|
||||
<th>{{ tup.0.num_paid }}</th>
|
||||
</tr>
|
||||
{% endif %}
|
||||
{% for item in tup.1 %}
|
||||
<tr class="item {% if tup.0 %}categorized{% endif %}">
|
||||
<td>{{ item.name }}</td>
|
||||
<td>{{ item.num_total }}</td>
|
||||
<td>{{ item.num_pending }}</td>
|
||||
<td>{{ item.num_cancelled }}</td>
|
||||
<td>{{ item.num_refunded }}</td>
|
||||
<td>{{ item.num_paid }}</td>
|
||||
</tr>
|
||||
{% if item.has_variations %}
|
||||
{% for var in item.all_variations %}
|
||||
<tr class="variation {% if tup.0 %}categorized{% endif %}">
|
||||
<td>{{ var }}</td>
|
||||
<td>{{ var.num_total }}</td>
|
||||
<td>{{ var.num_pending }}</td>
|
||||
<td>{{ var.num_cancelled }}</td>
|
||||
<td>{{ var.num_refunded }}</td>
|
||||
<td>{{ var.num_paid }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% endfor %}
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr class="total">
|
||||
<th>{% trans "Total" %}</th>
|
||||
<th>{{ total.num_total }}</th>
|
||||
<th>{{ total.num_pending }}</th>
|
||||
<th>{{ total.num_cancelled }}</th>
|
||||
<th>{{ total.num_refunded }}</th>
|
||||
<th>{{ total.num_paid }}</th>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr class="total">
|
||||
<th>{% trans "Total" %}</th>
|
||||
<th>{{ total.num_total }}</th>
|
||||
<th>{{ total.num_pending }}</th>
|
||||
<th>{{ total.num_cancelled }}</th>
|
||||
<th>{{ total.num_refunded }}</th>
|
||||
<th>{{ total.num_paid }}</th>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
@@ -53,7 +53,6 @@ class BankTransfer(BasePaymentProvider):
|
||||
def order_control_render(self, request, order) -> str:
|
||||
if order.payment_info:
|
||||
payment_info = json.loads(order.payment_info)
|
||||
payment_info['amount'] /= 100
|
||||
else:
|
||||
payment_info = None
|
||||
template = get_template('pretixplugins/banktransfer/control.html')
|
||||
|
||||
@@ -66,3 +66,11 @@
|
||||
.checkout-button-row {
|
||||
padding: 15px 0;
|
||||
}
|
||||
@media (max-width: @screen-sm-max) {
|
||||
.checkout-button-row div {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.page-header h1 small {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,4 +41,4 @@ footer {
|
||||
a:hover .panel-primary > .panel-heading {
|
||||
background-color: darken(@btn-primary-bg, 10%);
|
||||
border-color: darken(@btn-primary-border, 12%);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
<script type="text/javascript" src="{% static "pretixpresale/js/ui/main.js" %}"></script>
|
||||
{% endcompress %}
|
||||
{{ html_head|safe }}
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
</head>
|
||||
<body>
|
||||
<div class="container event">
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
Your order: {{ code }}
|
||||
{% endblocktrans %}
|
||||
{% include "pretixpresale/event/fragment_order_status.html" with order=order class="pull-right" %}
|
||||
<div class="clearfix"></div>
|
||||
</h2>
|
||||
{% if order.status == "n" %}
|
||||
<div class="panel panel-danger">
|
||||
|
||||
@@ -4,34 +4,37 @@
|
||||
|
||||
{% block content %}
|
||||
<h2>{% trans "Your orders" %}</h2>
|
||||
<table class="table">
|
||||
<thead>
|
||||
<th>{% trans "Order code" %}</th>
|
||||
<th>{% trans "Date" %}</th>
|
||||
<th>{% trans "Total" %}</th>
|
||||
<th>{% trans "Status" %}</th>
|
||||
<th></th>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for order in orders %}
|
||||
<tr>
|
||||
<td>{{ order.code }}</td>
|
||||
<td>{{ order.datetime|date:"SHORT_DATE_FORMAT" }}</td>
|
||||
<td>{{ event.currency }} {{ order.total|floatformat:2 }}</td>
|
||||
<td>{% include "pretixpresale/event/fragment_order_status.html" with order=order %}</td>
|
||||
<td><a href="{% url "presale:event.order" event=request.event.slug organizer=request.event.organizer.slug order=order.code %}">
|
||||
{% trans "View details" %}
|
||||
</a></td>
|
||||
</tr>
|
||||
{% empty %}
|
||||
<tr>
|
||||
<td colspan="5">
|
||||
<em>{% trans "You did not yet place any orders." %}</em>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="table-responsive">
|
||||
<table class="table">
|
||||
<thead>
|
||||
<th>{% trans "Order code" %}</th>
|
||||
<th>{% trans "Date" %}</th>
|
||||
<th>{% trans "Total" %}</th>
|
||||
<th>{% trans "Status" %}</th>
|
||||
<th></th>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for order in orders %}
|
||||
<tr>
|
||||
<td><a href="{% url "presale:event.order" event=request.event.slug organizer=request.event.organizer.slug order=order.code %}">
|
||||
<strong>{{ order.code }}</strong></td>
|
||||
<td>{{ order.datetime|date:"SHORT_DATE_FORMAT" }}</td>
|
||||
<td>{{ event.currency }} {{ order.total|floatformat:2 }}</td>
|
||||
<td>{% include "pretixpresale/event/fragment_order_status.html" with order=order %}</td>
|
||||
<td><a href="{% url "presale:event.order" event=request.event.slug organizer=request.event.organizer.slug order=order.code %}">
|
||||
{% trans "View details" %}
|
||||
</a></td>
|
||||
</tr>
|
||||
{% empty %}
|
||||
<tr>
|
||||
<td colspan="5">
|
||||
<em>{% trans "You did not yet place any orders." %}</em>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<a href="{% url "presale:event.index" event=request.event.slug organizer=request.event.organizer.slug %}"
|
||||
class="btn btn-primary btn-lg">
|
||||
<span class="fa fa-plus"></span>
|
||||
|
||||
+27
-6
@@ -38,7 +38,7 @@ DEBUG = TEMPLATE_DEBUG = config.getboolean('django', 'debug', fallback=False)
|
||||
DATABASES = {
|
||||
'default': {
|
||||
'ENGINE': 'django.db.backends.' + config.get('database', 'backend', fallback='sqlite3'),
|
||||
'NAME': config.get('database', 'name', fallback=os.path.join(BASE_DIR, 'db.sqlite3')),
|
||||
'NAME': config.get('database', 'name', fallback=os.path.join(DATA_DIR, 'db.sqlite3')),
|
||||
'USER': config.get('database', 'user', fallback=''),
|
||||
'PASSWORD': config.get('database', 'password', fallback=''),
|
||||
'HOST': config.get('database', 'host', fallback=''),
|
||||
@@ -76,13 +76,34 @@ SESSION_COOKIE_SECURE = SESSION_COOKIE_HTTPONLY = config.getboolean(
|
||||
LANGUAGE_COOKIE_DOMAIN = SESSION_COOKIE_DOMAIN = CSRF_COOKIE_DOMAIN = config.get(
|
||||
'pretix', 'cookiedomain', fallback=None)
|
||||
|
||||
if config.has_option('memcached', 'location'):
|
||||
CACHES = {
|
||||
'default': {
|
||||
'BACKEND': 'django.core.cache.backends.memcached.PyLibMCCache',
|
||||
'LOCATION': config.get('memcached', 'location'),
|
||||
CACHES = {
|
||||
'default': {
|
||||
'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',
|
||||
'LOCATION': 'unique-snowflake',
|
||||
}
|
||||
}
|
||||
|
||||
HAS_MEMCACHED = config.has_option('memcached', 'location')
|
||||
if HAS_MEMCACHED:
|
||||
CACHES['default'] = {
|
||||
'BACKEND': 'django.core.cache.backends.memcached.PyLibMCCache',
|
||||
'LOCATION': config.get('memcached', 'location'),
|
||||
}
|
||||
|
||||
HAS_REDIS = config.has_option('redis', 'location')
|
||||
if HAS_REDIS:
|
||||
CACHES['redis'] = {
|
||||
"BACKEND": "django_redis.cache.RedisCache",
|
||||
"LOCATION": config.get('redis', 'location'),
|
||||
"OPTIONS": {
|
||||
"CLIENT_CLASS": "django_redis.client.DefaultClient",
|
||||
}
|
||||
}
|
||||
if not HAS_MEMCACHED:
|
||||
CACHES['default'] = CACHES['redis']
|
||||
if config.getboolean('redis', 'sessions', fallback=False):
|
||||
SESSION_ENGINE = "django.contrib.sessions.backends.cache"
|
||||
SESSION_CACHE_ALIAS = "redis"
|
||||
|
||||
# Internal settings
|
||||
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
django-redis>=4.1,<4.2
|
||||
redis>=2.10,<2.11
|
||||
@@ -0,0 +1,54 @@
|
||||
# Always prefer setuptools over distutils
|
||||
from setuptools import setup, find_packages
|
||||
# To use a consistent encoding
|
||||
from codecs import open
|
||||
from os import path
|
||||
|
||||
here = path.abspath(path.dirname(__file__))
|
||||
|
||||
# Get the long description from the relevant file
|
||||
with open(path.join(here, '../README.md'), encoding='utf-8') as f:
|
||||
long_description = f.read()
|
||||
|
||||
setup(
|
||||
name='pretix',
|
||||
version='0.0.0',
|
||||
description='Reinventing ticket presales',
|
||||
long_description=long_description,
|
||||
url='http://pretix.eu',
|
||||
author='Raphael Michel',
|
||||
author_email='mail@raphaelmichel.de',
|
||||
license='Apache License 2.0',
|
||||
classifiers=[
|
||||
'Development Status :: 3 - Alpha',
|
||||
'Intended Audience :: Developers',
|
||||
'Intended Audience :: Other Audience',
|
||||
'License :: OSI Approved :: Apache Software License',
|
||||
'Programming Language :: Python :: 3.3',
|
||||
'Programming Language :: Python :: 3.4',
|
||||
'Framework :: Django :: 1.8'
|
||||
],
|
||||
|
||||
# What does your project relate to?
|
||||
keywords='tickets web shop ecommerce',
|
||||
packages=['pretix'],
|
||||
install_requires=[
|
||||
'Django>=1.8,<1.9', 'python-dateutil>=2.4,<2.5',
|
||||
'pytz', 'django-bootstrap3>=6.1,<6.2', 'django-formset-js',
|
||||
'cleanerversion>=1.5,<1.7', 'django-compressor>=1.6,<2.0',
|
||||
'reportlab>=3.1.44,<3.2', 'PyPDF2', 'BeautifulSoup4', 'html5lib',
|
||||
'slimit', 'lxml', 'static3==0.6.1', 'dj-static', 'chardet'
|
||||
],
|
||||
extras_require={
|
||||
'dev': ['django-debug-toolbar>=1.3.0,<2.0'],
|
||||
'test': ['pep8==1.5.7', 'pyflakes', 'pep8-naming', 'flake8', 'coverage',
|
||||
'selenium', 'pytest', 'pytest-django'],
|
||||
'memcached': ['pylibmc'],
|
||||
'mysql': ['mysqlclient'],
|
||||
'paypal': ['paypalrestsdk>=1.9,<1.10,<2.0'],
|
||||
'postgres': ['psycopg2'],
|
||||
'redis': ['django-redis>=4.1,<4.2', 'django-redis>=4.1,<4.2'],
|
||||
'stripe': ['stripe>=1.22,<1.23']
|
||||
},
|
||||
include_package_data=True,
|
||||
)
|
||||
Reference in New Issue
Block a user