diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index fa7ad94..c396610 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -8,9 +8,9 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: ["3.8", "3.10"] + python-version: ["3.10"] env: - MAIN_PYTHON_VERSION: "3.8" # same as Ubuntu 20 LTS + MAIN_PYTHON_VERSION: "3.10" # same as Ubuntu 22 LTS steps: - uses: actions/checkout@v3 @@ -18,16 +18,24 @@ jobs: uses: actions/setup-python@v4 with: python-version: ${{ matrix.python-version }} - - name: Install requirements - run: | - pip install -r requirements/testing.txt + - name: Install Ubuntu package dependencies + run: sudo apt-get install gettext graphviz graphviz-dev + - name: Install Poetry + uses: snok/install-poetry@v1 + with: + virtualenvs-create: true + virtualenvs-in-project: true + - name: Load cached venv + id: cached-poetry-dependencies + uses: actions/cache@v3 + with: + path: .venv + key: venv-${{ runner.os }}-${{ hashFiles('**/poetry.lock') }} + - name: Install dependencies + if: steps.cached-poetry-dependencies.outputs.cache-hit != 'true' + run: poetry install --no-interaction - name: Run the test suite - run: | - coverage run manage-testing.py test pygraz_website.apps.accounts pygraz_website.apps.companies pygraz_website.apps.core pygraz_website.apps.meetups - - name: Build coverage report - run: | - coverage html - coverage report + run: pytest check-style: runs-on: ubuntu-latest diff --git a/.gitignore b/.gitignore index 2df6773..eb4e0c8 100644 --- a/.gitignore +++ b/.gitignore @@ -1,23 +1,14 @@ *.pyc -.env *.css *.sass-cache* *.diff *.sql *.sublime* -.codeintel -.venv -*.retry -pygraz_website/static/css/icomoon *.DS_Store *.zip *.mo -pygraz_website/settings/live.py -pygraz_website/settings/stage.py -live.ini -stage.ini -Procfile -.tox .coverage htmlcov -/database.db +/pygraz.dump +/_old/ +/pygraz.sqlite3 diff --git a/.idea/misc.xml b/.idea/misc.xml index 6eca4f0..74c71f2 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -1,6 +1,6 @@ - + diff --git a/.idea/pygraz_website.iml b/.idea/pygraz_website.iml index 0ba96ca..8b2fa09 100644 --- a/.idea/pygraz_website.iml +++ b/.idea/pygraz_website.iml @@ -1,11 +1,24 @@ + + + + + + + - + @@ -19,7 +32,7 @@ diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index d36e014..0f8d997 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -7,17 +7,17 @@ repos: - id: isort - repo: https://github.com/ambv/black - rev: 23.7.0 + rev: 23.10.1 hooks: - id: black - repo: https://github.com/pre-commit/mirrors-prettier - rev: v3.0.0 + rev: v3.0.3 hooks: - id: prettier - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.4.0 + rev: v4.5.0 hooks: - id: fix-byte-order-marker - id: trailing-whitespace @@ -30,13 +30,13 @@ repos: - id: mixed-line-ending - repo: https://github.com/PyCQA/flake8 - rev: 6.0.0 + rev: 6.1.0 hooks: - id: flake8 additional_dependencies: ["pep8-naming==0.13.3"] - repo: https://github.com/asottile/pyupgrade - rev: v2.37.3 + rev: v3.15.0 hooks: - id: pyupgrade args: ["--py38-plus"] @@ -45,7 +45,7 @@ repos: # even for the rare case a commit should go into one of the protected # branches. - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.4.0 + rev: v4.5.0 hooks: - id: no-commit-to-branch args: ["--branch", "develop"] diff --git a/.python-version b/.python-version deleted file mode 100644 index 9ad6380..0000000 --- a/.python-version +++ /dev/null @@ -1 +0,0 @@ -3.8.18 diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index a848d71..0000000 --- a/.travis.yml +++ /dev/null @@ -1,13 +0,0 @@ -language: python -python: - - "2.7" -sudo: false -env: - matrix: - - TOXENV=py27 -install: - - pip install coveralls - - pip install tox -script: tox -after_success: - - coveralls diff --git a/AUTHORS.txt b/AUTHORS.txt index 6063de7..a093360 100644 --- a/AUTHORS.txt +++ b/AUTHORS.txt @@ -1 +1,3 @@ +Dorian Santner Horst Gutmann +Thomas Aglassinger diff --git a/Makefile b/Makefile deleted file mode 100644 index 93ad82d..0000000 --- a/Makefile +++ /dev/null @@ -1,5 +0,0 @@ -all: tests -tests: - export PYTHONPATH=. - coverage run manage-testing.py test meetups companies accounts --settings=pygraz_website.settings.testing - coverage report --include='pygraz_website*' --omit='*migrations*','*admin.py','*settings*' diff --git a/README.md b/README.md index 32bcb5e..deea749 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ [![Coverage Status](https://coveralls.io/repos/pygraz/website/badge.svg?branch=develop)](https://coveralls.io/r/pygraz/website?branch=develop) -The PyGRAZ website currently supports the creation of meetups and for users to make session proposal which can +The PyGRAZ website currently supports the creation of meetups and for admin to make session proposal which can then be assigned to a meetup. Each proposal can have descriptive information associated with it like an abstract, a description and notes. @@ -26,82 +26,44 @@ git clone cd website ``` -Then create a virtualenv for all the Python requirements, activate it and install the requirements: +Then install [poetry](https://python-poetry.org/) and install the requirements: ```bash -mkvirtualenv --no-site-packages env -source env/bin/active -pip install -r requirements/base.txt -pip install -r requirements/development.txt +poetry install ``` -We are using a multi-settings-file approach for handling settings on different target systems. For local development -you should use "pygraz_website/settings/development.py" which just sets some plain defaults and doesn't send emails. - Next, install the pre-commit hooks to perform static checks on your code everytime you commit: ```bash -pre-commit install -``` - -Now on to creating the database. By default, the website looks for a PostgreSQL database by the name of -"pygraz-website" accessibly by the current system user. - -If you want to use for instance a sqlite database, add following content to your development.py file you created in -the last step: - -```python -DATABASES = { - 'default': { - 'ENGINE': 'django.db.backends.sqlite3', - 'NAME': join(ROOT, 'localdb.sqlite3'), - 'USER': '', - 'PASSWORD': '', - 'HOST': '', - 'PORT': '', - } -} +poetry run pre-commit install ``` -Now run following commands to initialize the database: - -```bash -python manage-dev.py syncdb -python manage-dev.py migrate -``` +Currently, the site uses an SQLite database. No further setup is needed for this. -To finally start the server run ... +If you just want to run the application locally and want to fill the database with generated demonstration data, you can run: ```bash -python manage-dev.py runserver +poetry run python manage.py make_demo ``` -When you first visit http://localhost:8000, you will notice that all the stylesheets are still missing. -For local development we would recommend that you open another terminal, go to the pygraz_website/static folder and -execute following command: +To launch the application run: ```bash -compass watch +poetry run python manage.py runserver ``` -This will compile the stylesheets using Compass and keep the process running so that changes the .scss files are -automatically compiled into .css files. - -## Components not included +Then visit http://127.0.0.1:8000/ -The pygraz.org website uses the icomoon icon-font for its icons. Due to license restrictions we are not allowed to -bundle it with the website's source code. For details on this font visit http://keyamoon.com/icomoon/ +## Testing -## Deployment +All tests are located in the `tests` folder and its respective sub-folders. -For deployments, we are using an Ansible playbook which builds a production.zip -and deploys that onto the target server: +For testing, run: ```bash -cd ansible/playbooks -ansible-playbook -i ../hosts deploy.yml +poetry run pytest ``` -[pip]: http://pypi.python.org/pypi/pip -[rc]: http://recaptcha.net/ -[pm]: http://postmarkapp.com +## Deployment + +**To be defined.** diff --git a/ansible/hosts b/ansible/hosts deleted file mode 100644 index 8dfaba3..0000000 --- a/ansible/hosts +++ /dev/null @@ -1,2 +0,0 @@ -[live] -pygraz.org ansible_user=root diff --git a/ansible/playbooks/deploy.yml b/ansible/playbooks/deploy.yml deleted file mode 100644 index 2fe0bec..0000000 --- a/ansible/playbooks/deploy.yml +++ /dev/null @@ -1,46 +0,0 @@ ---- -- hosts: localhost - any_errors_fatal: true - vars: - - root: ../.. - tasks: - - stat: - path: "{{ root }}/.venv" - register: venv - - name: Create virtualenv if missing - when: not venv.stat.exists - shell: "virtualenv {{ root }}/.venv" - - name: Install all dependencies - shell: "{{ root }}/.venv/bin/pip install -r {{ root }}/requirements/base.txt" - - name: Build CSS - shell: compass compile -s compact - args: - chdir: "{{ root }}/pygraz_website/static" - - name: Compile messages - shell: "../.venv/bin/django-admin.py compilemessages" - args: - chdir: "{{ root}}/pygraz_website" - - name: Clean up previous artifacts - file: - path: production.zip - state: absent - - name: Build production.zip - shell: "zip -x@production-exclude.lst -r production.zip *" - args: - chdir: "{{ root }}" -- hosts: live - become_user: www-pygraz - become: true - tasks: - - name: Unzip package - unarchive: - src: ../../production.zip - dest: /srv/www/pygraz.org/live/app/ - - name: Install dependencies - shell: "CC=`which clang` ./env/bin/pip install -r app/requirements/live.txt" - args: - chdir: /srv/www/pygraz.org/live -- hosts: live - tasks: - - name: Restart server - shell: systemctl restart www-pygraz diff --git a/pygraz_website/apps/__init__.py b/core/__init__.py similarity index 100% rename from pygraz_website/apps/__init__.py rename to core/__init__.py diff --git a/core/admin.py b/core/admin.py new file mode 100644 index 0000000..d9e6e02 --- /dev/null +++ b/core/admin.py @@ -0,0 +1,6 @@ +from django.contrib import admin + +from core.models import Location, Meetup, Session, SessionType + +for model in [Location, Meetup, Session, SessionType]: + admin.site.register(model) diff --git a/core/apps.py b/core/apps.py new file mode 100644 index 0000000..c0ce093 --- /dev/null +++ b/core/apps.py @@ -0,0 +1,6 @@ +from django.apps import AppConfig + + +class CoreConfig(AppConfig): + default_auto_field = "django.db.models.BigAutoField" + name = "core" diff --git a/core/migrations/0001_initial.py b/core/migrations/0001_initial.py new file mode 100644 index 0000000..9f30076 --- /dev/null +++ b/core/migrations/0001_initial.py @@ -0,0 +1,121 @@ +import django.core.validators +import django.db.models.deletion +from django.conf import settings +from django.db import migrations, models + + +class Migration(migrations.Migration): + initial = True + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ] + + operations = [ + migrations.CreateModel( + name="Location", + fields=[ + ("id", models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name="ID")), + ("name", models.CharField(max_length=200)), + ("description", models.TextField(blank=True, default="")), + ("website", models.URLField(blank=True, default="")), + ("address", models.CharField(blank=True, default="", max_length=255)), + ("map_image", models.ImageField(blank=True, default=None, null=True, upload_to="")), + ], + options={ + "verbose_name": "location", + "verbose_name_plural": "locations", + }, + ), + migrations.CreateModel( + name="Meetup", + fields=[ + ("id", models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name="ID")), + ("start_date", models.DateField()), + ("meetupcom_id", models.CharField(blank=True, default="", max_length=20)), + ("description", models.TextField(blank=True, default="")), + ("notes", models.TextField(blank=True, default="")), + ( + "attendee_count", + models.IntegerField( + blank=True, null=True, validators=[django.core.validators.MinValueValidator(0)] + ), + ), + ( + "location", + models.ForeignKey( + blank=True, + default=None, + null=True, + on_delete=django.db.models.deletion.CASCADE, + to="core.location", + ), + ), + ], + options={ + "verbose_name": "Meetup", + "verbose_name_plural": "Meetups", + "ordering": ("-start_date",), + }, + ), + migrations.CreateModel( + name="SessionType", + fields=[ + ("id", models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name="ID")), + ("name", models.CharField(max_length=30, unique=True, verbose_name="Name")), + ("description", models.TextField(blank=True, default="", verbose_name="Beschreibung")), + ], + options={ + "verbose_name": "Session type", + "verbose_name_plural": "Session types", + }, + ), + migrations.CreateModel( + name="Session", + fields=[ + ("id", models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name="ID")), + ("title", models.CharField(max_length=255, verbose_name="Titel")), + ("abstract", models.TextField(verbose_name="Kurzbeschreibung")), + ("speaker_name", models.CharField(blank=True, default="", max_length=100, verbose_name="Vortragender")), + ( + "speaker_email", + models.EmailField(blank=True, default="", max_length=254, verbose_name="E-Mail-Adresse"), + ), + ("slides_url", models.URLField(blank=True, default="", verbose_name="Folien-URL")), + ("notes", models.TextField(blank=True, default="", verbose_name="Notizen")), + ( + "meetup", + models.ForeignKey( + blank=True, + default=None, + null=True, + on_delete=django.db.models.deletion.CASCADE, + related_name="sessions", + to="core.meetup", + verbose_name="Meetup", + ), + ), + ( + "speaker", + models.ForeignKey( + blank=True, + default="", + null=True, + on_delete=django.db.models.deletion.CASCADE, + to=settings.AUTH_USER_MODEL, + verbose_name="Vortragender", + ), + ), + ( + "type", + models.ForeignKey( + on_delete=django.db.models.deletion.PROTECT, to="core.sessiontype", verbose_name="Vortragsart" + ), + ), + ], + options={ + "verbose_name": "Session", + "verbose_name_plural": "Sessions", + }, + ), + ] diff --git a/pygraz_website/apps/accounts/__init__.py b/core/migrations/__init__.py similarity index 100% rename from pygraz_website/apps/accounts/__init__.py rename to core/migrations/__init__.py diff --git a/core/models.py b/core/models.py new file mode 100644 index 0000000..670f683 --- /dev/null +++ b/core/models.py @@ -0,0 +1,124 @@ +from typing import Optional + +from django.contrib.auth.models import User +from django.core import validators +from django.db import models +from django.db.models import QuerySet +from django.utils.timezone import now +from django.utils.translation import gettext_lazy as _ + + +class Location(models.Model): + name = models.CharField(max_length=200) + description = models.TextField(blank=True, default="") + website = models.URLField(blank=True, default="") + address = models.CharField(default="", blank=True, max_length=255) + map_image = models.ImageField(default=None, blank=True, null=True) + + def __str__(self): + return self.name + + class Meta: + verbose_name = _("location") + verbose_name_plural = _("locations") + + +class MeetupManager(models.Manager): + def past_meetups(self) -> QuerySet["Meetup"]: + return self.filter(start_date__lt=now()) + + def next_meetup(self) -> Optional["Meetup"]: + return self.filter(start_date__gte=now()).first() + + +class Meetup(models.Model): + objects = MeetupManager() + + start_date = models.DateField() + location = models.ForeignKey(Location, blank=True, default=None, null=True, on_delete=models.CASCADE) + meetupcom_id = models.CharField( + blank=True, default="", max_length=20, help_text=_("ID part of URL from meetup.com") + ) + description = models.TextField(blank=True, default="") + notes = models.TextField(blank=True, default="") + attendee_count = models.IntegerField( + null=True, + blank=True, + validators=[ + validators.MinValueValidator(0), + ], + ) + + @property + def meetup_url(self): + return f"https://www.meetup.com/PyGRAZ/events/{self.meetupcom_id}" + + def __str__(self): + return str(self.start_date) + + class Meta: + verbose_name = "Meetup" + verbose_name_plural = "Meetups" + ordering = ("-start_date",) + + +class Session(models.Model): + title = models.CharField("Titel", max_length=255) + abstract = models.TextField("Kurzbeschreibung") + meetup: Meetup = models.ForeignKey( + Meetup, + blank=True, + default=None, + null=True, + on_delete=models.CASCADE, + related_name="sessions", + verbose_name="Meetup", + ) + speaker_name = models.CharField("Vortragender", blank=True, default="", max_length=100) + speaker_email = models.EmailField("E-Mail-Adresse", blank=True, default="") + speaker: User = models.ForeignKey( + User, + verbose_name="Vortragender", + blank=True, + default="", + null=True, + on_delete=models.CASCADE, + ) + slides_url = models.URLField("Folien-URL", blank=True, default="") + notes = models.TextField("Notizen", blank=True, default="") + type = models.ForeignKey( + "SessionType", + verbose_name="Vortragsart", + on_delete=models.PROTECT, + ) + + def __str__(self): + return self.title + + @property + def get_speaker_name(self): + if self.speaker: + firstname = self.speaker.first_name + lastname = self.speaker.last_name + if firstname is not None and lastname is not None: + return f"{firstname} {lastname}" + if firstname is not None: + return firstname + return self.speaker.username + return self.speaker_name + + class Meta: + verbose_name = "Session" + verbose_name_plural = "Sessions" + + +class SessionType(models.Model): + name = models.CharField("Name", max_length=30, unique=True) + description = models.TextField("Beschreibung", blank=True, default="") + + def __str__(self): + return self.name + + class Meta: + verbose_name = "Session type" + verbose_name_plural = "Session types" diff --git a/core/templates/core/base.html b/core/templates/core/base.html new file mode 100644 index 0000000..505565e --- /dev/null +++ b/core/templates/core/base.html @@ -0,0 +1,28 @@ + +{% load i18n %} +{% load static %} +{% get_current_language as LANGUAGE_CODE %} + + + + + {% if meta_description %} + + {% endif %} + + {% if title %}{{ title }}{% else %}pyGRAZ{% endif %} + + {# TODO: Add favicon. #} + + + +
+ {% block content %} {% endblock %} +
+
+ TODO: Add footer. +
+ + diff --git a/core/templates/core/home.html b/core/templates/core/home.html new file mode 100644 index 0000000..15ca1ec --- /dev/null +++ b/core/templates/core/home.html @@ -0,0 +1,25 @@ +{# TODO: Add logo. #} + +

pyGRAZ

+ +

+ PyGRAZ ist eine Usergroup zur Python-Programmiersprache in Graz. Wir treffen uns regelmässig am ersten Dienstag im Monat entweder im spektral oder im Gösserbräu. +

+ +

Nächstes Treffen

+ +{% if next_meetup %} +

Am {{ next_meetup.start_date.date }} im {{ next_meetup.location }}

+

{{ next_meetup.description }}

+ {# TODO: Add more details about next Meetup. #} +{% else %} +

Derzeit gibt es leider noch keine Informationen zum nächsten Treffen.

+{% endif %} + + +

Vergangene Meetups

+ diff --git a/core/templates/core/meetup.html b/core/templates/core/meetup.html new file mode 100644 index 0000000..be1113e --- /dev/null +++ b/core/templates/core/meetup.html @@ -0,0 +1,5 @@ +

Meetup {{ meetup.start_date.date }}

+ +{# TODO: Add remaining information about the meetup. #} + +

{{ meetup.description }}

diff --git a/core/tests.py b/core/tests.py new file mode 100644 index 0000000..7ce503c --- /dev/null +++ b/core/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/core/urls.py b/core/urls.py new file mode 100644 index 0000000..1967c70 --- /dev/null +++ b/core/urls.py @@ -0,0 +1,8 @@ +from django.urls import path + +from core import views + +urlpatterns = [ + path("", views.home_view, name="home"), + path("meetup//", views.meetup_view, name="meetup"), +] diff --git a/core/views.py b/core/views.py new file mode 100644 index 0000000..aefbaf0 --- /dev/null +++ b/core/views.py @@ -0,0 +1,17 @@ +from django.http import HttpRequest +from django.shortcuts import get_object_or_404, render + +from core.models import Meetup + + +def home_view(request: HttpRequest): + return render( + request, + "core/home.html", + {"next_meetup": Meetup.objects.next_meetup(), "past_meetups": Meetup.objects.past_meetups()}, + ) + + +def meetup_view(request: HttpRequest, pk: int): + meetup = get_object_or_404(Meetup, pk=pk) + return render(request, "core/meetup.html", {"meetup": meetup}) diff --git a/pygraz_website/apps/accounts/migrations/__init__.py b/demo/__init__.py similarity index 100% rename from pygraz_website/apps/accounts/migrations/__init__.py rename to demo/__init__.py diff --git a/demo/apps.py b/demo/apps.py new file mode 100644 index 0000000..6fbee78 --- /dev/null +++ b/demo/apps.py @@ -0,0 +1,6 @@ +from django.apps import AppConfig + + +class DemoConfig(AppConfig): + default_auto_field = "django.db.models.BigAutoField" + name = "demo" diff --git a/demo/demo.py b/demo/demo.py new file mode 100644 index 0000000..77558f1 --- /dev/null +++ b/demo/demo.py @@ -0,0 +1,62 @@ +import random +from datetime import date, datetime, timedelta, timezone + +from django.contrib.auth.models import User +from django.db import transaction + +from core.models import Location, Meetup, Session, SessionType + +DEMO_ADMIN_USERNAMES = ["admin"] +DEMO_COMMON_USERNAMES = ["alice", "bob", "clara", "dean"] +DEMO_LOCATION_NAMES = ["Spektral", "Gösserbräu"] +DEMO_SESSION_TYPE_NAMES = ["Coding Dojo", "Lightning Talk", "Talk"] +_DEMO_PACKAGES = ["cheese", "eggs", "ham", "parrot", "spam"] +_DEMO_TITLE_FORMATS = [ + "Everything you need ot know about %(package)s", + "Understanding %(package)s", + "Working with %(package)s", + "%(package)s - an introduction", +] +_DAYS_BETWEEN_SESSION = 30 + + +def purge_demo(): + User.objects.filter(username__in=DEMO_ADMIN_USERNAMES + DEMO_COMMON_USERNAMES).delete() + for model in [Location, Session, SessionType, Meetup]: + model.objects.all().delete() + + +def build_demo(session_count: int = 20): + randomizer = random.Random(0) + for admin_username in DEMO_ADMIN_USERNAMES: + build_user_if_not_exists(admin_username, True) + for common_username in DEMO_COMMON_USERNAMES: + build_user_if_not_exists(common_username) + for location_name in DEMO_LOCATION_NAMES: + Location.objects.update_or_create(name=location_name) + for session_type_name in DEMO_SESSION_TYPE_NAMES: + SessionType.objects.update_or_create(name=session_type_name) + meetup_date = utc_now() + timedelta(days=11 - _DAYS_BETWEEN_SESSION * (session_count - 2)) + locations = list(Location.objects.order_by("id")) + session_types = list(SessionType.objects.order_by("id")) + for _ in range(session_count): + location = randomizer.choice(locations) + meetup, _ = Meetup.objects.update_or_create(start_date=meetup_date, defaults={"location": location}) + session_type = randomizer.choice(session_types) + package_name = randomizer.choice(_DEMO_PACKAGES) + title_format = randomizer.choice(_DEMO_TITLE_FORMATS) + title = title_format % {"package": package_name} + Session.objects.update_or_create(title=title, defaults={"type": session_type}) + # TODO Session.objects.create(meetup=meetup, title=title, type=session_type) + meetup_date = meetup_date + timedelta(days=_DAYS_BETWEEN_SESSION) + + +def build_user_if_not_exists(username: str, is_superuser: bool = False): + with transaction.atomic(): + user = User.objects.select_for_update().filter(username=username) + if user is None: + User.objects.create_user(username=username, is_staff=is_superuser, is_superuser=is_superuser) + + +def utc_now() -> datetime: + return datetime.utcnow().replace(tzinfo=timezone.utc) diff --git a/demo/management/commands/make_demo.py b/demo/management/commands/make_demo.py new file mode 100644 index 0000000..52165a4 --- /dev/null +++ b/demo/management/commands/make_demo.py @@ -0,0 +1,26 @@ +from django.core.management import CommandError +from django.core.management.base import BaseCommand +from django.db.models import ProtectedError + +from demo.demo import build_demo, purge_demo + + +class Command(BaseCommand): + help = "Add demo data to database" + + def add_arguments(self, parser): + parser.add_argument( + "--purge", "-P", action="store_true", help="Purge all existing data before creating new one" + ) + + def handle(self, *_args, **options): + has_to_be_purged = bool(options["purge"]) + + try: + if has_to_be_purged: + purge_demo() + build_demo() + except ProtectedError as error: + raise CommandError(f"Cannot create demo: {error}") from error + else: + self.stdout.write(self.style.SUCCESS("Successfully created demo")) diff --git a/manage-dev.py b/manage-dev.py deleted file mode 100755 index bb1ae93..0000000 --- a/manage-dev.py +++ /dev/null @@ -1,10 +0,0 @@ -#!/usr/bin/env python -import os -import sys - -if __name__ == "__main__": - os.environ.setdefault("DJANGO_SETTINGS_MODULE", "pygraz_website.settings.development") - - from django.core.management import execute_from_command_line - - execute_from_command_line(sys.argv) diff --git a/manage-live.py b/manage-live.py deleted file mode 100755 index 8847d47..0000000 --- a/manage-live.py +++ /dev/null @@ -1,10 +0,0 @@ -#!/usr/bin/env python -import os -import sys - -if __name__ == "__main__": - os.environ.setdefault("DJANGO_SETTINGS_MODULE", "pygraz_website.settings.live") - - from django.core.management import execute_from_command_line - - execute_from_command_line(sys.argv) diff --git a/manage-stage.py b/manage-stage.py deleted file mode 100755 index 36cefad..0000000 --- a/manage-stage.py +++ /dev/null @@ -1,10 +0,0 @@ -#!/usr/bin/env python -import os -import sys - -if __name__ == "__main__": - os.environ.setdefault("DJANGO_SETTINGS_MODULE", "pygraz_website.settings.stage") - - from django.core.management import execute_from_command_line - - execute_from_command_line(sys.argv) diff --git a/manage-testing.py b/manage-testing.py deleted file mode 100755 index 544c7b1..0000000 --- a/manage-testing.py +++ /dev/null @@ -1,10 +0,0 @@ -#!/usr/bin/env python -import os -import sys - -if __name__ == "__main__": - os.environ.setdefault("DJANGO_SETTINGS_MODULE", "pygraz_website.settings.testing") - - from django.core.management import execute_from_command_line - - execute_from_command_line(sys.argv) diff --git a/manage.py b/manage.py index b5da0ca..beb59a5 100755 --- a/manage.py +++ b/manage.py @@ -1,11 +1,22 @@ #!/usr/bin/env python +"""Django's command-line utility for administrative tasks.""" import os import sys -if __name__ == "__main__": - if os.environ.get("DJANGO_SETTINGS_MODULE") is None: - raise OSError("environment variable DJANGO_SETTINGS_MODULE must be set") - - from django.core.management import execute_from_command_line +def main(): + """Run administrative tasks.""" + os.environ.setdefault("DJANGO_SETTINGS_MODULE", "pygraz_website.settings") + try: + from django.core.management import execute_from_command_line + except ImportError as exc: + raise ImportError( + "Couldn't import Django. Are you sure it's installed and " + "available on your PYTHONPATH environment variable? Did you " + "forget to activate a virtual environment?" + ) from exc execute_from_command_line(sys.argv) + + +if __name__ == "__main__": + main() diff --git a/poetry.lock b/poetry.lock new file mode 100644 index 0000000..af51f00 --- /dev/null +++ b/poetry.lock @@ -0,0 +1,261 @@ +# This file is automatically @generated by Poetry 1.6.1 and should not be changed by hand. + +[[package]] +name = "asgiref" +version = "3.7.2" +description = "ASGI specs, helper code, and adapters" +optional = false +python-versions = ">=3.7" +files = [ + {file = "asgiref-3.7.2-py3-none-any.whl", hash = "sha256:89b2ef2247e3b562a16eef663bc0e2e703ec6468e2fa8a5cd61cd449786d4f6e"}, + {file = "asgiref-3.7.2.tar.gz", hash = "sha256:9e0ce3aa93a819ba5b45120216b23878cf6e8525eb3848653452b4192b92afed"}, +] + +[package.dependencies] +typing-extensions = {version = ">=4", markers = "python_version < \"3.11\""} + +[package.extras] +tests = ["mypy (>=0.800)", "pytest", "pytest-asyncio"] + +[[package]] +name = "colorama" +version = "0.4.6" +description = "Cross-platform colored terminal text." +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" +files = [ + {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"}, + {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, +] + +[[package]] +name = "django" +version = "4.2.6" +description = "A high-level Python web framework that encourages rapid development and clean, pragmatic design." +optional = false +python-versions = ">=3.8" +files = [ + {file = "Django-4.2.6-py3-none-any.whl", hash = "sha256:a64d2487cdb00ad7461434320ccc38e60af9c404773a2f95ab0093b4453a3215"}, + {file = "Django-4.2.6.tar.gz", hash = "sha256:08f41f468b63335aea0d904c5729e0250300f6a1907bf293a65499496cdbc68f"}, +] + +[package.dependencies] +asgiref = ">=3.6.0,<4" +sqlparse = ">=0.3.1" +tzdata = {version = "*", markers = "sys_platform == \"win32\""} + +[package.extras] +argon2 = ["argon2-cffi (>=19.1.0)"] +bcrypt = ["bcrypt"] + +[[package]] +name = "exceptiongroup" +version = "1.1.3" +description = "Backport of PEP 654 (exception groups)" +optional = false +python-versions = ">=3.7" +files = [ + {file = "exceptiongroup-1.1.3-py3-none-any.whl", hash = "sha256:343280667a4585d195ca1cf9cef84a4e178c4b6cf2274caef9859782b567d5e3"}, + {file = "exceptiongroup-1.1.3.tar.gz", hash = "sha256:097acd85d473d75af5bb98e41b61ff7fe35efe6675e4f9370ec6ec5126d160e9"}, +] + +[package.extras] +test = ["pytest (>=6)"] + +[[package]] +name = "iniconfig" +version = "2.0.0" +description = "brain-dead simple config-ini parsing" +optional = false +python-versions = ">=3.7" +files = [ + {file = "iniconfig-2.0.0-py3-none-any.whl", hash = "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374"}, + {file = "iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3"}, +] + +[[package]] +name = "packaging" +version = "23.2" +description = "Core utilities for Python packages" +optional = false +python-versions = ">=3.7" +files = [ + {file = "packaging-23.2-py3-none-any.whl", hash = "sha256:8c491190033a9af7e1d931d0b5dacc2ef47509b34dd0de67ed209b5203fc88c7"}, + {file = "packaging-23.2.tar.gz", hash = "sha256:048fb0e9405036518eaaf48a55953c750c11e1a1b68e0dd1a9d62ed0c092cfc5"}, +] + +[[package]] +name = "pillow" +version = "10.1.0" +description = "Python Imaging Library (Fork)" +optional = false +python-versions = ">=3.8" +files = [ + {file = "Pillow-10.1.0-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:1ab05f3db77e98f93964697c8efc49c7954b08dd61cff526b7f2531a22410106"}, + {file = "Pillow-10.1.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:6932a7652464746fcb484f7fc3618e6503d2066d853f68a4bd97193a3996e273"}, + {file = "Pillow-10.1.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a5f63b5a68daedc54c7c3464508d8c12075e56dcfbd42f8c1bf40169061ae666"}, + {file = "Pillow-10.1.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c0949b55eb607898e28eaccb525ab104b2d86542a85c74baf3a6dc24002edec2"}, + {file = "Pillow-10.1.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:ae88931f93214777c7a3aa0a8f92a683f83ecde27f65a45f95f22d289a69e593"}, + {file = "Pillow-10.1.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:b0eb01ca85b2361b09480784a7931fc648ed8b7836f01fb9241141b968feb1db"}, + {file = "Pillow-10.1.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:d27b5997bdd2eb9fb199982bb7eb6164db0426904020dc38c10203187ae2ff2f"}, + {file = "Pillow-10.1.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:7df5608bc38bd37ef585ae9c38c9cd46d7c81498f086915b0f97255ea60c2818"}, + {file = "Pillow-10.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:41f67248d92a5e0a2076d3517d8d4b1e41a97e2df10eb8f93106c89107f38b57"}, + {file = "Pillow-10.1.0-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:1fb29c07478e6c06a46b867e43b0bcdb241b44cc52be9bc25ce5944eed4648e7"}, + {file = "Pillow-10.1.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:2cdc65a46e74514ce742c2013cd4a2d12e8553e3a2563c64879f7c7e4d28bce7"}, + {file = "Pillow-10.1.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:50d08cd0a2ecd2a8657bd3d82c71efd5a58edb04d9308185d66c3a5a5bed9610"}, + {file = "Pillow-10.1.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:062a1610e3bc258bff2328ec43f34244fcec972ee0717200cb1425214fe5b839"}, + {file = "Pillow-10.1.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:61f1a9d247317fa08a308daaa8ee7b3f760ab1809ca2da14ecc88ae4257d6172"}, + {file = "Pillow-10.1.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:a646e48de237d860c36e0db37ecaecaa3619e6f3e9d5319e527ccbc8151df061"}, + {file = "Pillow-10.1.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:47e5bf85b80abc03be7455c95b6d6e4896a62f6541c1f2ce77a7d2bb832af262"}, + {file = "Pillow-10.1.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:a92386125e9ee90381c3369f57a2a50fa9e6aa8b1cf1d9c4b200d41a7dd8e992"}, + {file = "Pillow-10.1.0-cp311-cp311-win_amd64.whl", hash = "sha256:0f7c276c05a9767e877a0b4c5050c8bee6a6d960d7f0c11ebda6b99746068c2a"}, + {file = "Pillow-10.1.0-cp312-cp312-macosx_10_10_x86_64.whl", hash = "sha256:a89b8312d51715b510a4fe9fc13686283f376cfd5abca8cd1c65e4c76e21081b"}, + {file = "Pillow-10.1.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:00f438bb841382b15d7deb9a05cc946ee0f2c352653c7aa659e75e592f6fa17d"}, + {file = "Pillow-10.1.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3d929a19f5469b3f4df33a3df2983db070ebb2088a1e145e18facbc28cae5b27"}, + {file = "Pillow-10.1.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9a92109192b360634a4489c0c756364c0c3a2992906752165ecb50544c251312"}, + {file = "Pillow-10.1.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:0248f86b3ea061e67817c47ecbe82c23f9dd5d5226200eb9090b3873d3ca32de"}, + {file = "Pillow-10.1.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:9882a7451c680c12f232a422730f986a1fcd808da0fd428f08b671237237d651"}, + {file = "Pillow-10.1.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:1c3ac5423c8c1da5928aa12c6e258921956757d976405e9467c5f39d1d577a4b"}, + {file = "Pillow-10.1.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:806abdd8249ba3953c33742506fe414880bad78ac25cc9a9b1c6ae97bedd573f"}, + {file = "Pillow-10.1.0-cp312-cp312-win_amd64.whl", hash = "sha256:eaed6977fa73408b7b8a24e8b14e59e1668cfc0f4c40193ea7ced8e210adf996"}, + {file = "Pillow-10.1.0-cp38-cp38-macosx_10_10_x86_64.whl", hash = "sha256:fe1e26e1ffc38be097f0ba1d0d07fcade2bcfd1d023cda5b29935ae8052bd793"}, + {file = "Pillow-10.1.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:7a7e3daa202beb61821c06d2517428e8e7c1aab08943e92ec9e5755c2fc9ba5e"}, + {file = "Pillow-10.1.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:24fadc71218ad2b8ffe437b54876c9382b4a29e030a05a9879f615091f42ffc2"}, + {file = "Pillow-10.1.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fa1d323703cfdac2036af05191b969b910d8f115cf53093125e4058f62012c9a"}, + {file = "Pillow-10.1.0-cp38-cp38-manylinux_2_28_aarch64.whl", hash = "sha256:912e3812a1dbbc834da2b32299b124b5ddcb664ed354916fd1ed6f193f0e2d01"}, + {file = "Pillow-10.1.0-cp38-cp38-manylinux_2_28_x86_64.whl", hash = "sha256:7dbaa3c7de82ef37e7708521be41db5565004258ca76945ad74a8e998c30af8d"}, + {file = "Pillow-10.1.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:9d7bc666bd8c5a4225e7ac71f2f9d12466ec555e89092728ea0f5c0c2422ea80"}, + {file = "Pillow-10.1.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:baada14941c83079bf84c037e2d8b7506ce201e92e3d2fa0d1303507a8538212"}, + {file = "Pillow-10.1.0-cp38-cp38-win_amd64.whl", hash = "sha256:2ef6721c97894a7aa77723740a09547197533146fba8355e86d6d9a4a1056b14"}, + {file = "Pillow-10.1.0-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:0a026c188be3b443916179f5d04548092e253beb0c3e2ee0a4e2cdad72f66099"}, + {file = "Pillow-10.1.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:04f6f6149f266a100374ca3cc368b67fb27c4af9f1cc8cb6306d849dcdf12616"}, + {file = "Pillow-10.1.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bb40c011447712d2e19cc261c82655f75f32cb724788df315ed992a4d65696bb"}, + {file = "Pillow-10.1.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1a8413794b4ad9719346cd9306118450b7b00d9a15846451549314a58ac42219"}, + {file = "Pillow-10.1.0-cp39-cp39-manylinux_2_28_aarch64.whl", hash = "sha256:c9aeea7b63edb7884b031a35305629a7593272b54f429a9869a4f63a1bf04c34"}, + {file = "Pillow-10.1.0-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:b4005fee46ed9be0b8fb42be0c20e79411533d1fd58edabebc0dd24626882cfd"}, + {file = "Pillow-10.1.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:4d0152565c6aa6ebbfb1e5d8624140a440f2b99bf7afaafbdbf6430426497f28"}, + {file = "Pillow-10.1.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:d921bc90b1defa55c9917ca6b6b71430e4286fc9e44c55ead78ca1a9f9eba5f2"}, + {file = "Pillow-10.1.0-cp39-cp39-win_amd64.whl", hash = "sha256:cfe96560c6ce2f4c07d6647af2d0f3c54cc33289894ebd88cfbb3bcd5391e256"}, + {file = "Pillow-10.1.0-pp310-pypy310_pp73-macosx_10_10_x86_64.whl", hash = "sha256:937bdc5a7f5343d1c97dc98149a0be7eb9704e937fe3dc7140e229ae4fc572a7"}, + {file = "Pillow-10.1.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b1c25762197144e211efb5f4e8ad656f36c8d214d390585d1d21281f46d556ba"}, + {file = "Pillow-10.1.0-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:afc8eef765d948543a4775f00b7b8c079b3321d6b675dde0d02afa2ee23000b4"}, + {file = "Pillow-10.1.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:883f216eac8712b83a63f41b76ddfb7b2afab1b74abbb413c5df6680f071a6b9"}, + {file = "Pillow-10.1.0-pp39-pypy39_pp73-macosx_10_10_x86_64.whl", hash = "sha256:b920e4d028f6442bea9a75b7491c063f0b9a3972520731ed26c83e254302eb1e"}, + {file = "Pillow-10.1.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1c41d960babf951e01a49c9746f92c5a7e0d939d1652d7ba30f6b3090f27e412"}, + {file = "Pillow-10.1.0-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:1fafabe50a6977ac70dfe829b2d5735fd54e190ab55259ec8aea4aaea412fa0b"}, + {file = "Pillow-10.1.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:3b834f4b16173e5b92ab6566f0473bfb09f939ba14b23b8da1f54fa63e4b623f"}, + {file = "Pillow-10.1.0.tar.gz", hash = "sha256:e6bf8de6c36ed96c86ea3b6e1d5273c53f46ef518a062464cd7ef5dd2cf92e38"}, +] + +[package.extras] +docs = ["furo", "olefile", "sphinx (>=2.4)", "sphinx-copybutton", "sphinx-inline-tabs", "sphinx-removed-in", "sphinxext-opengraph"] +tests = ["check-manifest", "coverage", "defusedxml", "markdown2", "olefile", "packaging", "pyroma", "pytest", "pytest-cov", "pytest-timeout"] + +[[package]] +name = "pluggy" +version = "1.3.0" +description = "plugin and hook calling mechanisms for python" +optional = false +python-versions = ">=3.8" +files = [ + {file = "pluggy-1.3.0-py3-none-any.whl", hash = "sha256:d89c696a773f8bd377d18e5ecda92b7a3793cbe66c87060a6fb58c7b6e1061f7"}, + {file = "pluggy-1.3.0.tar.gz", hash = "sha256:cf61ae8f126ac6f7c451172cf30e3e43d3ca77615509771b3a984a0730651e12"}, +] + +[package.extras] +dev = ["pre-commit", "tox"] +testing = ["pytest", "pytest-benchmark"] + +[[package]] +name = "pytest" +version = "7.4.3" +description = "pytest: simple powerful testing with Python" +optional = false +python-versions = ">=3.7" +files = [ + {file = "pytest-7.4.3-py3-none-any.whl", hash = "sha256:0d009c083ea859a71b76adf7c1d502e4bc170b80a8ef002da5806527b9591fac"}, + {file = "pytest-7.4.3.tar.gz", hash = "sha256:d989d136982de4e3b29dabcc838ad581c64e8ed52c11fbe86ddebd9da0818cd5"}, +] + +[package.dependencies] +colorama = {version = "*", markers = "sys_platform == \"win32\""} +exceptiongroup = {version = ">=1.0.0rc8", markers = "python_version < \"3.11\""} +iniconfig = "*" +packaging = "*" +pluggy = ">=0.12,<2.0" +tomli = {version = ">=1.0.0", markers = "python_version < \"3.11\""} + +[package.extras] +testing = ["argcomplete", "attrs (>=19.2.0)", "hypothesis (>=3.56)", "mock", "nose", "pygments (>=2.7.2)", "requests", "setuptools", "xmlschema"] + +[[package]] +name = "pytest-django" +version = "4.5.2" +description = "A Django plugin for pytest." +optional = false +python-versions = ">=3.5" +files = [ + {file = "pytest-django-4.5.2.tar.gz", hash = "sha256:d9076f759bb7c36939dbdd5ae6633c18edfc2902d1a69fdbefd2426b970ce6c2"}, + {file = "pytest_django-4.5.2-py3-none-any.whl", hash = "sha256:c60834861933773109334fe5a53e83d1ef4828f2203a1d6a0fa9972f4f75ab3e"}, +] + +[package.dependencies] +pytest = ">=5.4.0" + +[package.extras] +docs = ["sphinx", "sphinx-rtd-theme"] +testing = ["Django", "django-configurations (>=2.0)"] + +[[package]] +name = "sqlparse" +version = "0.4.4" +description = "A non-validating SQL parser." +optional = false +python-versions = ">=3.5" +files = [ + {file = "sqlparse-0.4.4-py3-none-any.whl", hash = "sha256:5430a4fe2ac7d0f93e66f1efc6e1338a41884b7ddf2a350cedd20ccc4d9d28f3"}, + {file = "sqlparse-0.4.4.tar.gz", hash = "sha256:d446183e84b8349fa3061f0fe7f06ca94ba65b426946ffebe6e3e8295332420c"}, +] + +[package.extras] +dev = ["build", "flake8"] +doc = ["sphinx"] +test = ["pytest", "pytest-cov"] + +[[package]] +name = "tomli" +version = "2.0.1" +description = "A lil' TOML parser" +optional = false +python-versions = ">=3.7" +files = [ + {file = "tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc"}, + {file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"}, +] + +[[package]] +name = "typing-extensions" +version = "4.8.0" +description = "Backported and Experimental Type Hints for Python 3.8+" +optional = false +python-versions = ">=3.8" +files = [ + {file = "typing_extensions-4.8.0-py3-none-any.whl", hash = "sha256:8f92fc8806f9a6b641eaa5318da32b44d401efaac0f6678c9bc448ba3605faa0"}, + {file = "typing_extensions-4.8.0.tar.gz", hash = "sha256:df8e4339e9cb77357558cbdbceca33c303714cf861d1eef15e1070055ae8b7ef"}, +] + +[[package]] +name = "tzdata" +version = "2023.3" +description = "Provider of IANA time zone data" +optional = false +python-versions = ">=2" +files = [ + {file = "tzdata-2023.3-py2.py3-none-any.whl", hash = "sha256:7e65763eef3120314099b6939b5546db7adce1e7d6f2e179e3df563c70511eda"}, + {file = "tzdata-2023.3.tar.gz", hash = "sha256:11ef1e08e54acb0d4f95bdb1be05da659673de4acbd21bf9c69e94cc5e907a3a"}, +] + +[metadata] +lock-version = "2.0" +python-versions = ">=3.10, <4" +content-hash = "4dc87739563425ed74164e4d1e2bf7dd78d48a5888fb81cab5307962c1a6df05" diff --git a/production-exclude.lst b/production-exclude.lst deleted file mode 100644 index 038f105..0000000 --- a/production-exclude.lst +++ /dev/null @@ -1,10 +0,0 @@ -*.pyc -.env -*.sass-cache* -*.diff -*.sql -*.sublime* -.codeintel -*.DS_Store -*.zip -*.lst diff --git a/pygraz_website/apps/accounts/contents.py b/pygraz_website/apps/accounts/contents.py deleted file mode 100644 index f295da9..0000000 --- a/pygraz_website/apps/accounts/contents.py +++ /dev/null @@ -1,64 +0,0 @@ -class Registry: - """ - The content registry represents an index of all the model classes that - are relevant for user content. - """ - - _idx = [] - - def register(self, proxy): - """ - Adds a content proxy to the index. - """ - self._idx.append(proxy) - - def get_all(self, request, user=None): - """ - Returns a generator of tuples containing the label, model class and - queryset provided by each proxy already tailored to the given user. - """ - for proxy_cls in self._idx: - yield proxy_cls(request, user) - - -class BaseProxy: - """ - Every content provider has to register a so-called contentproxy which - should extend this base class. - """ - - _has_content = None - label = "Meine Daten" - model_class = None - - def __init__(self, request, user): - self.request = request - self.user = user - if not hasattr(self, "items_template") or self.item_template is None: - self.items_template = f"accounts/contents/{self.model_class.__name__.lower()}_items.html" - - def get_queryset(self): - return [] - - @property - def has_content(self): - if self._has_content is None: - self._has_content = bool(len(self.items)) - return self._has_content - - @property - def items(self): - if not hasattr(self, "_items") or self._items is None: - self._items = self.get_queryset() - return self._items - - -REGISTRY = Registry() - - -def register(proxy): - REGISTRY.register(proxy) - - -def get_all(request, user=None): - return REGISTRY.get_all(request, user) diff --git a/pygraz_website/apps/accounts/forms.py b/pygraz_website/apps/accounts/forms.py deleted file mode 100644 index 7deb4aa..0000000 --- a/pygraz_website/apps/accounts/forms.py +++ /dev/null @@ -1,86 +0,0 @@ -from crispy_forms.helper import FormHelper -from crispy_forms.layout import ButtonHolder, Field, Layout, Submit -from django.contrib.auth import forms as auth_forms -from django.utils.translation import gettext_lazy as _ -from userena import forms as userena_forms - - -class AuthenticationForm(userena_forms.AuthenticationForm): - def __init__(self, *args, **kwargs): - super().__init__(*args, **kwargs) - self.helper = FormHelper() - self.helper.layout = Layout( - Field("identification", autofocus="autofocus"), - Field("password"), - Field("remember_me"), - ButtonHolder(Submit("login", _("Log in"))), - ) - - -class ChangeEmailForm(userena_forms.ChangeEmailForm): - def __init__(self, *args, **kwargs): - super().__init__(*args, **kwargs) - self.helper = FormHelper() - self.helper.layout = Layout( - Field("email", autofocus="autofocus"), - ButtonHolder(Submit("save", _("Save changes"))), - ) - - -class PasswordChangeForm(auth_forms.PasswordChangeForm): - def __init__(self, *args, **kwargs): - super().__init__(*args, **kwargs) - self.helper = FormHelper() - self.helper.layout = Layout( - Field("old_password", autofocus="autofocus"), - Field("new_password1"), - Field("new_password2"), - ButtonHolder(Submit("save", _("Save changes"))), - ) - - -class PasswordResetForm(auth_forms.PasswordResetForm): - def __init__(self, *args, **kwargs): - super().__init__(*args, **kwargs) - self.helper = FormHelper() - self.helper.layout = Layout( - Field("email", autofocus="autofocus"), - ButtonHolder(Submit("save", _("Reset password"))), - ) - - -class SetPasswordForm(auth_forms.SetPasswordForm): - def __init__(self, *args, **kwargs): - super().__init__(*args, **kwargs) - self.helper = FormHelper() - self.helper.layout = Layout( - Field("new_password1", autofocus="autofocus"), - Field("new_password2"), - ButtonHolder(Submit("save", _("Reset password"))), - ) - - -class EditProfileForm(userena_forms.EditProfileForm): - def __init__(self, *args, **kwargs): - super().__init__(*args, **kwargs) - self.helper = FormHelper() - self.helper.layout = Layout( - Field("first_name", autofocus="autofocus"), - Field("last_name"), - Field("mugshot"), - Field("privacy"), - ButtonHolder(Submit("save", _("Save changes"))), - ) - - -class SignupForm(userena_forms.SignupForm): - def __init__(self, *args, **kwargs): - super().__init__(*args, **kwargs) - self.helper = FormHelper() - self.helper.layout = Layout( - Field("username"), - Field("email"), - Field("password1"), - Field("password2"), - ButtonHolder(Submit("register", _("Registrieren"))), - ) diff --git a/pygraz_website/apps/accounts/migrations/0001_initial.py b/pygraz_website/apps/accounts/migrations/0001_initial.py deleted file mode 100644 index 59f8394..0000000 --- a/pygraz_website/apps/accounts/migrations/0001_initial.py +++ /dev/null @@ -1,52 +0,0 @@ -import easy_thumbnails.fields -import userena.models -from django.conf import settings -from django.db import migrations, models - - -class Migration(migrations.Migration): - dependencies = [ - migrations.swappable_dependency(settings.AUTH_USER_MODEL), - ] - - operations = [ - migrations.CreateModel( - name="Profile", - fields=[ - ("id", models.AutoField(verbose_name="ID", serialize=False, auto_created=True, primary_key=True)), - ( - "mugshot", - easy_thumbnails.fields.ThumbnailerImageField( - help_text="A personal image displayed in your profile.", - upload_to=userena.models.upload_to_mugshot, - verbose_name="mugshot", - blank=True, - ), - ), - ( - "privacy", - models.CharField( - default=b"registered", - help_text="Designates who can view your profile.", - max_length=15, - verbose_name="privacy", - choices=[(b"open", "Open"), (b"registered", "Registered"), (b"closed", "Closed")], - ), - ), - ( - "user", - models.OneToOneField( - related_name="profile", - verbose_name="user", - to=settings.AUTH_USER_MODEL, - on_delete=models.deletion.PROTECT, - ), - ), - ], - options={ - "abstract": False, - "permissions": (("view_profile", "Can view profile"),), - }, - bases=(models.Model,), - ), - ] diff --git a/pygraz_website/apps/accounts/migrations/0002_alter_profile_options_alter_profile_privacy_and_more.py b/pygraz_website/apps/accounts/migrations/0002_alter_profile_options_alter_profile_privacy_and_more.py deleted file mode 100644 index 904e033..0000000 --- a/pygraz_website/apps/accounts/migrations/0002_alter_profile_options_alter_profile_privacy_and_more.py +++ /dev/null @@ -1,43 +0,0 @@ -# Generated by Django 4.0.8 on 2022-11-05 15:12 - -import django.db.models.deletion -from django.conf import settings -from django.db import migrations, models - - -class Migration(migrations.Migration): - dependencies = [ - migrations.swappable_dependency(settings.AUTH_USER_MODEL), - ("accounts", "0001_initial"), - ] - - operations = [ - migrations.AlterModelOptions( - name="profile", - options={ - "default_permissions": ("add", "change", "delete"), - "permissions": (("view_profile", "Can view profile"),), - }, - ), - migrations.AlterField( - model_name="profile", - name="privacy", - field=models.CharField( - choices=[("open", "Open"), ("registered", "Registered"), ("closed", "Closed")], - default="registered", - help_text="Designates who can view your profile.", - max_length=15, - verbose_name="privacy", - ), - ), - migrations.AlterField( - model_name="profile", - name="user", - field=models.OneToOneField( - on_delete=django.db.models.deletion.CASCADE, - related_name="profile", - to=settings.AUTH_USER_MODEL, - verbose_name="user", - ), - ), - ] diff --git a/pygraz_website/apps/accounts/models.py b/pygraz_website/apps/accounts/models.py deleted file mode 100644 index 09cc316..0000000 --- a/pygraz_website/apps/accounts/models.py +++ /dev/null @@ -1,17 +0,0 @@ -from django.contrib.auth import models as auth_models -from django.db import models -from django.utils.translation import gettext_lazy as _ -from userena.models import UserenaBaseProfile - - -class Profile(UserenaBaseProfile): - user = models.OneToOneField( - auth_models.User, - unique=True, - verbose_name=_("user"), - on_delete=models.CASCADE, - related_name="profile", - ) - - def __str__(self): - return self.user.username diff --git a/pygraz_website/apps/accounts/south_migrations/0001_initial.py b/pygraz_website/apps/accounts/south_migrations/0001_initial.py deleted file mode 100644 index d1bfaab..0000000 --- a/pygraz_website/apps/accounts/south_migrations/0001_initial.py +++ /dev/null @@ -1,106 +0,0 @@ -import datetime - -from django.db import models -from south.db import db -from south.v2 import SchemaMigration - - -class Migration(SchemaMigration): - def forwards(self, orm): - # Adding model 'Profile' - db.create_table( - "accounts_profile", - ( - ("id", self.gf("django.db.models.fields.AutoField")(primary_key=True)), - ("mugshot", self.gf("django.db.models.fields.files.ImageField")(max_length=100, blank=True)), - ("privacy", self.gf("django.db.models.fields.CharField")(default="registered", max_length=15)), - ( - "user", - self.gf("django.db.models.fields.related.OneToOneField")( - related_name="profile", unique=True, to=orm["auth.User"] - ), - ), - ), - ) - db.send_create_signal("accounts", ["Profile"]) - - def backwards(self, orm): - # Deleting model 'Profile' - db.delete_table("accounts_profile") - - models = { - "accounts.profile": { - "Meta": {"object_name": "Profile"}, - "id": ("django.db.models.fields.AutoField", [], {"primary_key": "True"}), - "mugshot": ("django.db.models.fields.files.ImageField", [], {"max_length": "100", "blank": "True"}), - "privacy": ("django.db.models.fields.CharField", [], {"default": "'registered'", "max_length": "15"}), - "user": ( - "django.db.models.fields.related.OneToOneField", - [], - {"related_name": "'profile'", "unique": "True", "to": "orm['auth.User']"}, - ), - }, - "auth.group": { - "Meta": {"object_name": "Group"}, - "id": ("django.db.models.fields.AutoField", [], {"primary_key": "True"}), - "name": ("django.db.models.fields.CharField", [], {"unique": "True", "max_length": "80"}), - "permissions": ( - "django.db.models.fields.related.ManyToManyField", - [], - {"to": "orm['auth.Permission']", "symmetrical": "False", "blank": "True"}, - ), - }, - "auth.permission": { - "Meta": { - "ordering": "('content_type__app_label', 'content_type__model', 'codename')", - "unique_together": "(('content_type', 'codename'),)", - "object_name": "Permission", - }, - "codename": ("django.db.models.fields.CharField", [], {"max_length": "100"}), - "content_type": ( - "django.db.models.fields.related.ForeignKey", - [], - {"to": "orm['contenttypes.ContentType']"}, - ), - "id": ("django.db.models.fields.AutoField", [], {"primary_key": "True"}), - "name": ("django.db.models.fields.CharField", [], {"max_length": "50"}), - }, - "auth.user": { - "Meta": {"object_name": "User"}, - "date_joined": ("django.db.models.fields.DateTimeField", [], {"default": "datetime.datetime.now"}), - "email": ("django.db.models.fields.EmailField", [], {"max_length": "75", "blank": "True"}), - "first_name": ("django.db.models.fields.CharField", [], {"max_length": "30", "blank": "True"}), - "groups": ( - "django.db.models.fields.related.ManyToManyField", - [], - {"to": "orm['auth.Group']", "symmetrical": "False", "blank": "True"}, - ), - "id": ("django.db.models.fields.AutoField", [], {"primary_key": "True"}), - "is_active": ("django.db.models.fields.BooleanField", [], {"default": "True"}), - "is_staff": ("django.db.models.fields.BooleanField", [], {"default": "False"}), - "is_superuser": ("django.db.models.fields.BooleanField", [], {"default": "False"}), - "last_login": ("django.db.models.fields.DateTimeField", [], {"default": "datetime.datetime.now"}), - "last_name": ("django.db.models.fields.CharField", [], {"max_length": "30", "blank": "True"}), - "password": ("django.db.models.fields.CharField", [], {"max_length": "128"}), - "user_permissions": ( - "django.db.models.fields.related.ManyToManyField", - [], - {"to": "orm['auth.Permission']", "symmetrical": "False", "blank": "True"}, - ), - "username": ("django.db.models.fields.CharField", [], {"unique": "True", "max_length": "30"}), - }, - "contenttypes.contenttype": { - "Meta": { - "ordering": "('name',)", - "unique_together": "(('app_label', 'model'),)", - "object_name": "ContentType", - "db_table": "'django_content_type'", - }, - "app_label": ("django.db.models.fields.CharField", [], {"max_length": "100"}), - "id": ("django.db.models.fields.AutoField", [], {"primary_key": "True"}), - "model": ("django.db.models.fields.CharField", [], {"max_length": "100"}), - "name": ("django.db.models.fields.CharField", [], {"max_length": "100"}), - }, - } - - complete_apps = ["accounts"] diff --git a/pygraz_website/apps/accounts/south_migrations/__init__.py b/pygraz_website/apps/accounts/south_migrations/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/pygraz_website/apps/accounts/templates/accounts/contents/company_items.html b/pygraz_website/apps/accounts/templates/accounts/contents/company_items.html deleted file mode 100644 index cb3d630..0000000 --- a/pygraz_website/apps/accounts/templates/accounts/contents/company_items.html +++ /dev/null @@ -1,5 +0,0 @@ - diff --git a/pygraz_website/apps/accounts/templates/accounts/contents/session_items.html b/pygraz_website/apps/accounts/templates/accounts/contents/session_items.html deleted file mode 100644 index 59d989e..0000000 --- a/pygraz_website/apps/accounts/templates/accounts/contents/session_items.html +++ /dev/null @@ -1,5 +0,0 @@ - diff --git a/pygraz_website/apps/accounts/templates/accounts/my_contents.html b/pygraz_website/apps/accounts/templates/accounts/my_contents.html deleted file mode 100644 index a72b3e8..0000000 --- a/pygraz_website/apps/accounts/templates/accounts/my_contents.html +++ /dev/null @@ -1,11 +0,0 @@ -{% extends "base.html" %} -{% block title %}Meine Inhalte « {% endblock %} -{% block body %} -

Meine Inhalte

- {% for type in contents %} -
-

{{ type.label }}

- {% include type.items_template %} -
- {% endfor %} -{% endblock body %} diff --git a/pygraz_website/apps/accounts/urls.py b/pygraz_website/apps/accounts/urls.py deleted file mode 100644 index a9056f9..0000000 --- a/pygraz_website/apps/accounts/urls.py +++ /dev/null @@ -1,80 +0,0 @@ -from django.contrib.auth import views as auth_views -from django.contrib.auth.decorators import login_required -from django.urls import path - -# from userena import settngs as userena_settings -from userena import views as userena_views - -from . import forms, views - - -def merge_dicts(a, b): - result = {} - result.update(a) - result.update(b) - return result - - -urlpatterns = [ - path( - "signin/", - userena_views.signin, - {"auth_form": forms.AuthenticationForm}, - name="userena_signin", - ), - path( - "signup/", - userena_views.signup, - {"signup_form": forms.SignupForm}, - name="userena_signup", - ), - path( - "/email/", - userena_views.email_change, - {"email_form": forms.ChangeEmailForm}, - name="userena_email_change", - ), - path( - "/password/", - userena_views.password_change, - {"pass_form": forms.PasswordChangeForm}, - name="userena_password_change", - ), - path( - "password/reset/", - auth_views.PasswordResetView.as_view(), - merge_dicts( - { - "template_name": "userena/password_reset_form.html", - "email_template_name": "userena/emails/password_reset_message.txt", - "password_reset_form": forms.PasswordResetForm, - "extra_context": {"without_usernames": False}, - }, - {"post_reset_redirect": "userena_password_reset_done"}, - ), - name="userena_password_reset", - ), - path( - "password/reset/confirm/uidb64-/", - auth_views.PasswordResetConfirmView.as_view(), - merge_dicts( - { - "template_name": "userena/password_reset_confirm_form.html", - "set_password_form": forms.SetPasswordForm, - }, - {"post_reset_redirect": "userena_password_reset_complete"}, - ), - name="userena_password_reset_confirm", - ), - path( - "/edit/", - userena_views.profile_edit, - {"edit_profile_form": forms.EditProfileForm}, - name="userena_profile_edit", - ), - path( - "Firma: {{ company.name }} {% if not company.approved %}(nicht freigeschalten){% endif %} -
-
-
-
Website:
-
{{ company.website|truncatechars:50 }}
-
-
-
Adresse:
-
{{ company.address_line}}, {{ company.postal_code }} {{ company.city }}, {{ company.country }}
-
-
- {% if company.description %} -
{{ company.description|markdown }}
- {% endif %} - {% if is_editor %} - {# FIXME#40: Enable text and link to company update form. #} - {% comment %} - - {% endcomment %} - {% endif %} -{% endblock body %} -{% block tail %} - -{% endblock %} diff --git a/pygraz_website/apps/companies/templates/companies/company_form.html b/pygraz_website/apps/companies/templates/companies/company_form.html deleted file mode 100644 index 3278b41..0000000 --- a/pygraz_website/apps/companies/templates/companies/company_form.html +++ /dev/null @@ -1,21 +0,0 @@ -{% extends "companies/base.html" %} -{% block page_class %}company-submission{% endblock %} -{% block title %}{% if object %}{{ object.name }} editieren{% else %}Neue Firma eintragen{% endif %} « {% endblock %} -{% load crispy_forms_tags %} -{% block body %} -

- {% if object %} - {{ object.name }} editieren - {% else %} - Neue Firma eintragen - {% endif %} -

-
-

Auf dieser Seite können Sie Ihre Firma zum Verzeichnis von Python-Firmen in Graz hinzufügen. Bitte füllen Sie dieses - Formular nur aus, wenn Sie auch wirklich für diese Firma arbeiten.

-

Bevor Ihr Eintrag auch tatsächlich auf der Seite erscheint, muss er zunächst noch von einme Administrator freigeschalten werden. - Wir bitten um Verständnis für diese Vorsichtsmassnahme.

-

Ihr Eintrag kann jederzeit ohne Nennung von Gründen wieder von der Seite entfernt werden.

-
- {% crispy form %} -{% endblock body %} diff --git a/pygraz_website/apps/companies/templates/companies/company_list.html b/pygraz_website/apps/companies/templates/companies/company_list.html deleted file mode 100644 index 934c336..0000000 --- a/pygraz_website/apps/companies/templates/companies/company_list.html +++ /dev/null @@ -1,43 +0,0 @@ -{% extends "companies/base.html" %} - -{% block body %} -
-

Auf dieser Seite werden Firmen aus und in Graz aufgelistet, die Python verwenden.

- {# FIXME#40: Enable text and link to submission form. #} - {% comment %} -

Falls Sie eine für eine Firma arbeiten, die Python verwendet, hier jedoch noch nicht aufscheint, - würden wir uns sehr freuen, wenn Sie dieses Formular ausfüllen könnten.

- {% endcomment %} -
- {% if company_list %} - - - - - - - - - {% for company in company_list %} - - - - - {% endfor %} - -
NameAdresse
{{ company.name }}{{ company.address_line }}, {{ company.postal_code }} {{company.city }}
- {% else %} -

Keine Firmen gefunden.

- {% endif %} - - {% if unapproved_companies %} -
-

Noch nicht freigeschaltene Einträge

- -
- {% endif %} -{% endblock %} diff --git a/pygraz_website/apps/companies/templates/companies/emails/admin_approval.txt b/pygraz_website/apps/companies/templates/companies/emails/admin_approval.txt deleted file mode 100644 index f190a1f..0000000 --- a/pygraz_website/apps/companies/templates/companies/emails/admin_approval.txt +++ /dev/null @@ -1,5 +0,0 @@ -Eine neue Firma wurde angelegt: {{ company.name }} - -Beschreibung: - -{{ company.description }} diff --git a/pygraz_website/apps/companies/tests.py b/pygraz_website/apps/companies/tests.py deleted file mode 100644 index f5ec4d2..0000000 --- a/pygraz_website/apps/companies/tests.py +++ /dev/null @@ -1,146 +0,0 @@ -from django.contrib.auth.models import User -from django.db import IntegrityError -from django.test import TestCase -from guardian.shortcuts import assign_perm - -from . import models - - -class CompanyTestsMixin: - def setUp(self): - self.approved = models.Company( - name="Approved", - website="http://company.com", - address_line="address", - postal_code="8010", - city="Graz", - country="AT", - approved=True, - ) - self.approved.save() - - self.user = User.objects.create_user(username="username", password="password", email="test@test.com") - - self.not_approved = models.Company( - name="Not-Approved", - website="http://company.com", - address_line="address", - postal_code="8010", - city="Graz", - country="AT", - approved=False, - ) - self.not_approved.save() - self.not_approved.editors.add(self.user) - assign_perm("change_company", self.user, self.not_approved) - - -class ModelTests(TestCase): - def test_unicode(self): - """The unicode representation of a company should contain its name.""" - company = models.Company(name="MyCompany") - self.assertIn("MyCompany", str(company)) - - def test_absolute_url(self): - company = models.Company(name="MyCompany", pk=123) - self.assertEqual("/companies/show/123/", company.get_absolute_url()) - - -class DetailsViewTests(CompanyTestsMixin, TestCase): - def test_approved_company(self): - response = self.client.get("/companies/show/1/") - self.assertEqual(response.status_code, 200) - - def test_not_approved_company(self): - response = self.client.get("/companies/show/2/") - self.assertEqual(response.status_code, 404) - - def test_not_approved_but_editor_visible(self): - self.client.login(username="username", password="password") - response = self.client.get("/companies/show/2/") - self.assertEqual(response.status_code, 200) - - -class ListingTests(CompanyTestsMixin, TestCase): - def test_listing_approved(self): - """ - Only approved companies should be included in the listing view. - """ - response = self.client.get("/companies/") - self.assertEqual(response.status_code, 200) - self.assertEqual(list(response.context["company_list"]), [self.approved]) - - def test_listing_editor_logged_in(self): - """ - If the editor of a not approved company is logged in, this company - is included in the context. - """ - self.client.login(username="username", password="password") - response = self.client.get("/companies/") - self.assertEqual(response.status_code, 200) - self.assertEqual(list(response.context["unapproved_companies"]), [self.not_approved]) - - -class CreationTests(TestCase): - def setUp(self): - # FIXME#40: Find out why the user already exists and clean up this code to simply create the test user. - self.user = User.objects.filter(username="user").first() - if self.user is None: - self.user = User.objects.create_user(username="user", password="password", email="e@mail.com") - - def tearDown(self): - self.user.delete() - self.client.logout() - - # FIXME#40: Remove initial "_" from test name and fix it. - def _test_create_logged_out(self): - """ - If the user is logged out, creating a new company entry should be - prohibited and redirect the user to the login form. - """ - response = self.client.get("/companies/submit/") - self.assertRedirects(response, "/accounts/signin/?next=/companies/submit/") - - # FIXME#40: Remove initial "_" from test name and fix it. - def _test_create_logged_in(self): - self.client.login(username="user", password="password") - response = self.client.get("/companies/submit/") - self.assertEqual(200, response.status_code) - - response = self.client.post( - "/companies/submit/", - { - "name": "My Company", - "website": "http://company.com", - "address_line": "Street 123", - "postal_code": "8010", - "city": "Graz", - "country": "AT", - }, - ) - self.assertRedirects(response, "/companies/show/1/") - - -class UpdateViewTests(CompanyTestsMixin, TestCase): - # FIXME#40: Remove initial "_" from test name and fix it. - def _test_login_required(self): - response = self.client.get("/companies/update/1/") - self.assertRedirects(response, "/accounts/signin/?next=/companies/update/1/") - - # FIXME#40: Remove initial "_" from test name and fix it. - def _test_404_on_not_existing_company(self): - self.client.login(username="username", password="password") - response = self.client.get("/companies/update/3/") - self.assertEqual(response.status_code, 404) - - # FIXME#40: Remove initial "_" from test name and fix it. - def _test_404_if_not_allowed(self): - self.client.login(username="username", password="password") - response = self.client.get("/companies/update/1/") - self.assertEqual(response.status_code, 404) - - # FIXME#40: Remove initial "_" from test name and fix it. - def _test_ok_if_editor(self): - self.client.login(username="username", password="password") - response = self.client.get("/companies/update/2/") - self.assertEqual(response.status_code, 200) diff --git a/pygraz_website/apps/companies/urls.py b/pygraz_website/apps/companies/urls.py deleted file mode 100644 index b7249fc..0000000 --- a/pygraz_website/apps/companies/urls.py +++ /dev/null @@ -1,21 +0,0 @@ -# FIXME#40: from django.contrib.auth.decorators import login_required -from django.urls import path - -from . import views - -urlpatterns = [ - path("", views.ListCompaniesView.as_view(), name="list-companies"), - path("show//", views.CompanyDetailsView.as_view(), name="company-details"), - # FIXME#40: Enable company update form. - # path( - # "update//", - # views.UpdateCompanyView.as_view(), - # name="update-company", - # ), - # FIXME#40: Enable company submission form. - # path( - # "submit/", - # views.SubmitCompanyView.as_view(), - # name="submit-company", - # ), -] diff --git a/pygraz_website/apps/companies/views.py b/pygraz_website/apps/companies/views.py deleted file mode 100644 index ade1827..0000000 --- a/pygraz_website/apps/companies/views.py +++ /dev/null @@ -1,62 +0,0 @@ -from django.http import Http404 -from django.views.generic import CreateView, DetailView, ListView, UpdateView -from guardian.shortcuts import assign_perm - -from . import emails, forms, models - - -class ListCompaniesView(ListView): - model = models.Company - queryset = models.Company.objects.filter(approved=True) - - def get_context_data(self, **kwargs): - data = super().get_context_data(**kwargs) - if hasattr(self.request, "user") and self.request.user.is_authenticated: - data["unapproved_companies"] = self.request.user.companies.filter(approved=False) - return data - - -class CompanyDetailsView(DetailView): - model = models.Company - - def get_context_data(self, **kwargs): - data = super().get_context_data(**kwargs) - # Make sure that the company is approved or editable by the current - # user. - data["approved"] = self.object.approved - data["is_editor"] = self.request.user.has_perm("change_company", self.object) - if not self.object.approved and not data["is_editor"]: - raise Http404("Company not found") - return data - - -class SubmitCompanyView(CreateView): - """ - Before a company appears on the website, it has to be approved by an admin. - Hence this view only creates an unapproved company object. - """ - - model = models.Company - form_class = forms.CompanySubmissionForm - - def form_valid(self, form): - result = super().form_valid(form) - self.object.editors.add(self.request.user) - assign_perm("change_company", self.request.user, self.object) - emails.notify_admins_for_approval(self.object) - return result - - -class UpdateCompanyView(UpdateView): - """ - An update view available to every "editor" or a company. - """ - - model = models.Company - form_class = forms.CompanySubmissionForm - - def get_object(self, **kwargs): - obj = super().get_object(**kwargs) - if not self.request.user.has_perm("change_company", obj): - raise Http404("Company not found") - return obj diff --git a/pygraz_website/apps/core/__init__.py b/pygraz_website/apps/core/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/pygraz_website/apps/core/migrations/__init__.py b/pygraz_website/apps/core/migrations/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/pygraz_website/apps/core/templatetags/__init__.py b/pygraz_website/apps/core/templatetags/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/pygraz_website/apps/core/templatetags/markdown_tags.py b/pygraz_website/apps/core/templatetags/markdown_tags.py deleted file mode 100644 index 85c33c5..0000000 --- a/pygraz_website/apps/core/templatetags/markdown_tags.py +++ /dev/null @@ -1,17 +0,0 @@ -import html - -from django.template import Library -from django.utils.safestring import mark_safe -from markdown import Markdown - -register = Library() - - -@register.filter(name="markdown") -def markdown(value): - """ - Basic markdown filter used throughout the site. - """ - md = Markdown() - markdown_html = md.convert(html.escape(value)) - return mark_safe(markdown_html) diff --git a/pygraz_website/apps/core/tests.py b/pygraz_website/apps/core/tests.py deleted file mode 100644 index de2c1f2..0000000 --- a/pygraz_website/apps/core/tests.py +++ /dev/null @@ -1,14 +0,0 @@ -from django.template import Context, Template -from django.test import TestCase - - -class MarkdownFilterTests(TestCase): - def test_html_escaping(self): - """ - The markdown template filter should remove HTML in its default - configuration. - """ - expected = "

<i>Some HTML</i>

" - tmpl = Template("{% load markdown_tags %}{{ data|markdown }}") - result = tmpl.render(Context({"data": "Some HTML"})) - self.assertEqual(expected, result) diff --git a/pygraz_website/apps/meetups/__init__.py b/pygraz_website/apps/meetups/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/pygraz_website/apps/meetups/admin.py b/pygraz_website/apps/meetups/admin.py deleted file mode 100644 index 085615f..0000000 --- a/pygraz_website/apps/meetups/admin.py +++ /dev/null @@ -1,128 +0,0 @@ -from django.contrib import admin -from django.db.models import Q -from django.utils.translation import gettext_lazy as _ - -from . import models - - -class AssignedMeetupFilter(admin.SimpleListFilter): - """ - Filters sessions that are assigned to a meetup. - """ - - parameter_name = "assigned" - title = "hat Meetup" - - def lookups(self, request, model_admin): - return ( - ("assigned", _("Yes")), - ("unassigned", _("No")), - ) - - def queryset(self, request, queryset): - val = self.value() - if not val: - return queryset - return queryset.filter(meetup__isnull=(val != "assigned")) - - -class SessionWithSlidesFilter(admin.SimpleListFilter): - """ - Filters session that contain a link to slides. - """ - - parameter_name = "has_slides" - title = "hat Folien" - - def lookups(self, request, model_admin): - return ( - ("yes", _("Yes")), - ("no", _("No")), - ) - - def queryset(self, request, queryset): - val = self.value() - if not val: - return queryset - if val == "yes": - return queryset.exclude(Q(slides_url__isnull=True) | Q(slides_url="")) - else: - return queryset.filter(Q(slides_url__isnull=True) | Q(slides_url="")) - - -class SessionBySpeakerType(admin.SimpleListFilter): - """ - Filters sessions by the type of speaker they have set: anonymous or - registered. - """ - - parameter_name = "speakertype" - title = _("speaker type") - - def lookups(self, request, model_admin): - return ( - ("anon", _("Anonymous")), - ("reg", _("Registered")), - ) - - def queryset(self, request, queryset): - val = self.value() - if not val: - return queryset - return queryset.filter(speaker__isnull=(val == "anon")) - - -class MeetupComAvailable(admin.SimpleListFilter): - """ - Filters meetups that have a meetupcom_id assigned. - """ - - parameter_name = "meetupcom_available" - title = _("meetup.com available") - - def lookups(self, request, model_admin): - return (("yes", _("Yes")), ("no", _("No"))) - - def queryset(self, request, queryset): - val = self.value() - if not val: - return queryset - if val == "no": - return queryset.filter(Q(meetupcom_id="") | Q(meetupcom_id__isnull=True)) - else: - return queryset.exclude(Q(meetupcom_id="") | Q(meetupcom_id__isnull=True)) - - -class RSVPAdmin(admin.ModelAdmin): - list_display = ["meetup", "remote_username", "status", "source"] - list_filter = ["meetup"] - - -class SessionTypeAdmin(admin.ModelAdmin): - pass - - -admin.site.register( - models.Meetup, - list_display=["start_date", "location", "attendee_count"], - list_filter=[ - MeetupComAvailable, - ], -) -admin.site.register( - models.Session, - list_display=["title", "meetup", "type", "speaker", "speaker_name"], - list_filter=[ - "type", - AssignedMeetupFilter, - SessionBySpeakerType, - SessionWithSlidesFilter, - ], -) -admin.site.register( - models.Location, - list_display=["name"], -) - -admin.site.register(models.RSVP, RSVPAdmin) -admin.site.register(models.SessionType, SessionTypeAdmin) diff --git a/pygraz_website/apps/meetups/decorators.py b/pygraz_website/apps/meetups/decorators.py deleted file mode 100644 index 7b3b103..0000000 --- a/pygraz_website/apps/meetups/decorators.py +++ /dev/null @@ -1,13 +0,0 @@ -from django.http import HttpResponseForbidden - - -def allow_only_staff_or_author_during_submission(method): - def _func(self, request, *args, **kwargs): - user = request.user - self.kwargs = kwargs - obj = self.get_object() - if user.is_superuser or user.is_staff or obj.speaker is not None and user == obj.speaker: - return method(self, request, *args, **kwargs) - return HttpResponseForbidden() - - return _func diff --git a/pygraz_website/apps/meetups/emails.py b/pygraz_website/apps/meetups/emails.py deleted file mode 100644 index 4374089..0000000 --- a/pygraz_website/apps/meetups/emails.py +++ /dev/null @@ -1,20 +0,0 @@ -from django.contrib.sites.models import Site -from django.core.mail import mail_admins -from django.template.loader import render_to_string - -__ALL__ = ["notify_admins_for_new_session"] - - -def notify_admins_for_new_session(session): - current_site = Site.objects.get_current() - mail_admins( - "Neue Session eingetragen", - render_to_string( - "meetups/emails/new_session.txt", - { - "session": session, - "session_url": f"https://{current_site.domain}{session.get_absolute_url()}", - }, - ), - fail_silently=False, - ) diff --git a/pygraz_website/apps/meetups/forms.py b/pygraz_website/apps/meetups/forms.py deleted file mode 100644 index d125719..0000000 --- a/pygraz_website/apps/meetups/forms.py +++ /dev/null @@ -1,115 +0,0 @@ -from crispy_forms.helper import FormHelper -from crispy_forms.layout import ButtonHolder, Field, Layout, Submit -from django import forms -from django.utils.safestring import mark_safe - -from . import models - -# from captcha.fields import ReCaptchaField - - -class AnonymousSessionSubmissionForm(forms.ModelForm): - speaker_name = forms.CharField(required=True, label="Dein Name") - speaker_email = forms.EmailField(required=True, label="Deine E-Mail-Adresse") - # captcha = ReCaptchaField(attrs={'theme': 'white'}) - - class Meta: - model = models.Session - fields = ("title", "abstract", "speaker_name", "speaker_email", "type") - widgets = {"type": forms.RadioSelect} - help_texts = { - "speaker_email": """Wir benötigen deine E-Mail-Adresse, um etwaige Termin - und Themefragen mit dir abklären zu können.""" - } - - def __init__(self, *args, **kwargs): - super().__init__(*args, **kwargs) - del self.fields["abstract"].widget.attrs["cols"] - self.fields["type"].required = True - self.fields["type"].empty_label = None - _extend_type_choice_labels(self.fields["type"]) - self.helper = FormHelper() - layout = Layout( - Field("title"), - Field("abstract"), - Field("speaker_name"), - Field("speaker_email"), - # Field('captcha'), - Field("type"), - ButtonHolder(Submit("submit", "Abschicken")), - ) - self.helper.add_layout(layout) - - -class RegisteredSessionSubmissionForm(forms.ModelForm): - class Meta: - model = models.Session - fields = ( - "title", - "abstract", - "type", - ) - widgets = {"type": forms.RadioSelect} - - def __init__(self, *args, **kwargs): - super().__init__(*args, **kwargs) - self.fields["type"].required = True - self.fields["type"].empty_label = None - _extend_type_choice_labels(self.fields["type"]) - self.helper = FormHelper() - layout = Layout( - Field("title"), - Field("abstract"), - Field("type"), - ButtonHolder(Submit("submit", "Abschicken")), - ) - self.helper.add_layout(layout) - - -class EditSessionForm(forms.ModelForm): - class Meta: - model = models.Session - fields = ("title", "abstract", "slides_url", "notes", "type") - widgets = {"type": forms.RadioSelect} - help_texts = { - "abstract": """Bitte beschreibe kurz, worum es in deiner Session geht. - Wo sind die Einsatzgebiete, wie komplex ist das Ganze usw.""" - } - - def __init__(self, *args, **kwargs): - super().__init__(*args, **kwargs) - self.fields["type"].required = True - self.fields["type"].empty_label = None - _extend_type_choice_labels(self.fields["type"]) - self.helper = FormHelper() - layout = Layout( - Field("title", autofocus="autofocus"), - Field("abstract"), - Field("type"), - Field("slides_url"), - Field("notes"), - ButtonHolder(Submit("submit", "Änderungen speichern")), - ) - self.helper.add_layout(layout) - - -def _extend_type_choice_labels(field): - types = {type_.pk: type_ for type_ in field.queryset.all()} - new_choices = [] - for choice in field.choices: - if choice[0] != "": - new_choices.append( - ( - choice[0], - mark_safe(f"{choice[1]}: {types[choice[0]].description}"), - ) - ) - else: - new_choices.append(choice) - field.choices = new_choices - - -def get_session_submission_form_class(request): - if request.user.is_authenticated: - return RegisteredSessionSubmissionForm - return AnonymousSessionSubmissionForm diff --git a/pygraz_website/apps/meetups/management/__init__.py b/pygraz_website/apps/meetups/management/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/pygraz_website/apps/meetups/management/commands/__init__.py b/pygraz_website/apps/meetups/management/commands/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/pygraz_website/apps/meetups/management/commands/fetch_rsvps.py b/pygraz_website/apps/meetups/management/commands/fetch_rsvps.py deleted file mode 100644 index 572f9e3..0000000 --- a/pygraz_website/apps/meetups/management/commands/fetch_rsvps.py +++ /dev/null @@ -1,56 +0,0 @@ -import logging - -import requests -from django.conf import settings -from django.core.management.base import BaseCommand -from django.db import transaction - -from ... import models - -LOG = logging.getLogger(__name__) - - -class Command(BaseCommand): - help = "Fetches RSVP responses from services like Google+ for future events" - - def _fetch_from_meetupcom(self, meetup): - rsvps = [] - meetupcom_id = meetup.meetupcom_id - seen = 0 - while True: - resp = requests.get( - "https://api.meetup.com/2/rsvps", - params={ - "key": settings.MEETUPCOM_API_KEY, - "event_id": meetupcom_id, - "sign": True, - "offset": seen, - "format": "json", - }, - ) - result = resp.json() - seen += result["meta"]["count"] - for rsvp in result["results"]: - # meetup.com has no "maybe" status - status = "coming" if rsvp["response"] == "yes" else "not_coming" - rsvps.append( - models.RSVP( - status=status, - remote_username=rsvp["member"]["name"], - remote_uid=rsvp["member"]["member_id"], - source="meetupcom", - meetup=meetup, - ) - ) - if seen >= result["meta"]["total_count"]: - break - - with transaction.atomic(): - models.RSVP.objects.filter(meetup=meetup, source="meetupcom").delete() - for rsvp in rsvps: - rsvp.save() - - def handle(self, *args, **options): - for meetup in models.Meetup.objects.get_future_meetups(): - if meetup.meetupcom_id: - self._fetch_from_meetupcom(meetup) diff --git a/pygraz_website/apps/meetups/migrations/0001_initial.py b/pygraz_website/apps/meetups/migrations/0001_initial.py deleted file mode 100644 index de026fa..0000000 --- a/pygraz_website/apps/meetups/migrations/0001_initial.py +++ /dev/null @@ -1,159 +0,0 @@ -import django.core.validators -import django.db.models.deletion -from django.conf import settings -from django.db import migrations, models - - -class Migration(migrations.Migration): - dependencies = [ - migrations.swappable_dependency(settings.AUTH_USER_MODEL), - ] - - operations = [ - migrations.CreateModel( - name="Location", - fields=[ - ("id", models.AutoField(verbose_name="ID", serialize=False, auto_created=True, primary_key=True)), - ("name", models.CharField(max_length=200)), - ("description", models.TextField(null=True, blank=True)), - ("website", models.URLField(null=True, blank=True)), - ("address", models.CharField(max_length=255, null=True, blank=True)), - ], - options={ - "verbose_name": "location", - "verbose_name_plural": "locations", - }, - bases=(models.Model,), - ), - migrations.CreateModel( - name="Meetup", - fields=[ - ("id", models.AutoField(verbose_name="ID", serialize=False, auto_created=True, primary_key=True)), - ("start_date", models.DateTimeField()), - ("meetupcom_id", models.CharField(max_length=20, null=True, blank=True)), - ("gplus_id", models.CharField(max_length=50, null=True, blank=True)), - ("description", models.TextField(null=True, blank=True)), - ("notes", models.TextField(null=True, blank=True)), - ( - "attendee_count", - models.IntegerField( - blank=True, null=True, validators=[django.core.validators.MinValueValidator(0)] - ), - ), - ( - "location", - models.ForeignKey( - blank=True, to="meetups.Location", null=True, on_delete=django.db.models.deletion.PROTECT - ), - ), - ], - options={ - "ordering": ("-start_date",), - "verbose_name": "Meetup", - "verbose_name_plural": "Meetups", - }, - bases=(models.Model,), - ), - migrations.CreateModel( - name="RSVP", - fields=[ - ("id", models.AutoField(verbose_name="ID", serialize=False, auto_created=True, primary_key=True)), - ( - "status", - models.CharField( - blank=True, - max_length=20, - null=True, - verbose_name="Status", - choices=[(b"not_coming", "Not coming"), (b"coming", "Coming"), (b"maybe", "Maybe")], - ), - ), - ( - "gplus_name", - models.CharField(max_length=100, null=True, verbose_name="Google+ Username", blank=True), - ), - ("gplus_uid", models.CharField(max_length=100, null=True, verbose_name="Google+ User ID", blank=True)), - ("source", models.CharField(max_length=20, null=True, blank=True)), - ( - "meetup", - models.ForeignKey( - related_name="rsvps", - verbose_name="Meetup", - to="meetups.Meetup", - on_delete=django.db.models.deletion.PROTECT, - ), - ), - ], - options={ - "verbose_name": "RSVP", - "verbose_name_plural": "RSVPs", - }, - bases=(models.Model,), - ), - migrations.CreateModel( - name="Session", - fields=[ - ("id", models.AutoField(verbose_name="ID", serialize=False, auto_created=True, primary_key=True)), - ("title", models.CharField(max_length=255, verbose_name=b"Titel")), - ("abstract", models.TextField(verbose_name=b"Kurzbeschreibung")), - ("speaker_name", models.CharField(max_length=100, null=True, verbose_name=b"Vortragender", blank=True)), - ( - "speaker_email", - models.EmailField(max_length=75, null=True, verbose_name=b"E-Mail-Adresse", blank=True), - ), - ("slides_url", models.URLField(null=True, verbose_name=b"Folien-URL", blank=True)), - ("notes", models.TextField(null=True, verbose_name=b"Notizen", blank=True)), - ( - "meetup", - models.ForeignKey( - related_name="sessions", - verbose_name=b"Meetup", - blank=True, - to="meetups.Meetup", - null=True, - on_delete=django.db.models.deletion.PROTECT, - ), - ), - ( - "speaker", - models.ForeignKey( - verbose_name=b"Vortragender", - blank=True, - to=settings.AUTH_USER_MODEL, - null=True, - on_delete=django.db.models.deletion.PROTECT, - ), - ), - ], - options={ - "verbose_name": "Session", - "verbose_name_plural": "Sessions", - }, - bases=(models.Model,), - ), - migrations.CreateModel( - name="SessionType", - fields=[ - ("id", models.AutoField(verbose_name="ID", serialize=False, auto_created=True, primary_key=True)), - ("name", models.CharField(unique=True, max_length=30, verbose_name=b"Name")), - ("description", models.TextField(null=True, verbose_name=b"Beschreibung", blank=True)), - ], - options={ - "verbose_name": "Session type", - "verbose_name_plural": "Session types", - }, - bases=(models.Model,), - ), - migrations.AddField( - model_name="session", - name="type", - field=models.ForeignKey( - on_delete=django.db.models.deletion.SET_NULL, - verbose_name=b"Vortragsart", - blank=True, - to="meetups.SessionType", - null=True, - ), - preserve_default=True, - ), - ] diff --git a/pygraz_website/apps/meetups/migrations/0002_rsvp_refactoring.py b/pygraz_website/apps/meetups/migrations/0002_rsvp_refactoring.py deleted file mode 100644 index f5e99f2..0000000 --- a/pygraz_website/apps/meetups/migrations/0002_rsvp_refactoring.py +++ /dev/null @@ -1,12 +0,0 @@ -from django.db import migrations, models - - -class Migration(migrations.Migration): - dependencies = [ - ("meetups", "0001_initial"), - ] - - operations = [ - migrations.RenameField(model_name="rsvp", old_name="gplus_name", new_name="remote_username"), - migrations.RenameField(model_name="rsvp", old_name="gplus_uid", new_name="remote_uid"), - ] diff --git a/pygraz_website/apps/meetups/migrations/0003_field_lengths.py b/pygraz_website/apps/meetups/migrations/0003_field_lengths.py deleted file mode 100644 index f68cd0c..0000000 --- a/pygraz_website/apps/meetups/migrations/0003_field_lengths.py +++ /dev/null @@ -1,25 +0,0 @@ -from django.db import migrations, models - - -class Migration(migrations.Migration): - dependencies = [ - ("meetups", "0002_rsvp_refactoring"), - ] - - operations = [ - migrations.AlterField( - model_name="rsvp", - name="remote_uid", - field=models.CharField(max_length=100, null=True, verbose_name="User ID", blank=True), - ), - migrations.AlterField( - model_name="rsvp", - name="remote_username", - field=models.CharField(max_length=100, null=True, verbose_name="Username", blank=True), - ), - migrations.AlterField( - model_name="session", - name="speaker_email", - field=models.EmailField(max_length=254, null=True, verbose_name="E-Mail-Adresse", blank=True), - ), - ] diff --git a/pygraz_website/apps/meetups/migrations/0004_alter_meetup_location_alter_rsvp_meetup_and_more.py b/pygraz_website/apps/meetups/migrations/0004_alter_meetup_location_alter_rsvp_meetup_and_more.py deleted file mode 100644 index 00f452d..0000000 --- a/pygraz_website/apps/meetups/migrations/0004_alter_meetup_location_alter_rsvp_meetup_and_more.py +++ /dev/null @@ -1,112 +0,0 @@ -# Generated by Django 4.0.8 on 2022-11-05 15:12 - -import django.db.models.deletion -from django.conf import settings -from django.db import migrations, models - - -class Migration(migrations.Migration): - dependencies = [ - migrations.swappable_dependency(settings.AUTH_USER_MODEL), - ("meetups", "0003_field_lengths"), - ] - - operations = [ - migrations.AlterField( - model_name="meetup", - name="location", - field=models.ForeignKey( - blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to="meetups.location" - ), - ), - migrations.AlterField( - model_name="rsvp", - name="meetup", - field=models.ForeignKey( - on_delete=django.db.models.deletion.CASCADE, - related_name="rsvps", - to="meetups.meetup", - verbose_name="Meetup", - ), - ), - migrations.AlterField( - model_name="rsvp", - name="status", - field=models.CharField( - blank=True, - choices=[("not_coming", "Not coming"), ("coming", "Coming"), ("maybe", "Maybe")], - max_length=20, - null=True, - verbose_name="Status", - ), - ), - migrations.AlterField( - model_name="session", - name="abstract", - field=models.TextField(verbose_name="Kurzbeschreibung"), - ), - migrations.AlterField( - model_name="session", - name="meetup", - field=models.ForeignKey( - blank=True, - null=True, - on_delete=django.db.models.deletion.CASCADE, - related_name="sessions", - to="meetups.meetup", - verbose_name="Meetup", - ), - ), - migrations.AlterField( - model_name="session", - name="notes", - field=models.TextField(blank=True, null=True, verbose_name="Notizen"), - ), - migrations.AlterField( - model_name="session", - name="slides_url", - field=models.URLField(blank=True, null=True, verbose_name="Folien-URL"), - ), - migrations.AlterField( - model_name="session", - name="speaker", - field=models.ForeignKey( - blank=True, - null=True, - on_delete=django.db.models.deletion.CASCADE, - to=settings.AUTH_USER_MODEL, - verbose_name="Vortragender", - ), - ), - migrations.AlterField( - model_name="session", - name="speaker_name", - field=models.CharField(blank=True, max_length=100, null=True, verbose_name="Vortragender"), - ), - migrations.AlterField( - model_name="session", - name="title", - field=models.CharField(max_length=255, verbose_name="Titel"), - ), - migrations.AlterField( - model_name="session", - name="type", - field=models.ForeignKey( - blank=True, - null=True, - on_delete=django.db.models.deletion.SET_NULL, - to="meetups.sessiontype", - verbose_name="Vortragsart", - ), - ), - migrations.AlterField( - model_name="sessiontype", - name="description", - field=models.TextField(blank=True, null=True, verbose_name="Beschreibung"), - ), - migrations.AlterField( - model_name="sessiontype", - name="name", - field=models.CharField(max_length=30, unique=True, verbose_name="Name"), - ), - ] diff --git a/pygraz_website/apps/meetups/migrations/0005_location_map_image.py b/pygraz_website/apps/meetups/migrations/0005_location_map_image.py deleted file mode 100644 index d3ec48a..0000000 --- a/pygraz_website/apps/meetups/migrations/0005_location_map_image.py +++ /dev/null @@ -1,17 +0,0 @@ -# Generated by Django 4.0.8 on 2022-12-06 19:11 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - dependencies = [ - ("meetups", "0004_alter_meetup_location_alter_rsvp_meetup_and_more"), - ] - - operations = [ - migrations.AddField( - model_name="location", - name="map_image", - field=models.ImageField(blank=True, null=True, upload_to=""), - ), - ] diff --git a/pygraz_website/apps/meetups/migrations/__init__.py b/pygraz_website/apps/meetups/migrations/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/pygraz_website/apps/meetups/models.py b/pygraz_website/apps/meetups/models.py deleted file mode 100644 index 31c3e41..0000000 --- a/pygraz_website/apps/meetups/models.py +++ /dev/null @@ -1,218 +0,0 @@ -from django.contrib.auth import models as auth_models -from django.contrib.sites.models import Site -from django.core import validators -from django.db import models -from django.urls import reverse -from django.utils import timezone -from django.utils.translation import gettext_lazy as _ - -from pygraz_website.apps.accounts import contents - -RSVP_STATUS_CHOICES = ( - ("not_coming", _("Not coming")), - ("coming", _("Coming")), - ("maybe", _("Maybe")), -) - - -class MeetupManager(models.Manager): - def get_past_meetups(self, now=None): - """ - Adds a filter for meetups that started in the past. - """ - if now is None: - now = timezone.now() - return self.get_queryset().filter(start_date__lte=now) - - def get_future_meetups(self, now=None): - if now is None: - now = timezone.now() - return self.get_queryset().filter(start_date__gt=now) - - -class SessionManager(models.Manager): - def get_proposals(self): - """ - Adds a filter for sessions that are not assigned to a meetup yet. - """ - return self.get_queryset().filter(meetup__isnull=True) - - -class Location(models.Model): - name = models.CharField(max_length=200) - description = models.TextField(blank=True, null=True) - website = models.URLField(blank=True, null=True) - address = models.CharField(max_length=255, blank=True, null=True) - map_image = models.ImageField(null=True, blank=True) - - def __str__(self): - return self.name - - class Meta: - verbose_name = _("location") - verbose_name_plural = _("locations") - - -class Meetup(models.Model): - start_date = models.DateTimeField() - location = models.ForeignKey(Location, blank=True, null=True, on_delete=models.CASCADE) - meetupcom_id = models.CharField(blank=True, null=True, max_length=20) - gplus_id = models.CharField(blank=True, null=True, max_length=50) - description = models.TextField(blank=True, null=True) - notes = models.TextField(blank=True, null=True) - attendee_count = models.IntegerField( - null=True, - blank=True, - validators=[ - validators.MinValueValidator(0), - ], - ) - - objects = MeetupManager() - - def __str__(self): - return str(self.start_date) - - def get_absolute_url(self): - return reverse( - "view-meetup", - kwargs={ - "year": f"{self.start_date.year:0>4d}", - "month": f"{self.start_date.month:0>2}", - "day": f"{self.start_date.day:0>2d}", - }, - ) - - def get_permalink(self): - return "http://{}{}".format( - Site.objects.get_current().domain, - reverse("meetup-permalink", kwargs={"pk": self.pk}), - ) - - def get_meetupcom_url(self): - return f"http://www.meetup.com/PyGRAZ/events/{self.meetupcom_id}" - - def is_in_future(self, now=None): - if now is None: - now = timezone.now() - return self.start_date > now - - class Meta: - verbose_name = "Meetup" - verbose_name_plural = "Meetups" - ordering = ("-start_date",) - - -class Session(models.Model): - title = models.CharField("Titel", max_length=255) - abstract = models.TextField("Kurzbeschreibung") - meetup = models.ForeignKey( - Meetup, - verbose_name="Meetup", - blank=True, - null=True, - on_delete=models.CASCADE, - related_name="sessions", - ) - speaker_name = models.CharField("Vortragender", max_length=100, blank=True, null=True) - speaker_email = models.EmailField("E-Mail-Adresse", blank=True, null=True) - speaker = models.ForeignKey( - auth_models.User, - verbose_name="Vortragender", - blank=True, - null=True, - on_delete=models.CASCADE, - ) - slides_url = models.URLField("Folien-URL", blank=True, null=True) - notes = models.TextField("Notizen", blank=True, null=True) - type = models.ForeignKey( - "SessionType", - verbose_name="Vortragsart", - blank=True, - null=True, - on_delete=models.SET_NULL, - ) - - objects = SessionManager() - - def __str__(self): - return self.title - - def get_absolute_url(self): - return reverse("view-session", kwargs={"pk": self.pk}) - - def get_permalink(self): - return f"http://{Site.objects.get_current()}{self.get_absolute_url()}" - - def get_speaker_name(self): - if self.speaker: - firstname = self.speaker.first_name - lastname = self.speaker.last_name - if firstname is not None and lastname is not None: - return f"{firstname} {lastname}" - if firstname is not None: - return firstname - return self.speaker.username - return self.speaker_name - - class Meta: - verbose_name = "Session" - verbose_name_plural = "Sessions" - - -class SessionType(models.Model): - name = models.CharField("Name", max_length=30, unique=True) - description = models.TextField("Beschreibung", blank=True, null=True) - - def __str__(self): - return self.name - - class Meta: - verbose_name = "Session type" - verbose_name_plural = "Session types" - - -class SessionContentProxy(contents.BaseProxy): - model_class = Session - label = "Meine Sessions" - - def get_queryset(self): - return Session.objects.filter(speaker=self.request.user) - - -contents.register(SessionContentProxy) - - -class RSVP(models.Model): - """ - A RSVP object represents the status of attendence of a person at a meetup. - The source of this information in the current implementation is Meetup.com - and not linked to a local user account. - - The status can be either coming, not coming, maybe or unknown (represented - by a null value). - """ - - status = models.CharField(_("Status"), choices=RSVP_STATUS_CHOICES, null=True, blank=True, max_length=20) - remote_username = models.CharField(_("Username"), null=True, blank=True, max_length=100) - remote_uid = models.CharField(_("User ID"), null=True, blank=True, max_length=100) - meetup = models.ForeignKey( - "Meetup", - null=False, - verbose_name=_("Meetup"), - on_delete=models.CASCADE, - related_name="rsvps", - ) - source = models.CharField(max_length=20, blank=True, null=True) - - @property - def name(self): - return self.remote_username - - @property - def url(self): - return f"http://www.meetup.com/members/{self.remote_uid}/" - - class Meta: - verbose_name = _("RSVP") - verbose_name_plural = _("RSVPs") diff --git a/pygraz_website/apps/meetups/south_migrations/0001_initial.py b/pygraz_website/apps/meetups/south_migrations/0001_initial.py deleted file mode 100644 index 718cfed..0000000 --- a/pygraz_website/apps/meetups/south_migrations/0001_initial.py +++ /dev/null @@ -1,178 +0,0 @@ -import datetime - -from django.db import models -from south.db import db -from south.v2 import SchemaMigration - - -class Migration(SchemaMigration): - def forwards(self, orm): - # Adding model 'Location' - db.create_table( - "meetups_location", - ( - ("id", self.gf("django.db.models.fields.AutoField")(primary_key=True)), - ("name", self.gf("django.db.models.fields.CharField")(max_length=200)), - ("description", self.gf("django.db.models.fields.TextField")(null=True, blank=True)), - ("website", self.gf("django.db.models.fields.URLField")(max_length=200, null=True, blank=True)), - ("address", self.gf("django.db.models.fields.CharField")(max_length=255, null=True, blank=True)), - ), - ) - db.send_create_signal("meetups", ["Location"]) - - # Adding model 'Meetup' - db.create_table( - "meetups_meetup", - ( - ("id", self.gf("django.db.models.fields.AutoField")(primary_key=True)), - ("start_date", self.gf("django.db.models.fields.DateTimeField")()), - ( - "location", - self.gf("django.db.models.fields.related.ForeignKey")( - to=orm["meetups.Location"], null=True, blank=True - ), - ), - ), - ) - db.send_create_signal("meetups", ["Meetup"]) - - # Adding model 'Session' - db.create_table( - "meetups_session", - ( - ("id", self.gf("django.db.models.fields.AutoField")(primary_key=True)), - ("title", self.gf("django.db.models.fields.CharField")(max_length=255)), - ("abstract", self.gf("django.db.models.fields.TextField")()), - ( - "meetup", - self.gf("django.db.models.fields.related.ForeignKey")( - to=orm["meetups.Meetup"], null=True, blank=True - ), - ), - ("speaker_name", self.gf("django.db.models.fields.CharField")(max_length=100, null=True, blank=True)), - ( - "speaker", - self.gf("django.db.models.fields.related.ForeignKey")(to=orm["auth.User"], null=True, blank=True), - ), - ), - ) - db.send_create_signal("meetups", ["Session"]) - - def backwards(self, orm): - # Deleting model 'Location' - db.delete_table("meetups_location") - - # Deleting model 'Meetup' - db.delete_table("meetups_meetup") - - # Deleting model 'Session' - db.delete_table("meetups_session") - - models = { - "auth.group": { - "Meta": {"object_name": "Group"}, - "id": ("django.db.models.fields.AutoField", [], {"primary_key": "True"}), - "name": ("django.db.models.fields.CharField", [], {"unique": "True", "max_length": "80"}), - "permissions": ( - "django.db.models.fields.related.ManyToManyField", - [], - {"to": "orm['auth.Permission']", "symmetrical": "False", "blank": "True"}, - ), - }, - "auth.permission": { - "Meta": { - "ordering": "('content_type__app_label', 'content_type__model', 'codename')", - "unique_together": "(('content_type', 'codename'),)", - "object_name": "Permission", - }, - "codename": ("django.db.models.fields.CharField", [], {"max_length": "100"}), - "content_type": ( - "django.db.models.fields.related.ForeignKey", - [], - {"to": "orm['contenttypes.ContentType']"}, - ), - "id": ("django.db.models.fields.AutoField", [], {"primary_key": "True"}), - "name": ("django.db.models.fields.CharField", [], {"max_length": "50"}), - }, - "auth.user": { - "Meta": {"object_name": "User"}, - "date_joined": ("django.db.models.fields.DateTimeField", [], {"default": "datetime.datetime.now"}), - "email": ("django.db.models.fields.EmailField", [], {"max_length": "75", "blank": "True"}), - "first_name": ("django.db.models.fields.CharField", [], {"max_length": "30", "blank": "True"}), - "groups": ( - "django.db.models.fields.related.ManyToManyField", - [], - {"to": "orm['auth.Group']", "symmetrical": "False", "blank": "True"}, - ), - "id": ("django.db.models.fields.AutoField", [], {"primary_key": "True"}), - "is_active": ("django.db.models.fields.BooleanField", [], {"default": "True"}), - "is_staff": ("django.db.models.fields.BooleanField", [], {"default": "False"}), - "is_superuser": ("django.db.models.fields.BooleanField", [], {"default": "False"}), - "last_login": ("django.db.models.fields.DateTimeField", [], {"default": "datetime.datetime.now"}), - "last_name": ("django.db.models.fields.CharField", [], {"max_length": "30", "blank": "True"}), - "password": ("django.db.models.fields.CharField", [], {"max_length": "128"}), - "user_permissions": ( - "django.db.models.fields.related.ManyToManyField", - [], - {"to": "orm['auth.Permission']", "symmetrical": "False", "blank": "True"}, - ), - "username": ("django.db.models.fields.CharField", [], {"unique": "True", "max_length": "30"}), - }, - "contenttypes.contenttype": { - "Meta": { - "ordering": "('name',)", - "unique_together": "(('app_label', 'model'),)", - "object_name": "ContentType", - "db_table": "'django_content_type'", - }, - "app_label": ("django.db.models.fields.CharField", [], {"max_length": "100"}), - "id": ("django.db.models.fields.AutoField", [], {"primary_key": "True"}), - "model": ("django.db.models.fields.CharField", [], {"max_length": "100"}), - "name": ("django.db.models.fields.CharField", [], {"max_length": "100"}), - }, - "meetups.location": { - "Meta": {"object_name": "Location"}, - "address": ( - "django.db.models.fields.CharField", - [], - {"max_length": "255", "null": "True", "blank": "True"}, - ), - "description": ("django.db.models.fields.TextField", [], {"null": "True", "blank": "True"}), - "id": ("django.db.models.fields.AutoField", [], {"primary_key": "True"}), - "name": ("django.db.models.fields.CharField", [], {"max_length": "200"}), - "website": ("django.db.models.fields.URLField", [], {"max_length": "200", "null": "True", "blank": "True"}), - }, - "meetups.meetup": { - "Meta": {"object_name": "Meetup"}, - "id": ("django.db.models.fields.AutoField", [], {"primary_key": "True"}), - "location": ( - "django.db.models.fields.related.ForeignKey", - [], - {"to": "orm['meetups.Location']", "null": "True", "blank": "True"}, - ), - "start_date": ("django.db.models.fields.DateTimeField", [], {}), - }, - "meetups.session": { - "Meta": {"object_name": "Session"}, - "abstract": ("django.db.models.fields.TextField", [], {}), - "id": ("django.db.models.fields.AutoField", [], {"primary_key": "True"}), - "meetup": ( - "django.db.models.fields.related.ForeignKey", - [], - {"to": "orm['meetups.Meetup']", "null": "True", "blank": "True"}, - ), - "speaker": ( - "django.db.models.fields.related.ForeignKey", - [], - {"to": "orm['auth.User']", "null": "True", "blank": "True"}, - ), - "speaker_name": ( - "django.db.models.fields.CharField", - [], - {"max_length": "100", "null": "True", "blank": "True"}, - ), - "title": ("django.db.models.fields.CharField", [], {"max_length": "255"}), - }, - } - - complete_apps = ["meetups"] diff --git a/pygraz_website/apps/meetups/south_migrations/0002_speaker_email.py b/pygraz_website/apps/meetups/south_migrations/0002_speaker_email.py deleted file mode 100644 index 4b90347..0000000 --- a/pygraz_website/apps/meetups/south_migrations/0002_speaker_email.py +++ /dev/null @@ -1,134 +0,0 @@ -import datetime - -from django.db import models -from south.db import db -from south.v2 import SchemaMigration - - -class Migration(SchemaMigration): - def forwards(self, orm): - # Adding field 'Session.speaker_email' - db.add_column( - "meetups_session", - "speaker_email", - self.gf("django.db.models.fields.EmailField")(max_length=75, null=True, blank=True), - keep_default=False, - ) - - def backwards(self, orm): - # Deleting field 'Session.speaker_email' - db.delete_column("meetups_session", "speaker_email") - - models = { - "auth.group": { - "Meta": {"object_name": "Group"}, - "id": ("django.db.models.fields.AutoField", [], {"primary_key": "True"}), - "name": ("django.db.models.fields.CharField", [], {"unique": "True", "max_length": "80"}), - "permissions": ( - "django.db.models.fields.related.ManyToManyField", - [], - {"to": "orm['auth.Permission']", "symmetrical": "False", "blank": "True"}, - ), - }, - "auth.permission": { - "Meta": { - "ordering": "('content_type__app_label', 'content_type__model', 'codename')", - "unique_together": "(('content_type', 'codename'),)", - "object_name": "Permission", - }, - "codename": ("django.db.models.fields.CharField", [], {"max_length": "100"}), - "content_type": ( - "django.db.models.fields.related.ForeignKey", - [], - {"to": "orm['contenttypes.ContentType']"}, - ), - "id": ("django.db.models.fields.AutoField", [], {"primary_key": "True"}), - "name": ("django.db.models.fields.CharField", [], {"max_length": "50"}), - }, - "auth.user": { - "Meta": {"object_name": "User"}, - "date_joined": ("django.db.models.fields.DateTimeField", [], {"default": "datetime.datetime.now"}), - "email": ("django.db.models.fields.EmailField", [], {"max_length": "75", "blank": "True"}), - "first_name": ("django.db.models.fields.CharField", [], {"max_length": "30", "blank": "True"}), - "groups": ( - "django.db.models.fields.related.ManyToManyField", - [], - {"to": "orm['auth.Group']", "symmetrical": "False", "blank": "True"}, - ), - "id": ("django.db.models.fields.AutoField", [], {"primary_key": "True"}), - "is_active": ("django.db.models.fields.BooleanField", [], {"default": "True"}), - "is_staff": ("django.db.models.fields.BooleanField", [], {"default": "False"}), - "is_superuser": ("django.db.models.fields.BooleanField", [], {"default": "False"}), - "last_login": ("django.db.models.fields.DateTimeField", [], {"default": "datetime.datetime.now"}), - "last_name": ("django.db.models.fields.CharField", [], {"max_length": "30", "blank": "True"}), - "password": ("django.db.models.fields.CharField", [], {"max_length": "128"}), - "user_permissions": ( - "django.db.models.fields.related.ManyToManyField", - [], - {"to": "orm['auth.Permission']", "symmetrical": "False", "blank": "True"}, - ), - "username": ("django.db.models.fields.CharField", [], {"unique": "True", "max_length": "30"}), - }, - "contenttypes.contenttype": { - "Meta": { - "ordering": "('name',)", - "unique_together": "(('app_label', 'model'),)", - "object_name": "ContentType", - "db_table": "'django_content_type'", - }, - "app_label": ("django.db.models.fields.CharField", [], {"max_length": "100"}), - "id": ("django.db.models.fields.AutoField", [], {"primary_key": "True"}), - "model": ("django.db.models.fields.CharField", [], {"max_length": "100"}), - "name": ("django.db.models.fields.CharField", [], {"max_length": "100"}), - }, - "meetups.location": { - "Meta": {"object_name": "Location"}, - "address": ( - "django.db.models.fields.CharField", - [], - {"max_length": "255", "null": "True", "blank": "True"}, - ), - "description": ("django.db.models.fields.TextField", [], {"null": "True", "blank": "True"}), - "id": ("django.db.models.fields.AutoField", [], {"primary_key": "True"}), - "name": ("django.db.models.fields.CharField", [], {"max_length": "200"}), - "website": ("django.db.models.fields.URLField", [], {"max_length": "200", "null": "True", "blank": "True"}), - }, - "meetups.meetup": { - "Meta": {"ordering": "('-start_date',)", "object_name": "Meetup"}, - "id": ("django.db.models.fields.AutoField", [], {"primary_key": "True"}), - "location": ( - "django.db.models.fields.related.ForeignKey", - [], - {"to": "orm['meetups.Location']", "null": "True", "blank": "True"}, - ), - "start_date": ("django.db.models.fields.DateTimeField", [], {}), - }, - "meetups.session": { - "Meta": {"object_name": "Session"}, - "abstract": ("django.db.models.fields.TextField", [], {}), - "id": ("django.db.models.fields.AutoField", [], {"primary_key": "True"}), - "meetup": ( - "django.db.models.fields.related.ForeignKey", - [], - {"blank": "True", "related_name": "'sessions'", "null": "True", "to": "orm['meetups.Meetup']"}, - ), - "speaker": ( - "django.db.models.fields.related.ForeignKey", - [], - {"to": "orm['auth.User']", "null": "True", "blank": "True"}, - ), - "speaker_email": ( - "django.db.models.fields.EmailField", - [], - {"max_length": "75", "null": "True", "blank": "True"}, - ), - "speaker_name": ( - "django.db.models.fields.CharField", - [], - {"max_length": "100", "null": "True", "blank": "True"}, - ), - "title": ("django.db.models.fields.CharField", [], {"max_length": "255"}), - }, - } - - complete_apps = ["meetups"] diff --git a/pygraz_website/apps/meetups/south_migrations/0003_extended_session_info.py b/pygraz_website/apps/meetups/south_migrations/0003_extended_session_info.py deleted file mode 100644 index cd4a19a..0000000 --- a/pygraz_website/apps/meetups/south_migrations/0003_extended_session_info.py +++ /dev/null @@ -1,151 +0,0 @@ -import datetime - -from django.db import models -from south.db import db -from south.v2 import SchemaMigration - - -class Migration(SchemaMigration): - def forwards(self, orm): - # Adding field 'Session.slides_url' - db.add_column( - "meetups_session", - "slides_url", - self.gf("django.db.models.fields.URLField")(max_length=200, null=True, blank=True), - keep_default=False, - ) - - # Adding field 'Session.notes' - db.add_column( - "meetups_session", - "notes", - self.gf("django.db.models.fields.TextField")(null=True, blank=True), - keep_default=False, - ) - - def backwards(self, orm): - # Deleting field 'Session.slides_url' - db.delete_column("meetups_session", "slides_url") - - # Deleting field 'Session.notes' - db.delete_column("meetups_session", "notes") - - models = { - "auth.group": { - "Meta": {"object_name": "Group"}, - "id": ("django.db.models.fields.AutoField", [], {"primary_key": "True"}), - "name": ("django.db.models.fields.CharField", [], {"unique": "True", "max_length": "80"}), - "permissions": ( - "django.db.models.fields.related.ManyToManyField", - [], - {"to": "orm['auth.Permission']", "symmetrical": "False", "blank": "True"}, - ), - }, - "auth.permission": { - "Meta": { - "ordering": "('content_type__app_label', 'content_type__model', 'codename')", - "unique_together": "(('content_type', 'codename'),)", - "object_name": "Permission", - }, - "codename": ("django.db.models.fields.CharField", [], {"max_length": "100"}), - "content_type": ( - "django.db.models.fields.related.ForeignKey", - [], - {"to": "orm['contenttypes.ContentType']"}, - ), - "id": ("django.db.models.fields.AutoField", [], {"primary_key": "True"}), - "name": ("django.db.models.fields.CharField", [], {"max_length": "50"}), - }, - "auth.user": { - "Meta": {"object_name": "User"}, - "date_joined": ("django.db.models.fields.DateTimeField", [], {"default": "datetime.datetime.now"}), - "email": ("django.db.models.fields.EmailField", [], {"max_length": "75", "blank": "True"}), - "first_name": ("django.db.models.fields.CharField", [], {"max_length": "30", "blank": "True"}), - "groups": ( - "django.db.models.fields.related.ManyToManyField", - [], - {"to": "orm['auth.Group']", "symmetrical": "False", "blank": "True"}, - ), - "id": ("django.db.models.fields.AutoField", [], {"primary_key": "True"}), - "is_active": ("django.db.models.fields.BooleanField", [], {"default": "True"}), - "is_staff": ("django.db.models.fields.BooleanField", [], {"default": "False"}), - "is_superuser": ("django.db.models.fields.BooleanField", [], {"default": "False"}), - "last_login": ("django.db.models.fields.DateTimeField", [], {"default": "datetime.datetime.now"}), - "last_name": ("django.db.models.fields.CharField", [], {"max_length": "30", "blank": "True"}), - "password": ("django.db.models.fields.CharField", [], {"max_length": "128"}), - "user_permissions": ( - "django.db.models.fields.related.ManyToManyField", - [], - {"to": "orm['auth.Permission']", "symmetrical": "False", "blank": "True"}, - ), - "username": ("django.db.models.fields.CharField", [], {"unique": "True", "max_length": "30"}), - }, - "contenttypes.contenttype": { - "Meta": { - "ordering": "('name',)", - "unique_together": "(('app_label', 'model'),)", - "object_name": "ContentType", - "db_table": "'django_content_type'", - }, - "app_label": ("django.db.models.fields.CharField", [], {"max_length": "100"}), - "id": ("django.db.models.fields.AutoField", [], {"primary_key": "True"}), - "model": ("django.db.models.fields.CharField", [], {"max_length": "100"}), - "name": ("django.db.models.fields.CharField", [], {"max_length": "100"}), - }, - "meetups.location": { - "Meta": {"object_name": "Location"}, - "address": ( - "django.db.models.fields.CharField", - [], - {"max_length": "255", "null": "True", "blank": "True"}, - ), - "description": ("django.db.models.fields.TextField", [], {"null": "True", "blank": "True"}), - "id": ("django.db.models.fields.AutoField", [], {"primary_key": "True"}), - "name": ("django.db.models.fields.CharField", [], {"max_length": "200"}), - "website": ("django.db.models.fields.URLField", [], {"max_length": "200", "null": "True", "blank": "True"}), - }, - "meetups.meetup": { - "Meta": {"ordering": "('-start_date',)", "object_name": "Meetup"}, - "id": ("django.db.models.fields.AutoField", [], {"primary_key": "True"}), - "location": ( - "django.db.models.fields.related.ForeignKey", - [], - {"to": "orm['meetups.Location']", "null": "True", "blank": "True"}, - ), - "start_date": ("django.db.models.fields.DateTimeField", [], {}), - }, - "meetups.session": { - "Meta": {"object_name": "Session"}, - "abstract": ("django.db.models.fields.TextField", [], {}), - "id": ("django.db.models.fields.AutoField", [], {"primary_key": "True"}), - "meetup": ( - "django.db.models.fields.related.ForeignKey", - [], - {"blank": "True", "related_name": "'sessions'", "null": "True", "to": "orm['meetups.Meetup']"}, - ), - "notes": ("django.db.models.fields.TextField", [], {"null": "True", "blank": "True"}), - "slides_url": ( - "django.db.models.fields.URLField", - [], - {"max_length": "200", "null": "True", "blank": "True"}, - ), - "speaker": ( - "django.db.models.fields.related.ForeignKey", - [], - {"to": "orm['auth.User']", "null": "True", "blank": "True"}, - ), - "speaker_email": ( - "django.db.models.fields.EmailField", - [], - {"max_length": "75", "null": "True", "blank": "True"}, - ), - "speaker_name": ( - "django.db.models.fields.CharField", - [], - {"max_length": "100", "null": "True", "blank": "True"}, - ), - "title": ("django.db.models.fields.CharField", [], {"max_length": "255"}), - }, - } - - complete_apps = ["meetups"] diff --git a/pygraz_website/apps/meetups/south_migrations/0004_meetupcom_field.py b/pygraz_website/apps/meetups/south_migrations/0004_meetupcom_field.py deleted file mode 100644 index cbe7d54..0000000 --- a/pygraz_website/apps/meetups/south_migrations/0004_meetupcom_field.py +++ /dev/null @@ -1,145 +0,0 @@ -import datetime - -from django.db import models -from south.db import db -from south.v2 import SchemaMigration - - -class Migration(SchemaMigration): - def forwards(self, orm): - # Adding field 'Meetup.meetupcom_id' - db.add_column( - "meetups_meetup", - "meetupcom_id", - self.gf("django.db.models.fields.CharField")(max_length=20, null=True, blank=True), - keep_default=False, - ) - - def backwards(self, orm): - # Deleting field 'Meetup.meetupcom_id' - db.delete_column("meetups_meetup", "meetupcom_id") - - models = { - "auth.group": { - "Meta": {"object_name": "Group"}, - "id": ("django.db.models.fields.AutoField", [], {"primary_key": "True"}), - "name": ("django.db.models.fields.CharField", [], {"unique": "True", "max_length": "80"}), - "permissions": ( - "django.db.models.fields.related.ManyToManyField", - [], - {"to": "orm['auth.Permission']", "symmetrical": "False", "blank": "True"}, - ), - }, - "auth.permission": { - "Meta": { - "ordering": "('content_type__app_label', 'content_type__model', 'codename')", - "unique_together": "(('content_type', 'codename'),)", - "object_name": "Permission", - }, - "codename": ("django.db.models.fields.CharField", [], {"max_length": "100"}), - "content_type": ( - "django.db.models.fields.related.ForeignKey", - [], - {"to": "orm['contenttypes.ContentType']"}, - ), - "id": ("django.db.models.fields.AutoField", [], {"primary_key": "True"}), - "name": ("django.db.models.fields.CharField", [], {"max_length": "50"}), - }, - "auth.user": { - "Meta": {"object_name": "User"}, - "date_joined": ("django.db.models.fields.DateTimeField", [], {"default": "datetime.datetime.now"}), - "email": ("django.db.models.fields.EmailField", [], {"max_length": "75", "blank": "True"}), - "first_name": ("django.db.models.fields.CharField", [], {"max_length": "30", "blank": "True"}), - "groups": ( - "django.db.models.fields.related.ManyToManyField", - [], - {"to": "orm['auth.Group']", "symmetrical": "False", "blank": "True"}, - ), - "id": ("django.db.models.fields.AutoField", [], {"primary_key": "True"}), - "is_active": ("django.db.models.fields.BooleanField", [], {"default": "True"}), - "is_staff": ("django.db.models.fields.BooleanField", [], {"default": "False"}), - "is_superuser": ("django.db.models.fields.BooleanField", [], {"default": "False"}), - "last_login": ("django.db.models.fields.DateTimeField", [], {"default": "datetime.datetime.now"}), - "last_name": ("django.db.models.fields.CharField", [], {"max_length": "30", "blank": "True"}), - "password": ("django.db.models.fields.CharField", [], {"max_length": "128"}), - "user_permissions": ( - "django.db.models.fields.related.ManyToManyField", - [], - {"to": "orm['auth.Permission']", "symmetrical": "False", "blank": "True"}, - ), - "username": ("django.db.models.fields.CharField", [], {"unique": "True", "max_length": "30"}), - }, - "contenttypes.contenttype": { - "Meta": { - "ordering": "('name',)", - "unique_together": "(('app_label', 'model'),)", - "object_name": "ContentType", - "db_table": "'django_content_type'", - }, - "app_label": ("django.db.models.fields.CharField", [], {"max_length": "100"}), - "id": ("django.db.models.fields.AutoField", [], {"primary_key": "True"}), - "model": ("django.db.models.fields.CharField", [], {"max_length": "100"}), - "name": ("django.db.models.fields.CharField", [], {"max_length": "100"}), - }, - "meetups.location": { - "Meta": {"object_name": "Location"}, - "address": ( - "django.db.models.fields.CharField", - [], - {"max_length": "255", "null": "True", "blank": "True"}, - ), - "description": ("django.db.models.fields.TextField", [], {"null": "True", "blank": "True"}), - "id": ("django.db.models.fields.AutoField", [], {"primary_key": "True"}), - "name": ("django.db.models.fields.CharField", [], {"max_length": "200"}), - "website": ("django.db.models.fields.URLField", [], {"max_length": "200", "null": "True", "blank": "True"}), - }, - "meetups.meetup": { - "Meta": {"ordering": "('-start_date',)", "object_name": "Meetup"}, - "id": ("django.db.models.fields.AutoField", [], {"primary_key": "True"}), - "location": ( - "django.db.models.fields.related.ForeignKey", - [], - {"to": "orm['meetups.Location']", "null": "True", "blank": "True"}, - ), - "meetupcom_id": ( - "django.db.models.fields.CharField", - [], - {"max_length": "20", "null": "True", "blank": "True"}, - ), - "start_date": ("django.db.models.fields.DateTimeField", [], {}), - }, - "meetups.session": { - "Meta": {"object_name": "Session"}, - "abstract": ("django.db.models.fields.TextField", [], {}), - "id": ("django.db.models.fields.AutoField", [], {"primary_key": "True"}), - "meetup": ( - "django.db.models.fields.related.ForeignKey", - [], - {"blank": "True", "related_name": "'sessions'", "null": "True", "to": "orm['meetups.Meetup']"}, - ), - "notes": ("django.db.models.fields.TextField", [], {"null": "True", "blank": "True"}), - "slides_url": ( - "django.db.models.fields.URLField", - [], - {"max_length": "200", "null": "True", "blank": "True"}, - ), - "speaker": ( - "django.db.models.fields.related.ForeignKey", - [], - {"to": "orm['auth.User']", "null": "True", "blank": "True"}, - ), - "speaker_email": ( - "django.db.models.fields.EmailField", - [], - {"max_length": "75", "null": "True", "blank": "True"}, - ), - "speaker_name": ( - "django.db.models.fields.CharField", - [], - {"max_length": "100", "null": "True", "blank": "True"}, - ), - "title": ("django.db.models.fields.CharField", [], {"max_length": "255"}), - }, - } - - complete_apps = ["meetups"] diff --git a/pygraz_website/apps/meetups/south_migrations/0005_meetup_notes.py b/pygraz_website/apps/meetups/south_migrations/0005_meetup_notes.py deleted file mode 100644 index 7a35c8b..0000000 --- a/pygraz_website/apps/meetups/south_migrations/0005_meetup_notes.py +++ /dev/null @@ -1,146 +0,0 @@ -import datetime - -from django.db import models -from south.db import db -from south.v2 import SchemaMigration - - -class Migration(SchemaMigration): - def forwards(self, orm): - # Adding field 'Meetup.notes' - db.add_column( - "meetups_meetup", - "notes", - self.gf("django.db.models.fields.TextField")(null=True, blank=True), - keep_default=False, - ) - - def backwards(self, orm): - # Deleting field 'Meetup.notes' - db.delete_column("meetups_meetup", "notes") - - models = { - "auth.group": { - "Meta": {"object_name": "Group"}, - "id": ("django.db.models.fields.AutoField", [], {"primary_key": "True"}), - "name": ("django.db.models.fields.CharField", [], {"unique": "True", "max_length": "80"}), - "permissions": ( - "django.db.models.fields.related.ManyToManyField", - [], - {"to": "orm['auth.Permission']", "symmetrical": "False", "blank": "True"}, - ), - }, - "auth.permission": { - "Meta": { - "ordering": "('content_type__app_label', 'content_type__model', 'codename')", - "unique_together": "(('content_type', 'codename'),)", - "object_name": "Permission", - }, - "codename": ("django.db.models.fields.CharField", [], {"max_length": "100"}), - "content_type": ( - "django.db.models.fields.related.ForeignKey", - [], - {"to": "orm['contenttypes.ContentType']"}, - ), - "id": ("django.db.models.fields.AutoField", [], {"primary_key": "True"}), - "name": ("django.db.models.fields.CharField", [], {"max_length": "50"}), - }, - "auth.user": { - "Meta": {"object_name": "User"}, - "date_joined": ("django.db.models.fields.DateTimeField", [], {"default": "datetime.datetime.now"}), - "email": ("django.db.models.fields.EmailField", [], {"max_length": "75", "blank": "True"}), - "first_name": ("django.db.models.fields.CharField", [], {"max_length": "30", "blank": "True"}), - "groups": ( - "django.db.models.fields.related.ManyToManyField", - [], - {"to": "orm['auth.Group']", "symmetrical": "False", "blank": "True"}, - ), - "id": ("django.db.models.fields.AutoField", [], {"primary_key": "True"}), - "is_active": ("django.db.models.fields.BooleanField", [], {"default": "True"}), - "is_staff": ("django.db.models.fields.BooleanField", [], {"default": "False"}), - "is_superuser": ("django.db.models.fields.BooleanField", [], {"default": "False"}), - "last_login": ("django.db.models.fields.DateTimeField", [], {"default": "datetime.datetime.now"}), - "last_name": ("django.db.models.fields.CharField", [], {"max_length": "30", "blank": "True"}), - "password": ("django.db.models.fields.CharField", [], {"max_length": "128"}), - "user_permissions": ( - "django.db.models.fields.related.ManyToManyField", - [], - {"to": "orm['auth.Permission']", "symmetrical": "False", "blank": "True"}, - ), - "username": ("django.db.models.fields.CharField", [], {"unique": "True", "max_length": "30"}), - }, - "contenttypes.contenttype": { - "Meta": { - "ordering": "('name',)", - "unique_together": "(('app_label', 'model'),)", - "object_name": "ContentType", - "db_table": "'django_content_type'", - }, - "app_label": ("django.db.models.fields.CharField", [], {"max_length": "100"}), - "id": ("django.db.models.fields.AutoField", [], {"primary_key": "True"}), - "model": ("django.db.models.fields.CharField", [], {"max_length": "100"}), - "name": ("django.db.models.fields.CharField", [], {"max_length": "100"}), - }, - "meetups.location": { - "Meta": {"object_name": "Location"}, - "address": ( - "django.db.models.fields.CharField", - [], - {"max_length": "255", "null": "True", "blank": "True"}, - ), - "description": ("django.db.models.fields.TextField", [], {"null": "True", "blank": "True"}), - "id": ("django.db.models.fields.AutoField", [], {"primary_key": "True"}), - "name": ("django.db.models.fields.CharField", [], {"max_length": "200"}), - "website": ("django.db.models.fields.URLField", [], {"max_length": "200", "null": "True", "blank": "True"}), - }, - "meetups.meetup": { - "Meta": {"ordering": "('-start_date',)", "object_name": "Meetup"}, - "id": ("django.db.models.fields.AutoField", [], {"primary_key": "True"}), - "location": ( - "django.db.models.fields.related.ForeignKey", - [], - {"to": "orm['meetups.Location']", "null": "True", "blank": "True"}, - ), - "meetupcom_id": ( - "django.db.models.fields.CharField", - [], - {"max_length": "20", "null": "True", "blank": "True"}, - ), - "notes": ("django.db.models.fields.TextField", [], {"null": "True", "blank": "True"}), - "start_date": ("django.db.models.fields.DateTimeField", [], {}), - }, - "meetups.session": { - "Meta": {"object_name": "Session"}, - "abstract": ("django.db.models.fields.TextField", [], {}), - "id": ("django.db.models.fields.AutoField", [], {"primary_key": "True"}), - "meetup": ( - "django.db.models.fields.related.ForeignKey", - [], - {"blank": "True", "related_name": "'sessions'", "null": "True", "to": "orm['meetups.Meetup']"}, - ), - "notes": ("django.db.models.fields.TextField", [], {"null": "True", "blank": "True"}), - "slides_url": ( - "django.db.models.fields.URLField", - [], - {"max_length": "200", "null": "True", "blank": "True"}, - ), - "speaker": ( - "django.db.models.fields.related.ForeignKey", - [], - {"to": "orm['auth.User']", "null": "True", "blank": "True"}, - ), - "speaker_email": ( - "django.db.models.fields.EmailField", - [], - {"max_length": "75", "null": "True", "blank": "True"}, - ), - "speaker_name": ( - "django.db.models.fields.CharField", - [], - {"max_length": "100", "null": "True", "blank": "True"}, - ), - "title": ("django.db.models.fields.CharField", [], {"max_length": "255"}), - }, - } - - complete_apps = ["meetups"] diff --git a/pygraz_website/apps/meetups/south_migrations/0006_auto__add_rsvp.py b/pygraz_website/apps/meetups/south_migrations/0006_auto__add_rsvp.py deleted file mode 100644 index 315a11c..0000000 --- a/pygraz_website/apps/meetups/south_migrations/0006_auto__add_rsvp.py +++ /dev/null @@ -1,178 +0,0 @@ -import datetime - -from django.db import models -from south.db import db -from south.v2 import SchemaMigration - - -class Migration(SchemaMigration): - def forwards(self, orm): - # Adding model 'RSVP' - db.create_table( - "meetups_rsvp", - ( - ("id", self.gf("django.db.models.fields.AutoField")(primary_key=True)), - ("status", self.gf("django.db.models.fields.CharField")(max_length=20, null=True, blank=True)), - ("gplus_name", self.gf("django.db.models.fields.CharField")(max_length=100, null=True, blank=True)), - ("gplus_uid", self.gf("django.db.models.fields.CharField")(max_length=100, null=True, blank=True)), - ( - "meetup", - self.gf("django.db.models.fields.related.ForeignKey")( - related_name="rsvps", to=orm["meetups.Meetup"] - ), - ), - ("source", self.gf("django.db.models.fields.CharField")(max_length=20, null=True, blank=True)), - ), - ) - db.send_create_signal("meetups", ["RSVP"]) - - def backwards(self, orm): - # Deleting model 'RSVP' - db.delete_table("meetups_rsvp") - - models = { - "auth.group": { - "Meta": {"object_name": "Group"}, - "id": ("django.db.models.fields.AutoField", [], {"primary_key": "True"}), - "name": ("django.db.models.fields.CharField", [], {"unique": "True", "max_length": "80"}), - "permissions": ( - "django.db.models.fields.related.ManyToManyField", - [], - {"to": "orm['auth.Permission']", "symmetrical": "False", "blank": "True"}, - ), - }, - "auth.permission": { - "Meta": { - "ordering": "('content_type__app_label', 'content_type__model', 'codename')", - "unique_together": "(('content_type', 'codename'),)", - "object_name": "Permission", - }, - "codename": ("django.db.models.fields.CharField", [], {"max_length": "100"}), - "content_type": ( - "django.db.models.fields.related.ForeignKey", - [], - {"to": "orm['contenttypes.ContentType']"}, - ), - "id": ("django.db.models.fields.AutoField", [], {"primary_key": "True"}), - "name": ("django.db.models.fields.CharField", [], {"max_length": "50"}), - }, - "auth.user": { - "Meta": {"object_name": "User"}, - "date_joined": ("django.db.models.fields.DateTimeField", [], {"default": "datetime.datetime.now"}), - "email": ("django.db.models.fields.EmailField", [], {"max_length": "75", "blank": "True"}), - "first_name": ("django.db.models.fields.CharField", [], {"max_length": "30", "blank": "True"}), - "groups": ( - "django.db.models.fields.related.ManyToManyField", - [], - {"to": "orm['auth.Group']", "symmetrical": "False", "blank": "True"}, - ), - "id": ("django.db.models.fields.AutoField", [], {"primary_key": "True"}), - "is_active": ("django.db.models.fields.BooleanField", [], {"default": "True"}), - "is_staff": ("django.db.models.fields.BooleanField", [], {"default": "False"}), - "is_superuser": ("django.db.models.fields.BooleanField", [], {"default": "False"}), - "last_login": ("django.db.models.fields.DateTimeField", [], {"default": "datetime.datetime.now"}), - "last_name": ("django.db.models.fields.CharField", [], {"max_length": "30", "blank": "True"}), - "password": ("django.db.models.fields.CharField", [], {"max_length": "128"}), - "user_permissions": ( - "django.db.models.fields.related.ManyToManyField", - [], - {"to": "orm['auth.Permission']", "symmetrical": "False", "blank": "True"}, - ), - "username": ("django.db.models.fields.CharField", [], {"unique": "True", "max_length": "30"}), - }, - "contenttypes.contenttype": { - "Meta": { - "ordering": "('name',)", - "unique_together": "(('app_label', 'model'),)", - "object_name": "ContentType", - "db_table": "'django_content_type'", - }, - "app_label": ("django.db.models.fields.CharField", [], {"max_length": "100"}), - "id": ("django.db.models.fields.AutoField", [], {"primary_key": "True"}), - "model": ("django.db.models.fields.CharField", [], {"max_length": "100"}), - "name": ("django.db.models.fields.CharField", [], {"max_length": "100"}), - }, - "meetups.location": { - "Meta": {"object_name": "Location"}, - "address": ( - "django.db.models.fields.CharField", - [], - {"max_length": "255", "null": "True", "blank": "True"}, - ), - "description": ("django.db.models.fields.TextField", [], {"null": "True", "blank": "True"}), - "id": ("django.db.models.fields.AutoField", [], {"primary_key": "True"}), - "name": ("django.db.models.fields.CharField", [], {"max_length": "200"}), - "website": ("django.db.models.fields.URLField", [], {"max_length": "200", "null": "True", "blank": "True"}), - }, - "meetups.meetup": { - "Meta": {"ordering": "('-start_date',)", "object_name": "Meetup"}, - "id": ("django.db.models.fields.AutoField", [], {"primary_key": "True"}), - "location": ( - "django.db.models.fields.related.ForeignKey", - [], - {"to": "orm['meetups.Location']", "null": "True", "blank": "True"}, - ), - "meetupcom_id": ( - "django.db.models.fields.CharField", - [], - {"max_length": "20", "null": "True", "blank": "True"}, - ), - "notes": ("django.db.models.fields.TextField", [], {"null": "True", "blank": "True"}), - "start_date": ("django.db.models.fields.DateTimeField", [], {}), - }, - "meetups.rsvp": { - "Meta": {"object_name": "RSVP"}, - "gplus_name": ( - "django.db.models.fields.CharField", - [], - {"max_length": "100", "null": "True", "blank": "True"}, - ), - "gplus_uid": ( - "django.db.models.fields.CharField", - [], - {"max_length": "100", "null": "True", "blank": "True"}, - ), - "id": ("django.db.models.fields.AutoField", [], {"primary_key": "True"}), - "meetup": ( - "django.db.models.fields.related.ForeignKey", - [], - {"related_name": "'rsvps'", "to": "orm['meetups.Meetup']"}, - ), - "source": ("django.db.models.fields.CharField", [], {"max_length": "20", "null": "True", "blank": "True"}), - "status": ("django.db.models.fields.CharField", [], {"max_length": "20", "null": "True", "blank": "True"}), - }, - "meetups.session": { - "Meta": {"object_name": "Session"}, - "abstract": ("django.db.models.fields.TextField", [], {}), - "id": ("django.db.models.fields.AutoField", [], {"primary_key": "True"}), - "meetup": ( - "django.db.models.fields.related.ForeignKey", - [], - {"blank": "True", "related_name": "'sessions'", "null": "True", "to": "orm['meetups.Meetup']"}, - ), - "notes": ("django.db.models.fields.TextField", [], {"null": "True", "blank": "True"}), - "slides_url": ( - "django.db.models.fields.URLField", - [], - {"max_length": "200", "null": "True", "blank": "True"}, - ), - "speaker": ( - "django.db.models.fields.related.ForeignKey", - [], - {"to": "orm['auth.User']", "null": "True", "blank": "True"}, - ), - "speaker_email": ( - "django.db.models.fields.EmailField", - [], - {"max_length": "75", "null": "True", "blank": "True"}, - ), - "speaker_name": ( - "django.db.models.fields.CharField", - [], - {"max_length": "100", "null": "True", "blank": "True"}, - ), - "title": ("django.db.models.fields.CharField", [], {"max_length": "255"}), - }, - } - - complete_apps = ["meetups"] diff --git a/pygraz_website/apps/meetups/south_migrations/0007_auto__add_field_meetup_gplus_id.py b/pygraz_website/apps/meetups/south_migrations/0007_auto__add_field_meetup_gplus_id.py deleted file mode 100644 index d395382..0000000 --- a/pygraz_website/apps/meetups/south_migrations/0007_auto__add_field_meetup_gplus_id.py +++ /dev/null @@ -1,172 +0,0 @@ -import datetime - -from django.db import models -from south.db import db -from south.v2 import SchemaMigration - - -class Migration(SchemaMigration): - def forwards(self, orm): - # Adding field 'Meetup.gplus_id' - db.add_column( - "meetups_meetup", - "gplus_id", - self.gf("django.db.models.fields.CharField")(max_length=50, null=True, blank=True), - keep_default=False, - ) - - def backwards(self, orm): - # Deleting field 'Meetup.gplus_id' - db.delete_column("meetups_meetup", "gplus_id") - - models = { - "auth.group": { - "Meta": {"object_name": "Group"}, - "id": ("django.db.models.fields.AutoField", [], {"primary_key": "True"}), - "name": ("django.db.models.fields.CharField", [], {"unique": "True", "max_length": "80"}), - "permissions": ( - "django.db.models.fields.related.ManyToManyField", - [], - {"to": "orm['auth.Permission']", "symmetrical": "False", "blank": "True"}, - ), - }, - "auth.permission": { - "Meta": { - "ordering": "('content_type__app_label', 'content_type__model', 'codename')", - "unique_together": "(('content_type', 'codename'),)", - "object_name": "Permission", - }, - "codename": ("django.db.models.fields.CharField", [], {"max_length": "100"}), - "content_type": ( - "django.db.models.fields.related.ForeignKey", - [], - {"to": "orm['contenttypes.ContentType']"}, - ), - "id": ("django.db.models.fields.AutoField", [], {"primary_key": "True"}), - "name": ("django.db.models.fields.CharField", [], {"max_length": "50"}), - }, - "auth.user": { - "Meta": {"object_name": "User"}, - "date_joined": ("django.db.models.fields.DateTimeField", [], {"default": "datetime.datetime.now"}), - "email": ("django.db.models.fields.EmailField", [], {"max_length": "75", "blank": "True"}), - "first_name": ("django.db.models.fields.CharField", [], {"max_length": "30", "blank": "True"}), - "groups": ( - "django.db.models.fields.related.ManyToManyField", - [], - {"to": "orm['auth.Group']", "symmetrical": "False", "blank": "True"}, - ), - "id": ("django.db.models.fields.AutoField", [], {"primary_key": "True"}), - "is_active": ("django.db.models.fields.BooleanField", [], {"default": "True"}), - "is_staff": ("django.db.models.fields.BooleanField", [], {"default": "False"}), - "is_superuser": ("django.db.models.fields.BooleanField", [], {"default": "False"}), - "last_login": ("django.db.models.fields.DateTimeField", [], {"default": "datetime.datetime.now"}), - "last_name": ("django.db.models.fields.CharField", [], {"max_length": "30", "blank": "True"}), - "password": ("django.db.models.fields.CharField", [], {"max_length": "128"}), - "user_permissions": ( - "django.db.models.fields.related.ManyToManyField", - [], - {"to": "orm['auth.Permission']", "symmetrical": "False", "blank": "True"}, - ), - "username": ("django.db.models.fields.CharField", [], {"unique": "True", "max_length": "30"}), - }, - "contenttypes.contenttype": { - "Meta": { - "ordering": "('name',)", - "unique_together": "(('app_label', 'model'),)", - "object_name": "ContentType", - "db_table": "'django_content_type'", - }, - "app_label": ("django.db.models.fields.CharField", [], {"max_length": "100"}), - "id": ("django.db.models.fields.AutoField", [], {"primary_key": "True"}), - "model": ("django.db.models.fields.CharField", [], {"max_length": "100"}), - "name": ("django.db.models.fields.CharField", [], {"max_length": "100"}), - }, - "meetups.location": { - "Meta": {"object_name": "Location"}, - "address": ( - "django.db.models.fields.CharField", - [], - {"max_length": "255", "null": "True", "blank": "True"}, - ), - "description": ("django.db.models.fields.TextField", [], {"null": "True", "blank": "True"}), - "id": ("django.db.models.fields.AutoField", [], {"primary_key": "True"}), - "name": ("django.db.models.fields.CharField", [], {"max_length": "200"}), - "website": ("django.db.models.fields.URLField", [], {"max_length": "200", "null": "True", "blank": "True"}), - }, - "meetups.meetup": { - "Meta": {"ordering": "('-start_date',)", "object_name": "Meetup"}, - "gplus_id": ( - "django.db.models.fields.CharField", - [], - {"max_length": "50", "null": "True", "blank": "True"}, - ), - "id": ("django.db.models.fields.AutoField", [], {"primary_key": "True"}), - "location": ( - "django.db.models.fields.related.ForeignKey", - [], - {"to": "orm['meetups.Location']", "null": "True", "blank": "True"}, - ), - "meetupcom_id": ( - "django.db.models.fields.CharField", - [], - {"max_length": "20", "null": "True", "blank": "True"}, - ), - "notes": ("django.db.models.fields.TextField", [], {"null": "True", "blank": "True"}), - "start_date": ("django.db.models.fields.DateTimeField", [], {}), - }, - "meetups.rsvp": { - "Meta": {"object_name": "RSVP"}, - "gplus_name": ( - "django.db.models.fields.CharField", - [], - {"max_length": "100", "null": "True", "blank": "True"}, - ), - "gplus_uid": ( - "django.db.models.fields.CharField", - [], - {"max_length": "100", "null": "True", "blank": "True"}, - ), - "id": ("django.db.models.fields.AutoField", [], {"primary_key": "True"}), - "meetup": ( - "django.db.models.fields.related.ForeignKey", - [], - {"related_name": "'rsvps'", "to": "orm['meetups.Meetup']"}, - ), - "source": ("django.db.models.fields.CharField", [], {"max_length": "20", "null": "True", "blank": "True"}), - "status": ("django.db.models.fields.CharField", [], {"max_length": "20", "null": "True", "blank": "True"}), - }, - "meetups.session": { - "Meta": {"object_name": "Session"}, - "abstract": ("django.db.models.fields.TextField", [], {}), - "id": ("django.db.models.fields.AutoField", [], {"primary_key": "True"}), - "meetup": ( - "django.db.models.fields.related.ForeignKey", - [], - {"blank": "True", "related_name": "'sessions'", "null": "True", "to": "orm['meetups.Meetup']"}, - ), - "notes": ("django.db.models.fields.TextField", [], {"null": "True", "blank": "True"}), - "slides_url": ( - "django.db.models.fields.URLField", - [], - {"max_length": "200", "null": "True", "blank": "True"}, - ), - "speaker": ( - "django.db.models.fields.related.ForeignKey", - [], - {"to": "orm['auth.User']", "null": "True", "blank": "True"}, - ), - "speaker_email": ( - "django.db.models.fields.EmailField", - [], - {"max_length": "75", "null": "True", "blank": "True"}, - ), - "speaker_name": ( - "django.db.models.fields.CharField", - [], - {"max_length": "100", "null": "True", "blank": "True"}, - ), - "title": ("django.db.models.fields.CharField", [], {"max_length": "255"}), - }, - } - - complete_apps = ["meetups"] diff --git a/pygraz_website/apps/meetups/south_migrations/0008_auto__add_field_meetup_attendee_count.py b/pygraz_website/apps/meetups/south_migrations/0008_auto__add_field_meetup_attendee_count.py deleted file mode 100644 index fa0ca89..0000000 --- a/pygraz_website/apps/meetups/south_migrations/0008_auto__add_field_meetup_attendee_count.py +++ /dev/null @@ -1,173 +0,0 @@ -import datetime - -from django.db import models -from south.db import db -from south.v2 import SchemaMigration - - -class Migration(SchemaMigration): - def forwards(self, orm): - # Adding field 'Meetup.attendee_count' - db.add_column( - "meetups_meetup", - "attendee_count", - self.gf("django.db.models.fields.IntegerField")(null=True, blank=True), - keep_default=False, - ) - - def backwards(self, orm): - # Deleting field 'Meetup.attendee_count' - db.delete_column("meetups_meetup", "attendee_count") - - models = { - "auth.group": { - "Meta": {"object_name": "Group"}, - "id": ("django.db.models.fields.AutoField", [], {"primary_key": "True"}), - "name": ("django.db.models.fields.CharField", [], {"unique": "True", "max_length": "80"}), - "permissions": ( - "django.db.models.fields.related.ManyToManyField", - [], - {"to": "orm['auth.Permission']", "symmetrical": "False", "blank": "True"}, - ), - }, - "auth.permission": { - "Meta": { - "ordering": "('content_type__app_label', 'content_type__model', 'codename')", - "unique_together": "(('content_type', 'codename'),)", - "object_name": "Permission", - }, - "codename": ("django.db.models.fields.CharField", [], {"max_length": "100"}), - "content_type": ( - "django.db.models.fields.related.ForeignKey", - [], - {"to": "orm['contenttypes.ContentType']"}, - ), - "id": ("django.db.models.fields.AutoField", [], {"primary_key": "True"}), - "name": ("django.db.models.fields.CharField", [], {"max_length": "50"}), - }, - "auth.user": { - "Meta": {"object_name": "User"}, - "date_joined": ("django.db.models.fields.DateTimeField", [], {"default": "datetime.datetime.now"}), - "email": ("django.db.models.fields.EmailField", [], {"max_length": "75", "blank": "True"}), - "first_name": ("django.db.models.fields.CharField", [], {"max_length": "30", "blank": "True"}), - "groups": ( - "django.db.models.fields.related.ManyToManyField", - [], - {"to": "orm['auth.Group']", "symmetrical": "False", "blank": "True"}, - ), - "id": ("django.db.models.fields.AutoField", [], {"primary_key": "True"}), - "is_active": ("django.db.models.fields.BooleanField", [], {"default": "True"}), - "is_staff": ("django.db.models.fields.BooleanField", [], {"default": "False"}), - "is_superuser": ("django.db.models.fields.BooleanField", [], {"default": "False"}), - "last_login": ("django.db.models.fields.DateTimeField", [], {"default": "datetime.datetime.now"}), - "last_name": ("django.db.models.fields.CharField", [], {"max_length": "30", "blank": "True"}), - "password": ("django.db.models.fields.CharField", [], {"max_length": "128"}), - "user_permissions": ( - "django.db.models.fields.related.ManyToManyField", - [], - {"to": "orm['auth.Permission']", "symmetrical": "False", "blank": "True"}, - ), - "username": ("django.db.models.fields.CharField", [], {"unique": "True", "max_length": "30"}), - }, - "contenttypes.contenttype": { - "Meta": { - "ordering": "('name',)", - "unique_together": "(('app_label', 'model'),)", - "object_name": "ContentType", - "db_table": "'django_content_type'", - }, - "app_label": ("django.db.models.fields.CharField", [], {"max_length": "100"}), - "id": ("django.db.models.fields.AutoField", [], {"primary_key": "True"}), - "model": ("django.db.models.fields.CharField", [], {"max_length": "100"}), - "name": ("django.db.models.fields.CharField", [], {"max_length": "100"}), - }, - "meetups.location": { - "Meta": {"object_name": "Location"}, - "address": ( - "django.db.models.fields.CharField", - [], - {"max_length": "255", "null": "True", "blank": "True"}, - ), - "description": ("django.db.models.fields.TextField", [], {"null": "True", "blank": "True"}), - "id": ("django.db.models.fields.AutoField", [], {"primary_key": "True"}), - "name": ("django.db.models.fields.CharField", [], {"max_length": "200"}), - "website": ("django.db.models.fields.URLField", [], {"max_length": "200", "null": "True", "blank": "True"}), - }, - "meetups.meetup": { - "Meta": {"ordering": "('-start_date',)", "object_name": "Meetup"}, - "attendee_count": ("django.db.models.fields.IntegerField", [], {"null": "True", "blank": "True"}), - "gplus_id": ( - "django.db.models.fields.CharField", - [], - {"max_length": "50", "null": "True", "blank": "True"}, - ), - "id": ("django.db.models.fields.AutoField", [], {"primary_key": "True"}), - "location": ( - "django.db.models.fields.related.ForeignKey", - [], - {"to": "orm['meetups.Location']", "null": "True", "blank": "True"}, - ), - "meetupcom_id": ( - "django.db.models.fields.CharField", - [], - {"max_length": "20", "null": "True", "blank": "True"}, - ), - "notes": ("django.db.models.fields.TextField", [], {"null": "True", "blank": "True"}), - "start_date": ("django.db.models.fields.DateTimeField", [], {}), - }, - "meetups.rsvp": { - "Meta": {"object_name": "RSVP"}, - "gplus_name": ( - "django.db.models.fields.CharField", - [], - {"max_length": "100", "null": "True", "blank": "True"}, - ), - "gplus_uid": ( - "django.db.models.fields.CharField", - [], - {"max_length": "100", "null": "True", "blank": "True"}, - ), - "id": ("django.db.models.fields.AutoField", [], {"primary_key": "True"}), - "meetup": ( - "django.db.models.fields.related.ForeignKey", - [], - {"related_name": "'rsvps'", "to": "orm['meetups.Meetup']"}, - ), - "source": ("django.db.models.fields.CharField", [], {"max_length": "20", "null": "True", "blank": "True"}), - "status": ("django.db.models.fields.CharField", [], {"max_length": "20", "null": "True", "blank": "True"}), - }, - "meetups.session": { - "Meta": {"object_name": "Session"}, - "abstract": ("django.db.models.fields.TextField", [], {}), - "id": ("django.db.models.fields.AutoField", [], {"primary_key": "True"}), - "meetup": ( - "django.db.models.fields.related.ForeignKey", - [], - {"blank": "True", "related_name": "'sessions'", "null": "True", "to": "orm['meetups.Meetup']"}, - ), - "notes": ("django.db.models.fields.TextField", [], {"null": "True", "blank": "True"}), - "slides_url": ( - "django.db.models.fields.URLField", - [], - {"max_length": "200", "null": "True", "blank": "True"}, - ), - "speaker": ( - "django.db.models.fields.related.ForeignKey", - [], - {"to": "orm['auth.User']", "null": "True", "blank": "True"}, - ), - "speaker_email": ( - "django.db.models.fields.EmailField", - [], - {"max_length": "75", "null": "True", "blank": "True"}, - ), - "speaker_name": ( - "django.db.models.fields.CharField", - [], - {"max_length": "100", "null": "True", "blank": "True"}, - ), - "title": ("django.db.models.fields.CharField", [], {"max_length": "255"}), - }, - } - - complete_apps = ["meetups"] diff --git a/pygraz_website/apps/meetups/south_migrations/0009_auto__add_sessiontype__add_field_session_type.py b/pygraz_website/apps/meetups/south_migrations/0009_auto__add_sessiontype__add_field_session_type.py deleted file mode 100644 index b985468..0000000 --- a/pygraz_website/apps/meetups/south_migrations/0009_auto__add_sessiontype__add_field_session_type.py +++ /dev/null @@ -1,202 +0,0 @@ -from django.db import models -from south.db import db -from south.utils import datetime_utils as datetime -from south.v2 import SchemaMigration - - -class Migration(SchemaMigration): - def forwards(self, orm): - # Adding model 'SessionType' - db.create_table( - "meetups_sessiontype", - ( - ("id", self.gf("django.db.models.fields.AutoField")(primary_key=True)), - ("name", self.gf("django.db.models.fields.CharField")(unique=True, max_length=30)), - ("description", self.gf("django.db.models.fields.TextField")(null=True, blank=True)), - ), - ) - db.send_create_signal("meetups", ["SessionType"]) - - # Adding field 'Session.type' - db.add_column( - "meetups_session", - "type", - self.gf("django.db.models.fields.related.ForeignKey")(to=orm["meetups.SessionType"], null=True, blank=True), - keep_default=False, - ) - - def backwards(self, orm): - # Deleting model 'SessionType' - db.delete_table("meetups_sessiontype") - - # Deleting field 'Session.type' - db.delete_column("meetups_session", "type_id") - - models = { - "auth.group": { - "Meta": {"object_name": "Group"}, - "id": ("django.db.models.fields.AutoField", [], {"primary_key": "True"}), - "name": ("django.db.models.fields.CharField", [], {"unique": "True", "max_length": "80"}), - "permissions": ( - "django.db.models.fields.related.ManyToManyField", - [], - {"to": "orm['auth.Permission']", "symmetrical": "False", "blank": "True"}, - ), - }, - "auth.permission": { - "Meta": { - "ordering": "(u'content_type__app_label', u'content_type__model', u'codename')", - "unique_together": "((u'content_type', u'codename'),)", - "object_name": "Permission", - }, - "codename": ("django.db.models.fields.CharField", [], {"max_length": "100"}), - "content_type": ( - "django.db.models.fields.related.ForeignKey", - [], - {"to": "orm['contenttypes.ContentType']"}, - ), - "id": ("django.db.models.fields.AutoField", [], {"primary_key": "True"}), - "name": ("django.db.models.fields.CharField", [], {"max_length": "50"}), - }, - "auth.user": { - "Meta": {"object_name": "User"}, - "date_joined": ("django.db.models.fields.DateTimeField", [], {"default": "datetime.datetime.now"}), - "email": ("django.db.models.fields.EmailField", [], {"max_length": "75", "blank": "True"}), - "first_name": ("django.db.models.fields.CharField", [], {"max_length": "30", "blank": "True"}), - "groups": ( - "django.db.models.fields.related.ManyToManyField", - [], - {"symmetrical": "False", "related_name": "u'user_set'", "blank": "True", "to": "orm['auth.Group']"}, - ), - "id": ("django.db.models.fields.AutoField", [], {"primary_key": "True"}), - "is_active": ("django.db.models.fields.BooleanField", [], {"default": "True"}), - "is_staff": ("django.db.models.fields.BooleanField", [], {"default": "False"}), - "is_superuser": ("django.db.models.fields.BooleanField", [], {"default": "False"}), - "last_login": ("django.db.models.fields.DateTimeField", [], {"default": "datetime.datetime.now"}), - "last_name": ("django.db.models.fields.CharField", [], {"max_length": "30", "blank": "True"}), - "password": ("django.db.models.fields.CharField", [], {"max_length": "128"}), - "user_permissions": ( - "django.db.models.fields.related.ManyToManyField", - [], - { - "symmetrical": "False", - "related_name": "u'user_set'", - "blank": "True", - "to": "orm['auth.Permission']", - }, - ), - "username": ("django.db.models.fields.CharField", [], {"unique": "True", "max_length": "30"}), - }, - "contenttypes.contenttype": { - "Meta": { - "ordering": "('name',)", - "unique_together": "(('app_label', 'model'),)", - "object_name": "ContentType", - "db_table": "'django_content_type'", - }, - "app_label": ("django.db.models.fields.CharField", [], {"max_length": "100"}), - "id": ("django.db.models.fields.AutoField", [], {"primary_key": "True"}), - "model": ("django.db.models.fields.CharField", [], {"max_length": "100"}), - "name": ("django.db.models.fields.CharField", [], {"max_length": "100"}), - }, - "meetups.location": { - "Meta": {"object_name": "Location"}, - "address": ( - "django.db.models.fields.CharField", - [], - {"max_length": "255", "null": "True", "blank": "True"}, - ), - "description": ("django.db.models.fields.TextField", [], {"null": "True", "blank": "True"}), - "id": ("django.db.models.fields.AutoField", [], {"primary_key": "True"}), - "name": ("django.db.models.fields.CharField", [], {"max_length": "200"}), - "website": ("django.db.models.fields.URLField", [], {"max_length": "200", "null": "True", "blank": "True"}), - }, - "meetups.meetup": { - "Meta": {"ordering": "('-start_date',)", "object_name": "Meetup"}, - "attendee_count": ("django.db.models.fields.IntegerField", [], {"null": "True", "blank": "True"}), - "gplus_id": ( - "django.db.models.fields.CharField", - [], - {"max_length": "50", "null": "True", "blank": "True"}, - ), - "id": ("django.db.models.fields.AutoField", [], {"primary_key": "True"}), - "location": ( - "django.db.models.fields.related.ForeignKey", - [], - {"to": "orm['meetups.Location']", "null": "True", "blank": "True"}, - ), - "meetupcom_id": ( - "django.db.models.fields.CharField", - [], - {"max_length": "20", "null": "True", "blank": "True"}, - ), - "notes": ("django.db.models.fields.TextField", [], {"null": "True", "blank": "True"}), - "start_date": ("django.db.models.fields.DateTimeField", [], {}), - }, - "meetups.rsvp": { - "Meta": {"object_name": "RSVP"}, - "gplus_name": ( - "django.db.models.fields.CharField", - [], - {"max_length": "100", "null": "True", "blank": "True"}, - ), - "gplus_uid": ( - "django.db.models.fields.CharField", - [], - {"max_length": "100", "null": "True", "blank": "True"}, - ), - "id": ("django.db.models.fields.AutoField", [], {"primary_key": "True"}), - "meetup": ( - "django.db.models.fields.related.ForeignKey", - [], - {"related_name": "'rsvps'", "to": "orm['meetups.Meetup']"}, - ), - "source": ("django.db.models.fields.CharField", [], {"max_length": "20", "null": "True", "blank": "True"}), - "status": ("django.db.models.fields.CharField", [], {"max_length": "20", "null": "True", "blank": "True"}), - }, - "meetups.session": { - "Meta": {"object_name": "Session"}, - "abstract": ("django.db.models.fields.TextField", [], {}), - "id": ("django.db.models.fields.AutoField", [], {"primary_key": "True"}), - "meetup": ( - "django.db.models.fields.related.ForeignKey", - [], - {"blank": "True", "related_name": "'sessions'", "null": "True", "to": "orm['meetups.Meetup']"}, - ), - "notes": ("django.db.models.fields.TextField", [], {"null": "True", "blank": "True"}), - "slides_url": ( - "django.db.models.fields.URLField", - [], - {"max_length": "200", "null": "True", "blank": "True"}, - ), - "speaker": ( - "django.db.models.fields.related.ForeignKey", - [], - {"to": "orm['auth.User']", "null": "True", "blank": "True"}, - ), - "speaker_email": ( - "django.db.models.fields.EmailField", - [], - {"max_length": "75", "null": "True", "blank": "True"}, - ), - "speaker_name": ( - "django.db.models.fields.CharField", - [], - {"max_length": "100", "null": "True", "blank": "True"}, - ), - "title": ("django.db.models.fields.CharField", [], {"max_length": "255"}), - "type": ( - "django.db.models.fields.related.ForeignKey", - [], - {"to": "orm['meetups.SessionType']", "null": "True", "blank": "True"}, - ), - }, - "meetups.sessiontype": { - "Meta": {"object_name": "SessionType"}, - "description": ("django.db.models.fields.TextField", [], {"null": "True", "blank": "True"}), - "id": ("django.db.models.fields.AutoField", [], {"primary_key": "True"}), - "name": ("django.db.models.fields.CharField", [], {"unique": "True", "max_length": "30"}), - }, - } - - complete_apps = ["meetups"] diff --git a/pygraz_website/apps/meetups/south_migrations/0010_auto__chg_field_session_type__add_field_meetup_description.py b/pygraz_website/apps/meetups/south_migrations/0010_auto__chg_field_session_type__add_field_meetup_description.py deleted file mode 100644 index 2e0c764..0000000 --- a/pygraz_website/apps/meetups/south_migrations/0010_auto__chg_field_session_type__add_field_meetup_description.py +++ /dev/null @@ -1,203 +0,0 @@ -from django.db import models -from south.db import db -from south.utils import datetime_utils as datetime -from south.v2 import SchemaMigration - - -class Migration(SchemaMigration): - def forwards(self, orm): - # Changing field 'Session.type' - db.alter_column( - "meetups_session", - "type_id", - self.gf("django.db.models.fields.related.ForeignKey")( - to=orm["meetups.SessionType"], null=True, on_delete=models.SET_NULL - ), - ) - # Adding field 'Meetup.description' - db.add_column( - "meetups_meetup", - "description", - self.gf("django.db.models.fields.TextField")(null=True, blank=True), - keep_default=False, - ) - - def backwards(self, orm): - # Changing field 'Session.type' - db.alter_column( - "meetups_session", - "type_id", - self.gf("django.db.models.fields.related.ForeignKey")(to=orm["meetups.SessionType"], null=True), - ) - # Deleting field 'Meetup.description' - db.delete_column("meetups_meetup", "description") - - models = { - "auth.group": { - "Meta": {"object_name": "Group"}, - "id": ("django.db.models.fields.AutoField", [], {"primary_key": "True"}), - "name": ("django.db.models.fields.CharField", [], {"unique": "True", "max_length": "80"}), - "permissions": ( - "django.db.models.fields.related.ManyToManyField", - [], - {"to": "orm['auth.Permission']", "symmetrical": "False", "blank": "True"}, - ), - }, - "auth.permission": { - "Meta": { - "ordering": "(u'content_type__app_label', u'content_type__model', u'codename')", - "unique_together": "((u'content_type', u'codename'),)", - "object_name": "Permission", - }, - "codename": ("django.db.models.fields.CharField", [], {"max_length": "100"}), - "content_type": ( - "django.db.models.fields.related.ForeignKey", - [], - {"to": "orm['contenttypes.ContentType']"}, - ), - "id": ("django.db.models.fields.AutoField", [], {"primary_key": "True"}), - "name": ("django.db.models.fields.CharField", [], {"max_length": "50"}), - }, - "auth.user": { - "Meta": {"object_name": "User"}, - "date_joined": ("django.db.models.fields.DateTimeField", [], {"default": "datetime.datetime.now"}), - "email": ("django.db.models.fields.EmailField", [], {"max_length": "75", "blank": "True"}), - "first_name": ("django.db.models.fields.CharField", [], {"max_length": "30", "blank": "True"}), - "groups": ( - "django.db.models.fields.related.ManyToManyField", - [], - {"symmetrical": "False", "related_name": "u'user_set'", "blank": "True", "to": "orm['auth.Group']"}, - ), - "id": ("django.db.models.fields.AutoField", [], {"primary_key": "True"}), - "is_active": ("django.db.models.fields.BooleanField", [], {"default": "True"}), - "is_staff": ("django.db.models.fields.BooleanField", [], {"default": "False"}), - "is_superuser": ("django.db.models.fields.BooleanField", [], {"default": "False"}), - "last_login": ("django.db.models.fields.DateTimeField", [], {"default": "datetime.datetime.now"}), - "last_name": ("django.db.models.fields.CharField", [], {"max_length": "30", "blank": "True"}), - "password": ("django.db.models.fields.CharField", [], {"max_length": "128"}), - "user_permissions": ( - "django.db.models.fields.related.ManyToManyField", - [], - { - "symmetrical": "False", - "related_name": "u'user_set'", - "blank": "True", - "to": "orm['auth.Permission']", - }, - ), - "username": ("django.db.models.fields.CharField", [], {"unique": "True", "max_length": "30"}), - }, - "contenttypes.contenttype": { - "Meta": { - "ordering": "('name',)", - "unique_together": "(('app_label', 'model'),)", - "object_name": "ContentType", - "db_table": "'django_content_type'", - }, - "app_label": ("django.db.models.fields.CharField", [], {"max_length": "100"}), - "id": ("django.db.models.fields.AutoField", [], {"primary_key": "True"}), - "model": ("django.db.models.fields.CharField", [], {"max_length": "100"}), - "name": ("django.db.models.fields.CharField", [], {"max_length": "100"}), - }, - "meetups.location": { - "Meta": {"object_name": "Location"}, - "address": ( - "django.db.models.fields.CharField", - [], - {"max_length": "255", "null": "True", "blank": "True"}, - ), - "description": ("django.db.models.fields.TextField", [], {"null": "True", "blank": "True"}), - "id": ("django.db.models.fields.AutoField", [], {"primary_key": "True"}), - "name": ("django.db.models.fields.CharField", [], {"max_length": "200"}), - "website": ("django.db.models.fields.URLField", [], {"max_length": "200", "null": "True", "blank": "True"}), - }, - "meetups.meetup": { - "Meta": {"ordering": "('-start_date',)", "object_name": "Meetup"}, - "attendee_count": ("django.db.models.fields.IntegerField", [], {"null": "True", "blank": "True"}), - "description": ("django.db.models.fields.TextField", [], {"null": "True", "blank": "True"}), - "gplus_id": ( - "django.db.models.fields.CharField", - [], - {"max_length": "50", "null": "True", "blank": "True"}, - ), - "id": ("django.db.models.fields.AutoField", [], {"primary_key": "True"}), - "location": ( - "django.db.models.fields.related.ForeignKey", - [], - {"to": "orm['meetups.Location']", "null": "True", "blank": "True"}, - ), - "meetupcom_id": ( - "django.db.models.fields.CharField", - [], - {"max_length": "20", "null": "True", "blank": "True"}, - ), - "notes": ("django.db.models.fields.TextField", [], {"null": "True", "blank": "True"}), - "start_date": ("django.db.models.fields.DateTimeField", [], {}), - }, - "meetups.rsvp": { - "Meta": {"object_name": "RSVP"}, - "gplus_name": ( - "django.db.models.fields.CharField", - [], - {"max_length": "100", "null": "True", "blank": "True"}, - ), - "gplus_uid": ( - "django.db.models.fields.CharField", - [], - {"max_length": "100", "null": "True", "blank": "True"}, - ), - "id": ("django.db.models.fields.AutoField", [], {"primary_key": "True"}), - "meetup": ( - "django.db.models.fields.related.ForeignKey", - [], - {"related_name": "'rsvps'", "to": "orm['meetups.Meetup']"}, - ), - "source": ("django.db.models.fields.CharField", [], {"max_length": "20", "null": "True", "blank": "True"}), - "status": ("django.db.models.fields.CharField", [], {"max_length": "20", "null": "True", "blank": "True"}), - }, - "meetups.session": { - "Meta": {"object_name": "Session"}, - "abstract": ("django.db.models.fields.TextField", [], {}), - "id": ("django.db.models.fields.AutoField", [], {"primary_key": "True"}), - "meetup": ( - "django.db.models.fields.related.ForeignKey", - [], - {"blank": "True", "related_name": "'sessions'", "null": "True", "to": "orm['meetups.Meetup']"}, - ), - "notes": ("django.db.models.fields.TextField", [], {"null": "True", "blank": "True"}), - "slides_url": ( - "django.db.models.fields.URLField", - [], - {"max_length": "200", "null": "True", "blank": "True"}, - ), - "speaker": ( - "django.db.models.fields.related.ForeignKey", - [], - {"to": "orm['auth.User']", "null": "True", "blank": "True"}, - ), - "speaker_email": ( - "django.db.models.fields.EmailField", - [], - {"max_length": "75", "null": "True", "blank": "True"}, - ), - "speaker_name": ( - "django.db.models.fields.CharField", - [], - {"max_length": "100", "null": "True", "blank": "True"}, - ), - "title": ("django.db.models.fields.CharField", [], {"max_length": "255"}), - "type": ( - "django.db.models.fields.related.ForeignKey", - [], - {"to": "orm['meetups.SessionType']", "null": "True", "on_delete": "models.SET_NULL", "blank": "True"}, - ), - }, - "meetups.sessiontype": { - "Meta": {"object_name": "SessionType"}, - "description": ("django.db.models.fields.TextField", [], {"null": "True", "blank": "True"}), - "id": ("django.db.models.fields.AutoField", [], {"primary_key": "True"}), - "name": ("django.db.models.fields.CharField", [], {"unique": "True", "max_length": "30"}), - }, - } - - complete_apps = ["meetups"] diff --git a/pygraz_website/apps/meetups/south_migrations/__init__.py b/pygraz_website/apps/meetups/south_migrations/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/pygraz_website/apps/meetups/templates/meetups/404.html b/pygraz_website/apps/meetups/templates/meetups/404.html deleted file mode 100644 index 457f282..0000000 --- a/pygraz_website/apps/meetups/templates/meetups/404.html +++ /dev/null @@ -1,5 +0,0 @@ -{% extends "base.html" %} -{% block body %} -

Seite nicht gefunden

-

Die gewünschte Seite konnte leider nicht gefunden werden.

-{% endblock %} diff --git a/pygraz_website/apps/meetups/templates/meetups/500.html b/pygraz_website/apps/meetups/templates/meetups/500.html deleted file mode 100644 index 7bd28b2..0000000 --- a/pygraz_website/apps/meetups/templates/meetups/500.html +++ /dev/null @@ -1,10 +0,0 @@ - - - Fehler - - -

Fehler

-

Es ist leider ein Fehler aufgetreten.

-

Startseite

- - diff --git a/pygraz_website/apps/meetups/templates/meetups/base.html b/pygraz_website/apps/meetups/templates/meetups/base.html deleted file mode 100644 index 8a4fa10..0000000 --- a/pygraz_website/apps/meetups/templates/meetups/base.html +++ /dev/null @@ -1,2 +0,0 @@ -{% extends "base.html" %} -{% block nav-meetups %}active{% endblock %} diff --git a/pygraz_website/apps/meetups/templates/meetups/base_original.html b/pygraz_website/apps/meetups/templates/meetups/base_original.html deleted file mode 100644 index d4bde0d..0000000 --- a/pygraz_website/apps/meetups/templates/meetups/base_original.html +++ /dev/null @@ -1,63 +0,0 @@ - - - - {% block title %}{% endblock %}PyGRAZ - - - - - -Menü - -
-
- -

PyGRAZ ist eine Usergroup mit die Python-Programmiersprache in Graz. Wir treffen uns regelmässig am ersten Dienstag im Monat entweder - im realraum oder im Gösserbräu.

-
-
- {% if messages %} - {% for msg in messages %} -
- × - {{ msg.message }} -
- {% endfor %} - {% endif %} - {% block body %} - {% endblock %} -
-
-
- © 2010-{% now "Y" %}, PyGRAZ -
Powered by Django -
Hosted by DigitalOcean (Referal link) -
-
-
- -{% block tail %}{% endblock %} - - diff --git a/pygraz_website/apps/meetups/templates/meetups/emails/new_session.txt b/pygraz_website/apps/meetups/templates/meetups/emails/new_session.txt deleted file mode 100644 index 1b3ddd7..0000000 --- a/pygraz_website/apps/meetups/templates/meetups/emails/new_session.txt +++ /dev/null @@ -1,6 +0,0 @@ -Es wurde eine neue Session eingetragen: - -Title: {{ session.title }} -Vortragender: {% if session.speaker %}{{ session.speaker }}{% else %}{{ session.speaker_name }}{% endif %} - -{{ session_url }} diff --git a/pygraz_website/apps/meetups/templates/meetups/index.html b/pygraz_website/apps/meetups/templates/meetups/index.html deleted file mode 100644 index b36f4ce..0000000 --- a/pygraz_website/apps/meetups/templates/meetups/index.html +++ /dev/null @@ -1,58 +0,0 @@ -{% extends "base.html" %} -{% load crispy_forms_tags %} -{% block page_class %}frontpage{% endblock %} -{% block nav-start %}active{% endblock %} -{% block body %} -
- {% if next_meetup %} -

Nächstes Treffen am {{ next_meetup.start_date|date:"DATE_FORMAT" }} um {{ next_meetup.start_date|time:"TIME_FORMAT" }} Uhr

- {% with next_meetup as meetup %} - {% include "meetups/meetup-data.html" %} - {% endwith %} - {% else %} -

Derzeit gibt es leider noch keine Informationen zum nächsten Treffen.

- {% endif %} -
-
-

Session-Ideen

- {% if session_proposals %} - - - - - - - - - {% for proposal in session_proposals %} - - - - {% endfor %} - -
TitelVortragender
{{ proposal.title }} - {% if proposal.speaker %} - {{ proposal.get_speaker_name }} - {% else %} - {{ proposal.get_speaker_name }} - {% endif %} -
- {% endif %} -
-

Deine Session-Idee

-

Möchtest du etwas präsentieren? Dann trage deinen Vorschlag hier ein. Wenn es dann wieder auf ein neues Meetup zugeht, werden wir dich - via E-Mail kontaktieren, um einen Termin auszumachen.

- {% crispy submission_form %} -
-
- {% if past_meetups %} -
-

Vergangene Meetups

- -
- {% endif %} -{% endblock %} diff --git a/pygraz_website/apps/meetups/templates/meetups/meetup-data.html b/pygraz_website/apps/meetups/templates/meetups/meetup-data.html deleted file mode 100644 index 4c00887..0000000 --- a/pygraz_website/apps/meetups/templates/meetups/meetup-data.html +++ /dev/null @@ -1,85 +0,0 @@ -{% load markdown_tags %} -
-
- {% if meetup.description %} -
{{ meetup.description|markdown }}
- {% endif %} -
-

{% if meetup.is_in_future %}Geplante {% endif %}Sessions

- {% with meetup.sessions.all as sessions %} - {% if sessions %} - {% for session in sessions %} -
-

{{ session.title }}

- {% if session.speaker_name or session.speaker %} -

von {% if session.speaker %}{{ session.get_speaker_name }}{% else %}{{ session.speaker_name }}{% endif %}

- {% endif %} - {% if session.abstract %} -
{{ session.abstract|markdown }}
- {% endif %} - {% if session.slides_url %} -

Folien

- {% endif %} -
- {% endfor %} - {% else %} - {% if meetup.is_in_future %} -

Derzeit sind noch keine Sessions für dieses Meetup fix geplant. Falls du einen Session-Vorschlag eingereicht hast, bitte lass - uns wissen, falls du die Session bei diesem Meetup halten möchtest.

- {% else %} -

Keine Sessions für dieses Meetup eingetragen.

- {% endif %} - {% endif %} - {% endwith %} -
- {% if show_notes and meetup.notes %} -
-

Notizen, Links, etc.

- {{ meetup.notes|markdown }} -
- {% endif %} - {% if show_rsvps %} - {% if rsvps.coming %} -
-

Folgende Personen haben ihr Kommen angekündigt:

-
    - {% for rsvp in rsvps.coming %} -
  • {{ rsvp.name }} {% if rsvp.source == 'meetupcom' %}(via Meetup.com){% endif %}
  • - {% endfor %} -
-

Diese Liste enthält derzeit nur Anmeldungen auf Meetup.com.

-
- {% endif %} - {% if meetup.gplus_id %} -
- Event auf Google+ -

Dieses Treffen wurde auch auf Google+ - angekündigt. Wenn Du teilnehmen möchtest, trage dich bitte dort ein.

-
- {% endif %} - {% endif %} -
- {% if meetup.meetupcom_id and meetup.is_in_future %} -
-

Falls du vorhast, zu kommen, bitte trage dich auf Meetup.com ein! Es ist nicht zwingend erforderlich, macht aber unsere Arbeit leichter, wenn wir abschätzen können, wie viele Leute in etwa kommen.

-
- {% endif %} -
- {% if meetup.location %} -

Location: {{ meetup.location.name }}

- {% if meetup.location.address %} -

{{ meetup.location.address }}

- {% endif %} - {% if meetup.location.map_image %} - Birdview image to location {{ meetup.location.name }} - {% endif %} -
{{ meetup.location.description }}
- {% else %} - {% if meetup.is_in_future %} -

Die Location steht zum jetzigen Zeitpunkt leider noch nicht fest.

- {% else %} -

Keine Location für dieses Meetup eingetragen.

- {% endif %} - {% endif %} -
-
diff --git a/pygraz_website/apps/meetups/templates/meetups/meetup_detail.html b/pygraz_website/apps/meetups/templates/meetups/meetup_detail.html deleted file mode 100644 index 09eb425..0000000 --- a/pygraz_website/apps/meetups/templates/meetups/meetup_detail.html +++ /dev/null @@ -1,22 +0,0 @@ -{% extends "meetups/base.html" %} -{% block page_class %}meetup-details{% endblock%} -{% block title %}{{ meetup.start_date|date:"DATE_FORMAT" }} « Meetups « {% endblock %} -{% block body %} -

Meetup vom {{ meetup.start_date.date|date:"DATE_FORMAT" }} um {{ meetup.start_date|time:"TIME_FORMAT" }} Uhr

- {% include "meetups/meetup-data.html" with show_notes="True" show_rsvps="True" %} -
- - - Comments powered by Disqus -{% endblock body %} diff --git a/pygraz_website/apps/meetups/templates/meetups/session_confirm_delete.html b/pygraz_website/apps/meetups/templates/meetups/session_confirm_delete.html deleted file mode 100644 index 8fc73ae..0000000 --- a/pygraz_website/apps/meetups/templates/meetups/session_confirm_delete.html +++ /dev/null @@ -1,9 +0,0 @@ -{% extends "meetups/base.html" %} -{% block body %} -
- {% csrf_token %} -

Bist du sicher, dass du diese Session löschen möchtest?

- - Abbrechen -
-{% endblock body %} diff --git a/pygraz_website/apps/meetups/templates/meetups/session_detail.html b/pygraz_website/apps/meetups/templates/meetups/session_detail.html deleted file mode 100644 index 073f4ec..0000000 --- a/pygraz_website/apps/meetups/templates/meetups/session_detail.html +++ /dev/null @@ -1,50 +0,0 @@ -{% extends "meetups/base.html" %} -{% load markdown_tags %} -{% block page_class %}session-details{% endblock %} -{% block title %}{% if session.meetup %}Session{% else %}Session-Vorschlag{% endif %}: {{ session.title }} « {% endblock %} -{% block body %} -
-

{% if session.meetup %}Session{% else %}Session-Vorschlag{% endif %}: {{ session.title }}

-

von {{ session.get_speaker_name }}

-
    - {% if can_edit %} -
  • Editieren
  • - {% endif %} - {% if can_delete %} -
  • Löschen
  • - {% endif %} -
- {% if not session.meetup %} -

Das ist bisher nur ein Session-Vorschlag.

- {% else %} -

Diese Session {% if session.meetup.is_in_future %}wird{% else %}wurde{% endif %} am {{ session.meetup.start_date|date:"DATE_FORMAT" }} gehalten.

- {% endif %} - {% if session.slides_url %} -

Folien

- {% endif %} -
{{ session.abstract|markdown }}
- {% if session.notes %} -
-

Notizen

- {{ session.notes|markdown }} -
- {% endif %} - - -
- - - Comments powered by Disqus -
-{% endblock body %} diff --git a/pygraz_website/apps/meetups/templates/meetups/session_form.html b/pygraz_website/apps/meetups/templates/meetups/session_form.html deleted file mode 100644 index 1b4276b..0000000 --- a/pygraz_website/apps/meetups/templates/meetups/session_form.html +++ /dev/null @@ -1,7 +0,0 @@ -{% extends "meetups/base.html" %} -{% load crispy_forms_tags %} -{% block page_class %}fullpage-form{% endblock page_class %} -{% block body %} -

Lege einen Session-Vorschlag an

- {% crispy form %} -{% endblock body %} diff --git a/pygraz_website/apps/meetups/templates/userena/base_userena.html b/pygraz_website/apps/meetups/templates/userena/base_userena.html deleted file mode 100644 index c97d521..0000000 --- a/pygraz_website/apps/meetups/templates/userena/base_userena.html +++ /dev/null @@ -1,4 +0,0 @@ -{% extends "base.html" %} -{% block body %} - {% block content %}{% endblock %} -{% endblock body %} diff --git a/pygraz_website/apps/meetups/templates/userena/email_form.html b/pygraz_website/apps/meetups/templates/userena/email_form.html deleted file mode 100644 index f1ac727..0000000 --- a/pygraz_website/apps/meetups/templates/userena/email_form.html +++ /dev/null @@ -1,9 +0,0 @@ -{% extends "userena/base_userena.html" %} -{% load crispy_forms_tags %} -{% block page_class %}fullpage-form{% endblock %} -{% block title %}E-Mail ändern « {% endblock %} -{% block content %} -

E-Mail ändern

-

Deine aktuelle E-Mail-Adresse lautet {{ user.email }}.

- {% crispy form %} -{% endblock content %} diff --git a/pygraz_website/apps/meetups/templates/userena/emails/activation_email_message.txt b/pygraz_website/apps/meetups/templates/userena/emails/activation_email_message.txt deleted file mode 100644 index 435af20..0000000 --- a/pygraz_website/apps/meetups/templates/userena/emails/activation_email_message.txt +++ /dev/null @@ -1,11 +0,0 @@ -{% load i18n %}{% autoescape off %} -{% if not without_usernames %}{% blocktrans with user.username as username %}Hallo {{ username }},{% endblocktrans %} -{% endif %} -{% blocktrans with site.name as site %}Danke, dass du dich auf {{ site }} angemeldet hast.{% endblocktrans %} - -{% trans "Um deinen Account zu aktivieren, klicke bitte untenstehenden Link:" %} - -{{ protocol }}://{{ site.domain }}{% url "userena_activate" activation_key %} - -{% trans "Vielen Dank!" %} -{% endautoescape %} diff --git a/pygraz_website/apps/meetups/templates/userena/emails/activation_email_subject.txt b/pygraz_website/apps/meetups/templates/userena/emails/activation_email_subject.txt deleted file mode 100644 index cc7c4f6..0000000 --- a/pygraz_website/apps/meetups/templates/userena/emails/activation_email_subject.txt +++ /dev/null @@ -1,2 +0,0 @@ -{% load i18n %} -{% blocktrans with site.name as site %}Deine Anmeldung bei {{ site }}.{% endblocktrans %} diff --git a/pygraz_website/apps/meetups/templates/userena/emails/confirmation_email_message_new.txt b/pygraz_website/apps/meetups/templates/userena/emails/confirmation_email_message_new.txt deleted file mode 100644 index e325683..0000000 --- a/pygraz_website/apps/meetups/templates/userena/emails/confirmation_email_message_new.txt +++ /dev/null @@ -1,10 +0,0 @@ -{% load i18n %}{% autoescape off %} -{% if not without_usernames %}{% blocktrans with user.username as username %}Hallo {{ username }},{% endblocktrans %} -{% endif %} -{% blocktrans with site.name as site %}Du möchtest deine E-Mail-Adresse auf {{ site }} ändern?{% endblocktrans %} - - -{% trans "Klicke bitte untenstehenden Link, um deine neue E-Mail-Adresse zu bestätigen:" %} - -{{ protocol }}://{{ site.domain }}{% url "userena_email_confirm" confirmation_key %} -{% endautoescape %} diff --git a/pygraz_website/apps/meetups/templates/userena/emails/confirmation_email_message_old.txt b/pygraz_website/apps/meetups/templates/userena/emails/confirmation_email_message_old.txt deleted file mode 100644 index caa1812..0000000 --- a/pygraz_website/apps/meetups/templates/userena/emails/confirmation_email_message_old.txt +++ /dev/null @@ -1,7 +0,0 @@ -{% load i18n %}{% autoescape off %} -{% if not without_usernames %}{% blocktrans with user.username as username %}Hallo {{ username }},{% endblocktrans %} -{% endif %} -{% blocktrans with site.name as site %}Du möchtest deine E-Mail-Adresse auf {{ site }} ändern?{% endblocktrans %} - -{% blocktrans %}Eine E-Mail mit einem Bestätigungslink wurden an {{ new_email }} gesandt. Bitte klicke den Link in dieser E-Mail, um deine neue E-Mail-Adresse zu aktivieren.{% endblocktrans %} -{% endautoescape %} diff --git a/pygraz_website/apps/meetups/templates/userena/emails/confirmation_email_subject_new.txt b/pygraz_website/apps/meetups/templates/userena/emails/confirmation_email_subject_new.txt deleted file mode 100644 index ea05448..0000000 --- a/pygraz_website/apps/meetups/templates/userena/emails/confirmation_email_subject_new.txt +++ /dev/null @@ -1,2 +0,0 @@ -{% load i18n %} -{% blocktrans with site.name as site %}E-Mail-Verifikation für {{ site }}.{% endblocktrans %} diff --git a/pygraz_website/apps/meetups/templates/userena/emails/confirmation_email_subject_old.txt b/pygraz_website/apps/meetups/templates/userena/emails/confirmation_email_subject_old.txt deleted file mode 100644 index e20fc91..0000000 --- a/pygraz_website/apps/meetups/templates/userena/emails/confirmation_email_subject_old.txt +++ /dev/null @@ -1,2 +0,0 @@ -{% load i18n %} -{% blocktrans with site.name as site %}Möchtest du deine E-Mail-Adresse auf {{ site }} ändern?{% endblocktrans %} diff --git a/pygraz_website/apps/meetups/templates/userena/emails/password_reset_message.txt b/pygraz_website/apps/meetups/templates/userena/emails/password_reset_message.txt deleted file mode 100644 index 7a128f5..0000000 --- a/pygraz_website/apps/meetups/templates/userena/emails/password_reset_message.txt +++ /dev/null @@ -1,13 +0,0 @@ -{% load i18n %}{% autoescape off %} -{% blocktrans %}Du hast diese E-Mail bekommen, weil du den "Passwort ändern"-Prozess auf {{ site_name }} angestoßen hast.{% endblocktrans %}. - -{% trans "Bitte gehe auf folgende Seite und trage ein neues Passwort ein:" %} -{% block reset_link %} -{{ protocol }}://{{ domain }}{% url 'userena_password_reset_confirm' uid token %} -{% endblock %} - -{% if not without_usernames %}{% blocktrans with user.username as username %} -Dein Benutzername: {{ username }} -{% endblocktrans %} -{% endif %} -{% endautoescape %} diff --git a/pygraz_website/apps/meetups/templates/userena/password_form.html b/pygraz_website/apps/meetups/templates/userena/password_form.html deleted file mode 100644 index 9beebff..0000000 --- a/pygraz_website/apps/meetups/templates/userena/password_form.html +++ /dev/null @@ -1,8 +0,0 @@ -{% extends "userena/base_userena.html" %} -{% load crispy_forms_tags %} -{% block page_class %}fullpage-form{% endblock %} -{% block title %}Passwort ändern « {% endblock %} -{% block content %} -

Passwort ändern

- {% crispy form %} -{% endblock content %} diff --git a/pygraz_website/apps/meetups/templates/userena/password_reset_confirm_form.html b/pygraz_website/apps/meetups/templates/userena/password_reset_confirm_form.html deleted file mode 100644 index 29eb7b4..0000000 --- a/pygraz_website/apps/meetups/templates/userena/password_reset_confirm_form.html +++ /dev/null @@ -1,8 +0,0 @@ -{% extends 'userena/base_userena.html' %} -{% load i18n crispy_forms_tags %} -{% block page_class %}fullpage-form{% endblock %} -{% block title %}{% trans "Reset password" %}{% endblock %} -{% block content %} -

Passwort zurücksetzen

- {% crispy form %} -{% endblock %} diff --git a/pygraz_website/apps/meetups/templates/userena/password_reset_form.html b/pygraz_website/apps/meetups/templates/userena/password_reset_form.html deleted file mode 100644 index 29eb7b4..0000000 --- a/pygraz_website/apps/meetups/templates/userena/password_reset_form.html +++ /dev/null @@ -1,8 +0,0 @@ -{% extends 'userena/base_userena.html' %} -{% load i18n crispy_forms_tags %} -{% block page_class %}fullpage-form{% endblock %} -{% block title %}{% trans "Reset password" %}{% endblock %} -{% block content %} -

Passwort zurücksetzen

- {% crispy form %} -{% endblock %} diff --git a/pygraz_website/apps/meetups/templates/userena/profile_form.html b/pygraz_website/apps/meetups/templates/userena/profile_form.html deleted file mode 100644 index 61e471b..0000000 --- a/pygraz_website/apps/meetups/templates/userena/profile_form.html +++ /dev/null @@ -1,7 +0,0 @@ -{% extends "userena/base_userena.html" %} -{% load crispy_forms_tags %} -{% block page_class %}fullpage-form{% endblock %} -{% block content %} -

Profil ändern

- {% crispy form %} -{% endblock content %} diff --git a/pygraz_website/apps/meetups/templates/userena/signin_form.html b/pygraz_website/apps/meetups/templates/userena/signin_form.html deleted file mode 100644 index 6e83e94..0000000 --- a/pygraz_website/apps/meetups/templates/userena/signin_form.html +++ /dev/null @@ -1,9 +0,0 @@ -{% extends "userena/base_userena.html" %} -{% load crispy_forms_tags %} -{% block page_class %}fullpage-form{% endblock %} -{% block title %}Anmelden « {% endblock %} -{% block content %} -

Anmelden

- {% crispy form %} -

Passwort vergessen?

-{% endblock %} diff --git a/pygraz_website/apps/meetups/templates/userena/signup_form.html b/pygraz_website/apps/meetups/templates/userena/signup_form.html deleted file mode 100644 index e3eee49..0000000 --- a/pygraz_website/apps/meetups/templates/userena/signup_form.html +++ /dev/null @@ -1,11 +0,0 @@ -{% extends "userena/base_userena.html" %} -{% load crispy_forms_tags %} -{% block page_class %}fullpage-form{% endblock %} -{% block title %}Registrieren « {% endblock %} -{% block content %} -

Registrieren

-

Derzeit bringt Registrieren vor allem eines: Du kannst Session-Proposals und Sessions, die du selbst angelegt bzw. gehalten hast, auch wieder - editieren, falls dir mehr zu dem Thema eingefallen ist.

-

Wir lassen uns aber noch ein paar Goodies einfallen :-)

- {% crispy form %} -{% endblock content %} diff --git a/pygraz_website/apps/meetups/tests/__init__.py b/pygraz_website/apps/meetups/tests/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/pygraz_website/apps/meetups/tests/test_calendar.py b/pygraz_website/apps/meetups/tests/test_calendar.py deleted file mode 100644 index 59ce2a4..0000000 --- a/pygraz_website/apps/meetups/tests/test_calendar.py +++ /dev/null @@ -1,31 +0,0 @@ -import arrow -from django.test import TestCase - -from .. import models - - -class MeetupCalendarViewTests(TestCase): - def setUp(self): - start = arrow.utcnow().replace(month=1, day=2, hour=18) - self.meetup = models.Meetup(start_date=start.datetime, meetupcom_id="test") - self.meetup.save() - - def test_simple_calendar(self): - resp = self.client.get("/meetups/ical/") - self.assertEqual(200, resp.status_code) - self.assertEqual("text/calendar", resp["Content-Type"]) - date = arrow.get(self.meetup.start_date).format("YYYY-MM-DD") - timestamp = arrow.get(self.meetup.start_date).format("YYYYMMDDTHHmmss") + "Z" - expected_content = ( - f"BEGIN:VCALENDAR\r\n" - f"X-WR-CALNAME:PyGRAZ-Meetups\r\n" - f"BEGIN:VEVENT\r\n" - f"SUMMARY:PyGRAZ-Meetup am {date}\r\n" - f"DTSTART:{timestamp}\r\n" - f"UID:example.com/meetups/1\r\n" - f"DESCRIPTION:Details: https://example.com/meetups/{date}/\r\n" - f"END:VEVENT\r\n" - f"END:VCALENDAR\r\n" - ).encode() - actual_content = resp.content - self.assertEqual(expected_content, actual_content) diff --git a/pygraz_website/apps/meetups/tests/test_commands.py b/pygraz_website/apps/meetups/tests/test_commands.py deleted file mode 100644 index 9d2eb18..0000000 --- a/pygraz_website/apps/meetups/tests/test_commands.py +++ /dev/null @@ -1,64 +0,0 @@ -import re - -import arrow -import requests_mock -from django.core.management import call_command -from django.test import TestCase -from django.utils import timezone - -from .. import models - - -class FetchRsvpsCommandTests(TestCase): - def setUp(self): - future_year = timezone.now().year + 2 - start = arrow.utcnow().replace(year=future_year, month=1, day=2, hour=18) - self.meetup = models.Meetup(start_date=start.datetime, meetupcom_id="test") - self.meetup.save() - models.Meetup(start_date=start.replace(year=future_year, month=2).datetime).save() - self.previous_rsvp = models.RSVP( - meetup=self.meetup, status="coming", remote_username="test", remote_uid="test", source="meetupcom" - ) - self.previous_rsvp.save() - - def test_failure_should_keep_rsvps(self): - with requests_mock.Mocker() as mock: - mock.get(re.compile("api.meetup.com/2/rsvp"), text="invalid_response") - with self.assertRaises(Exception): - call_command("fetch_rsvps") - existing_rsvps = models.RSVP.objects.filter(meetup=self.meetup).all() - self.assertEqual(len(list(existing_rsvps)), 1) - - def test_success(self): - with requests_mock.Mocker() as mock: - mock.get( - re.compile("api.meetup.com/2/rsvp"), - [ - { - "json": { - "meta": {"count": 1, "total_count": 2}, - "results": [{"response": "no", "member": {"name": "new user", "member_id": "12345"}}], - } - }, - { - "json": { - "meta": {"count": 1, "total_count": 2}, - "results": [{"response": "yes", "member": {"name": "new user 2", "member_id": "12346"}}], - } - }, - ], - ) - call_command("fetch_rsvps") - rsvps = list(models.RSVP.objects.filter(meetup=self.meetup).all()) - self.assertEqual(2, len(rsvps)) - - rsvp = rsvps[0] - self.assertEqual("not_coming", rsvp.status) - self.assertEqual("new user", rsvp.remote_username) - self.assertEqual("12345", rsvp.remote_uid) - self.assertEqual("meetupcom", rsvp.source) - rsvp = rsvps[1] - self.assertEqual("coming", rsvp.status) - self.assertEqual("new user 2", rsvp.remote_username) - self.assertEqual("12346", rsvp.remote_uid) - self.assertEqual("meetupcom", rsvp.source) diff --git a/pygraz_website/apps/meetups/tests/test_models.py b/pygraz_website/apps/meetups/tests/test_models.py deleted file mode 100644 index f237b43..0000000 --- a/pygraz_website/apps/meetups/tests/test_models.py +++ /dev/null @@ -1,108 +0,0 @@ -import datetime -import unittest - -import pytz -from django.core.exceptions import ValidationError -from django.test import TestCase -from django.utils import timezone - -from .. import models - - -class MeetupModelTests(TestCase): - def test_required_fields(self): - """ - Tests that only the start_date is required. - """ - with self.assertRaises(ValidationError): - models.Meetup().full_clean() - models.Meetup(start_date=datetime.datetime.now().replace(tzinfo=pytz.UTC)).full_clean() - - def test_is_in_future(self): - """ - Is_in_future should return true if the start_date of the meetup is in - the future. - """ - now = timezone.now() - future_meetup = models.Meetup(start_date=now + datetime.timedelta(days=2)) - past_meetup = models.Meetup(start_date=now - datetime.timedelta(days=2)) - now_meetup = models.Meetup(start_date=now) - self.assertTrue(future_meetup.is_in_future(now=now)) - self.assertFalse(past_meetup.is_in_future(now=now)) - self.assertFalse(now_meetup.is_in_future(now=now)) - - def test_future_meetups_through_manager(self): - """ - Tests that the manager returns future meetups as requested. - """ - now = timezone.now() - past_meetup = models.Meetup(start_date=now - datetime.timedelta(days=1)).save() - now_meetup = models.Meetup(start_date=now).save() - future_meetup_1 = models.Meetup(start_date=now + datetime.timedelta(days=1)) - future_meetup_1.save() - future_meetup_2 = models.Meetup(start_date=now + datetime.timedelta(days=2)) - future_meetup_2.save() - found_meetups = list(models.Meetup.objects.get_future_meetups(now=now)) - self.assertEqual([future_meetup_2, future_meetup_1], found_meetups) - for m in found_meetups: - self.assertTrue(m.is_in_future(now)) - - def test_past_meetups_through_manager(self): - """ - Tests that the manager returns future meetups as requested. - """ - now = timezone.now() - past_meetup = models.Meetup(start_date=now - datetime.timedelta(days=1)).save() - now_meetup = models.Meetup(start_date=now).save() - future_meetup_1 = models.Meetup(start_date=now + datetime.timedelta(days=1)).save() - future_meetup_2 = models.Meetup(start_date=now + datetime.timedelta(days=2)).save() - for m in models.Meetup.objects.get_past_meetups(now=now): - self.assertFalse(m.is_in_future(now)) - - def test_set_attendee_count(self): - """ - It should be possible to set a number of attendees of a meetup outside - of who responded to the RSVP. - """ - models.Meetup(start_date=timezone.now(), attendee_count=10).full_clean() - m = models.Meetup(start_date=timezone.now()) - m.attendee_count = 10 - - def test_valid_attendee_count(self): - """ - A valid number of attendees is a positive integer, 0 or None - """ - t = timezone.now() - meetup = models.Meetup(start_date=t) - meetup.full_clean() - meetup.attendee_count = None - meetup.full_clean() - meetup.attendee_count = 1 - meetup.full_clean() - meetup.attendee_count = 10 - meetup.full_clean() - meetup.attendee_count = 0 - meetup.full_clean() - with self.assertRaises(ValidationError): - meetup.attendee_count = -1 - meetup.full_clean() - - -class LocationModelTests(unittest.TestCase): - def test_required_fields(self): - """ - Only the name of the location is required. - """ - with self.assertRaises(ValidationError): - models.Location().full_clean() - models.Location(name="Name").full_clean() - - -class SessionModelTests(unittest.TestCase): - def test_required_fields(self): - """ - Title and abstract are required. - """ - with self.assertRaises(ValidationError): - models.Session().full_clean() - models.Session(title="title", abstract="abstract").full_clean() diff --git a/pygraz_website/apps/meetups/tests/test_views.py b/pygraz_website/apps/meetups/tests/test_views.py deleted file mode 100644 index 2c26f1f..0000000 --- a/pygraz_website/apps/meetups/tests/test_views.py +++ /dev/null @@ -1,169 +0,0 @@ -from http import HTTPStatus - -import arrow -from django.contrib.auth.models import User -from django.http import Http404, HttpResponseNotFound -from django.test import TestCase -from django.utils import timezone - -from .. import models - - -class MeetupViewTests(TestCase): - def setUp(self): - self.now = timezone.now() - self.past_meetup = models.Meetup(start_date=self.now - timezone.timedelta(days=2)) - self.past_meetup.save() - rsvp = models.RSVP( - meetup=self.past_meetup, - remote_username="remote_user", - remote_uid="remote_uid", - source="meetupcom", - status="coming", - ) - rsvp.save() - self.future_meetup = models.Meetup(start_date=self.now + timezone.timedelta(days=2)) - self.future_meetup.save() - - def tearDown(self): - self.future_meetup.delete() - self.past_meetup.delete() - - def test_view_not_existing(self): - """ - Tests that a request for a not-existing meetup results in a 404 page. - """ - self.assertEqual(self.client.get("/meetups/123/").status_code, HTTPStatus.NOT_FOUND) - self.assertEqual(self.client.get("/meetups/2015-05-01/").status_code, HTTPStatus.NOT_FOUND) - - def test_view_existing(self): - """ - Tests that a meetup can be accessed by its URL. - """ - resp = self.client.get(f"/meetups/{self.past_meetup.pk}/") - self.assertEqual(200, resp.status_code) - self.assertEqual(1, len(resp.context["rsvps"].coming)) - - def test_view_existing_via_date(self): - """ - The primary URL of a meetup is one containing its date for better SEO. - """ - date = arrow.get(self.past_meetup.start_date).format("YYYY-MM-DD") - response = self.client.get(f"/meetups/{date}/") - self.assertEqual(200, response.status_code) - - def test_upcoming_on_frontpage(self): - """ - Tests that the next meetup is displayed on the frontpage. - """ - resp = self.client.get("/") - self.assertEqual(200, resp.status_code) - self.assertEqual(self.future_meetup, resp.context["next_meetup"]) - - -class SessionViewTests(TestCase): - def setUp(self): - self.user = User.objects.create_user(username="username", password="password", email="test@test.com") - self.session = models.Session(title="Some session", abstract="abstract", speaker=self.user) - self.session.save() - - def test_anonymous_view(self): - resp = self.client.get(f"/meetups/sessions/{self.session.pk}/") - self.assertEqual(resp.status_code, HTTPStatus.OK) - self.assertFalse(resp.context["can_edit"]) - self.assertFalse(resp.context["can_delete"]) - - def test_author_view(self): - self.client.login(username="username", password="password") - resp = self.client.get(f"/meetups/sessions/{self.session.pk}/") - self.assertEqual(resp.status_code, HTTPStatus.OK) - self.assertTrue(resp.context["can_edit"]) - self.assertTrue(resp.context["can_delete"]) - - -class DeleteSessionViewTests(TestCase): - def setUp(self): - self.user = User.objects.create_user(username="username", password="password", email="test@test.com") - self.other_user = User.objects.create_user( - username="other_username", password="password", email="other@test.com" - ) - self.session = models.Session(title="Some session", abstract="abstract", speaker=self.user) - self.session.save() - - def test_anonymous_view(self): - url = f"/meetups/sessions/{self.session.pk}/delete/" - resp = self.client.get(url) - self.assertRedirects(resp, f"/accounts/signin/?next={url}") - - def test_otheruser_view(self): - self.client.login(username="other_username", password="password") - url = f"/meetups/sessions/{self.session.pk}/delete/" - resp = self.client.get(url) - self.assertEqual(403, resp.status_code) - - def test_author_view(self): - self.client.login(username="username", password="password") - url = f"/meetups/sessions/{self.session.pk}/delete/" - resp = self.client.get(url) - self.assertEqual(200, resp.status_code) - - resp = self.client.post(url) - self.assertEqual(302, resp.status_code) - self.assertEqual(0, models.Session.objects.count()) - - -class SubmitSessionViewTests(TestCase): - def setUp(self): - self.user = User.objects.create_user(username="username", password="password", email="test@test.com") - self.talk_type = models.SessionType(name="Talk") - self.talk_type.save() - - def test_loggedin_view(self): - url = "/meetups/sessions/submit/?next=/" - self.client.login(username="username", password="password") - resp = self.client.get(url) - self.assertEqual(200, resp.status_code) - - resp = self.client.post( - url, - { - "title": "title", - "abstract": "abstract", - "type": self.talk_type.pk, - }, - ) - self.assertRedirects(resp, "/") - sessions = list(models.Session.objects.all()) - self.assertEqual(1, len(sessions)) - self.assertEqual("title", sessions[0].title) - self.assertEqual("abstract", sessions[0].abstract) - self.assertEqual(self.user, sessions[0].speaker) - - -class EditSessionViewTests(TestCase): - def setUp(self): - self.user = User.objects.create_user(username="username", password="password", email="test@test.com") - self.other_user = User.objects.create_user( - username="other_username", password="password", email="other@test.com" - ) - self.talk_type = models.SessionType(name="Talk") - self.talk_type.save() - self.session = models.Session(title="Some session", abstract="abstract", speaker=self.user, type=self.talk_type) - self.session.save() - - def test_anonymous_view(self): - url = "/meetups/sessions/1/edit/" - resp = self.client.get(url) - self.assertRedirects(resp, f"/accounts/signin/?next={url}") - - def test_author_view(self): - self.client.login(username="username", password="password") - url = "/meetups/sessions/1/edit/" - resp = self.client.get(url) - self.assertEqual(200, resp.status_code) - - resp = self.client.post(url, {"title": "New title", "abstract": "New abstract", "type": self.talk_type.pk}) - self.assertEqual(302, resp.status_code) - session = models.Session.objects.get(pk=self.session.pk) - self.assertEqual(session.title, "New title") - self.assertEqual(session.abstract, "New abstract") diff --git a/pygraz_website/apps/meetups/urls.py b/pygraz_website/apps/meetups/urls.py deleted file mode 100644 index 30dcbdf..0000000 --- a/pygraz_website/apps/meetups/urls.py +++ /dev/null @@ -1,26 +0,0 @@ -from django.contrib.auth.decorators import login_required -from django.urls import path - -from . import views - -urlpatterns = [ - path( - "--/", - views.DetailView.as_view(), - name="view-meetup", - ), - path("/", views.DetailView.as_view(), name="meetup-permalink"), - path("sessions/submit/", views.SubmitSession.as_view(), name="submit-session"), - path("sessions//", views.ViewSession.as_view(), name="view-session"), - path( - "sessions//edit/", - login_required(views.EditSession.as_view()), - name="edit-session", - ), - path( - "sessions//delete/", - login_required(views.DeleteSession.as_view()), - name="delete-session", - ), - path("ical/", views.ICalendarView.as_view(), name="ical"), -] diff --git a/pygraz_website/apps/meetups/views.py b/pygraz_website/apps/meetups/views.py deleted file mode 100644 index 6f23cde..0000000 --- a/pygraz_website/apps/meetups/views.py +++ /dev/null @@ -1,209 +0,0 @@ -import collections -import datetime -from urllib.parse import urlparse - -import icalendar -import pytz -from django.conf import settings -from django.contrib import messages -from django.contrib.sites.models import Site -from django.http import Http404, HttpResponse, HttpResponseRedirect -from django.shortcuts import get_object_or_404 -from django.utils import timezone -from django.views import generic as generic_views - -from . import emails, forms, models -from .decorators import allow_only_staff_or_author_during_submission - -RSVPCollection = collections.namedtuple("RSVPCollection", "coming maybe not_coming") - - -class NextRedirectMixin: - """ - A simple mixin for checking for a next parameter for redirects. - """ - - redirect_param = "next" - - def get_next_redirect(self): - next = self.request.GET.get(self.redirect_param) - if next is None: - return None - netloc = urlparse(next)[1] - if netloc is None or netloc == "" or netloc == self.request.get_host(): - return next - return None - - def get_success_url(self): - next = self.get_next_redirect() - if next: - return next - return super().get_success_url() - - -class DetailView(generic_views.DetailView): - """ - Shows the details of a single meetup. There are two entry points: Via the - PK of the meetup and via its date. - - If neither criteria match a meetup, a 404 error page is shown. - """ - - model = models.Meetup - - def get_object(self): - if "pk" in self.kwargs: - return get_object_or_404(self.model.objects.select_related("location"), pk=self.kwargs.get("pk")) - else: - date_start = datetime.datetime( - int(self.kwargs.get("year")), int(self.kwargs.get("month")), int(self.kwargs.get("day")), 0, 0, 0 - ) - date_end = date_start + datetime.timedelta(days=1) - local_tz = timezone.get_default_timezone() - date_start = date_start.replace(tzinfo=local_tz) - date_end = date_end.replace(tzinfo=local_tz) - utc_date_start = date_start.astimezone(pytz.utc) - utc_date_end = date_end.astimezone(pytz.utc) - result = self.model.objects.filter( - start_date__gte=utc_date_start, start_date__lte=utc_date_end - ).select_related("location") - if not len(result): - raise Http404 - return result[0] - - def get_context_data(self, *args, **kwargs): - data = super().get_context_data(*args, **kwargs) - data["rsvps"] = self._get_rsvps() - return data - - def _get_rsvps(self): - result = RSVPCollection([], [], []) - for rsvp in self.object.rsvps.all(): - if rsvp.status: - getattr(result, rsvp.status).append(rsvp) - return result - - -class SubmitSession(NextRedirectMixin, generic_views.CreateView): - """ - Allows a user or guest to submit a session. - """ - - model = models.Session - - def get_form_class(self): - return forms.get_session_submission_form_class(self.request) - - def form_valid(self, form): - session = form.save(commit=False) - if self.request.user.is_authenticated: - session.speaker = self.request.user - session.save() - emails.notify_admins_for_new_session(session) - messages.success(self.request, "Session erstellt.") - return HttpResponseRedirect(self.get_success_url()) - - -class ViewSession(generic_views.DetailView): - """ - Shows a single session by its PK and returns a 404 page if no matching - session could be found. - """ - - model = models.Session - - def get_context_data(self, **kwargs): - data = super().get_context_data(**kwargs) - can_delete = ( - self.request.user.is_superuser - or self.request.user.is_staff - or (self.object.speaker and self.object.speaker == self.request.user) - ) - data.update( - { - "can_delete": can_delete, - "can_edit": can_delete, - } - ) - return data - - def get_object(self): - return get_object_or_404(self.model, pk=self.kwargs["pk"]) - - -class EditSession(generic_views.UpdateView): - """ - During the submission period, the author as well as staff members can edit - the session. Once it has been attached to a meetup, only staff members can - edit the proposal anymore. - """ - - model = models.Session - form_class = forms.EditSessionForm - - @allow_only_staff_or_author_during_submission - def dispatch(self, request, *args, **kwargs): - return super().dispatch(request, *args, **kwargs) - - def get_object(self): - if hasattr(self, "object") and self.object: - return self.object - return get_object_or_404(self.model, pk=self.kwargs["pk"]) - - def form_valid(self, form): - messages.success(self.request, "Session aktualisiert.") - return super().form_valid(form) - - -class DeleteSession(NextRedirectMixin, generic_views.DeleteView): - """ - During the submission period, author and staff can delete a session. - Afterwards only the staff. - """ - - model = models.Session - success_url = "/" - - def get_object(self): - return get_object_or_404(self.model, pk=self.kwargs["pk"]) - - def get_context_data(self, **kwargs): - data = super().get_context_data(**kwargs) - data.update({"cancel_url": self.get_success_url()}) - return data - - def delete(self, request, *args, **kwargs): - response = super().delete(request, *args, **kwargs) - messages.success(request, "Session gelöscht.") - return response - - @allow_only_staff_or_author_during_submission - def dispatch(self, request, *args, **kwargs): - return super().dispatch(request, *args, **kwargs) - - -class ICalendarView(generic_views.View): - """ - This offers a simple ical rendering of all the meetups. - """ - - def get_meetup_summary(self, meetup): - return f"PyGRAZ-Meetup am {meetup.start_date.date()}" - - def get_meetup_description(self, meetup): - return f"""Details: https://{Site.objects.get_current().domain}{meetup.get_absolute_url()}""" - - def get(self, request, *args, **kwargs): - cal = icalendar.Calendar() - cal.add("X-WR-CALNAME", settings.MEETUPS_CALENDAR_NAME) - site = Site.objects.get_current() - for meetup in models.Meetup.objects.all(): - evt = icalendar.Event() - evt.add("summary", self.get_meetup_summary(meetup)) - evt.add("description", self.get_meetup_description(meetup)) - evt.add("dtstart", meetup.start_date) - evt["uid"] = f"{site.domain}/meetups/{meetup.pk}" - cal.add_component(evt) - response = HttpResponse(cal.to_ical(), content_type="text/calendar") - response["Content-Disposition"] = "attachment;filename=pygraz.ics" - return response diff --git a/pygraz_website/asgi.py b/pygraz_website/asgi.py new file mode 100644 index 0000000..c3bebec --- /dev/null +++ b/pygraz_website/asgi.py @@ -0,0 +1,16 @@ +""" +ASGI config for pygraz_website project. + +It exposes the ASGI callable as a module-level variable named ``application``. + +For more information on this file, see +https://docs.djangoproject.com/en/4.2/howto/deployment/asgi/ +""" + +import os + +from django.core.asgi import get_asgi_application + +os.environ.setdefault("DJANGO_SETTINGS_MODULE", "pygraz_website.settings") + +application = get_asgi_application() diff --git a/pygraz_website/context_processors.py b/pygraz_website/context_processors.py deleted file mode 100644 index 4e5aef6..0000000 --- a/pygraz_website/context_processors.py +++ /dev/null @@ -1,16 +0,0 @@ -from django.conf import settings - - -def disqus(request): - """ - Adds the disqus settings to the context. - """ - return {"disqus": settings.DISQUS_SETTINGS} - - -def googlemaps(request): - """ - Adds the Google Maps API key to the context. - """ - assert False - # return {"GOOGLEMAPS_API_KEY": settings.GOOGLEMAPS_API_KEY} diff --git a/pygraz_website/locale/de/LC_MESSAGES/django.po b/pygraz_website/locale/de/LC_MESSAGES/django.po deleted file mode 100644 index 22c2e12..0000000 --- a/pygraz_website/locale/de/LC_MESSAGES/django.po +++ /dev/null @@ -1,252 +0,0 @@ -# SOME DESCRIPTIVE TITLE. -# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER -# This file is distributed under the same license as the PACKAGE package. -# FIRST AUTHOR , YEAR. -# -#, fuzzy -msgid "" -msgstr "" -"Project-Id-Version: PACKAGE VERSION\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-05-18 17:02+0200\n" -"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" -"Last-Translator: FULL NAME \n" -"Language-Team: LANGUAGE \n" -"Language: \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=2; plural=(n != 1)\n" - -#: apps/accounts/forms.py:18 -msgid "Log in" -msgstr "" - -#: apps/accounts/forms.py:28 apps/accounts/forms.py:40 -#: apps/accounts/forms.py:53 -msgid "Save changes" -msgstr "" - -#: apps/accounts/forms.py:66 -msgid "Registrieren" -msgstr "" - -#: apps/accounts/models.py:11 -msgid "user" -msgstr "" - -#: apps/companies/models.py:11 -msgid "Austria" -msgstr "Österreich" - -#: apps/companies/models.py:16 -msgid "name" -msgstr "Name" - -#: apps/companies/models.py:17 -msgid "website" -msgstr "Webseite" - -#: apps/companies/models.py:18 -msgid "contact e-mail" -msgstr "E-Mail-Kontakt" - -#: apps/companies/models.py:19 -msgid "description" -msgstr "Beschreibung" - -#: apps/companies/models.py:21 -msgid "address line" -msgstr "Adresse" - -#: apps/companies/models.py:22 -msgid "postal code" -msgstr "Postleitzahl" - -#: apps/companies/models.py:23 -msgid "city" -msgstr "Stadt" - -#: apps/companies/models.py:24 -msgid "country" -msgstr "Land" - -#: apps/companies/models.py:27 -msgid "approved" -msgstr "Verifziert" - -#: apps/companies/models.py:32 -msgid "Published at" -msgstr "Erstellt am" - -#: apps/companies/models.py:38 -msgid "company" -msgstr "Firma" - -#: apps/companies/models.py:39 -msgid "companies" -msgstr "Firmen" - -#: apps/companies/models.py:45 -msgid "My companies" -msgstr "Meine Firmen" - -#: apps/meetups/admin.py:17 apps/meetups/admin.py:37 apps/meetups/admin.py:81 -msgid "Yes" -msgstr "Ja" - -#: apps/meetups/admin.py:18 apps/meetups/admin.py:38 apps/meetups/admin.py:82 -msgid "No" -msgstr "Nein" - -#: apps/meetups/admin.py:57 -msgid "speaker type" -msgstr "" - -#: apps/meetups/admin.py:61 -msgid "Anonymous" -msgstr "" - -#: apps/meetups/admin.py:62 -msgid "Registered" -msgstr "Angemeldet" - -#: apps/meetups/admin.py:77 -msgid "meetup.com available" -msgstr "Meetup.com verfügbar" - -#: apps/meetups/models.py:13 -msgid "Not coming" -msgstr "Kommt nicht" - -#: apps/meetups/models.py:14 -msgid "Coming" -msgstr "Kommt" - -#: apps/meetups/models.py:15 -msgid "Maybe" -msgstr "Vielleicht" - -#: apps/meetups/models.py:52 -msgid "location" -msgstr "Ort" - -#: apps/meetups/models.py:53 -msgid "locations" -msgstr "Orte" - -#: apps/meetups/models.py:158 -msgid "Status" -msgstr "" - -#: apps/meetups/models.py:160 -msgid "Google+ Username" -msgstr "Google+-Name" - -#: apps/meetups/models.py:162 -msgid "Google+ User ID" -msgstr "Google+-BenutzerID" - -#: apps/meetups/models.py:164 -msgid "Meetup" -msgstr "" - -#: apps/meetups/models.py:177 -msgid "RSVP" -msgstr "" - -#: apps/meetups/models.py:178 -msgid "RSVPs" -msgstr "" - -#: templates/userena/emails/activation_email_message.txt:2 -#: templates/userena/emails/confirmation_email_message_new.txt:2 -#: templates/userena/emails/confirmation_email_message_old.txt:2 -#, python-format -msgid "Hallo %(username)s," -msgstr "" - -#: templates/userena/emails/activation_email_message.txt:4 -#, python-format -msgid "Danke, dass du dich auf %(site)s angemeldet hast." -msgstr "" - -#: templates/userena/emails/activation_email_message.txt:6 -msgid "Um deinen Account zu aktivieren, klicke bitte untenstehenden Link:" -msgstr "" - -#: templates/userena/emails/activation_email_message.txt:10 -msgid "Vielen Dank!" -msgstr "" - -#: templates/userena/emails/activation_email_subject.txt:2 -#, python-format -msgid "Deine Anmeldung bei %(site)s." -msgstr "" - -#: templates/userena/emails/confirmation_email_message_new.txt:4 -#: templates/userena/emails/confirmation_email_message_old.txt:4 -#, python-format -msgid "Du möchtest deine E-Mail-Adresse auf %(site)s ändern?" -msgstr "" - -#: templates/userena/emails/confirmation_email_message_new.txt:7 -msgid "" -"Klicke bitte untenstehenden Link, um deine neue E-Mail-Adresse zu bestätigen:" -msgstr "" - -#: templates/userena/emails/confirmation_email_message_old.txt:6 -#, python-format -msgid "" -"Eine E-Mail mit einem Bestätigungslink wurden an %(new_email)s gesandt. " -"Bitte klicke den Link in dieser E-Mail, um deine neue E-Mail-Adresse zu " -"aktivieren." -msgstr "" - -#: templates/userena/emails/confirmation_email_subject_new.txt:2 -#, python-format -msgid "E-Mail-Verifikation für %(site)s." -msgstr "" - -#: templates/userena/emails/confirmation_email_subject_old.txt:2 -#, python-format -msgid "Möchtest du deine E-Mail-Adresse auf %(site)s ändern?" -msgstr "" - -#: templates/userena/emails/password_reset_message.txt:2 -#, python-format -msgid "" -"Du hast diese E-Mail bekommen, weil du den \"Passwort ändern\"-Prozess auf " -"%(site_name)s angestoßen hast." -msgstr "" - -#: templates/userena/emails/password_reset_message.txt:4 -msgid "Bitte gehe auf folgende Seite und trage ein neues Passwort ein:" -msgstr "" - -#: templates/userena/emails/password_reset_message.txt:9 -#, python-format -msgid "" -"\n" -"Dein Benutzername: %(username)s\n" -msgstr "" - -#~ msgid "" -#~ "We will store your signup information for %(userena_activation_days)s " -#~ "days on our server. " -#~ msgstr "" -#~ "Ihre Registrierungsinformationen werden für %(userena_activation_days)s " -#~ "Tag(e) bei uns gespeichert." - -#~ msgid "You have been signed out." -#~ msgstr "Sie wurden abgemeldet." - -#~ msgid "" -#~ "You have been sent an e-mail with an activation link to the supplied " -#~ "email." -#~ msgstr "" -#~ "Sie erhalten umgehend eine E-Mail, mit dem Sie Ihren neuen Account " -#~ "aktivieren können." - -#~ msgid "Signup almost done!" -#~ msgstr "Registrierung fast abgeschlossen" diff --git a/pygraz_website/settings.py b/pygraz_website/settings.py new file mode 100644 index 0000000..1c3f94a --- /dev/null +++ b/pygraz_website/settings.py @@ -0,0 +1,125 @@ +""" +Django settings for pygraz_website project. + +Generated by 'django-admin startproject' using Django 4.2.6. + +For more information on this file, see +https://docs.djangoproject.com/en/4.2/topics/settings/ + +For the full list of settings and their values, see +https://docs.djangoproject.com/en/4.2/ref/settings/ +""" + +from pathlib import Path + +# Build paths inside the project like this: BASE_DIR / 'subdir'. +BASE_DIR = Path(__file__).resolve().parent.parent + + +# Quick-start development settings - unsuitable for production +# See https://docs.djangoproject.com/en/4.2/howto/deployment/checklist/ + +# SECURITY WARNING: keep the secret key used in production secret! +SECRET_KEY = "django-insecure-yam2a2vzm2!ml+&91h&a15j&p+-@n&y!0=t@fhf1fswa4zojk=" + +# SECURITY WARNING: don't run with debug turned on in production! +DEBUG = True + +ALLOWED_HOSTS = [] + + +# Application definition + +INSTALLED_APPS = [ + "django.contrib.admin", + "django.contrib.auth", + "django.contrib.contenttypes", + "django.contrib.sessions", + "django.contrib.messages", + "django.contrib.staticfiles", + "core.apps.CoreConfig", + "demo.apps.DemoConfig", +] + +MIDDLEWARE = [ + "django.middleware.security.SecurityMiddleware", + "django.contrib.sessions.middleware.SessionMiddleware", + "django.middleware.common.CommonMiddleware", + "django.middleware.csrf.CsrfViewMiddleware", + "django.contrib.auth.middleware.AuthenticationMiddleware", + "django.contrib.messages.middleware.MessageMiddleware", + "django.middleware.clickjacking.XFrameOptionsMiddleware", +] + +ROOT_URLCONF = "pygraz_website.urls" + +TEMPLATES = [ + { + "BACKEND": "django.template.backends.django.DjangoTemplates", + "DIRS": [], + "APP_DIRS": True, + "OPTIONS": { + "context_processors": [ + "django.template.context_processors.debug", + "django.template.context_processors.request", + "django.contrib.auth.context_processors.auth", + "django.contrib.messages.context_processors.messages", + ], + }, + }, +] + +WSGI_APPLICATION = "pygraz_website.wsgi.application" + + +# Database +# https://docs.djangoproject.com/en/4.2/ref/settings/#databases + +DATABASES = { + "default": { + "ENGINE": "django.db.backends.sqlite3", + "NAME": BASE_DIR / "pygraz.sqlite3", + } +} + + +# Password validation +# https://docs.djangoproject.com/en/4.2/ref/settings/#auth-password-validators + +AUTH_PASSWORD_VALIDATORS = [ + { + "NAME": "django.contrib.auth.password_validation.UserAttributeSimilarityValidator", + }, + { + "NAME": "django.contrib.auth.password_validation.MinimumLengthValidator", + }, + { + "NAME": "django.contrib.auth.password_validation.CommonPasswordValidator", + }, + { + "NAME": "django.contrib.auth.password_validation.NumericPasswordValidator", + }, +] + + +# Internationalization +# https://docs.djangoproject.com/en/4.2/topics/i18n/ + +LANGUAGE_CODE = "en-us" + +TIME_ZONE = "UTC" + +USE_I18N = True + +USE_TZ = True + + +# Static files (CSS, JavaScript, Images) +# https://docs.djangoproject.com/en/4.2/howto/static-files/ + +STATIC_URL = "static/" + +# Default primary key field type +# https://docs.djangoproject.com/en/4.2/ref/settings/#default-auto-field + +DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField" diff --git a/pygraz_website/settings/__init__.py b/pygraz_website/settings/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/pygraz_website/settings/base.py b/pygraz_website/settings/base.py deleted file mode 100644 index 6f097fe..0000000 --- a/pygraz_website/settings/base.py +++ /dev/null @@ -1,213 +0,0 @@ -# Django settings for pygraz_website project. -# -# The following settings have to be provided by an actual settings file -# -# RECAPTCHA_PRIVATE_KEY -# RECAPTCHA_PUBLIC_KEY -# POSTMARK_API_KEY -# SECRET_KEY -# - -import os -from os.path import abspath, dirname, join - -from django.conf import global_settings as default_settings - -DEBUG = True -ROOT = dirname(dirname(abspath(__file__))) - -INTERNAL_IPS = ["127.0.0.1"] - -ADMINS = (("Horst Gutmann", "zerok@zerokspot.com"),) - -MANAGERS = ADMINS - -DATABASES = { - "default": { - "ENGINE": "django.db.backends.postgresql_psycopg2", - "NAME": "pygraz-django", # Or path to database file if using sqlite3. - "USER": "", # Not used with sqlite3. - "PASSWORD": "", # Not used with sqlite3. - "HOST": "", # Set to empty string for localhost. Not used with sqlite3. - "PORT": "", # Set to empty string for default. Not used with sqlite3. - } -} - -# Local time zone for this installation. Choices can be found here: -# http://en.wikipedia.org/wiki/List_of_tz_zones_by_name -# although not all choices may be available on all operating systems. -# On Unix systems, a value of None will cause Django to use the same -# timezone as the operating system. -# If running in a Windows environment this must be set to the same as your -# system time zone. -TIME_ZONE = "Europe/Vienna" - -# Language code for this installation. All choices can be found here: -# http://www.i18nguy.com/unicode/language-identifiers.html -LANGUAGE_CODE = "de-at" - -SITE_ID = 1 - -# If you set this to False, Django will make some optimizations so as not -# to load the internationalization machinery. -USE_I18N = True - -# If you set this to False, Django will not format dates, numbers and -# calendars according to the current locale. -USE_L10N = True - -# If you set this to False, Django will not use timezone-aware datetimes. -USE_TZ = True - -LOCALE_PATHS = (join(ROOT, "locale"),) - -# Absolute filesystem path to the directory that will hold user-uploaded files. -# Example: "/home/media/media.lawrence.com/media/" -MEDIA_ROOT = join(ROOT, "media") - -# URL that handles the media served from MEDIA_ROOT. Make sure to use a -# trailing slash. -# Examples: "http://media.lawrence.com/media/", "http://example.com/media/" -MEDIA_URL = "/media/" - -# Absolute path to the directory static files should be collected to. -# Don't put anything in this directory yourself; store your static files -# in apps' "static/" subdirectories and in STATICFILES_DIRS. -# Example: "/home/media/media.lawrence.com/static/" -STATIC_ROOT = join(ROOT, "static_collected") - -# URL prefix for static files. -# Example: "http://media.lawrence.com/static/" -STATIC_URL = "/static/" - -# Additional locations of static files -STATICFILES_DIRS = (join(ROOT, "static"),) - -# List of finder classes that know how to find static files in -# various locations. -STATICFILES_FINDERS = ( - "django.contrib.staticfiles.finders.FileSystemFinder", - "django.contrib.staticfiles.finders.AppDirectoriesFinder", -) - -MIDDLEWARE = [ - "django.middleware.security.SecurityMiddleware", - "django.contrib.sessions.middleware.SessionMiddleware", - "django.middleware.common.CommonMiddleware", - "django.middleware.csrf.CsrfViewMiddleware", - "django.contrib.auth.middleware.AuthenticationMiddleware", - "django.contrib.messages.middleware.MessageMiddleware", - "django.middleware.clickjacking.XFrameOptionsMiddleware", -] - -ROOT_URLCONF = "pygraz_website.urls" - -# Python dotted path to the WSGI application used by Django's runserver. -WSGI_APPLICATION = "pygraz_website.wsgi.application" - -prev_ctx_processors = [] -if default_settings.TEMPLATES and "CONTEXT_PROCESSORS" in default_settings.TEMPLATES[0]: - prev_ctx_processors.extend(default_settings.TEMPLATES[0].get("CONTEXT_PROCESSORS", [])) - -TEMPLATES = [ - { - "BACKEND": "django.template.backends.django.DjangoTemplates", - "DIRS": [], # templates - "APP_DIRS": True, - "OPTIONS": { - "context_processors": ( - prev_ctx_processors - + [ - "django.template.context_processors.debug", - "django.template.context_processors.request", - "django.contrib.messages.context_processors.messages", - "django.contrib.auth.context_processors.auth", - "django.template.context_processors.request", - "pygraz_website.context_processors.disqus", - ] - ), - # "debug": DEBUG, - # # List of callables that know how to import templates from various sources. - # "loaders": ( - # "django.template.loaders.filesystem.Loader", - # "django.template.loaders.app_directories.Loader", - # ), - }, - } -] - - -TEST_RUNNER = "django.test.runner.DiscoverRunner" - -INSTALLED_APPS = [ - "django.contrib.auth", - "django.contrib.contenttypes", - "django.contrib.sessions", - "django.contrib.sites", - "django.contrib.messages", - "django.contrib.staticfiles", - "django.contrib.admin", - "django_extensions", - "easy_thumbnails", - "crispy_forms", - "userena", - "guardian", - "pygraz_website.apps.core", - "pygraz_website.apps.meetups", - "pygraz_website.apps.accounts", - "pygraz_website.apps.companies", -] - -# A sample logging configuration. The only tangible logging -# performed by this configuration is to send an email to -# the site admins on every HTTP 500 error when DEBUG=False. -# See http://docs.djangoproject.com/en/dev/topics/logging for -# more details on how to customize your logging configuration. -LOGGING = { - "version": 1, - "disable_existing_loggers": False, - "filters": {"require_debug_false": {"()": "django.utils.log.RequireDebugFalse"}}, - "handlers": { - "mail_admins": { - "level": "ERROR", - "filters": ["require_debug_false"], - "class": "django.utils.log.AdminEmailHandler", - } - }, - "loggers": { - "django.request": { - "handlers": ["mail_admins"], - "level": "ERROR", - "propagate": True, - }, - }, -} - - -DEFAULT_AUTO_FIELD = "django.db.models.AutoField" -CRISPY_FAIL_SILENTLY = False -CRISPY_TEMPLATE_PACK = "bootstrap" - -ANONYMOUS_USER_NAME = "user" -AUTHENTICATION_BACKENDS = ( - "userena.backends.UserenaAuthenticationBackend", - "guardian.backends.ObjectPermissionBackend", - "django.contrib.auth.backends.ModelBackend", -) -LOGIN_REDIRECT_URL = "/accounts/%(username)s/" -LOGIN_URL = "/accounts/signin/" -LOGOUT_URL = "/accounts/signout/" -AUTH_PROFILE_MODULE = "accounts.Profile" - -DISQUS_SETTINGS = {"developer_mode": True, "site_id": "pygrazdev"} -DEBUG_TOOLBAR_CONFIG = {"INTERCEPT_REDIRECTS": False} - -EMAIL_BACKEND = "postmark.django_backend.EmailBackend" -DEFAULT_FROM_EMAIL = "info@pygraz.org" -POSTMARK_SENDER = DEFAULT_FROM_EMAIL -SERVER_EMAIL = DEFAULT_FROM_EMAIL - -MEETUPS_CALENDAR_NAME = "PyGRAZ-Meetups" -MEETUPCOM_API_KEY = os.environ.get("DJANGO_MEETUPCOM_API_KEY") -NOCAPTCHA = True -RECAPTCHA_USE_SSL = True diff --git a/pygraz_website/settings/development.py b/pygraz_website/settings/development.py deleted file mode 100644 index 070b0a8..0000000 --- a/pygraz_website/settings/development.py +++ /dev/null @@ -1,17 +0,0 @@ -from .base import * - -DATABASES = { - "default": { - "ENGINE": "django.db.backends.postgresql_psycopg2", - "NAME": "pygraz-django", - "USER": "postgres", - "PASSWORD": "deMo.123", - "HOST": "localhost", - "PORT": "5433", - } -} - -SOUTH_TESTS_MIGRATE = False -SECRET_KEY = "SECRET_KEY" -POSTMARK_TEST_MODE = True -POSTMARK_API_KEY = "test-token" diff --git a/pygraz_website/settings/secrets.py b/pygraz_website/settings/secrets.py deleted file mode 100644 index b5a3769..0000000 --- a/pygraz_website/settings/secrets.py +++ /dev/null @@ -1,5 +0,0 @@ -DB_USER = "pguser" -DB_PASSWORD = "1234" -DB_NAME = "pygraz_test" -DB_HOST = "localhost" -SECRET_KEY = "1234123412341234" diff --git a/pygraz_website/settings/testing.py b/pygraz_website/settings/testing.py deleted file mode 100644 index f10a1c0..0000000 --- a/pygraz_website/settings/testing.py +++ /dev/null @@ -1,17 +0,0 @@ -from .base import * - -DATABASES = { - "default": { - "ENGINE": "django.db.backends.sqlite3", - "NAME": ":memory:", - "USER": "", - "PASSWORD": "", - "HOST": "", - "PORT": "", - } -} - -SOUTH_TESTS_MIGRATE = False -SECRET_KEY = "SECRET_KEY" -# RECAPTCHA_PUBLIC_KEY = 'RECAPTCHA_PUBLIC_KEY' -# RECAPTCHA_PRIVATE_KEY = 'RECAPTCHA_PRIVATE_KEY' diff --git a/pygraz_website/static/config.rb b/pygraz_website/static/config.rb deleted file mode 100644 index cc43b13..0000000 --- a/pygraz_website/static/config.rb +++ /dev/null @@ -1,12 +0,0 @@ -# Require any additional compass plugins here. -# Set this to the root of your project when deployed: -http_path = "/" -css_dir = "./css" -sass_dir = "./css" -images_dir = "./imgs" -javascripts_dir = "./js" -# To enable relative paths to assets via compass helper functions. Uncomment: -# relative_assets = true - -# sync stdout so foreman and others can properly capture the output. -$stdout.sync = true diff --git a/pygraz_website/static/css/_fonts.scss b/pygraz_website/static/css/_fonts.scss deleted file mode 100644 index e8e9371..0000000 --- a/pygraz_website/static/css/_fonts.scss +++ /dev/null @@ -1,77 +0,0 @@ -@mixin create-fontface( - $name, - $filebase, - $weight: normal, - $style: normal, - $svgid: "webfont" -) { - @font-face { - font-family: "#{$name}"; - src: url("#{$filebase}.eot"); - src: - url("#{$filebase}.eot?#iefix") format("embedded-opentype"), - url("/static/fonts/#{$filebase}.woff") format("woff"), - url("/static/fonts/#{$filebase}.ttf") format("truetype"), - url("/static/fonts/#{$filebase}.svg##{$svgid}") format("svg"); - font-weight: $weight; - font-style: $style; - } -} - -@include create-fontface("LeagueGothic", "League_Gothic-webfont"); -@include create-fontface( - "PTCaptionNarrow", - "PTC55F-webfont", - normal, - normal, - "PTSansCaptionRegular" -); -@include create-fontface( - "PTCaptionNarrow", - "PTC75F-webfont", - bold, - normal, - "PTSansCaptionBold" -); -@include create-fontface( - "PTSansNarrow", - "PTN57F-webfont", - normal, - normal, - "PTSansNarrowRegular" -); -@include create-fontface( - "PTSansNarrow", - "PTN77F-webfont", - bold, - normal, - "PTSansNarrowBold" -); -@include create-fontface( - "PTSans", - "PTS75F-webfont", - bold, - normal, - "PTSansBold" -); -@include create-fontface( - "PTSans", - "PTS76F-webfont", - bold, - italic, - "PTSansBoldItalic" -); -@include create-fontface( - "PTSans", - "PTS56F-webfont", - normal, - italic, - "PTSansItalic" -); -@include create-fontface( - "PTSans", - "PTS55F-webfont", - normal, - normal, - "PTSansRegular" -); diff --git a/pygraz_website/static/css/_forms.scss b/pygraz_website/static/css/_forms.scss deleted file mode 100644 index c9b0583..0000000 --- a/pygraz_website/static/css/_forms.scss +++ /dev/null @@ -1,110 +0,0 @@ -form { - label { - display: block; - font-size: 14px; - } - input, - textarea { - border: 1px solid #ccc; - padding: 7px; - line-height: 120%; - background: #fafafa; - &:focus { - border-color: $blue; - background: #fff; - } - } - input[type="text"], - input[type="email"], - input[type="password"] { - width: 250px; - } - input[type="submit"], - button[type="submit"] { - background: $blue; - @include background-image(linear-gradient(lighten($blue, 10), $blue)); - @include border-radius(3px); - color: #fff; - font-weight: bold; - display: inline-block; - padding: 5px; - &:hover { - background: lighten($blue, 10); - } - } - textarea { - width: 400px; - height: 250px; - line-height: 130%; - } - .help-inline, - .help-block { - display: block; - font-size: 90%; - color: #888; - margin-top: 3px; - } - .control-group { - margin-bottom: 10px; - &.error { - input, - textarea { - border-color: $red; - } - label, - .help-inline { - color: $red; - } - } - } - .buttonHolder { - border-top: 1px dotted #ccc; - padding: 10px 0; - input { - font-size: 13px; - } - } - label.radio { - margin-bottom: 5px; - - span { - display: block; - font-size: 80%; - padding-left: 18px; - } - } -} - -.btn { - border: 0; - display: inline-block; - padding: 5px; - line-height: 18px; - font-weight: bold; - font-size: 14px; -} - -/** - * On fullpage-form pages we can put the help to the right of the input field and the label - */ -.fullpage-form form { - .control-group { - @include pie-clearfix; - border-top: 1px dotted #ddd; - margin-bottom: 0; - padding: 10px 0; - } - .control-group > label { - width: 150px; - display: table-cell; - vertical-align: middle; - } - .controls { - display: table-cell; - width: 770px; - } - .help-block { - float: right; - width: 310px; - } -} diff --git a/pygraz_website/static/css/icomoon/_style.scss b/pygraz_website/static/css/icomoon/_style.scss deleted file mode 100644 index e20ebcd..0000000 --- a/pygraz_website/static/css/icomoon/_style.scss +++ /dev/null @@ -1,51 +0,0 @@ -/** - * edit: ✍ - * clock: ◷ - * link: → - * trash: ♽ - * proposals: ■ - * ok: ✓ - * cancel: ✕ - * location: ◉ - * user: ☺ - * slides: ❏ - */ - -@font-face { - font-family: "IcoMoon"; - src: url("icomoon/IcoMoon.eot"); - src: url("icomoon/IcoMoon.eot?#iefix") format("embedded-opentype"), - url("icomoon/IcoMoon.svg#IcoMoon") format("svg"), - url("icomoon/IcoMoon.woff") format("woff"), - url("icomoon/IcoMoon.ttf") format("truetype"); - font-weight: normal; - font-style: normal; -} - -/* Add the following classes to your stylesheet if you want to use data attributes for inserting your icons */ -.iconb:before, -.icona:after { - font-family: "IcoMoon"; - content: attr(data-icon); - font-weight: normal; -} - -/* Add the following CSS properties to your stylesheet if you want to have a class per icon */ -[class^="icon-"], -[class*=" icon-"] { - font-family: "IcoMoon"; - font-style: normal; -} - -.icon-link:before { - content: "\2192"; -} -.icon-clock:before { - content: "\25f7"; -} -.icon-pencil:before { - content: "\270d"; -} -.icon-remove:before { - content: "\267d"; -} diff --git a/pygraz_website/static/css/screen.scss b/pygraz_website/static/css/screen.scss deleted file mode 100644 index a2efb33..0000000 --- a/pygraz_website/static/css/screen.scss +++ /dev/null @@ -1,639 +0,0 @@ -$blue: #306998; -$yellow: #ffd743; -$red: darken(red, 10); -$green: green; -$baseColor: #333; - -@import "compass/utilities/general/clearfix"; -@import "compass/css3/images"; -@import "compass/css3/border-radius"; -@import "compass/css3/box-shadow"; -@import "fonts"; -@import "forms"; -@import "icomoon/style"; - -html { - //background-color: #EEE; -} -body { - font-family: "PTSans", Arial; - margin: 0; - color: $baseColor; - //@include background(linear-gradient(#FFF, #DDD)); - //background: #FAFAFA; -} - -body > .container { - max-width: 920px; - margin: auto; - //@include border-radius(2px); - //@include box-shadow(#cecece 0 3px 3px); - padding: 20px; - padding-top: 80px; - background: #fff; -} - -a { - color: #666; - text-decoration: underline; - &:hover { - color: $blue; - } -} - -.icona:after { - padding-left: 5px; -} - -.iconb:before { - padding-right: 5px; -} - -#nav-helper { - display: none; - text-align: center; - font-weight: bold; - background: #333; - color: white; - text-decoration: none; - padding: 10px; -} - -#primary-nav { - z-index: 1000; - background: #333; - margin-bottom: 30px; - position: fixed; - width: 100%; - color: #fff; - .w { - max-width: 920px; - margin: 0 auto; - position: relative; - @include pie-clearfix; - } - &:hover { - background: #333; - } - ul { - width: 620px; - float: left; - padding: 0; - margin: 0 auto; - list-style: none; - @include pie-clearfix; - } - li { - float: left; - padding: 7px; - display: block; - } - a { - color: #fff; - text-decoration: none; - font-weight: bold; - } - li.active a, - a:hover { - color: $yellow; - } - - #accountbox { - position: absolute; - right: 0; - top: 0; - width: 250px; - text-align: right; - > a { - display: block; - padding: 7px; - } - &.logged-out { - a { - display: inline-block; - } - } - ul { - display: none; - li { - float: none; - border-top: 1px dotted #fff; - } - } - &:hover ul { - width: 100%; - display: block; - background: #333; - } - } -} - -header { - @include pie-clearfix; - //border-bottom: 1px solid #E1E1E1; - padding-bottom: 30px; -} - -#mission { - min-width: 200px; - max-width: 575px; - float: right; - line-height: 1.3em; - padding: 10px; - font-weight: bold; - margin: 0; - color: #666; -} - -#logo { - display: block; - width: 276px; - height: 80px; - float: left; -} - -#body { - padding: 10px 0; - @include pie-clearfix; -} - -footer { - border-top: 1px solid #e1e1e1; - padding: 10px 0; - font-size: 90%; - h2 { - font-weight: bold; - font-size: 100%; - text-transform: uppercase; - } - #credits { - text-align: right; - } -} - -table { - width: 100%; - margin-bottom: 1em; - border-collapse: collapse; - td, - th { - padding: 3px 5px; - border-bottom: 1px solid #ddd; - } - thead { - th { - color: #aaa; - font-weight: bold; - text-align: left; - } - } - tbody { - tr:nth-child(even) td { - background: #efefef; - } - tr:hover { - background: #fafafa; - } - } -} - -.session, -.session-details { - h1 { - margin-bottom: 5px; - font-size: 19px; - a { - text-decoration: none; - } - } - .meta { - margin-top: 0; - font-size: 95%; - font-style: italic; - padding-left: 25px; - } -} - -/** - * Frontpage - */ -body.frontpage { - #next-meetup { - @include pie-clearfix; - &.empty { - font-size: 120%; - text-align: center; - @include border-radius(5px); - padding: 10px; - background: #efefef; - } - } - - .upcoming { - background: #eee url(../imgs/toparrow-bg.png) 50% 0% no-repeat; - padding: 20px 0; - border-bottom: 3px solid #ddd; - - > h1, - > h1 > a { - //background: $blue; - //@include background(linear-gradient(lighten($blue, 10), $blue)); - color: $blue; - color: $yellow; - padding: 10px; - background: #333; - margin: 0; - text-align: center; - font-family: "LeagueGothic"; - font-weight: normal; - font-size: 32px; - text-decoration: none; - } - } - #sessions-and-notes, - #location-info, - .meetupcom { - padding: 2%; - } - #sessions-and-notes { - padding-right: 0; - } - #sessions-and-notes { - @include pie-clearfix; - float: left; - max-width: 59%; - } - .session { - margin-top: 10px; - &:first-child { - margin-top: 0; - } - } - #location-info, - .meetupcom { - float: right; - max-width: 35%; - min-width: 250px; - background: none; - clear: right; - } - #past-meetups, - #session-proposals { - margin-top: 2em; - padding: 10px; - } - #past-meetups { - float: right; - max-width: 35%; - min-width: 250px; - @include background-image(linear-gradient(lighten($blue, 55), #fff)); - @include border-radius(5px 5px 0 0); - } - #session-proposals { - float: left; - max-width: 60%; - // min-width: 380px; - } -} - -#location-info { - font-size: 90%; -} - -.meetupcom { - .logo { - float: left; - margin: 0 10px 0px 0; - } -} -.meetup-data { - .map { - height: 250px; - margin-bottom: 1em; - } - .meetupcom { - font-size: 90%; - @include background-image(linear-gradient(lighten(red, 40), white)); - a { - font-weight: bold; - font-size: 120%; - color: black; - text-decoration: none; - } - } -} - -#info { - background: #efefef; - padding: 10px; - @include border-radius(5px); - margin-bottom: 30px; -} - -body.meetup-details { - h1 .time { - font-size: 22px; - } - #sessions-and-notes { - float: left; - max-width: 60%; - } - .meetupcom, - #location-info { - float: right; - max-width: 31%; - padding: 0px 2% 10px 2%; - clear: right; - } - #location-info { - background: lighten($blue, 40); - min-width: 250px; - @include background-image(linear-gradient(lighten($blue, 50), #fff)); - @include border-radius(5px 5px 0 0); - } -} - -article.session-details { - position: relative; - .actions { - position: absolute; - top: 0; - right: 0; - padding: 0; - margin: 0; - } -} - -.actions { - list-style: none; - float: right; - li { - padding: 0; - @include border-radius(3px); - background: #efefef; - &:first-child { - margin-bottom: 2px; - } - } - a { - padding: 5px 8px; - display: block; - text-decoration: none; - &:hover { - color: #fff; - @include border-radius(3px); - background: $blue; - } - } -} - -.alert { - padding: 10px; - border: 2px solid lighten($yellow, 30); - background: lighten($yellow, 30); - @include background-image( - linear-gradient(lighten($yellow, 35), lighten($yellow, 30)) - ); - @include border-radius(5px); - margin-bottom: 5px; - &:first-child { - margin-top: 5px; - } - .close { - display: none; - } - &.alert-success { - border-color: lighten($green, 65); - background: lighten($green, 65); - @include background-image( - linear-gradient(lighten($green, 70), lighten($green, 65)) - ); - color: darken($green, 30); - } - &.alert-error { - border-color: lighten($red, 50); - background: lighten($red, 50); - @include background-image( - linear-gradient(lighten($red, 55), lighten($red, 50)) - ); - color: darken($red, 20); - } -} - -#disqus_thread { - clear: both; - padding-top: 20px; -} - -@media all and (max-width: 950px) { - #mission { - max-width: 50%; - } -} - -@media all and (max-width: 765px) { - body > .container { - padding: 0 10px 10px 10px; - } - #mission { - max-width: 98%; - padding: 10px 1% 0px 1%; - float: none; - clear: both; - } - body.frontpage { - #session-proposals, - #past-meetups { - float: none; - max-width: 100%; - padding: 0; - h1 { - margin: 5px 0; - } - } - #past-meetups { - padding: 2%; - } - } - form { - textarea { - max-width: 90%; - min-width: 90%; - width: auto; - } - input[type="text"], - input[type="email"], - input[type="password"] { - max-width: 250px; - min-width: 90%; - } - } - article.session-details .actions { - position: static; - } - body.frontpage, - body.meetup-details { - #sessions-and-notes, - #location-info, - .meetupcom { - max-width: 96%; - padding: 5px 2%; - float: none; - h1 { - margin: 5px 0; - } - } - #location-info { - min-width: 250px; - } - } - #primary-nav { - position: static; - margin-bottom: 20px; - ul, - #accountbox { - position: static; - display: block; - float: none; - width: auto; - text-align: left; - } - } -} - -#gplus { - padding: 10px; - background: $yellow; - @include border-radius(5px); - @include background-image(linear-gradient(lighten($yellow, 30), #fff)); - @include pie-clearfix; - position: relative; - h1 { - margin: 0; - } - .evt-link { - position: absolute; - top: 10px; - left: 10px; - } - .info { - float: right; - margin: 0 0 0 80px; - font-size: 90%; - } - .fineprint { - text-align: right; - margin-left: 20%; - padding-top: 20px; - color: lighten($baseColor, 30); - } - #rsvps { - float: left; - width: 40%; - margin-left: 20%; - h1 { - font-size: 100%; - } - ul { - margin: 3px 0 0 0; - padding: 0 0 0 20px; - } - } -} - -.fineprint { - font-size: 75%; - clear: both; -} - -body.company-details { - #map { - height: 300px; - } - .meta { - float: right; - width: 300px; - background: #efefef; - padding: 10px; - margin: 16px 0 20px 20px; - dl { - margin: 0; - } - dt { - font-weight: bold; - } - } -} - -body.company-submission { - fieldset { - float: left; - width: 46%; - margin: 0 0 10px 0; - border: 1px solid #ccc; - } - fieldset:nth-child(3) { - float: right; - } - .buttonHolder { - clear: both; - } -} - -.contenttype { - width: 31%; - float: left; - margin: 0 1% 1% 20px; -} - -// This redesigns the menu for smaller screens and puts it at the bottom of the -// output on browsers that support flexbox. -@media screen and (max-width: 480px) { - body { - display: -webkit-box; - display: -webkit-flex; - -webkit-box-orient: vertical; - -webkit-flex-direction: column; - display: flex; - flex-direction: column; - } - #nav-helper { - display: block; - } - #primary-nav { - -webkit-box-ordinal-group: 2; - -webkit-order: 2; - order: 2; - li { - border-top: 1px dotted #fff; - float: none; - } - > .w > ul > li:first-child { - border-top: none; - } - #accountbox { - margin-top: 20px; - } - #accountbox ul { - display: block; - } - } - body > .container { - -webkit-box-ordinal-group: 1; - -webkit-order: 1; - order: 1; - padding-top: 20px; - } -} - -.meetup__rsvps__disclaimer { - text-align: right; - font-size: 80%; - font-style: italic; -} - -.meetup__rsvps__coming { - padding: 5px 2%; - @include border-radius(5px); - @include background-image(linear-gradient(lighten($blue, 55), #fff)); -} diff --git a/pygraz_website/static/fonts/League_Gothic-webfont.eot b/pygraz_website/static/fonts/League_Gothic-webfont.eot deleted file mode 100755 index 08deeb7..0000000 Binary files a/pygraz_website/static/fonts/League_Gothic-webfont.eot and /dev/null differ diff --git a/pygraz_website/static/fonts/League_Gothic-webfont.license.txt b/pygraz_website/static/fonts/League_Gothic-webfont.license.txt deleted file mode 100644 index fcd6784..0000000 --- a/pygraz_website/static/fonts/League_Gothic-webfont.license.txt +++ /dev/null @@ -1,105 +0,0 @@ - Copyright (c) 2010, Caroline Hadilaksono & Micah Rich , with Reserved Font Name: "League Gothic". - - This Font Software is licensed under the SIL Open Font License, Version 1.1. - This license is copied below, and is also available with a FAQ at: - http://scripts.sil.org/OFL - - Version 1.1 - 26 February 2007 - - -SIL Open Font License -==================================================== - - -Preamble ----------- - -The goals of the Open Font License (OFL) are to stimulate worldwide -development of collaborative font projects, to support the font creation -efforts of academic and linguistic communities, and to provide a free and -open framework in which fonts may be shared and improved in partnership -with others. - -The OFL allows the licensed fonts to be used, studied, modified and -redistributed freely as long as they are not sold by themselves. The -fonts, including any derivative works, can be bundled, embedded, -redistributed and/or sold with any software provided that any reserved -names are not used by derivative works. The fonts and derivatives, -however, cannot be released under any other type of license. The -requirement for fonts to remain under this license does not apply -to any document created using the fonts or their derivatives. - -Definitions -------------- - -`"Font Software"` refers to the set of files released by the Copyright -Holder(s) under this license and clearly marked as such. This may -include source files, build scripts and documentation. - -`"Reserved Font Name"` refers to any names specified as such after the -copyright statement(s). - -`"Original Version"` refers to the collection of Font Software components as -distributed by the Copyright Holder(s). - -`"Modified Version"` refers to any derivative made by adding to, deleting, -or substituting -- in part or in whole -- any of the components of the -Original Version, by changing formats or by porting the Font Software to a -new environment. - -`"Author"` refers to any designer, engineer, programmer, technical -writer or other person who contributed to the Font Software. - -Permission & Conditions ------------------------- - -Permission is hereby granted, free of charge, to any person obtaining -a copy of the Font Software, to use, study, copy, merge, embed, modify, -redistribute, and sell modified and unmodified copies of the Font -Software, subject to the following conditions: - -1. Neither the Font Software nor any of its individual components, -in Original or Modified Versions, may be sold by itself. - -2. Original or Modified Versions of the Font Software may be bundled, -redistributed and/or sold with any software, provided that each copy -contains the above copyright notice and this license. These can be -included either as stand-alone text files, human-readable headers or -in the appropriate machine-readable metadata fields within text or -binary files as long as those fields can be easily viewed by the user. - -3. No Modified Version of the Font Software may use the Reserved Font -Name(s) unless explicit written permission is granted by the corresponding -Copyright Holder. This restriction only applies to the primary font name as -presented to the users. - -4. The name(s) of the Copyright Holder(s) or the Author(s) of the Font -Software shall not be used to promote, endorse or advertise any -Modified Version, except to acknowledge the contribution(s) of the -Copyright Holder(s) and the Author(s) or with their explicit written -permission. - -5. The Font Software, modified or unmodified, in part or in whole, -must be distributed entirely under this license, and must not be -distributed under any other license. The requirement for fonts to -remain under this license does not apply to any document created -using the Font Software. - -Termination ------------ - -This license becomes null and void if any of the above conditions are -not met. - - - DISCLAIMER - - THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT - OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE - COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL - DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM - OTHER DEALINGS IN THE FONT SOFTWARE. diff --git a/pygraz_website/static/fonts/League_Gothic-webfont.svg b/pygraz_website/static/fonts/League_Gothic-webfont.svg deleted file mode 100755 index 96d2704..0000000 --- a/pygraz_website/static/fonts/League_Gothic-webfont.svg +++ /dev/null @@ -1,235 +0,0 @@ - - - - -This is a custom SVG webfont generated by Font Squirrel. -Copyright : Generated in 2009 by FontLab Studio Copyright info pending - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/pygraz_website/static/fonts/League_Gothic-webfont.ttf b/pygraz_website/static/fonts/League_Gothic-webfont.ttf deleted file mode 100755 index efbe8b4..0000000 Binary files a/pygraz_website/static/fonts/League_Gothic-webfont.ttf and /dev/null differ diff --git a/pygraz_website/static/fonts/League_Gothic-webfont.woff b/pygraz_website/static/fonts/League_Gothic-webfont.woff deleted file mode 100755 index 2e2cda9..0000000 Binary files a/pygraz_website/static/fonts/League_Gothic-webfont.woff and /dev/null differ diff --git a/pygraz_website/static/fonts/PTC55F-webfont.eot b/pygraz_website/static/fonts/PTC55F-webfont.eot deleted file mode 100755 index af1b47a..0000000 Binary files a/pygraz_website/static/fonts/PTC55F-webfont.eot and /dev/null differ diff --git a/pygraz_website/static/fonts/PTC55F-webfont.svg b/pygraz_website/static/fonts/PTC55F-webfont.svg deleted file mode 100755 index 7b99874..0000000 --- a/pygraz_website/static/fonts/PTC55F-webfont.svg +++ /dev/null @@ -1,154 +0,0 @@ - - - - -This is a custom SVG webfont generated by Font Squirrel. -Copyright : Copyright 2009 ParaType Ltd All rights reserved -Designer : AKorolkova OUmpeleva VYefimov -Foundry : ParaType Ltd -Foundry URL : httpwwwparatypecom - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/pygraz_website/static/fonts/PTC55F-webfont.ttf b/pygraz_website/static/fonts/PTC55F-webfont.ttf deleted file mode 100755 index 15c8a0c..0000000 Binary files a/pygraz_website/static/fonts/PTC55F-webfont.ttf and /dev/null differ diff --git a/pygraz_website/static/fonts/PTC55F-webfont.woff b/pygraz_website/static/fonts/PTC55F-webfont.woff deleted file mode 100755 index ebbaee2..0000000 Binary files a/pygraz_website/static/fonts/PTC55F-webfont.woff and /dev/null differ diff --git a/pygraz_website/static/fonts/PTC75F-webfont.eot b/pygraz_website/static/fonts/PTC75F-webfont.eot deleted file mode 100755 index 4664db7..0000000 Binary files a/pygraz_website/static/fonts/PTC75F-webfont.eot and /dev/null differ diff --git a/pygraz_website/static/fonts/PTC75F-webfont.svg b/pygraz_website/static/fonts/PTC75F-webfont.svg deleted file mode 100755 index 078c5c3..0000000 --- a/pygraz_website/static/fonts/PTC75F-webfont.svg +++ /dev/null @@ -1,154 +0,0 @@ - - - - -This is a custom SVG webfont generated by Font Squirrel. -Copyright : Copyright 2009 ParaType Ltd All rights reserved -Designer : AKorolkova OUmpeleva VYefimov -Foundry : ParaType Ltd -Foundry URL : httpwwwparatypecom - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/pygraz_website/static/fonts/PTC75F-webfont.ttf b/pygraz_website/static/fonts/PTC75F-webfont.ttf deleted file mode 100755 index 549f96b..0000000 Binary files a/pygraz_website/static/fonts/PTC75F-webfont.ttf and /dev/null differ diff --git a/pygraz_website/static/fonts/PTC75F-webfont.woff b/pygraz_website/static/fonts/PTC75F-webfont.woff deleted file mode 100755 index 4512412..0000000 Binary files a/pygraz_website/static/fonts/PTC75F-webfont.woff and /dev/null differ diff --git a/pygraz_website/static/fonts/PTN57F-webfont.eot b/pygraz_website/static/fonts/PTN57F-webfont.eot deleted file mode 100755 index 1f55ea8..0000000 Binary files a/pygraz_website/static/fonts/PTN57F-webfont.eot and /dev/null differ diff --git a/pygraz_website/static/fonts/PTN57F-webfont.svg b/pygraz_website/static/fonts/PTN57F-webfont.svg deleted file mode 100755 index 5509a88..0000000 --- a/pygraz_website/static/fonts/PTN57F-webfont.svg +++ /dev/null @@ -1,154 +0,0 @@ - - - - -This is a custom SVG webfont generated by Font Squirrel. -Copyright : Copyright 2009 ParaType Ltd All rights reserved -Designer : AKorolkova OUmpeleva VYefimov -Foundry : ParaType Ltd -Foundry URL : httpwwwparatypecom - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/pygraz_website/static/fonts/PTN57F-webfont.ttf b/pygraz_website/static/fonts/PTN57F-webfont.ttf deleted file mode 100755 index 30fd9b9..0000000 Binary files a/pygraz_website/static/fonts/PTN57F-webfont.ttf and /dev/null differ diff --git a/pygraz_website/static/fonts/PTN57F-webfont.woff b/pygraz_website/static/fonts/PTN57F-webfont.woff deleted file mode 100755 index 8434217..0000000 Binary files a/pygraz_website/static/fonts/PTN57F-webfont.woff and /dev/null differ diff --git a/pygraz_website/static/fonts/PTN77F-webfont.eot b/pygraz_website/static/fonts/PTN77F-webfont.eot deleted file mode 100755 index 10ef4f1..0000000 Binary files a/pygraz_website/static/fonts/PTN77F-webfont.eot and /dev/null differ diff --git a/pygraz_website/static/fonts/PTN77F-webfont.svg b/pygraz_website/static/fonts/PTN77F-webfont.svg deleted file mode 100755 index e132de2..0000000 --- a/pygraz_website/static/fonts/PTN77F-webfont.svg +++ /dev/null @@ -1,157 +0,0 @@ - - - - -This is a custom SVG webfont generated by Font Squirrel. -Copyright : Copyright 2009 ParaType Ltd All rights reserved -Designer : AKorolkova OUmpeleva VYefimov -Foundry : ParaType Ltd -Foundry URL : httpwwwparatypecom - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/pygraz_website/static/fonts/PTN77F-webfont.ttf b/pygraz_website/static/fonts/PTN77F-webfont.ttf deleted file mode 100755 index 5b4dd93..0000000 Binary files a/pygraz_website/static/fonts/PTN77F-webfont.ttf and /dev/null differ diff --git a/pygraz_website/static/fonts/PTN77F-webfont.woff b/pygraz_website/static/fonts/PTN77F-webfont.woff deleted file mode 100755 index ba8c069..0000000 Binary files a/pygraz_website/static/fonts/PTN77F-webfont.woff and /dev/null differ diff --git a/pygraz_website/static/fonts/PTS55F-webfont.eot b/pygraz_website/static/fonts/PTS55F-webfont.eot deleted file mode 100755 index 0c30b5e..0000000 Binary files a/pygraz_website/static/fonts/PTS55F-webfont.eot and /dev/null differ diff --git a/pygraz_website/static/fonts/PTS55F-webfont.svg b/pygraz_website/static/fonts/PTS55F-webfont.svg deleted file mode 100755 index c8e2059..0000000 --- a/pygraz_website/static/fonts/PTS55F-webfont.svg +++ /dev/null @@ -1,153 +0,0 @@ - - - - -This is a custom SVG webfont generated by Font Squirrel. -Copyright : Copyright 2009 ParaType Ltd All rights reserved -Designer : AKorolkova OUmpeleva VYefimov -Foundry : ParaType Ltd -Foundry URL : httpwwwparatypecom - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/pygraz_website/static/fonts/PTS55F-webfont.ttf b/pygraz_website/static/fonts/PTS55F-webfont.ttf deleted file mode 100755 index c530f69..0000000 Binary files a/pygraz_website/static/fonts/PTS55F-webfont.ttf and /dev/null differ diff --git a/pygraz_website/static/fonts/PTS55F-webfont.woff b/pygraz_website/static/fonts/PTS55F-webfont.woff deleted file mode 100755 index 07db10d..0000000 Binary files a/pygraz_website/static/fonts/PTS55F-webfont.woff and /dev/null differ diff --git a/pygraz_website/static/fonts/PTS56F-webfont.eot b/pygraz_website/static/fonts/PTS56F-webfont.eot deleted file mode 100755 index 4544409..0000000 Binary files a/pygraz_website/static/fonts/PTS56F-webfont.eot and /dev/null differ diff --git a/pygraz_website/static/fonts/PTS56F-webfont.svg b/pygraz_website/static/fonts/PTS56F-webfont.svg deleted file mode 100755 index b26cb9e..0000000 --- a/pygraz_website/static/fonts/PTS56F-webfont.svg +++ /dev/null @@ -1,153 +0,0 @@ - - - - -This is a custom SVG webfont generated by Font Squirrel. -Copyright : Copyright 2009 ParaType Ltd All rights reserved -Designer : AKorolkova OUmpeleva VYefimov -Foundry : ParaType Ltd -Foundry URL : httpwwwparatypecom - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/pygraz_website/static/fonts/PTS56F-webfont.ttf b/pygraz_website/static/fonts/PTS56F-webfont.ttf deleted file mode 100755 index a847072..0000000 Binary files a/pygraz_website/static/fonts/PTS56F-webfont.ttf and /dev/null differ diff --git a/pygraz_website/static/fonts/PTS56F-webfont.woff b/pygraz_website/static/fonts/PTS56F-webfont.woff deleted file mode 100755 index 1841053..0000000 Binary files a/pygraz_website/static/fonts/PTS56F-webfont.woff and /dev/null differ diff --git a/pygraz_website/static/fonts/PTS75F-webfont.eot b/pygraz_website/static/fonts/PTS75F-webfont.eot deleted file mode 100755 index c6a95fc..0000000 Binary files a/pygraz_website/static/fonts/PTS75F-webfont.eot and /dev/null differ diff --git a/pygraz_website/static/fonts/PTS75F-webfont.svg b/pygraz_website/static/fonts/PTS75F-webfont.svg deleted file mode 100755 index 54ec711..0000000 --- a/pygraz_website/static/fonts/PTS75F-webfont.svg +++ /dev/null @@ -1,157 +0,0 @@ - - - - -This is a custom SVG webfont generated by Font Squirrel. -Copyright : Copyright 2009 ParaType Ltd All rights reserved -Designer : AKorolkova OUmpeleva VYefimov -Foundry : ParaType Ltd -Foundry URL : httpwwwparatypecom - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/pygraz_website/static/fonts/PTS75F-webfont.ttf b/pygraz_website/static/fonts/PTS75F-webfont.ttf deleted file mode 100755 index 86c21f5..0000000 Binary files a/pygraz_website/static/fonts/PTS75F-webfont.ttf and /dev/null differ diff --git a/pygraz_website/static/fonts/PTS75F-webfont.woff b/pygraz_website/static/fonts/PTS75F-webfont.woff deleted file mode 100755 index 9857a06..0000000 Binary files a/pygraz_website/static/fonts/PTS75F-webfont.woff and /dev/null differ diff --git a/pygraz_website/static/fonts/PTS76F-webfont.eot b/pygraz_website/static/fonts/PTS76F-webfont.eot deleted file mode 100755 index 2066ce5..0000000 Binary files a/pygraz_website/static/fonts/PTS76F-webfont.eot and /dev/null differ diff --git a/pygraz_website/static/fonts/PTS76F-webfont.svg b/pygraz_website/static/fonts/PTS76F-webfont.svg deleted file mode 100755 index b27d760..0000000 --- a/pygraz_website/static/fonts/PTS76F-webfont.svg +++ /dev/null @@ -1,157 +0,0 @@ - - - - -This is a custom SVG webfont generated by Font Squirrel. -Copyright : Copyright 2009 ParaType Ltd All rights reserved -Designer : AKorolkova OUmpeleva VYefimov -Foundry : ParaType Ltd -Foundry URL : httpwwwparatypecom - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/pygraz_website/static/fonts/PTS76F-webfont.ttf b/pygraz_website/static/fonts/PTS76F-webfont.ttf deleted file mode 100755 index 6e146b6..0000000 Binary files a/pygraz_website/static/fonts/PTS76F-webfont.ttf and /dev/null differ diff --git a/pygraz_website/static/fonts/PTS76F-webfont.woff b/pygraz_website/static/fonts/PTS76F-webfont.woff deleted file mode 100755 index 30dbeb7..0000000 Binary files a/pygraz_website/static/fonts/PTS76F-webfont.woff and /dev/null differ diff --git a/pygraz_website/static/fonts/Paratype PT Sans Free Font License.txt b/pygraz_website/static/fonts/Paratype PT Sans Free Font License.txt deleted file mode 100755 index 9a82436..0000000 --- a/pygraz_website/static/fonts/Paratype PT Sans Free Font License.txt +++ /dev/null @@ -1,26 +0,0 @@ -Copyright © 2009 ParaType Ltd. -with Reserved Names "PT Sans" and "ParaType". - -FONT LICENSE - -PERMISSION & CONDITIONS -Permission is hereby granted, free of charge, to any person obtaining a copy of the font software, to use, study, copy, merge, embed, modify, redistribute, and sell modified and unmodified copies of the font software, subject to the following conditions: - -1) Neither the font software nor any of its individual components, in original or modified versions, may be sold by itself. - -2) Original or modified versions of the font software may be bundled, redistributed and/or sold with any software, provided that each copy contains the above copyright notice and this license. These can be included either as stand-alone text files, human-readable headers or in the appropriate machine-readable metadata fields within text or binary files as long as those fields can be easily viewed by the user. - -3) No modified version of the font software may use the Reserved Name(s) or combinations of Reserved Names with other words unless explicit written permission is granted by the ParaType. This restriction only applies to the primary font name as presented to the users. - -4) The name of ParaType or the author(s) of the font software shall not be used to promote, endorse or advertise any modified version, except to acknowledge the contribution(s) of ParaType and the author(s) or with explicit written permission of ParaType. - -5) The font software, modified or unmodified, in part or in whole, must be distributed entirely under this license, and must not be distributed under any other license. The requirement for fonts to remain under this license does not apply to any document created using the Font Software. - -TERMINATION & TERRITORY -This license has no limits on time and territory, but it becomes null and void if any of the above conditions are not met. - -DISCLAIMER -THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL PARATYPE BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE FONT SOFTWARE. - -ParaType Ltd -http://www.paratype.ru diff --git a/pygraz_website/static/imgs/base-bg.jpg b/pygraz_website/static/imgs/base-bg.jpg deleted file mode 100644 index 7d51d63..0000000 Binary files a/pygraz_website/static/imgs/base-bg.jpg and /dev/null differ diff --git a/pygraz_website/static/imgs/gplus-64.png b/pygraz_website/static/imgs/gplus-64.png deleted file mode 100644 index c2baf76..0000000 Binary files a/pygraz_website/static/imgs/gplus-64.png and /dev/null differ diff --git a/pygraz_website/static/imgs/logo.png b/pygraz_website/static/imgs/logo.png deleted file mode 100644 index 68c2cfb..0000000 Binary files a/pygraz_website/static/imgs/logo.png and /dev/null differ diff --git a/pygraz_website/static/imgs/meetup-logo.png b/pygraz_website/static/imgs/meetup-logo.png deleted file mode 100644 index e7162c5..0000000 Binary files a/pygraz_website/static/imgs/meetup-logo.png and /dev/null differ diff --git a/pygraz_website/static/imgs/toparrow-bg.png b/pygraz_website/static/imgs/toparrow-bg.png deleted file mode 100644 index ef88868..0000000 Binary files a/pygraz_website/static/imgs/toparrow-bg.png and /dev/null differ diff --git a/pygraz_website/static/imgs/toparrow-bg.pxm b/pygraz_website/static/imgs/toparrow-bg.pxm deleted file mode 100644 index a2c9137..0000000 Binary files a/pygraz_website/static/imgs/toparrow-bg.pxm and /dev/null differ diff --git a/pygraz_website/static/js/jquery-1.7.2.min.js b/pygraz_website/static/js/jquery-1.7.2.min.js deleted file mode 100644 index 0bc0d83..0000000 --- a/pygraz_website/static/js/jquery-1.7.2.min.js +++ /dev/null @@ -1,5405 +0,0 @@ -/*! jQuery v1.7.2 jquery.com | jquery.org/license */ -(function (a, b) { - function cy(a) { - return f.isWindow(a) - ? a - : a.nodeType === 9 - ? a.defaultView || a.parentWindow - : !1; - } - function cu(a) { - if (!cj[a]) { - var b = c.body, - d = f("<" + a + ">").appendTo(b), - e = d.css("display"); - d.remove(); - if (e === "none" || e === "") { - ck || - ((ck = c.createElement("iframe")), - (ck.frameBorder = ck.width = ck.height = 0)), - b.appendChild(ck); - if (!cl || !ck.createElement) - (cl = (ck.contentWindow || ck.contentDocument).document), - cl.write( - (f.support.boxModel ? "" : "") + "", - ), - cl.close(); - (d = cl.createElement(a)), - cl.body.appendChild(d), - (e = f.css(d, "display")), - b.removeChild(ck); - } - cj[a] = e; - } - return cj[a]; - } - function ct(a, b) { - var c = {}; - f.each(cp.concat.apply([], cp.slice(0, b)), function () { - c[this] = a; - }); - return c; - } - function cs() { - cq = b; - } - function cr() { - setTimeout(cs, 0); - return (cq = f.now()); - } - function ci() { - try { - return new a.ActiveXObject("Microsoft.XMLHTTP"); - } catch (b) {} - } - function ch() { - try { - return new a.XMLHttpRequest(); - } catch (b) {} - } - function cb(a, c) { - a.dataFilter && (c = a.dataFilter(c, a.dataType)); - var d = a.dataTypes, - e = {}, - g, - h, - i = d.length, - j, - k = d[0], - l, - m, - n, - o, - p; - for (g = 1; g < i; g++) { - if (g === 1) - for (h in a.converters) - typeof h == "string" && (e[h.toLowerCase()] = a.converters[h]); - (l = k), (k = d[g]); - if (k === "*") k = l; - else if (l !== "*" && l !== k) { - (m = l + " " + k), (n = e[m] || e["* " + k]); - if (!n) { - p = b; - for (o in e) { - j = o.split(" "); - if (j[0] === l || j[0] === "*") { - p = e[j[1] + " " + k]; - if (p) { - (o = e[o]), o === !0 ? (n = p) : p === !0 && (n = o); - break; - } - } - } - } - !n && !p && f.error("No conversion from " + m.replace(" ", " to ")), - n !== !0 && (c = n ? n(c) : p(o(c))); - } - } - return c; - } - function ca(a, c, d) { - var e = a.contents, - f = a.dataTypes, - g = a.responseFields, - h, - i, - j, - k; - for (i in g) i in d && (c[g[i]] = d[i]); - while (f[0] === "*") - f.shift(), - h === b && (h = a.mimeType || c.getResponseHeader("content-type")); - if (h) - for (i in e) - if (e[i] && e[i].test(h)) { - f.unshift(i); - break; - } - if (f[0] in d) j = f[0]; - else { - for (i in d) { - if (!f[0] || a.converters[i + " " + f[0]]) { - j = i; - break; - } - k || (k = i); - } - j = j || k; - } - if (j) { - j !== f[0] && f.unshift(j); - return d[j]; - } - } - function b_(a, b, c, d) { - if (f.isArray(b)) - f.each(b, function (b, e) { - c || bD.test(a) - ? d(a, e) - : b_(a + "[" + (typeof e == "object" ? b : "") + "]", e, c, d); - }); - else if (!c && f.type(b) === "object") - for (var e in b) b_(a + "[" + e + "]", b[e], c, d); - else d(a, b); - } - function b$(a, c) { - var d, - e, - g = f.ajaxSettings.flatOptions || {}; - for (d in c) c[d] !== b && ((g[d] ? a : e || (e = {}))[d] = c[d]); - e && f.extend(!0, a, e); - } - function bZ(a, c, d, e, f, g) { - (f = f || c.dataTypes[0]), (g = g || {}), (g[f] = !0); - var h = a[f], - i = 0, - j = h ? h.length : 0, - k = a === bS, - l; - for (; i < j && (k || !l); i++) - (l = h[i](c, d, e)), - typeof l == "string" && - (!k || g[l] - ? (l = b) - : (c.dataTypes.unshift(l), (l = bZ(a, c, d, e, l, g)))); - (k || !l) && !g["*"] && (l = bZ(a, c, d, e, "*", g)); - return l; - } - function bY(a) { - return function (b, c) { - typeof b != "string" && ((c = b), (b = "*")); - if (f.isFunction(c)) { - var d = b.toLowerCase().split(bO), - e = 0, - g = d.length, - h, - i, - j; - for (; e < g; e++) - (h = d[e]), - (j = /^\+/.test(h)), - j && (h = h.substr(1) || "*"), - (i = a[h] = a[h] || []), - i[j ? "unshift" : "push"](c); - } - }; - } - function bB(a, b, c) { - var d = b === "width" ? a.offsetWidth : a.offsetHeight, - e = b === "width" ? 1 : 0, - g = 4; - if (d > 0) { - if (c !== "border") - for (; e < g; e += 2) - c || (d -= parseFloat(f.css(a, "padding" + bx[e])) || 0), - c === "margin" - ? (d += parseFloat(f.css(a, c + bx[e])) || 0) - : (d -= parseFloat(f.css(a, "border" + bx[e] + "Width")) || 0); - return d + "px"; - } - d = by(a, b); - if (d < 0 || d == null) d = a.style[b]; - if (bt.test(d)) return d; - d = parseFloat(d) || 0; - if (c) - for (; e < g; e += 2) - (d += parseFloat(f.css(a, "padding" + bx[e])) || 0), - c !== "padding" && - (d += parseFloat(f.css(a, "border" + bx[e] + "Width")) || 0), - c === "margin" && (d += parseFloat(f.css(a, c + bx[e])) || 0); - return d + "px"; - } - function bo(a) { - var b = c.createElement("div"); - bh.appendChild(b), (b.innerHTML = a.outerHTML); - return b.firstChild; - } - function bn(a) { - var b = (a.nodeName || "").toLowerCase(); - b === "input" - ? bm(a) - : b !== "script" && - typeof a.getElementsByTagName != "undefined" && - f.grep(a.getElementsByTagName("input"), bm); - } - function bm(a) { - if (a.type === "checkbox" || a.type === "radio") - a.defaultChecked = a.checked; - } - function bl(a) { - return typeof a.getElementsByTagName != "undefined" - ? a.getElementsByTagName("*") - : typeof a.querySelectorAll != "undefined" - ? a.querySelectorAll("*") - : []; - } - function bk(a, b) { - var c; - b.nodeType === 1 && - (b.clearAttributes && b.clearAttributes(), - b.mergeAttributes && b.mergeAttributes(a), - (c = b.nodeName.toLowerCase()), - c === "object" - ? (b.outerHTML = a.outerHTML) - : c !== "input" || (a.type !== "checkbox" && a.type !== "radio") - ? c === "option" - ? (b.selected = a.defaultSelected) - : c === "input" || c === "textarea" - ? (b.defaultValue = a.defaultValue) - : c === "script" && b.text !== a.text && (b.text = a.text) - : (a.checked && (b.defaultChecked = b.checked = a.checked), - b.value !== a.value && (b.value = a.value)), - b.removeAttribute(f.expando), - b.removeAttribute("_submit_attached"), - b.removeAttribute("_change_attached")); - } - function bj(a, b) { - if (b.nodeType === 1 && !!f.hasData(a)) { - var c, - d, - e, - g = f._data(a), - h = f._data(b, g), - i = g.events; - if (i) { - delete h.handle, (h.events = {}); - for (c in i) - for (d = 0, e = i[c].length; d < e; d++) f.event.add(b, c, i[c][d]); - } - h.data && (h.data = f.extend({}, h.data)); - } - } - function bi(a, b) { - return f.nodeName(a, "table") - ? a.getElementsByTagName("tbody")[0] || - a.appendChild(a.ownerDocument.createElement("tbody")) - : a; - } - function U(a) { - var b = V.split("|"), - c = a.createDocumentFragment(); - if (c.createElement) while (b.length) c.createElement(b.pop()); - return c; - } - function T(a, b, c) { - b = b || 0; - if (f.isFunction(b)) - return f.grep(a, function (a, d) { - var e = !!b.call(a, d, a); - return e === c; - }); - if (b.nodeType) - return f.grep(a, function (a, d) { - return (a === b) === c; - }); - if (typeof b == "string") { - var d = f.grep(a, function (a) { - return a.nodeType === 1; - }); - if (O.test(b)) return f.filter(b, d, !c); - b = f.filter(b, d); - } - return f.grep(a, function (a, d) { - return f.inArray(a, b) >= 0 === c; - }); - } - function S(a) { - return !a || !a.parentNode || a.parentNode.nodeType === 11; - } - function K() { - return !0; - } - function J() { - return !1; - } - function n(a, b, c) { - var d = b + "defer", - e = b + "queue", - g = b + "mark", - h = f._data(a, d); - h && - (c === "queue" || !f._data(a, e)) && - (c === "mark" || !f._data(a, g)) && - setTimeout(function () { - !f._data(a, e) && !f._data(a, g) && (f.removeData(a, d, !0), h.fire()); - }, 0); - } - function m(a) { - for (var b in a) { - if (b === "data" && f.isEmptyObject(a[b])) continue; - if (b !== "toJSON") return !1; - } - return !0; - } - function l(a, c, d) { - if (d === b && a.nodeType === 1) { - var e = "data-" + c.replace(k, "-$1").toLowerCase(); - d = a.getAttribute(e); - if (typeof d == "string") { - try { - d = - d === "true" - ? !0 - : d === "false" - ? !1 - : d === "null" - ? null - : f.isNumeric(d) - ? +d - : j.test(d) - ? f.parseJSON(d) - : d; - } catch (g) {} - f.data(a, c, d); - } else d = b; - } - return d; - } - function h(a) { - var b = (g[a] = {}), - c, - d; - a = a.split(/\s+/); - for (c = 0, d = a.length; c < d; c++) b[a[c]] = !0; - return b; - } - var c = a.document, - d = a.navigator, - e = a.location, - f = (function () { - function J() { - if (!e.isReady) { - try { - c.documentElement.doScroll("left"); - } catch (a) { - setTimeout(J, 1); - return; - } - e.ready(); - } - } - var e = function (a, b) { - return new e.fn.init(a, b, h); - }, - f = a.jQuery, - g = a.$, - h, - i = /^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/, - j = /\S/, - k = /^\s+/, - l = /\s+$/, - m = /^<(\w+)\s*\/?>(?:<\/\1>)?$/, - n = /^[\],:{}\s]*$/, - o = /\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, - p = /"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, - q = /(?:^|:|,)(?:\s*\[)+/g, - r = /(webkit)[ \/]([\w.]+)/, - s = /(opera)(?:.*version)?[ \/]([\w.]+)/, - t = /(msie) ([\w.]+)/, - u = /(mozilla)(?:.*? rv:([\w.]+))?/, - v = /-([a-z]|[0-9])/gi, - w = /^-ms-/, - x = function (a, b) { - return (b + "").toUpperCase(); - }, - y = d.userAgent, - z, - A, - B, - C = Object.prototype.toString, - D = Object.prototype.hasOwnProperty, - E = Array.prototype.push, - F = Array.prototype.slice, - G = String.prototype.trim, - H = Array.prototype.indexOf, - I = {}; - (e.fn = e.prototype = - { - constructor: e, - init: function (a, d, f) { - var g, h, j, k; - if (!a) return this; - if (a.nodeType) { - (this.context = this[0] = a), (this.length = 1); - return this; - } - if (a === "body" && !d && c.body) { - (this.context = c), - (this[0] = c.body), - (this.selector = a), - (this.length = 1); - return this; - } - if (typeof a == "string") { - a.charAt(0) !== "<" || - a.charAt(a.length - 1) !== ">" || - a.length < 3 - ? (g = i.exec(a)) - : (g = [null, a, null]); - if (g && (g[1] || !d)) { - if (g[1]) { - (d = d instanceof e ? d[0] : d), - (k = d ? d.ownerDocument || d : c), - (j = m.exec(a)), - j - ? e.isPlainObject(d) - ? ((a = [c.createElement(j[1])]), - e.fn.attr.call(a, d, !0)) - : (a = [k.createElement(j[1])]) - : ((j = e.buildFragment([g[1]], [k])), - (a = (j.cacheable ? e.clone(j.fragment) : j.fragment) - .childNodes)); - return e.merge(this, a); - } - h = c.getElementById(g[2]); - if (h && h.parentNode) { - if (h.id !== g[2]) return f.find(a); - (this.length = 1), (this[0] = h); - } - (this.context = c), (this.selector = a); - return this; - } - return !d || d.jquery - ? (d || f).find(a) - : this.constructor(d).find(a); - } - if (e.isFunction(a)) return f.ready(a); - a.selector !== b && - ((this.selector = a.selector), (this.context = a.context)); - return e.makeArray(a, this); - }, - selector: "", - jquery: "1.7.2", - length: 0, - size: function () { - return this.length; - }, - toArray: function () { - return F.call(this, 0); - }, - get: function (a) { - return a == null - ? this.toArray() - : a < 0 - ? this[this.length + a] - : this[a]; - }, - pushStack: function (a, b, c) { - var d = this.constructor(); - e.isArray(a) ? E.apply(d, a) : e.merge(d, a), - (d.prevObject = this), - (d.context = this.context), - b === "find" - ? (d.selector = this.selector + (this.selector ? " " : "") + c) - : b && (d.selector = this.selector + "." + b + "(" + c + ")"); - return d; - }, - each: function (a, b) { - return e.each(this, a, b); - }, - ready: function (a) { - e.bindReady(), A.add(a); - return this; - }, - eq: function (a) { - a = +a; - return a === -1 ? this.slice(a) : this.slice(a, a + 1); - }, - first: function () { - return this.eq(0); - }, - last: function () { - return this.eq(-1); - }, - slice: function () { - return this.pushStack( - F.apply(this, arguments), - "slice", - F.call(arguments).join(","), - ); - }, - map: function (a) { - return this.pushStack( - e.map(this, function (b, c) { - return a.call(b, c, b); - }), - ); - }, - end: function () { - return this.prevObject || this.constructor(null); - }, - push: E, - sort: [].sort, - splice: [].splice, - }), - (e.fn.init.prototype = e.fn), - (e.extend = e.fn.extend = - function () { - var a, - c, - d, - f, - g, - h, - i = arguments[0] || {}, - j = 1, - k = arguments.length, - l = !1; - typeof i == "boolean" && - ((l = i), (i = arguments[1] || {}), (j = 2)), - typeof i != "object" && !e.isFunction(i) && (i = {}), - k === j && ((i = this), --j); - for (; j < k; j++) - if ((a = arguments[j]) != null) - for (c in a) { - (d = i[c]), (f = a[c]); - if (i === f) continue; - l && f && (e.isPlainObject(f) || (g = e.isArray(f))) - ? (g - ? ((g = !1), (h = d && e.isArray(d) ? d : [])) - : (h = d && e.isPlainObject(d) ? d : {}), - (i[c] = e.extend(l, h, f))) - : f !== b && (i[c] = f); - } - return i; - }), - e.extend({ - noConflict: function (b) { - a.$ === e && (a.$ = g), b && a.jQuery === e && (a.jQuery = f); - return e; - }, - isReady: !1, - readyWait: 1, - holdReady: function (a) { - a ? e.readyWait++ : e.ready(!0); - }, - ready: function (a) { - if ((a === !0 && !--e.readyWait) || (a !== !0 && !e.isReady)) { - if (!c.body) return setTimeout(e.ready, 1); - e.isReady = !0; - if (a !== !0 && --e.readyWait > 0) return; - A.fireWith(c, [e]), - e.fn.trigger && e(c).trigger("ready").off("ready"); - } - }, - bindReady: function () { - if (!A) { - A = e.Callbacks("once memory"); - if (c.readyState === "complete") return setTimeout(e.ready, 1); - if (c.addEventListener) - c.addEventListener("DOMContentLoaded", B, !1), - a.addEventListener("load", e.ready, !1); - else if (c.attachEvent) { - c.attachEvent("onreadystatechange", B), - a.attachEvent("onload", e.ready); - var b = !1; - try { - b = a.frameElement == null; - } catch (d) {} - c.documentElement.doScroll && b && J(); - } - } - }, - isFunction: function (a) { - return e.type(a) === "function"; - }, - isArray: - Array.isArray || - function (a) { - return e.type(a) === "array"; - }, - isWindow: function (a) { - return a != null && a == a.window; - }, - isNumeric: function (a) { - return !isNaN(parseFloat(a)) && isFinite(a); - }, - type: function (a) { - return a == null ? String(a) : I[C.call(a)] || "object"; - }, - isPlainObject: function (a) { - if (!a || e.type(a) !== "object" || a.nodeType || e.isWindow(a)) - return !1; - try { - if ( - a.constructor && - !D.call(a, "constructor") && - !D.call(a.constructor.prototype, "isPrototypeOf") - ) - return !1; - } catch (c) { - return !1; - } - var d; - for (d in a); - return d === b || D.call(a, d); - }, - isEmptyObject: function (a) { - for (var b in a) return !1; - return !0; - }, - error: function (a) { - throw new Error(a); - }, - parseJSON: function (b) { - if (typeof b != "string" || !b) return null; - b = e.trim(b); - if (a.JSON && a.JSON.parse) return a.JSON.parse(b); - if (n.test(b.replace(o, "@").replace(p, "]").replace(q, ""))) - return new Function("return " + b)(); - e.error("Invalid JSON: " + b); - }, - parseXML: function (c) { - if (typeof c != "string" || !c) return null; - var d, f; - try { - a.DOMParser - ? ((f = new DOMParser()), - (d = f.parseFromString(c, "text/xml"))) - : ((d = new ActiveXObject("Microsoft.XMLDOM")), - (d.async = "false"), - d.loadXML(c)); - } catch (g) { - d = b; - } - (!d || - !d.documentElement || - d.getElementsByTagName("parsererror").length) && - e.error("Invalid XML: " + c); - return d; - }, - noop: function () {}, - globalEval: function (b) { - b && - j.test(b) && - ( - a.execScript || - function (b) { - a.eval.call(a, b); - } - )(b); - }, - camelCase: function (a) { - return a.replace(w, "ms-").replace(v, x); - }, - nodeName: function (a, b) { - return a.nodeName && a.nodeName.toUpperCase() === b.toUpperCase(); - }, - each: function (a, c, d) { - var f, - g = 0, - h = a.length, - i = h === b || e.isFunction(a); - if (d) { - if (i) { - for (f in a) if (c.apply(a[f], d) === !1) break; - } else for (; g < h; ) if (c.apply(a[g++], d) === !1) break; - } else if (i) { - for (f in a) if (c.call(a[f], f, a[f]) === !1) break; - } else for (; g < h; ) if (c.call(a[g], g, a[g++]) === !1) break; - return a; - }, - trim: G - ? function (a) { - return a == null ? "" : G.call(a); - } - : function (a) { - return a == null ? "" : (a + "").replace(k, "").replace(l, ""); - }, - makeArray: function (a, b) { - var c = b || []; - if (a != null) { - var d = e.type(a); - a.length == null || - d === "string" || - d === "function" || - d === "regexp" || - e.isWindow(a) - ? E.call(c, a) - : e.merge(c, a); - } - return c; - }, - inArray: function (a, b, c) { - var d; - if (b) { - if (H) return H.call(b, a, c); - (d = b.length), (c = c ? (c < 0 ? Math.max(0, d + c) : c) : 0); - for (; c < d; c++) if (c in b && b[c] === a) return c; - } - return -1; - }, - merge: function (a, c) { - var d = a.length, - e = 0; - if (typeof c.length == "number") - for (var f = c.length; e < f; e++) a[d++] = c[e]; - else while (c[e] !== b) a[d++] = c[e++]; - a.length = d; - return a; - }, - grep: function (a, b, c) { - var d = [], - e; - c = !!c; - for (var f = 0, g = a.length; f < g; f++) - (e = !!b(a[f], f)), c !== e && d.push(a[f]); - return d; - }, - map: function (a, c, d) { - var f, - g, - h = [], - i = 0, - j = a.length, - k = - a instanceof e || - (j !== b && - typeof j == "number" && - ((j > 0 && a[0] && a[j - 1]) || j === 0 || e.isArray(a))); - if (k) - for (; i < j; i++) - (f = c(a[i], i, d)), f != null && (h[h.length] = f); - else - for (g in a) (f = c(a[g], g, d)), f != null && (h[h.length] = f); - return h.concat.apply([], h); - }, - guid: 1, - proxy: function (a, c) { - if (typeof c == "string") { - var d = a[c]; - (c = a), (a = d); - } - if (!e.isFunction(a)) return b; - var f = F.call(arguments, 2), - g = function () { - return a.apply(c, f.concat(F.call(arguments))); - }; - g.guid = a.guid = a.guid || g.guid || e.guid++; - return g; - }, - access: function (a, c, d, f, g, h, i) { - var j, - k = d == null, - l = 0, - m = a.length; - if (d && typeof d == "object") { - for (l in d) e.access(a, c, l, d[l], 1, h, f); - g = 1; - } else if (f !== b) { - (j = i === b && e.isFunction(f)), - k && - (j - ? ((j = c), - (c = function (a, b, c) { - return j.call(e(a), c); - })) - : (c.call(a, f), (c = null))); - if (c) - for (; l < m; l++) - c(a[l], d, j ? f.call(a[l], l, c(a[l], d)) : f, i); - g = 1; - } - return g ? a : k ? c.call(a) : m ? c(a[0], d) : h; - }, - now: function () { - return new Date().getTime(); - }, - uaMatch: function (a) { - a = a.toLowerCase(); - var b = - r.exec(a) || - s.exec(a) || - t.exec(a) || - (a.indexOf("compatible") < 0 && u.exec(a)) || - []; - return { browser: b[1] || "", version: b[2] || "0" }; - }, - sub: function () { - function a(b, c) { - return new a.fn.init(b, c); - } - e.extend(!0, a, this), - (a.superclass = this), - (a.fn = a.prototype = this()), - (a.fn.constructor = a), - (a.sub = this.sub), - (a.fn.init = function (d, f) { - f && f instanceof e && !(f instanceof a) && (f = a(f)); - return e.fn.init.call(this, d, f, b); - }), - (a.fn.init.prototype = a.fn); - var b = a(c); - return a; - }, - browser: {}, - }), - e.each( - "Boolean Number String Function Array Date RegExp Object".split(" "), - function (a, b) { - I["[object " + b + "]"] = b.toLowerCase(); - }, - ), - (z = e.uaMatch(y)), - z.browser && - ((e.browser[z.browser] = !0), (e.browser.version = z.version)), - e.browser.webkit && (e.browser.safari = !0), - j.test(" ") && ((k = /^[\s\xA0]+/), (l = /[\s\xA0]+$/)), - (h = e(c)), - c.addEventListener - ? (B = function () { - c.removeEventListener("DOMContentLoaded", B, !1), e.ready(); - }) - : c.attachEvent && - (B = function () { - c.readyState === "complete" && - (c.detachEvent("onreadystatechange", B), e.ready()); - }); - return e; - })(), - g = {}; - f.Callbacks = function (a) { - a = a ? g[a] || h(a) : {}; - var c = [], - d = [], - e, - i, - j, - k, - l, - m, - n = function (b) { - var d, e, g, h, i; - for (d = 0, e = b.length; d < e; d++) - (g = b[d]), - (h = f.type(g)), - h === "array" - ? n(g) - : h === "function" && (!a.unique || !p.has(g)) && c.push(g); - }, - o = function (b, f) { - (f = f || []), - (e = !a.memory || [b, f]), - (i = !0), - (j = !0), - (m = k || 0), - (k = 0), - (l = c.length); - for (; c && m < l; m++) - if (c[m].apply(b, f) === !1 && a.stopOnFalse) { - e = !0; - break; - } - (j = !1), - c && - (a.once - ? e === !0 - ? p.disable() - : (c = []) - : d && d.length && ((e = d.shift()), p.fireWith(e[0], e[1]))); - }, - p = { - add: function () { - if (c) { - var a = c.length; - n(arguments), - j ? (l = c.length) : e && e !== !0 && ((k = a), o(e[0], e[1])); - } - return this; - }, - remove: function () { - if (c) { - var b = arguments, - d = 0, - e = b.length; - for (; d < e; d++) - for (var f = 0; f < c.length; f++) - if (b[d] === c[f]) { - j && f <= l && (l--, f <= m && m--), c.splice(f--, 1); - if (a.unique) break; - } - } - return this; - }, - has: function (a) { - if (c) { - var b = 0, - d = c.length; - for (; b < d; b++) if (a === c[b]) return !0; - } - return !1; - }, - empty: function () { - c = []; - return this; - }, - disable: function () { - c = d = e = b; - return this; - }, - disabled: function () { - return !c; - }, - lock: function () { - (d = b), (!e || e === !0) && p.disable(); - return this; - }, - locked: function () { - return !d; - }, - fireWith: function (b, c) { - d && (j ? a.once || d.push([b, c]) : (!a.once || !e) && o(b, c)); - return this; - }, - fire: function () { - p.fireWith(this, arguments); - return this; - }, - fired: function () { - return !!i; - }, - }; - return p; - }; - var i = [].slice; - f.extend({ - Deferred: function (a) { - var b = f.Callbacks("once memory"), - c = f.Callbacks("once memory"), - d = f.Callbacks("memory"), - e = "pending", - g = { resolve: b, reject: c, notify: d }, - h = { - done: b.add, - fail: c.add, - progress: d.add, - state: function () { - return e; - }, - isResolved: b.fired, - isRejected: c.fired, - then: function (a, b, c) { - i.done(a).fail(b).progress(c); - return this; - }, - always: function () { - i.done.apply(i, arguments).fail.apply(i, arguments); - return this; - }, - pipe: function (a, b, c) { - return f - .Deferred(function (d) { - f.each( - { - done: [a, "resolve"], - fail: [b, "reject"], - progress: [c, "notify"], - }, - function (a, b) { - var c = b[0], - e = b[1], - g; - f.isFunction(c) - ? i[a](function () { - (g = c.apply(this, arguments)), - g && f.isFunction(g.promise) - ? g.promise().then(d.resolve, d.reject, d.notify) - : d[e + "With"](this === i ? d : this, [g]); - }) - : i[a](d[e]); - }, - ); - }) - .promise(); - }, - promise: function (a) { - if (a == null) a = h; - else for (var b in h) a[b] = h[b]; - return a; - }, - }, - i = h.promise({}), - j; - for (j in g) (i[j] = g[j].fire), (i[j + "With"] = g[j].fireWith); - i - .done( - function () { - e = "resolved"; - }, - c.disable, - d.lock, - ) - .fail( - function () { - e = "rejected"; - }, - b.disable, - d.lock, - ), - a && a.call(i, i); - return i; - }, - when: function (a) { - function m(a) { - return function (b) { - (e[a] = arguments.length > 1 ? i.call(arguments, 0) : b), - j.notifyWith(k, e); - }; - } - function l(a) { - return function (c) { - (b[a] = arguments.length > 1 ? i.call(arguments, 0) : c), - --g || j.resolveWith(j, b); - }; - } - var b = i.call(arguments, 0), - c = 0, - d = b.length, - e = Array(d), - g = d, - h = d, - j = d <= 1 && a && f.isFunction(a.promise) ? a : f.Deferred(), - k = j.promise(); - if (d > 1) { - for (; c < d; c++) - b[c] && b[c].promise && f.isFunction(b[c].promise) - ? b[c].promise().then(l(c), j.reject, m(c)) - : --g; - g || j.resolveWith(j, b); - } else j !== a && j.resolveWith(j, d ? [a] : []); - return k; - }, - }), - (f.support = (function () { - var b, - d, - e, - g, - h, - i, - j, - k, - l, - m, - n, - o, - p = c.createElement("div"), - q = c.documentElement; - p.setAttribute("className", "t"), - (p.innerHTML = - "
a"), - (d = p.getElementsByTagName("*")), - (e = p.getElementsByTagName("a")[0]); - if (!d || !d.length || !e) return {}; - (g = c.createElement("select")), - (h = g.appendChild(c.createElement("option"))), - (i = p.getElementsByTagName("input")[0]), - (b = { - leadingWhitespace: p.firstChild.nodeType === 3, - tbody: !p.getElementsByTagName("tbody").length, - htmlSerialize: !!p.getElementsByTagName("link").length, - style: /top/.test(e.getAttribute("style")), - hrefNormalized: e.getAttribute("href") === "/a", - opacity: /^0.55/.test(e.style.opacity), - cssFloat: !!e.style.cssFloat, - checkOn: i.value === "on", - optSelected: h.selected, - getSetAttribute: p.className !== "t", - enctype: !!c.createElement("form").enctype, - html5Clone: - c.createElement("nav").cloneNode(!0).outerHTML !== "<:nav>", - submitBubbles: !0, - changeBubbles: !0, - focusinBubbles: !1, - deleteExpando: !0, - noCloneEvent: !0, - inlineBlockNeedsLayout: !1, - shrinkWrapBlocks: !1, - reliableMarginRight: !0, - pixelMargin: !0, - }), - (f.boxModel = b.boxModel = c.compatMode === "CSS1Compat"), - (i.checked = !0), - (b.noCloneChecked = i.cloneNode(!0).checked), - (g.disabled = !0), - (b.optDisabled = !h.disabled); - try { - delete p.test; - } catch (r) { - b.deleteExpando = !1; - } - !p.addEventListener && - p.attachEvent && - p.fireEvent && - (p.attachEvent("onclick", function () { - b.noCloneEvent = !1; - }), - p.cloneNode(!0).fireEvent("onclick")), - (i = c.createElement("input")), - (i.value = "t"), - i.setAttribute("type", "radio"), - (b.radioValue = i.value === "t"), - i.setAttribute("checked", "checked"), - i.setAttribute("name", "t"), - p.appendChild(i), - (j = c.createDocumentFragment()), - j.appendChild(p.lastChild), - (b.checkClone = j.cloneNode(!0).cloneNode(!0).lastChild.checked), - (b.appendChecked = i.checked), - j.removeChild(i), - j.appendChild(p); - if (p.attachEvent) - for (n in { submit: 1, change: 1, focusin: 1 }) - (m = "on" + n), - (o = m in p), - o || - (p.setAttribute(m, "return;"), (o = typeof p[m] == "function")), - (b[n + "Bubbles"] = o); - j.removeChild(p), - (j = g = h = p = i = null), - f(function () { - var d, - e, - g, - h, - i, - j, - l, - m, - n, - q, - r, - s, - t, - u = c.getElementsByTagName("body")[0]; - !u || - ((m = 1), - (t = "padding:0;margin:0;border:"), - (r = "position:absolute;top:0;left:0;width:1px;height:1px;"), - (s = t + "0;visibility:hidden;"), - (n = "style='" + r + t + "5px solid #000;"), - (q = - "
" + - "" + - "
"), - (d = c.createElement("div")), - (d.style.cssText = - s + - "width:0;height:0;position:static;top:0;margin-top:" + - m + - "px"), - u.insertBefore(d, u.firstChild), - (p = c.createElement("div")), - d.appendChild(p), - (p.innerHTML = - "
t
"), - (k = p.getElementsByTagName("td")), - (o = k[0].offsetHeight === 0), - (k[0].style.display = ""), - (k[1].style.display = "none"), - (b.reliableHiddenOffsets = o && k[0].offsetHeight === 0), - a.getComputedStyle && - ((p.innerHTML = ""), - (l = c.createElement("div")), - (l.style.width = "0"), - (l.style.marginRight = "0"), - (p.style.width = "2px"), - p.appendChild(l), - (b.reliableMarginRight = - (parseInt( - (a.getComputedStyle(l, null) || { marginRight: 0 }) - .marginRight, - 10, - ) || 0) === 0)), - typeof p.style.zoom != "undefined" && - ((p.innerHTML = ""), - (p.style.width = p.style.padding = "1px"), - (p.style.border = 0), - (p.style.overflow = "hidden"), - (p.style.display = "inline"), - (p.style.zoom = 1), - (b.inlineBlockNeedsLayout = p.offsetWidth === 3), - (p.style.display = "block"), - (p.style.overflow = "visible"), - (p.innerHTML = "
"), - (b.shrinkWrapBlocks = p.offsetWidth !== 3)), - (p.style.cssText = r + s), - (p.innerHTML = q), - (e = p.firstChild), - (g = e.firstChild), - (i = e.nextSibling.firstChild.firstChild), - (j = { - doesNotAddBorder: g.offsetTop !== 5, - doesAddBorderForTableAndCells: i.offsetTop === 5, - }), - (g.style.position = "fixed"), - (g.style.top = "20px"), - (j.fixedPosition = g.offsetTop === 20 || g.offsetTop === 15), - (g.style.position = g.style.top = ""), - (e.style.overflow = "hidden"), - (e.style.position = "relative"), - (j.subtractsBorderForOverflowNotVisible = g.offsetTop === -5), - (j.doesNotIncludeMarginInBodyOffset = u.offsetTop !== m), - a.getComputedStyle && - ((p.style.marginTop = "1%"), - (b.pixelMargin = - (a.getComputedStyle(p, null) || { marginTop: 0 }).marginTop !== - "1%")), - typeof d.style.zoom != "undefined" && (d.style.zoom = 1), - u.removeChild(d), - (l = p = d = null), - f.extend(b, j)); - }); - return b; - })()); - var j = /^(?:\{.*\}|\[.*\])$/, - k = /([A-Z])/g; - f.extend({ - cache: {}, - uuid: 0, - expando: "jQuery" + (f.fn.jquery + Math.random()).replace(/\D/g, ""), - noData: { - embed: !0, - object: "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000", - applet: !0, - }, - hasData: function (a) { - a = a.nodeType ? f.cache[a[f.expando]] : a[f.expando]; - return !!a && !m(a); - }, - data: function (a, c, d, e) { - if (!!f.acceptData(a)) { - var g, - h, - i, - j = f.expando, - k = typeof c == "string", - l = a.nodeType, - m = l ? f.cache : a, - n = l ? a[j] : a[j] && j, - o = c === "events"; - if ((!n || !m[n] || (!o && !e && !m[n].data)) && k && d === b) return; - n || (l ? (a[j] = n = ++f.uuid) : (n = j)), - m[n] || ((m[n] = {}), l || (m[n].toJSON = f.noop)); - if (typeof c == "object" || typeof c == "function") - e ? (m[n] = f.extend(m[n], c)) : (m[n].data = f.extend(m[n].data, c)); - (g = h = m[n]), - e || (h.data || (h.data = {}), (h = h.data)), - d !== b && (h[f.camelCase(c)] = d); - if (o && !h[c]) return g.events; - k ? ((i = h[c]), i == null && (i = h[f.camelCase(c)])) : (i = h); - return i; - } - }, - removeData: function (a, b, c) { - if (!!f.acceptData(a)) { - var d, - e, - g, - h = f.expando, - i = a.nodeType, - j = i ? f.cache : a, - k = i ? a[h] : h; - if (!j[k]) return; - if (b) { - d = c ? j[k] : j[k].data; - if (d) { - f.isArray(b) || - (b in d - ? (b = [b]) - : ((b = f.camelCase(b)), - b in d ? (b = [b]) : (b = b.split(" ")))); - for (e = 0, g = b.length; e < g; e++) delete d[b[e]]; - if (!(c ? m : f.isEmptyObject)(d)) return; - } - } - if (!c) { - delete j[k].data; - if (!m(j[k])) return; - } - f.support.deleteExpando || !j.setInterval ? delete j[k] : (j[k] = null), - i && - (f.support.deleteExpando - ? delete a[h] - : a.removeAttribute - ? a.removeAttribute(h) - : (a[h] = null)); - } - }, - _data: function (a, b, c) { - return f.data(a, b, c, !0); - }, - acceptData: function (a) { - if (a.nodeName) { - var b = f.noData[a.nodeName.toLowerCase()]; - if (b) return b !== !0 && a.getAttribute("classid") === b; - } - return !0; - }, - }), - f.fn.extend({ - data: function (a, c) { - var d, - e, - g, - h, - i, - j = this[0], - k = 0, - m = null; - if (a === b) { - if (this.length) { - m = f.data(j); - if (j.nodeType === 1 && !f._data(j, "parsedAttrs")) { - g = j.attributes; - for (i = g.length; k < i; k++) - (h = g[k].name), - h.indexOf("data-") === 0 && - ((h = f.camelCase(h.substring(5))), l(j, h, m[h])); - f._data(j, "parsedAttrs", !0); - } - } - return m; - } - if (typeof a == "object") - return this.each(function () { - f.data(this, a); - }); - (d = a.split(".", 2)), - (d[1] = d[1] ? "." + d[1] : ""), - (e = d[1] + "!"); - return f.access( - this, - function (c) { - if (c === b) { - (m = this.triggerHandler("getData" + e, [d[0]])), - m === b && j && ((m = f.data(j, a)), (m = l(j, a, m))); - return m === b && d[1] ? this.data(d[0]) : m; - } - (d[1] = c), - this.each(function () { - var b = f(this); - b.triggerHandler("setData" + e, d), - f.data(this, a, c), - b.triggerHandler("changeData" + e, d); - }); - }, - null, - c, - arguments.length > 1, - null, - !1, - ); - }, - removeData: function (a) { - return this.each(function () { - f.removeData(this, a); - }); - }, - }), - f.extend({ - _mark: function (a, b) { - a && - ((b = (b || "fx") + "mark"), f._data(a, b, (f._data(a, b) || 0) + 1)); - }, - _unmark: function (a, b, c) { - a !== !0 && ((c = b), (b = a), (a = !1)); - if (b) { - c = c || "fx"; - var d = c + "mark", - e = a ? 0 : (f._data(b, d) || 1) - 1; - e ? f._data(b, d, e) : (f.removeData(b, d, !0), n(b, c, "mark")); - } - }, - queue: function (a, b, c) { - var d; - if (a) { - (b = (b || "fx") + "queue"), - (d = f._data(a, b)), - c && - (!d || f.isArray(c) - ? (d = f._data(a, b, f.makeArray(c))) - : d.push(c)); - return d || []; - } - }, - dequeue: function (a, b) { - b = b || "fx"; - var c = f.queue(a, b), - d = c.shift(), - e = {}; - d === "inprogress" && (d = c.shift()), - d && - (b === "fx" && c.unshift("inprogress"), - f._data(a, b + ".run", e), - d.call( - a, - function () { - f.dequeue(a, b); - }, - e, - )), - c.length || - (f.removeData(a, b + "queue " + b + ".run", !0), n(a, b, "queue")); - }, - }), - f.fn.extend({ - queue: function (a, c) { - var d = 2; - typeof a != "string" && ((c = a), (a = "fx"), d--); - if (arguments.length < d) return f.queue(this[0], a); - return c === b - ? this - : this.each(function () { - var b = f.queue(this, a, c); - a === "fx" && b[0] !== "inprogress" && f.dequeue(this, a); - }); - }, - dequeue: function (a) { - return this.each(function () { - f.dequeue(this, a); - }); - }, - delay: function (a, b) { - (a = f.fx ? f.fx.speeds[a] || a : a), (b = b || "fx"); - return this.queue(b, function (b, c) { - var d = setTimeout(b, a); - c.stop = function () { - clearTimeout(d); - }; - }); - }, - clearQueue: function (a) { - return this.queue(a || "fx", []); - }, - promise: function (a, c) { - function m() { - --h || d.resolveWith(e, [e]); - } - typeof a != "string" && ((c = a), (a = b)), (a = a || "fx"); - var d = f.Deferred(), - e = this, - g = e.length, - h = 1, - i = a + "defer", - j = a + "queue", - k = a + "mark", - l; - while (g--) - if ( - (l = - f.data(e[g], i, b, !0) || - ((f.data(e[g], j, b, !0) || f.data(e[g], k, b, !0)) && - f.data(e[g], i, f.Callbacks("once memory"), !0))) - ) - h++, l.add(m); - m(); - return d.promise(c); - }, - }); - var o = /[\n\t\r]/g, - p = /\s+/, - q = /\r/g, - r = /^(?:button|input)$/i, - s = /^(?:button|input|object|select|textarea)$/i, - t = /^a(?:rea)?$/i, - u = - /^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i, - v = f.support.getSetAttribute, - w, - x, - y; - f.fn.extend({ - attr: function (a, b) { - return f.access(this, f.attr, a, b, arguments.length > 1); - }, - removeAttr: function (a) { - return this.each(function () { - f.removeAttr(this, a); - }); - }, - prop: function (a, b) { - return f.access(this, f.prop, a, b, arguments.length > 1); - }, - removeProp: function (a) { - a = f.propFix[a] || a; - return this.each(function () { - try { - (this[a] = b), delete this[a]; - } catch (c) {} - }); - }, - addClass: function (a) { - var b, c, d, e, g, h, i; - if (f.isFunction(a)) - return this.each(function (b) { - f(this).addClass(a.call(this, b, this.className)); - }); - if (a && typeof a == "string") { - b = a.split(p); - for (c = 0, d = this.length; c < d; c++) { - e = this[c]; - if (e.nodeType === 1) - if (!e.className && b.length === 1) e.className = a; - else { - g = " " + e.className + " "; - for (h = 0, i = b.length; h < i; h++) - ~g.indexOf(" " + b[h] + " ") || (g += b[h] + " "); - e.className = f.trim(g); - } - } - } - return this; - }, - removeClass: function (a) { - var c, d, e, g, h, i, j; - if (f.isFunction(a)) - return this.each(function (b) { - f(this).removeClass(a.call(this, b, this.className)); - }); - if ((a && typeof a == "string") || a === b) { - c = (a || "").split(p); - for (d = 0, e = this.length; d < e; d++) { - g = this[d]; - if (g.nodeType === 1 && g.className) - if (a) { - h = (" " + g.className + " ").replace(o, " "); - for (i = 0, j = c.length; i < j; i++) - h = h.replace(" " + c[i] + " ", " "); - g.className = f.trim(h); - } else g.className = ""; - } - } - return this; - }, - toggleClass: function (a, b) { - var c = typeof a, - d = typeof b == "boolean"; - if (f.isFunction(a)) - return this.each(function (c) { - f(this).toggleClass(a.call(this, c, this.className, b), b); - }); - return this.each(function () { - if (c === "string") { - var e, - g = 0, - h = f(this), - i = b, - j = a.split(p); - while ((e = j[g++])) - (i = d ? i : !h.hasClass(e)), h[i ? "addClass" : "removeClass"](e); - } else if (c === "undefined" || c === "boolean") - this.className && f._data(this, "__className__", this.className), - (this.className = - this.className || a === !1 - ? "" - : f._data(this, "__className__") || ""); - }); - }, - hasClass: function (a) { - var b = " " + a + " ", - c = 0, - d = this.length; - for (; c < d; c++) - if ( - this[c].nodeType === 1 && - (" " + this[c].className + " ").replace(o, " ").indexOf(b) > -1 - ) - return !0; - return !1; - }, - val: function (a) { - var c, - d, - e, - g = this[0]; - { - if (!!arguments.length) { - e = f.isFunction(a); - return this.each(function (d) { - var g = f(this), - h; - if (this.nodeType === 1) { - e ? (h = a.call(this, d, g.val())) : (h = a), - h == null - ? (h = "") - : typeof h == "number" - ? (h += "") - : f.isArray(h) && - (h = f.map(h, function (a) { - return a == null ? "" : a + ""; - })), - (c = - f.valHooks[this.type] || - f.valHooks[this.nodeName.toLowerCase()]); - if (!c || !("set" in c) || c.set(this, h, "value") === b) - this.value = h; - } - }); - } - if (g) { - c = f.valHooks[g.type] || f.valHooks[g.nodeName.toLowerCase()]; - if (c && "get" in c && (d = c.get(g, "value")) !== b) return d; - d = g.value; - return typeof d == "string" ? d.replace(q, "") : d == null ? "" : d; - } - } - }, - }), - f.extend({ - valHooks: { - option: { - get: function (a) { - var b = a.attributes.value; - return !b || b.specified ? a.value : a.text; - }, - }, - select: { - get: function (a) { - var b, - c, - d, - e, - g = a.selectedIndex, - h = [], - i = a.options, - j = a.type === "select-one"; - if (g < 0) return null; - (c = j ? g : 0), (d = j ? g + 1 : i.length); - for (; c < d; c++) { - e = i[c]; - if ( - e.selected && - (f.support.optDisabled - ? !e.disabled - : e.getAttribute("disabled") === null) && - (!e.parentNode.disabled || - !f.nodeName(e.parentNode, "optgroup")) - ) { - b = f(e).val(); - if (j) return b; - h.push(b); - } - } - if (j && !h.length && i.length) return f(i[g]).val(); - return h; - }, - set: function (a, b) { - var c = f.makeArray(b); - f(a) - .find("option") - .each(function () { - this.selected = f.inArray(f(this).val(), c) >= 0; - }), - c.length || (a.selectedIndex = -1); - return c; - }, - }, - }, - attrFn: { - val: !0, - css: !0, - html: !0, - text: !0, - data: !0, - width: !0, - height: !0, - offset: !0, - }, - attr: function (a, c, d, e) { - var g, - h, - i, - j = a.nodeType; - if (!!a && j !== 3 && j !== 8 && j !== 2) { - if (e && c in f.attrFn) return f(a)[c](d); - if (typeof a.getAttribute == "undefined") return f.prop(a, c, d); - (i = j !== 1 || !f.isXMLDoc(a)), - i && - ((c = c.toLowerCase()), - (h = f.attrHooks[c] || (u.test(c) ? x : w))); - if (d !== b) { - if (d === null) { - f.removeAttr(a, c); - return; - } - if (h && "set" in h && i && (g = h.set(a, d, c)) !== b) return g; - a.setAttribute(c, "" + d); - return d; - } - if (h && "get" in h && i && (g = h.get(a, c)) !== null) return g; - g = a.getAttribute(c); - return g === null ? b : g; - } - }, - removeAttr: function (a, b) { - var c, - d, - e, - g, - h, - i = 0; - if (b && a.nodeType === 1) { - (d = b.toLowerCase().split(p)), (g = d.length); - for (; i < g; i++) - (e = d[i]), - e && - ((c = f.propFix[e] || e), - (h = u.test(e)), - h || f.attr(a, e, ""), - a.removeAttribute(v ? e : c), - h && c in a && (a[c] = !1)); - } - }, - attrHooks: { - type: { - set: function (a, b) { - if (r.test(a.nodeName) && a.parentNode) - f.error("type property can't be changed"); - else if ( - !f.support.radioValue && - b === "radio" && - f.nodeName(a, "input") - ) { - var c = a.value; - a.setAttribute("type", b), c && (a.value = c); - return b; - } - }, - }, - value: { - get: function (a, b) { - if (w && f.nodeName(a, "button")) return w.get(a, b); - return b in a ? a.value : null; - }, - set: function (a, b, c) { - if (w && f.nodeName(a, "button")) return w.set(a, b, c); - a.value = b; - }, - }, - }, - propFix: { - tabindex: "tabIndex", - readonly: "readOnly", - for: "htmlFor", - class: "className", - maxlength: "maxLength", - cellspacing: "cellSpacing", - cellpadding: "cellPadding", - rowspan: "rowSpan", - colspan: "colSpan", - usemap: "useMap", - frameborder: "frameBorder", - contenteditable: "contentEditable", - }, - prop: function (a, c, d) { - var e, - g, - h, - i = a.nodeType; - if (!!a && i !== 3 && i !== 8 && i !== 2) { - (h = i !== 1 || !f.isXMLDoc(a)), - h && ((c = f.propFix[c] || c), (g = f.propHooks[c])); - return d !== b - ? g && "set" in g && (e = g.set(a, d, c)) !== b - ? e - : (a[c] = d) - : g && "get" in g && (e = g.get(a, c)) !== null - ? e - : a[c]; - } - }, - propHooks: { - tabIndex: { - get: function (a) { - var c = a.getAttributeNode("tabindex"); - return c && c.specified - ? parseInt(c.value, 10) - : s.test(a.nodeName) || (t.test(a.nodeName) && a.href) - ? 0 - : b; - }, - }, - }, - }), - (f.attrHooks.tabindex = f.propHooks.tabIndex), - (x = { - get: function (a, c) { - var d, - e = f.prop(a, c); - return e === !0 || - (typeof e != "boolean" && - (d = a.getAttributeNode(c)) && - d.nodeValue !== !1) - ? c.toLowerCase() - : b; - }, - set: function (a, b, c) { - var d; - b === !1 - ? f.removeAttr(a, c) - : ((d = f.propFix[c] || c), - d in a && (a[d] = !0), - a.setAttribute(c, c.toLowerCase())); - return c; - }, - }), - v || - ((y = { name: !0, id: !0, coords: !0 }), - (w = f.valHooks.button = - { - get: function (a, c) { - var d; - d = a.getAttributeNode(c); - return d && (y[c] ? d.nodeValue !== "" : d.specified) - ? d.nodeValue - : b; - }, - set: function (a, b, d) { - var e = a.getAttributeNode(d); - e || ((e = c.createAttribute(d)), a.setAttributeNode(e)); - return (e.nodeValue = b + ""); - }, - }), - (f.attrHooks.tabindex.set = w.set), - f.each(["width", "height"], function (a, b) { - f.attrHooks[b] = f.extend(f.attrHooks[b], { - set: function (a, c) { - if (c === "") { - a.setAttribute(b, "auto"); - return c; - } - }, - }); - }), - (f.attrHooks.contenteditable = { - get: w.get, - set: function (a, b, c) { - b === "" && (b = "false"), w.set(a, b, c); - }, - })), - f.support.hrefNormalized || - f.each(["href", "src", "width", "height"], function (a, c) { - f.attrHooks[c] = f.extend(f.attrHooks[c], { - get: function (a) { - var d = a.getAttribute(c, 2); - return d === null ? b : d; - }, - }); - }), - f.support.style || - (f.attrHooks.style = { - get: function (a) { - return a.style.cssText.toLowerCase() || b; - }, - set: function (a, b) { - return (a.style.cssText = "" + b); - }, - }), - f.support.optSelected || - (f.propHooks.selected = f.extend(f.propHooks.selected, { - get: function (a) { - var b = a.parentNode; - b && (b.selectedIndex, b.parentNode && b.parentNode.selectedIndex); - return null; - }, - })), - f.support.enctype || (f.propFix.enctype = "encoding"), - f.support.checkOn || - f.each(["radio", "checkbox"], function () { - f.valHooks[this] = { - get: function (a) { - return a.getAttribute("value") === null ? "on" : a.value; - }, - }; - }), - f.each(["radio", "checkbox"], function () { - f.valHooks[this] = f.extend(f.valHooks[this], { - set: function (a, b) { - if (f.isArray(b)) return (a.checked = f.inArray(f(a).val(), b) >= 0); - }, - }); - }); - var z = /^(?:textarea|input|select)$/i, - A = /^([^\.]*)?(?:\.(.+))?$/, - B = /(?:^|\s)hover(\.\S+)?\b/, - C = /^key/, - D = /^(?:mouse|contextmenu)|click/, - E = /^(?:focusinfocus|focusoutblur)$/, - F = /^(\w*)(?:#([\w\-]+))?(?:\.([\w\-]+))?$/, - G = function (a) { - var b = F.exec(a); - b && - ((b[1] = (b[1] || "").toLowerCase()), - (b[3] = b[3] && new RegExp("(?:^|\\s)" + b[3] + "(?:\\s|$)"))); - return b; - }, - H = function (a, b) { - var c = a.attributes || {}; - return ( - (!b[1] || a.nodeName.toLowerCase() === b[1]) && - (!b[2] || (c.id || {}).value === b[2]) && - (!b[3] || b[3].test((c["class"] || {}).value)) - ); - }, - I = function (a) { - return f.event.special.hover - ? a - : a.replace(B, "mouseenter$1 mouseleave$1"); - }; - (f.event = { - add: function (a, c, d, e, g) { - var h, i, j, k, l, m, n, o, p, q, r, s; - if ( - !(a.nodeType === 3 || a.nodeType === 8 || !c || !d || !(h = f._data(a))) - ) { - d.handler && ((p = d), (d = p.handler), (g = p.selector)), - d.guid || (d.guid = f.guid++), - (j = h.events), - j || (h.events = j = {}), - (i = h.handle), - i || - ((h.handle = i = - function (a) { - return typeof f != "undefined" && - (!a || f.event.triggered !== a.type) - ? f.event.dispatch.apply(i.elem, arguments) - : b; - }), - (i.elem = a)), - (c = f.trim(I(c)).split(" ")); - for (k = 0; k < c.length; k++) { - (l = A.exec(c[k]) || []), - (m = l[1]), - (n = (l[2] || "").split(".").sort()), - (s = f.event.special[m] || {}), - (m = (g ? s.delegateType : s.bindType) || m), - (s = f.event.special[m] || {}), - (o = f.extend( - { - type: m, - origType: l[1], - data: e, - handler: d, - guid: d.guid, - selector: g, - quick: g && G(g), - namespace: n.join("."), - }, - p, - )), - (r = j[m]); - if (!r) { - (r = j[m] = []), (r.delegateCount = 0); - if (!s.setup || s.setup.call(a, e, n, i) === !1) - a.addEventListener - ? a.addEventListener(m, i, !1) - : a.attachEvent && a.attachEvent("on" + m, i); - } - s.add && - (s.add.call(a, o), o.handler.guid || (o.handler.guid = d.guid)), - g ? r.splice(r.delegateCount++, 0, o) : r.push(o), - (f.event.global[m] = !0); - } - a = null; - } - }, - global: {}, - remove: function (a, b, c, d, e) { - var g = f.hasData(a) && f._data(a), - h, - i, - j, - k, - l, - m, - n, - o, - p, - q, - r, - s; - if (!!g && !!(o = g.events)) { - b = f.trim(I(b || "")).split(" "); - for (h = 0; h < b.length; h++) { - (i = A.exec(b[h]) || []), (j = k = i[1]), (l = i[2]); - if (!j) { - for (j in o) f.event.remove(a, j + b[h], c, d, !0); - continue; - } - (p = f.event.special[j] || {}), - (j = (d ? p.delegateType : p.bindType) || j), - (r = o[j] || []), - (m = r.length), - (l = l - ? new RegExp( - "(^|\\.)" + - l.split(".").sort().join("\\.(?:.*\\.)?") + - "(\\.|$)", - ) - : null); - for (n = 0; n < r.length; n++) - (s = r[n]), - (e || k === s.origType) && - (!c || c.guid === s.guid) && - (!l || l.test(s.namespace)) && - (!d || d === s.selector || (d === "**" && s.selector)) && - (r.splice(n--, 1), - s.selector && r.delegateCount--, - p.remove && p.remove.call(a, s)); - r.length === 0 && - m !== r.length && - ((!p.teardown || p.teardown.call(a, l) === !1) && - f.removeEvent(a, j, g.handle), - delete o[j]); - } - f.isEmptyObject(o) && - ((q = g.handle), - q && (q.elem = null), - f.removeData(a, ["events", "handle"], !0)); - } - }, - customEvent: { getData: !0, setData: !0, changeData: !0 }, - trigger: function (c, d, e, g) { - if (!e || (e.nodeType !== 3 && e.nodeType !== 8)) { - var h = c.type || c, - i = [], - j, - k, - l, - m, - n, - o, - p, - q, - r, - s; - if (E.test(h + f.event.triggered)) return; - h.indexOf("!") >= 0 && ((h = h.slice(0, -1)), (k = !0)), - h.indexOf(".") >= 0 && - ((i = h.split(".")), (h = i.shift()), i.sort()); - if ((!e || f.event.customEvent[h]) && !f.event.global[h]) return; - (c = - typeof c == "object" - ? c[f.expando] - ? c - : new f.Event(h, c) - : new f.Event(h)), - (c.type = h), - (c.isTrigger = !0), - (c.exclusive = k), - (c.namespace = i.join(".")), - (c.namespace_re = c.namespace - ? new RegExp("(^|\\.)" + i.join("\\.(?:.*\\.)?") + "(\\.|$)") - : null), - (o = h.indexOf(":") < 0 ? "on" + h : ""); - if (!e) { - j = f.cache; - for (l in j) - j[l].events && - j[l].events[h] && - f.event.trigger(c, d, j[l].handle.elem, !0); - return; - } - (c.result = b), - c.target || (c.target = e), - (d = d != null ? f.makeArray(d) : []), - d.unshift(c), - (p = f.event.special[h] || {}); - if (p.trigger && p.trigger.apply(e, d) === !1) return; - r = [[e, p.bindType || h]]; - if (!g && !p.noBubble && !f.isWindow(e)) { - (s = p.delegateType || h), - (m = E.test(s + h) ? e : e.parentNode), - (n = null); - for (; m; m = m.parentNode) r.push([m, s]), (n = m); - n && - n === e.ownerDocument && - r.push([n.defaultView || n.parentWindow || a, s]); - } - for (l = 0; l < r.length && !c.isPropagationStopped(); l++) - (m = r[l][0]), - (c.type = r[l][1]), - (q = (f._data(m, "events") || {})[c.type] && f._data(m, "handle")), - q && q.apply(m, d), - (q = o && m[o]), - q && f.acceptData(m) && q.apply(m, d) === !1 && c.preventDefault(); - (c.type = h), - !g && - !c.isDefaultPrevented() && - (!p._default || p._default.apply(e.ownerDocument, d) === !1) && - (h !== "click" || !f.nodeName(e, "a")) && - f.acceptData(e) && - o && - e[h] && - ((h !== "focus" && h !== "blur") || c.target.offsetWidth !== 0) && - !f.isWindow(e) && - ((n = e[o]), - n && (e[o] = null), - (f.event.triggered = h), - e[h](), - (f.event.triggered = b), - n && (e[o] = n)); - return c.result; - } - }, - dispatch: function (c) { - c = f.event.fix(c || a.event); - var d = (f._data(this, "events") || {})[c.type] || [], - e = d.delegateCount, - g = [].slice.call(arguments, 0), - h = !c.exclusive && !c.namespace, - i = f.event.special[c.type] || {}, - j = [], - k, - l, - m, - n, - o, - p, - q, - r, - s, - t, - u; - (g[0] = c), (c.delegateTarget = this); - if (!i.preDispatch || i.preDispatch.call(this, c) !== !1) { - if (e && (!c.button || c.type !== "click")) { - (n = f(this)), (n.context = this.ownerDocument || this); - for (m = c.target; m != this; m = m.parentNode || this) - if (m.disabled !== !0) { - (p = {}), (r = []), (n[0] = m); - for (k = 0; k < e; k++) - (s = d[k]), - (t = s.selector), - p[t] === b && (p[t] = s.quick ? H(m, s.quick) : n.is(t)), - p[t] && r.push(s); - r.length && j.push({ elem: m, matches: r }); - } - } - d.length > e && j.push({ elem: this, matches: d.slice(e) }); - for (k = 0; k < j.length && !c.isPropagationStopped(); k++) { - (q = j[k]), (c.currentTarget = q.elem); - for ( - l = 0; - l < q.matches.length && !c.isImmediatePropagationStopped(); - l++ - ) { - s = q.matches[l]; - if ( - h || - (!c.namespace && !s.namespace) || - (c.namespace_re && c.namespace_re.test(s.namespace)) - ) - (c.data = s.data), - (c.handleObj = s), - (o = ( - (f.event.special[s.origType] || {}).handle || s.handler - ).apply(q.elem, g)), - o !== b && - ((c.result = o), - o === !1 && (c.preventDefault(), c.stopPropagation())); - } - } - i.postDispatch && i.postDispatch.call(this, c); - return c.result; - } - }, - props: - "attrChange attrName relatedNode srcElement altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split( - " ", - ), - fixHooks: {}, - keyHooks: { - props: "char charCode key keyCode".split(" "), - filter: function (a, b) { - a.which == null && - (a.which = b.charCode != null ? b.charCode : b.keyCode); - return a; - }, - }, - mouseHooks: { - props: - "button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split( - " ", - ), - filter: function (a, d) { - var e, - f, - g, - h = d.button, - i = d.fromElement; - a.pageX == null && - d.clientX != null && - ((e = a.target.ownerDocument || c), - (f = e.documentElement), - (g = e.body), - (a.pageX = - d.clientX + - ((f && f.scrollLeft) || (g && g.scrollLeft) || 0) - - ((f && f.clientLeft) || (g && g.clientLeft) || 0)), - (a.pageY = - d.clientY + - ((f && f.scrollTop) || (g && g.scrollTop) || 0) - - ((f && f.clientTop) || (g && g.clientTop) || 0))), - !a.relatedTarget && - i && - (a.relatedTarget = i === a.target ? d.toElement : i), - !a.which && - h !== b && - (a.which = h & 1 ? 1 : h & 2 ? 3 : h & 4 ? 2 : 0); - return a; - }, - }, - fix: function (a) { - if (a[f.expando]) return a; - var d, - e, - g = a, - h = f.event.fixHooks[a.type] || {}, - i = h.props ? this.props.concat(h.props) : this.props; - a = f.Event(g); - for (d = i.length; d; ) (e = i[--d]), (a[e] = g[e]); - a.target || (a.target = g.srcElement || c), - a.target.nodeType === 3 && (a.target = a.target.parentNode), - a.metaKey === b && (a.metaKey = a.ctrlKey); - return h.filter ? h.filter(a, g) : a; - }, - special: { - ready: { setup: f.bindReady }, - load: { noBubble: !0 }, - focus: { delegateType: "focusin" }, - blur: { delegateType: "focusout" }, - beforeunload: { - setup: function (a, b, c) { - f.isWindow(this) && (this.onbeforeunload = c); - }, - teardown: function (a, b) { - this.onbeforeunload === b && (this.onbeforeunload = null); - }, - }, - }, - simulate: function (a, b, c, d) { - var e = f.extend(new f.Event(), c, { - type: a, - isSimulated: !0, - originalEvent: {}, - }); - d ? f.event.trigger(e, null, b) : f.event.dispatch.call(b, e), - e.isDefaultPrevented() && c.preventDefault(); - }, - }), - (f.event.handle = f.event.dispatch), - (f.removeEvent = c.removeEventListener - ? function (a, b, c) { - a.removeEventListener && a.removeEventListener(b, c, !1); - } - : function (a, b, c) { - a.detachEvent && a.detachEvent("on" + b, c); - }), - (f.Event = function (a, b) { - if (!(this instanceof f.Event)) return new f.Event(a, b); - a && a.type - ? ((this.originalEvent = a), - (this.type = a.type), - (this.isDefaultPrevented = - a.defaultPrevented || - a.returnValue === !1 || - (a.getPreventDefault && a.getPreventDefault()) - ? K - : J)) - : (this.type = a), - b && f.extend(this, b), - (this.timeStamp = (a && a.timeStamp) || f.now()), - (this[f.expando] = !0); - }), - (f.Event.prototype = { - preventDefault: function () { - this.isDefaultPrevented = K; - var a = this.originalEvent; - !a || (a.preventDefault ? a.preventDefault() : (a.returnValue = !1)); - }, - stopPropagation: function () { - this.isPropagationStopped = K; - var a = this.originalEvent; - !a || (a.stopPropagation && a.stopPropagation(), (a.cancelBubble = !0)); - }, - stopImmediatePropagation: function () { - (this.isImmediatePropagationStopped = K), this.stopPropagation(); - }, - isDefaultPrevented: J, - isPropagationStopped: J, - isImmediatePropagationStopped: J, - }), - f.each( - { mouseenter: "mouseover", mouseleave: "mouseout" }, - function (a, b) { - f.event.special[a] = { - delegateType: b, - bindType: b, - handle: function (a) { - var c = this, - d = a.relatedTarget, - e = a.handleObj, - g = e.selector, - h; - if (!d || (d !== c && !f.contains(c, d))) - (a.type = e.origType), - (h = e.handler.apply(this, arguments)), - (a.type = b); - return h; - }, - }; - }, - ), - f.support.submitBubbles || - (f.event.special.submit = { - setup: function () { - if (f.nodeName(this, "form")) return !1; - f.event.add(this, "click._submit keypress._submit", function (a) { - var c = a.target, - d = - f.nodeName(c, "input") || f.nodeName(c, "button") ? c.form : b; - d && - !d._submit_attached && - (f.event.add(d, "submit._submit", function (a) { - a._submit_bubble = !0; - }), - (d._submit_attached = !0)); - }); - }, - postDispatch: function (a) { - a._submit_bubble && - (delete a._submit_bubble, - this.parentNode && - !a.isTrigger && - f.event.simulate("submit", this.parentNode, a, !0)); - }, - teardown: function () { - if (f.nodeName(this, "form")) return !1; - f.event.remove(this, "._submit"); - }, - }), - f.support.changeBubbles || - (f.event.special.change = { - setup: function () { - if (z.test(this.nodeName)) { - if (this.type === "checkbox" || this.type === "radio") - f.event.add(this, "propertychange._change", function (a) { - a.originalEvent.propertyName === "checked" && - (this._just_changed = !0); - }), - f.event.add(this, "click._change", function (a) { - this._just_changed && - !a.isTrigger && - ((this._just_changed = !1), - f.event.simulate("change", this, a, !0)); - }); - return !1; - } - f.event.add(this, "beforeactivate._change", function (a) { - var b = a.target; - z.test(b.nodeName) && - !b._change_attached && - (f.event.add(b, "change._change", function (a) { - this.parentNode && - !a.isSimulated && - !a.isTrigger && - f.event.simulate("change", this.parentNode, a, !0); - }), - (b._change_attached = !0)); - }); - }, - handle: function (a) { - var b = a.target; - if ( - this !== b || - a.isSimulated || - a.isTrigger || - (b.type !== "radio" && b.type !== "checkbox") - ) - return a.handleObj.handler.apply(this, arguments); - }, - teardown: function () { - f.event.remove(this, "._change"); - return z.test(this.nodeName); - }, - }), - f.support.focusinBubbles || - f.each({ focus: "focusin", blur: "focusout" }, function (a, b) { - var d = 0, - e = function (a) { - f.event.simulate(b, a.target, f.event.fix(a), !0); - }; - f.event.special[b] = { - setup: function () { - d++ === 0 && c.addEventListener(a, e, !0); - }, - teardown: function () { - --d === 0 && c.removeEventListener(a, e, !0); - }, - }; - }), - f.fn.extend({ - on: function (a, c, d, e, g) { - var h, i; - if (typeof a == "object") { - typeof c != "string" && ((d = d || c), (c = b)); - for (i in a) this.on(i, c, d, a[i], g); - return this; - } - d == null && e == null - ? ((e = c), (d = c = b)) - : e == null && - (typeof c == "string" - ? ((e = d), (d = b)) - : ((e = d), (d = c), (c = b))); - if (e === !1) e = J; - else if (!e) return this; - g === 1 && - ((h = e), - (e = function (a) { - f().off(a); - return h.apply(this, arguments); - }), - (e.guid = h.guid || (h.guid = f.guid++))); - return this.each(function () { - f.event.add(this, a, e, d, c); - }); - }, - one: function (a, b, c, d) { - return this.on(a, b, c, d, 1); - }, - off: function (a, c, d) { - if (a && a.preventDefault && a.handleObj) { - var e = a.handleObj; - f(a.delegateTarget).off( - e.namespace ? e.origType + "." + e.namespace : e.origType, - e.selector, - e.handler, - ); - return this; - } - if (typeof a == "object") { - for (var g in a) this.off(g, c, a[g]); - return this; - } - if (c === !1 || typeof c == "function") (d = c), (c = b); - d === !1 && (d = J); - return this.each(function () { - f.event.remove(this, a, d, c); - }); - }, - bind: function (a, b, c) { - return this.on(a, null, b, c); - }, - unbind: function (a, b) { - return this.off(a, null, b); - }, - live: function (a, b, c) { - f(this.context).on(a, this.selector, b, c); - return this; - }, - die: function (a, b) { - f(this.context).off(a, this.selector || "**", b); - return this; - }, - delegate: function (a, b, c, d) { - return this.on(b, a, c, d); - }, - undelegate: function (a, b, c) { - return arguments.length == 1 ? this.off(a, "**") : this.off(b, a, c); - }, - trigger: function (a, b) { - return this.each(function () { - f.event.trigger(a, b, this); - }); - }, - triggerHandler: function (a, b) { - if (this[0]) return f.event.trigger(a, b, this[0], !0); - }, - toggle: function (a) { - var b = arguments, - c = a.guid || f.guid++, - d = 0, - e = function (c) { - var e = (f._data(this, "lastToggle" + a.guid) || 0) % d; - f._data(this, "lastToggle" + a.guid, e + 1), c.preventDefault(); - return b[e].apply(this, arguments) || !1; - }; - e.guid = c; - while (d < b.length) b[d++].guid = c; - return this.click(e); - }, - hover: function (a, b) { - return this.mouseenter(a).mouseleave(b || a); - }, - }), - f.each( - "blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error contextmenu".split( - " ", - ), - function (a, b) { - (f.fn[b] = function (a, c) { - c == null && ((c = a), (a = null)); - return arguments.length > 0 - ? this.on(b, null, a, c) - : this.trigger(b); - }), - f.attrFn && (f.attrFn[b] = !0), - C.test(b) && (f.event.fixHooks[b] = f.event.keyHooks), - D.test(b) && (f.event.fixHooks[b] = f.event.mouseHooks); - }, - ), - (function () { - function x(a, b, c, e, f, g) { - for (var h = 0, i = e.length; h < i; h++) { - var j = e[h]; - if (j) { - var k = !1; - j = j[a]; - while (j) { - if (j[d] === c) { - k = e[j.sizset]; - break; - } - if (j.nodeType === 1) { - g || ((j[d] = c), (j.sizset = h)); - if (typeof b != "string") { - if (j === b) { - k = !0; - break; - } - } else if (m.filter(b, [j]).length > 0) { - k = j; - break; - } - } - j = j[a]; - } - e[h] = k; - } - } - } - function w(a, b, c, e, f, g) { - for (var h = 0, i = e.length; h < i; h++) { - var j = e[h]; - if (j) { - var k = !1; - j = j[a]; - while (j) { - if (j[d] === c) { - k = e[j.sizset]; - break; - } - j.nodeType === 1 && !g && ((j[d] = c), (j.sizset = h)); - if (j.nodeName.toLowerCase() === b) { - k = j; - break; - } - j = j[a]; - } - e[h] = k; - } - } - } - var a = - /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g, - d = "sizcache" + (Math.random() + "").replace(".", ""), - e = 0, - g = Object.prototype.toString, - h = !1, - i = !0, - j = /\\/g, - k = /\r\n/g, - l = /\W/; - [0, 0].sort(function () { - i = !1; - return 0; - }); - var m = function (b, d, e, f) { - (e = e || []), (d = d || c); - var h = d; - if (d.nodeType !== 1 && d.nodeType !== 9) return []; - if (!b || typeof b != "string") return e; - var i, - j, - k, - l, - n, - q, - r, - t, - u = !0, - v = m.isXML(d), - w = [], - x = b; - do { - a.exec(""), (i = a.exec(x)); - if (i) { - (x = i[3]), w.push(i[1]); - if (i[2]) { - l = i[3]; - break; - } - } - } while (i); - if (w.length > 1 && p.exec(b)) - if (w.length === 2 && o.relative[w[0]]) j = y(w[0] + w[1], d, f); - else { - j = o.relative[w[0]] ? [d] : m(w.shift(), d); - while (w.length) - (b = w.shift()), - o.relative[b] && (b += w.shift()), - (j = y(b, j, f)); - } - else { - !f && - w.length > 1 && - d.nodeType === 9 && - !v && - o.match.ID.test(w[0]) && - !o.match.ID.test(w[w.length - 1]) && - ((n = m.find(w.shift(), d, v)), - (d = n.expr ? m.filter(n.expr, n.set)[0] : n.set[0])); - if (d) { - (n = f - ? { expr: w.pop(), set: s(f) } - : m.find( - w.pop(), - w.length === 1 && - (w[0] === "~" || w[0] === "+") && - d.parentNode - ? d.parentNode - : d, - v, - )), - (j = n.expr ? m.filter(n.expr, n.set) : n.set), - w.length > 0 ? (k = s(j)) : (u = !1); - while (w.length) - (q = w.pop()), - (r = q), - o.relative[q] ? (r = w.pop()) : (q = ""), - r == null && (r = d), - o.relative[q](k, r, v); - } else k = w = []; - } - k || (k = j), k || m.error(q || b); - if (g.call(k) === "[object Array]") - if (!u) e.push.apply(e, k); - else if (d && d.nodeType === 1) - for (t = 0; k[t] != null; t++) - k[t] && - (k[t] === !0 || (k[t].nodeType === 1 && m.contains(d, k[t]))) && - e.push(j[t]); - else - for (t = 0; k[t] != null; t++) - k[t] && k[t].nodeType === 1 && e.push(j[t]); - else s(k, e); - l && (m(l, h, e, f), m.uniqueSort(e)); - return e; - }; - (m.uniqueSort = function (a) { - if (u) { - (h = i), a.sort(u); - if (h) - for (var b = 1; b < a.length; b++) - a[b] === a[b - 1] && a.splice(b--, 1); - } - return a; - }), - (m.matches = function (a, b) { - return m(a, null, null, b); - }), - (m.matchesSelector = function (a, b) { - return m(b, null, null, [a]).length > 0; - }), - (m.find = function (a, b, c) { - var d, e, f, g, h, i; - if (!a) return []; - for (e = 0, f = o.order.length; e < f; e++) { - h = o.order[e]; - if ((g = o.leftMatch[h].exec(a))) { - (i = g[1]), g.splice(1, 1); - if (i.substr(i.length - 1) !== "\\") { - (g[1] = (g[1] || "").replace(j, "")), (d = o.find[h](g, b, c)); - if (d != null) { - a = a.replace(o.match[h], ""); - break; - } - } - } - } - d || - (d = - typeof b.getElementsByTagName != "undefined" - ? b.getElementsByTagName("*") - : []); - return { set: d, expr: a }; - }), - (m.filter = function (a, c, d, e) { - var f, - g, - h, - i, - j, - k, - l, - n, - p, - q = a, - r = [], - s = c, - t = c && c[0] && m.isXML(c[0]); - while (a && c.length) { - for (h in o.filter) - if ((f = o.leftMatch[h].exec(a)) != null && f[2]) { - (k = o.filter[h]), (l = f[1]), (g = !1), f.splice(1, 1); - if (l.substr(l.length - 1) === "\\") continue; - s === r && (r = []); - if (o.preFilter[h]) { - f = o.preFilter[h](f, s, d, r, e, t); - if (!f) g = i = !0; - else if (f === !0) continue; - } - if (f) - for (n = 0; (j = s[n]) != null; n++) - j && - ((i = k(j, f, n, s)), - (p = e ^ i), - d && i != null - ? p - ? (g = !0) - : (s[n] = !1) - : p && (r.push(j), (g = !0))); - if (i !== b) { - d || (s = r), (a = a.replace(o.match[h], "")); - if (!g) return []; - break; - } - } - if (a === q) - if (g == null) m.error(a); - else break; - q = a; - } - return s; - }), - (m.error = function (a) { - throw new Error("Syntax error, unrecognized expression: " + a); - }); - var n = (m.getText = function (a) { - var b, - c, - d = a.nodeType, - e = ""; - if (d) { - if (d === 1 || d === 9 || d === 11) { - if (typeof a.textContent == "string") return a.textContent; - if (typeof a.innerText == "string") - return a.innerText.replace(k, ""); - for (a = a.firstChild; a; a = a.nextSibling) e += n(a); - } else if (d === 3 || d === 4) return a.nodeValue; - } else for (b = 0; (c = a[b]); b++) c.nodeType !== 8 && (e += n(c)); - return e; - }), - o = (m.selectors = { - order: ["ID", "NAME", "TAG"], - match: { - ID: /#((?:[\w\u00c0-\uFFFF\-]|\\.)+)/, - CLASS: /\.((?:[\w\u00c0-\uFFFF\-]|\\.)+)/, - NAME: /\[name=['"]*((?:[\w\u00c0-\uFFFF\-]|\\.)+)['"]*\]/, - ATTR: /\[\s*((?:[\w\u00c0-\uFFFF\-]|\\.)+)\s*(?:(\S?=)\s*(?:(['"])(.*?)\3|(#?(?:[\w\u00c0-\uFFFF\-]|\\.)*)|)|)\s*\]/, - TAG: /^((?:[\w\u00c0-\uFFFF\*\-]|\\.)+)/, - CHILD: - /:(only|nth|last|first)-child(?:\(\s*(even|odd|(?:[+\-]?\d+|(?:[+\-]?\d*)?n\s*(?:[+\-]\s*\d+)?))\s*\))?/, - POS: /:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^\-]|$)/, - PSEUDO: - /:((?:[\w\u00c0-\uFFFF\-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/, - }, - leftMatch: {}, - attrMap: { class: "className", for: "htmlFor" }, - attrHandle: { - href: function (a) { - return a.getAttribute("href"); - }, - type: function (a) { - return a.getAttribute("type"); - }, - }, - relative: { - "+": function (a, b) { - var c = typeof b == "string", - d = c && !l.test(b), - e = c && !d; - d && (b = b.toLowerCase()); - for (var f = 0, g = a.length, h; f < g; f++) - if ((h = a[f])) { - while ((h = h.previousSibling) && h.nodeType !== 1); - a[f] = - e || (h && h.nodeName.toLowerCase() === b) - ? h || !1 - : h === b; - } - e && m.filter(b, a, !0); - }, - ">": function (a, b) { - var c, - d = typeof b == "string", - e = 0, - f = a.length; - if (d && !l.test(b)) { - b = b.toLowerCase(); - for (; e < f; e++) { - c = a[e]; - if (c) { - var g = c.parentNode; - a[e] = g.nodeName.toLowerCase() === b ? g : !1; - } - } - } else { - for (; e < f; e++) - (c = a[e]), - c && (a[e] = d ? c.parentNode : c.parentNode === b); - d && m.filter(b, a, !0); - } - }, - "": function (a, b, c) { - var d, - f = e++, - g = x; - typeof b == "string" && - !l.test(b) && - ((b = b.toLowerCase()), (d = b), (g = w)), - g("parentNode", b, f, a, d, c); - }, - "~": function (a, b, c) { - var d, - f = e++, - g = x; - typeof b == "string" && - !l.test(b) && - ((b = b.toLowerCase()), (d = b), (g = w)), - g("previousSibling", b, f, a, d, c); - }, - }, - find: { - ID: function (a, b, c) { - if (typeof b.getElementById != "undefined" && !c) { - var d = b.getElementById(a[1]); - return d && d.parentNode ? [d] : []; - } - }, - NAME: function (a, b) { - if (typeof b.getElementsByName != "undefined") { - var c = [], - d = b.getElementsByName(a[1]); - for (var e = 0, f = d.length; e < f; e++) - d[e].getAttribute("name") === a[1] && c.push(d[e]); - return c.length === 0 ? null : c; - } - }, - TAG: function (a, b) { - if (typeof b.getElementsByTagName != "undefined") - return b.getElementsByTagName(a[1]); - }, - }, - preFilter: { - CLASS: function (a, b, c, d, e, f) { - a = " " + a[1].replace(j, "") + " "; - if (f) return a; - for (var g = 0, h; (h = b[g]) != null; g++) - h && - (e ^ - (h.className && - (" " + h.className + " ") - .replace(/[\t\n\r]/g, " ") - .indexOf(a) >= 0) - ? c || d.push(h) - : c && (b[g] = !1)); - return !1; - }, - ID: function (a) { - return a[1].replace(j, ""); - }, - TAG: function (a, b) { - return a[1].replace(j, "").toLowerCase(); - }, - CHILD: function (a) { - if (a[1] === "nth") { - a[2] || m.error(a[0]), (a[2] = a[2].replace(/^\+|\s*/g, "")); - var b = /(-?)(\d*)(?:n([+\-]?\d*))?/.exec( - (a[2] === "even" && "2n") || - (a[2] === "odd" && "2n+1") || - (!/\D/.test(a[2]) && "0n+" + a[2]) || - a[2], - ); - (a[2] = b[1] + (b[2] || 1) - 0), (a[3] = b[3] - 0); - } else a[2] && m.error(a[0]); - a[0] = e++; - return a; - }, - ATTR: function (a, b, c, d, e, f) { - var g = (a[1] = a[1].replace(j, "")); - !f && o.attrMap[g] && (a[1] = o.attrMap[g]), - (a[4] = (a[4] || a[5] || "").replace(j, "")), - a[2] === "~=" && (a[4] = " " + a[4] + " "); - return a; - }, - PSEUDO: function (b, c, d, e, f) { - if (b[1] === "not") - if ((a.exec(b[3]) || "").length > 1 || /^\w/.test(b[3])) - b[3] = m(b[3], null, null, c); - else { - var g = m.filter(b[3], c, d, !0 ^ f); - d || e.push.apply(e, g); - return !1; - } - else if (o.match.POS.test(b[0]) || o.match.CHILD.test(b[0])) - return !0; - return b; - }, - POS: function (a) { - a.unshift(!0); - return a; - }, - }, - filters: { - enabled: function (a) { - return a.disabled === !1 && a.type !== "hidden"; - }, - disabled: function (a) { - return a.disabled === !0; - }, - checked: function (a) { - return a.checked === !0; - }, - selected: function (a) { - a.parentNode && a.parentNode.selectedIndex; - return a.selected === !0; - }, - parent: function (a) { - return !!a.firstChild; - }, - empty: function (a) { - return !a.firstChild; - }, - has: function (a, b, c) { - return !!m(c[3], a).length; - }, - header: function (a) { - return /h\d/i.test(a.nodeName); - }, - text: function (a) { - var b = a.getAttribute("type"), - c = a.type; - return ( - a.nodeName.toLowerCase() === "input" && - "text" === c && - (b === c || b === null) - ); - }, - radio: function (a) { - return a.nodeName.toLowerCase() === "input" && "radio" === a.type; - }, - checkbox: function (a) { - return ( - a.nodeName.toLowerCase() === "input" && "checkbox" === a.type - ); - }, - file: function (a) { - return a.nodeName.toLowerCase() === "input" && "file" === a.type; - }, - password: function (a) { - return ( - a.nodeName.toLowerCase() === "input" && "password" === a.type - ); - }, - submit: function (a) { - var b = a.nodeName.toLowerCase(); - return (b === "input" || b === "button") && "submit" === a.type; - }, - image: function (a) { - return a.nodeName.toLowerCase() === "input" && "image" === a.type; - }, - reset: function (a) { - var b = a.nodeName.toLowerCase(); - return (b === "input" || b === "button") && "reset" === a.type; - }, - button: function (a) { - var b = a.nodeName.toLowerCase(); - return (b === "input" && "button" === a.type) || b === "button"; - }, - input: function (a) { - return /input|select|textarea|button/i.test(a.nodeName); - }, - focus: function (a) { - return a === a.ownerDocument.activeElement; - }, - }, - setFilters: { - first: function (a, b) { - return b === 0; - }, - last: function (a, b, c, d) { - return b === d.length - 1; - }, - even: function (a, b) { - return b % 2 === 0; - }, - odd: function (a, b) { - return b % 2 === 1; - }, - lt: function (a, b, c) { - return b < c[3] - 0; - }, - gt: function (a, b, c) { - return b > c[3] - 0; - }, - nth: function (a, b, c) { - return c[3] - 0 === b; - }, - eq: function (a, b, c) { - return c[3] - 0 === b; - }, - }, - filter: { - PSEUDO: function (a, b, c, d) { - var e = b[1], - f = o.filters[e]; - if (f) return f(a, c, b, d); - if (e === "contains") - return ( - (a.textContent || a.innerText || n([a]) || "").indexOf( - b[3], - ) >= 0 - ); - if (e === "not") { - var g = b[3]; - for (var h = 0, i = g.length; h < i; h++) - if (g[h] === a) return !1; - return !0; - } - m.error(e); - }, - CHILD: function (a, b) { - var c, - e, - f, - g, - h, - i, - j, - k = b[1], - l = a; - switch (k) { - case "only": - case "first": - while ((l = l.previousSibling)) - if (l.nodeType === 1) return !1; - if (k === "first") return !0; - l = a; - case "last": - while ((l = l.nextSibling)) if (l.nodeType === 1) return !1; - return !0; - case "nth": - (c = b[2]), (e = b[3]); - if (c === 1 && e === 0) return !0; - (f = b[0]), (g = a.parentNode); - if (g && (g[d] !== f || !a.nodeIndex)) { - i = 0; - for (l = g.firstChild; l; l = l.nextSibling) - l.nodeType === 1 && (l.nodeIndex = ++i); - g[d] = f; - } - j = a.nodeIndex - e; - return c === 0 ? j === 0 : j % c === 0 && j / c >= 0; - } - }, - ID: function (a, b) { - return a.nodeType === 1 && a.getAttribute("id") === b; - }, - TAG: function (a, b) { - return ( - (b === "*" && a.nodeType === 1) || - (!!a.nodeName && a.nodeName.toLowerCase() === b) - ); - }, - CLASS: function (a, b) { - return ( - (" " + (a.className || a.getAttribute("class")) + " ").indexOf( - b, - ) > -1 - ); - }, - ATTR: function (a, b) { - var c = b[1], - d = m.attr - ? m.attr(a, c) - : o.attrHandle[c] - ? o.attrHandle[c](a) - : a[c] != null - ? a[c] - : a.getAttribute(c), - e = d + "", - f = b[2], - g = b[4]; - return d == null - ? f === "!=" - : !f && m.attr - ? d != null - : f === "=" - ? e === g - : f === "*=" - ? e.indexOf(g) >= 0 - : f === "~=" - ? (" " + e + " ").indexOf(g) >= 0 - : g - ? f === "!=" - ? e !== g - : f === "^=" - ? e.indexOf(g) === 0 - : f === "$=" - ? e.substr(e.length - g.length) === g - : f === "|=" - ? e === g || e.substr(0, g.length + 1) === g + "-" - : !1 - : e && d !== !1; - }, - POS: function (a, b, c, d) { - var e = b[2], - f = o.setFilters[e]; - if (f) return f(a, c, b, d); - }, - }, - }), - p = o.match.POS, - q = function (a, b) { - return "\\" + (b - 0 + 1); - }; - for (var r in o.match) - (o.match[r] = new RegExp( - o.match[r].source + /(?![^\[]*\])(?![^\(]*\))/.source, - )), - (o.leftMatch[r] = new RegExp( - /(^(?:.|\r|\n)*?)/.source + - o.match[r].source.replace(/\\(\d+)/g, q), - )); - o.match.globalPOS = p; - var s = function (a, b) { - a = Array.prototype.slice.call(a, 0); - if (b) { - b.push.apply(b, a); - return b; - } - return a; - }; - try { - Array.prototype.slice.call(c.documentElement.childNodes, 0)[0].nodeType; - } catch (t) { - s = function (a, b) { - var c = 0, - d = b || []; - if (g.call(a) === "[object Array]") Array.prototype.push.apply(d, a); - else if (typeof a.length == "number") - for (var e = a.length; c < e; c++) d.push(a[c]); - else for (; a[c]; c++) d.push(a[c]); - return d; - }; - } - var u, v; - c.documentElement.compareDocumentPosition - ? (u = function (a, b) { - if (a === b) { - h = !0; - return 0; - } - if (!a.compareDocumentPosition || !b.compareDocumentPosition) - return a.compareDocumentPosition ? -1 : 1; - return a.compareDocumentPosition(b) & 4 ? -1 : 1; - }) - : ((u = function (a, b) { - if (a === b) { - h = !0; - return 0; - } - if (a.sourceIndex && b.sourceIndex) - return a.sourceIndex - b.sourceIndex; - var c, - d, - e = [], - f = [], - g = a.parentNode, - i = b.parentNode, - j = g; - if (g === i) return v(a, b); - if (!g) return -1; - if (!i) return 1; - while (j) e.unshift(j), (j = j.parentNode); - j = i; - while (j) f.unshift(j), (j = j.parentNode); - (c = e.length), (d = f.length); - for (var k = 0; k < c && k < d; k++) - if (e[k] !== f[k]) return v(e[k], f[k]); - return k === c ? v(a, f[k], -1) : v(e[k], b, 1); - }), - (v = function (a, b, c) { - if (a === b) return c; - var d = a.nextSibling; - while (d) { - if (d === b) return -1; - d = d.nextSibling; - } - return 1; - })), - (function () { - var a = c.createElement("div"), - d = "script" + new Date().getTime(), - e = c.documentElement; - (a.innerHTML = ""), - e.insertBefore(a, e.firstChild), - c.getElementById(d) && - ((o.find.ID = function (a, c, d) { - if (typeof c.getElementById != "undefined" && !d) { - var e = c.getElementById(a[1]); - return e - ? e.id === a[1] || - (typeof e.getAttributeNode != "undefined" && - e.getAttributeNode("id").nodeValue === a[1]) - ? [e] - : b - : []; - } - }), - (o.filter.ID = function (a, b) { - var c = - typeof a.getAttributeNode != "undefined" && - a.getAttributeNode("id"); - return a.nodeType === 1 && c && c.nodeValue === b; - })), - e.removeChild(a), - (e = a = null); - })(), - (function () { - var a = c.createElement("div"); - a.appendChild(c.createComment("")), - a.getElementsByTagName("*").length > 0 && - (o.find.TAG = function (a, b) { - var c = b.getElementsByTagName(a[1]); - if (a[1] === "*") { - var d = []; - for (var e = 0; c[e]; e++) - c[e].nodeType === 1 && d.push(c[e]); - c = d; - } - return c; - }), - (a.innerHTML = ""), - a.firstChild && - typeof a.firstChild.getAttribute != "undefined" && - a.firstChild.getAttribute("href") !== "#" && - (o.attrHandle.href = function (a) { - return a.getAttribute("href", 2); - }), - (a = null); - })(), - c.querySelectorAll && - (function () { - var a = m, - b = c.createElement("div"), - d = "__sizzle__"; - b.innerHTML = "

"; - if ( - !b.querySelectorAll || - b.querySelectorAll(".TEST").length !== 0 - ) { - m = function (b, e, f, g) { - e = e || c; - if (!g && !m.isXML(e)) { - var h = /^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec(b); - if (h && (e.nodeType === 1 || e.nodeType === 9)) { - if (h[1]) return s(e.getElementsByTagName(b), f); - if (h[2] && o.find.CLASS && e.getElementsByClassName) - return s(e.getElementsByClassName(h[2]), f); - } - if (e.nodeType === 9) { - if (b === "body" && e.body) return s([e.body], f); - if (h && h[3]) { - var i = e.getElementById(h[3]); - if (!i || !i.parentNode) return s([], f); - if (i.id === h[3]) return s([i], f); - } - try { - return s(e.querySelectorAll(b), f); - } catch (j) {} - } else if ( - e.nodeType === 1 && - e.nodeName.toLowerCase() !== "object" - ) { - var k = e, - l = e.getAttribute("id"), - n = l || d, - p = e.parentNode, - q = /^\s*[+~]/.test(b); - l ? (n = n.replace(/'/g, "\\$&")) : e.setAttribute("id", n), - q && p && (e = e.parentNode); - try { - if (!q || p) - return s( - e.querySelectorAll("[id='" + n + "'] " + b), - f, - ); - } catch (r) { - } finally { - l || k.removeAttribute("id"); - } - } - } - return a(b, e, f, g); - }; - for (var e in a) m[e] = a[e]; - b = null; - } - })(), - (function () { - var a = c.documentElement, - b = - a.matchesSelector || - a.mozMatchesSelector || - a.webkitMatchesSelector || - a.msMatchesSelector; - if (b) { - var d = !b.call(c.createElement("div"), "div"), - e = !1; - try { - b.call(c.documentElement, "[test!='']:sizzle"); - } catch (f) { - e = !0; - } - m.matchesSelector = function (a, c) { - c = c.replace(/\=\s*([^'"\]]*)\s*\]/g, "='$1']"); - if (!m.isXML(a)) - try { - if (e || (!o.match.PSEUDO.test(c) && !/!=/.test(c))) { - var f = b.call(a, c); - if (f || !d || (a.document && a.document.nodeType !== 11)) - return f; - } - } catch (g) {} - return m(c, null, null, [a]).length > 0; - }; - } - })(), - (function () { - var a = c.createElement("div"); - a.innerHTML = "
"; - if ( - !!a.getElementsByClassName && - a.getElementsByClassName("e").length !== 0 - ) { - a.lastChild.className = "e"; - if (a.getElementsByClassName("e").length === 1) return; - o.order.splice(1, 0, "CLASS"), - (o.find.CLASS = function (a, b, c) { - if (typeof b.getElementsByClassName != "undefined" && !c) - return b.getElementsByClassName(a[1]); - }), - (a = null); - } - })(), - c.documentElement.contains - ? (m.contains = function (a, b) { - return a !== b && (a.contains ? a.contains(b) : !0); - }) - : c.documentElement.compareDocumentPosition - ? (m.contains = function (a, b) { - return !!(a.compareDocumentPosition(b) & 16); - }) - : (m.contains = function () { - return !1; - }), - (m.isXML = function (a) { - var b = (a ? a.ownerDocument || a : 0).documentElement; - return b ? b.nodeName !== "HTML" : !1; - }); - var y = function (a, b, c) { - var d, - e = [], - f = "", - g = b.nodeType ? [b] : b; - while ((d = o.match.PSEUDO.exec(a))) - (f += d[0]), (a = a.replace(o.match.PSEUDO, "")); - a = o.relative[a] ? a + "*" : a; - for (var h = 0, i = g.length; h < i; h++) m(a, g[h], e, c); - return m.filter(f, e); - }; - (m.attr = f.attr), - (m.selectors.attrMap = {}), - (f.find = m), - (f.expr = m.selectors), - (f.expr[":"] = f.expr.filters), - (f.unique = m.uniqueSort), - (f.text = m.getText), - (f.isXMLDoc = m.isXML), - (f.contains = m.contains); - })(); - var L = /Until$/, - M = /^(?:parents|prevUntil|prevAll)/, - N = /,/, - O = /^.[^:#\[\.,]*$/, - P = Array.prototype.slice, - Q = f.expr.match.globalPOS, - R = { children: !0, contents: !0, next: !0, prev: !0 }; - f.fn.extend({ - find: function (a) { - var b = this, - c, - d; - if (typeof a != "string") - return f(a).filter(function () { - for (c = 0, d = b.length; c < d; c++) - if (f.contains(b[c], this)) return !0; - }); - var e = this.pushStack("", "find", a), - g, - h, - i; - for (c = 0, d = this.length; c < d; c++) { - (g = e.length), f.find(a, this[c], e); - if (c > 0) - for (h = g; h < e.length; h++) - for (i = 0; i < g; i++) - if (e[i] === e[h]) { - e.splice(h--, 1); - break; - } - } - return e; - }, - has: function (a) { - var b = f(a); - return this.filter(function () { - for (var a = 0, c = b.length; a < c; a++) - if (f.contains(this, b[a])) return !0; - }); - }, - not: function (a) { - return this.pushStack(T(this, a, !1), "not", a); - }, - filter: function (a) { - return this.pushStack(T(this, a, !0), "filter", a); - }, - is: function (a) { - return ( - !!a && - (typeof a == "string" - ? Q.test(a) - ? f(a, this.context).index(this[0]) >= 0 - : f.filter(a, this).length > 0 - : this.filter(a).length > 0) - ); - }, - closest: function (a, b) { - var c = [], - d, - e, - g = this[0]; - if (f.isArray(a)) { - var h = 1; - while (g && g.ownerDocument && g !== b) { - for (d = 0; d < a.length; d++) - f(g).is(a[d]) && c.push({ selector: a[d], elem: g, level: h }); - (g = g.parentNode), h++; - } - return c; - } - var i = Q.test(a) || typeof a != "string" ? f(a, b || this.context) : 0; - for (d = 0, e = this.length; d < e; d++) { - g = this[d]; - while (g) { - if (i ? i.index(g) > -1 : f.find.matchesSelector(g, a)) { - c.push(g); - break; - } - g = g.parentNode; - if (!g || !g.ownerDocument || g === b || g.nodeType === 11) break; - } - } - c = c.length > 1 ? f.unique(c) : c; - return this.pushStack(c, "closest", a); - }, - index: function (a) { - if (!a) return this[0] && this[0].parentNode ? this.prevAll().length : -1; - if (typeof a == "string") return f.inArray(this[0], f(a)); - return f.inArray(a.jquery ? a[0] : a, this); - }, - add: function (a, b) { - var c = - typeof a == "string" - ? f(a, b) - : f.makeArray(a && a.nodeType ? [a] : a), - d = f.merge(this.get(), c); - return this.pushStack(S(c[0]) || S(d[0]) ? d : f.unique(d)); - }, - andSelf: function () { - return this.add(this.prevObject); - }, - }), - f.each( - { - parent: function (a) { - var b = a.parentNode; - return b && b.nodeType !== 11 ? b : null; - }, - parents: function (a) { - return f.dir(a, "parentNode"); - }, - parentsUntil: function (a, b, c) { - return f.dir(a, "parentNode", c); - }, - next: function (a) { - return f.nth(a, 2, "nextSibling"); - }, - prev: function (a) { - return f.nth(a, 2, "previousSibling"); - }, - nextAll: function (a) { - return f.dir(a, "nextSibling"); - }, - prevAll: function (a) { - return f.dir(a, "previousSibling"); - }, - nextUntil: function (a, b, c) { - return f.dir(a, "nextSibling", c); - }, - prevUntil: function (a, b, c) { - return f.dir(a, "previousSibling", c); - }, - siblings: function (a) { - return f.sibling((a.parentNode || {}).firstChild, a); - }, - children: function (a) { - return f.sibling(a.firstChild); - }, - contents: function (a) { - return f.nodeName(a, "iframe") - ? a.contentDocument || a.contentWindow.document - : f.makeArray(a.childNodes); - }, - }, - function (a, b) { - f.fn[a] = function (c, d) { - var e = f.map(this, b, c); - L.test(a) || (d = c), - d && typeof d == "string" && (e = f.filter(d, e)), - (e = this.length > 1 && !R[a] ? f.unique(e) : e), - (this.length > 1 || N.test(d)) && M.test(a) && (e = e.reverse()); - return this.pushStack(e, a, P.call(arguments).join(",")); - }; - }, - ), - f.extend({ - filter: function (a, b, c) { - c && (a = ":not(" + a + ")"); - return b.length === 1 - ? f.find.matchesSelector(b[0], a) - ? [b[0]] - : [] - : f.find.matches(a, b); - }, - dir: function (a, c, d) { - var e = [], - g = a[c]; - while ( - g && - g.nodeType !== 9 && - (d === b || g.nodeType !== 1 || !f(g).is(d)) - ) - g.nodeType === 1 && e.push(g), (g = g[c]); - return e; - }, - nth: function (a, b, c, d) { - b = b || 1; - var e = 0; - for (; a; a = a[c]) if (a.nodeType === 1 && ++e === b) break; - return a; - }, - sibling: function (a, b) { - var c = []; - for (; a; a = a.nextSibling) a.nodeType === 1 && a !== b && c.push(a); - return c; - }, - }); - var V = - "abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video", - W = / jQuery\d+="(?:\d+|null)"/g, - X = /^\s+/, - Y = - /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi, - Z = /<([\w:]+)/, - $ = /]", "i"), - bd = /checked\s*(?:[^=]|=\s*.checked.)/i, - be = /\/(java|ecma)script/i, - bf = /^\s*", ""], - legend: [1, "
", "
"], - thead: [1, "", "
"], - tr: [2, "", "
"], - td: [3, "", "
"], - col: [2, "", "
"], - area: [1, "", ""], - _default: [0, "", ""], - }, - bh = U(c); - (bg.optgroup = bg.option), - (bg.tbody = bg.tfoot = bg.colgroup = bg.caption = bg.thead), - (bg.th = bg.td), - f.support.htmlSerialize || (bg._default = [1, "div
", "
"]), - f.fn.extend({ - text: function (a) { - return f.access( - this, - function (a) { - return a === b - ? f.text(this) - : this.empty().append( - ((this[0] && this[0].ownerDocument) || c).createTextNode(a), - ); - }, - null, - a, - arguments.length, - ); - }, - wrapAll: function (a) { - if (f.isFunction(a)) - return this.each(function (b) { - f(this).wrapAll(a.call(this, b)); - }); - if (this[0]) { - var b = f(a, this[0].ownerDocument).eq(0).clone(!0); - this[0].parentNode && b.insertBefore(this[0]), - b - .map(function () { - var a = this; - while (a.firstChild && a.firstChild.nodeType === 1) - a = a.firstChild; - return a; - }) - .append(this); - } - return this; - }, - wrapInner: function (a) { - if (f.isFunction(a)) - return this.each(function (b) { - f(this).wrapInner(a.call(this, b)); - }); - return this.each(function () { - var b = f(this), - c = b.contents(); - c.length ? c.wrapAll(a) : b.append(a); - }); - }, - wrap: function (a) { - var b = f.isFunction(a); - return this.each(function (c) { - f(this).wrapAll(b ? a.call(this, c) : a); - }); - }, - unwrap: function () { - return this.parent() - .each(function () { - f.nodeName(this, "body") || f(this).replaceWith(this.childNodes); - }) - .end(); - }, - append: function () { - return this.domManip(arguments, !0, function (a) { - this.nodeType === 1 && this.appendChild(a); - }); - }, - prepend: function () { - return this.domManip(arguments, !0, function (a) { - this.nodeType === 1 && this.insertBefore(a, this.firstChild); - }); - }, - before: function () { - if (this[0] && this[0].parentNode) - return this.domManip(arguments, !1, function (a) { - this.parentNode.insertBefore(a, this); - }); - if (arguments.length) { - var a = f.clean(arguments); - a.push.apply(a, this.toArray()); - return this.pushStack(a, "before", arguments); - } - }, - after: function () { - if (this[0] && this[0].parentNode) - return this.domManip(arguments, !1, function (a) { - this.parentNode.insertBefore(a, this.nextSibling); - }); - if (arguments.length) { - var a = this.pushStack(this, "after", arguments); - a.push.apply(a, f.clean(arguments)); - return a; - } - }, - remove: function (a, b) { - for (var c = 0, d; (d = this[c]) != null; c++) - if (!a || f.filter(a, [d]).length) - !b && - d.nodeType === 1 && - (f.cleanData(d.getElementsByTagName("*")), f.cleanData([d])), - d.parentNode && d.parentNode.removeChild(d); - return this; - }, - empty: function () { - for (var a = 0, b; (b = this[a]) != null; a++) { - b.nodeType === 1 && f.cleanData(b.getElementsByTagName("*")); - while (b.firstChild) b.removeChild(b.firstChild); - } - return this; - }, - clone: function (a, b) { - (a = a == null ? !1 : a), (b = b == null ? a : b); - return this.map(function () { - return f.clone(this, a, b); - }); - }, - html: function (a) { - return f.access( - this, - function (a) { - var c = this[0] || {}, - d = 0, - e = this.length; - if (a === b) - return c.nodeType === 1 ? c.innerHTML.replace(W, "") : null; - if ( - typeof a == "string" && - !ba.test(a) && - (f.support.leadingWhitespace || !X.test(a)) && - !bg[(Z.exec(a) || ["", ""])[1].toLowerCase()] - ) { - a = a.replace(Y, "<$1>"); - try { - for (; d < e; d++) - (c = this[d] || {}), - c.nodeType === 1 && - (f.cleanData(c.getElementsByTagName("*")), - (c.innerHTML = a)); - c = 0; - } catch (g) {} - } - c && this.empty().append(a); - }, - null, - a, - arguments.length, - ); - }, - replaceWith: function (a) { - if (this[0] && this[0].parentNode) { - if (f.isFunction(a)) - return this.each(function (b) { - var c = f(this), - d = c.html(); - c.replaceWith(a.call(this, b, d)); - }); - typeof a != "string" && (a = f(a).detach()); - return this.each(function () { - var b = this.nextSibling, - c = this.parentNode; - f(this).remove(), b ? f(b).before(a) : f(c).append(a); - }); - } - return this.length - ? this.pushStack(f(f.isFunction(a) ? a() : a), "replaceWith", a) - : this; - }, - detach: function (a) { - return this.remove(a, !0); - }, - domManip: function (a, c, d) { - var e, - g, - h, - i, - j = a[0], - k = []; - if ( - !f.support.checkClone && - arguments.length === 3 && - typeof j == "string" && - bd.test(j) - ) - return this.each(function () { - f(this).domManip(a, c, d, !0); - }); - if (f.isFunction(j)) - return this.each(function (e) { - var g = f(this); - (a[0] = j.call(this, e, c ? g.html() : b)), g.domManip(a, c, d); - }); - if (this[0]) { - (i = j && j.parentNode), - f.support.parentNode && - i && - i.nodeType === 11 && - i.childNodes.length === this.length - ? (e = { fragment: i }) - : (e = f.buildFragment(a, this, k)), - (h = e.fragment), - h.childNodes.length === 1 - ? (g = h = h.firstChild) - : (g = h.firstChild); - if (g) { - c = c && f.nodeName(g, "tr"); - for (var l = 0, m = this.length, n = m - 1; l < m; l++) - d.call( - c ? bi(this[l], g) : this[l], - e.cacheable || (m > 1 && l < n) ? f.clone(h, !0, !0) : h, - ); - } - k.length && - f.each(k, function (a, b) { - b.src - ? f.ajax({ - type: "GET", - global: !1, - url: b.src, - async: !1, - dataType: "script", - }) - : f.globalEval( - (b.text || b.textContent || b.innerHTML || "").replace( - bf, - "/*$0*/", - ), - ), - b.parentNode && b.parentNode.removeChild(b); - }); - } - return this; - }, - }), - (f.buildFragment = function (a, b, d) { - var e, - g, - h, - i, - j = a[0]; - b && b[0] && (i = b[0].ownerDocument || b[0]), - i.createDocumentFragment || (i = c), - a.length === 1 && - typeof j == "string" && - j.length < 512 && - i === c && - j.charAt(0) === "<" && - !bb.test(j) && - (f.support.checkClone || !bd.test(j)) && - (f.support.html5Clone || !bc.test(j)) && - ((g = !0), (h = f.fragments[j]), h && h !== 1 && (e = h)), - e || ((e = i.createDocumentFragment()), f.clean(a, i, e, d)), - g && (f.fragments[j] = h ? e : 1); - return { fragment: e, cacheable: g }; - }), - (f.fragments = {}), - f.each( - { - appendTo: "append", - prependTo: "prepend", - insertBefore: "before", - insertAfter: "after", - replaceAll: "replaceWith", - }, - function (a, b) { - f.fn[a] = function (c) { - var d = [], - e = f(c), - g = this.length === 1 && this[0].parentNode; - if ( - g && - g.nodeType === 11 && - g.childNodes.length === 1 && - e.length === 1 - ) { - e[b](this[0]); - return this; - } - for (var h = 0, i = e.length; h < i; h++) { - var j = (h > 0 ? this.clone(!0) : this).get(); - f(e[h])[b](j), (d = d.concat(j)); - } - return this.pushStack(d, a, e.selector); - }; - }, - ), - f.extend({ - clone: function (a, b, c) { - var d, - e, - g, - h = - f.support.html5Clone || - f.isXMLDoc(a) || - !bc.test("<" + a.nodeName + ">") - ? a.cloneNode(!0) - : bo(a); - if ( - (!f.support.noCloneEvent || !f.support.noCloneChecked) && - (a.nodeType === 1 || a.nodeType === 11) && - !f.isXMLDoc(a) - ) { - bk(a, h), (d = bl(a)), (e = bl(h)); - for (g = 0; d[g]; ++g) e[g] && bk(d[g], e[g]); - } - if (b) { - bj(a, h); - if (c) { - (d = bl(a)), (e = bl(h)); - for (g = 0; d[g]; ++g) bj(d[g], e[g]); - } - } - d = e = null; - return h; - }, - clean: function (a, b, d, e) { - var g, - h, - i, - j = []; - (b = b || c), - typeof b.createElement == "undefined" && - (b = b.ownerDocument || (b[0] && b[0].ownerDocument) || c); - for (var k = 0, l; (l = a[k]) != null; k++) { - typeof l == "number" && (l += ""); - if (!l) continue; - if (typeof l == "string") - if (!_.test(l)) l = b.createTextNode(l); - else { - l = l.replace(Y, "<$1>"); - var m = (Z.exec(l) || ["", ""])[1].toLowerCase(), - n = bg[m] || bg._default, - o = n[0], - p = b.createElement("div"), - q = bh.childNodes, - r; - b === c ? bh.appendChild(p) : U(b).appendChild(p), - (p.innerHTML = n[1] + l + n[2]); - while (o--) p = p.lastChild; - if (!f.support.tbody) { - var s = $.test(l), - t = - m === "table" && !s - ? p.firstChild && p.firstChild.childNodes - : n[1] === "" && !s - ? p.childNodes - : []; - for (i = t.length - 1; i >= 0; --i) - f.nodeName(t[i], "tbody") && - !t[i].childNodes.length && - t[i].parentNode.removeChild(t[i]); - } - !f.support.leadingWhitespace && - X.test(l) && - p.insertBefore(b.createTextNode(X.exec(l)[0]), p.firstChild), - (l = p.childNodes), - p && - (p.parentNode.removeChild(p), - q.length > 0 && - ((r = q[q.length - 1]), - r && r.parentNode && r.parentNode.removeChild(r))); - } - var u; - if (!f.support.appendChecked) - if (l[0] && typeof (u = l.length) == "number") - for (i = 0; i < u; i++) bn(l[i]); - else bn(l); - l.nodeType ? j.push(l) : (j = f.merge(j, l)); - } - if (d) { - g = function (a) { - return !a.type || be.test(a.type); - }; - for (k = 0; j[k]; k++) { - h = j[k]; - if (e && f.nodeName(h, "script") && (!h.type || be.test(h.type))) - e.push(h.parentNode ? h.parentNode.removeChild(h) : h); - else { - if (h.nodeType === 1) { - var v = f.grep(h.getElementsByTagName("script"), g); - j.splice.apply(j, [k + 1, 0].concat(v)); - } - d.appendChild(h); - } - } - } - return j; - }, - cleanData: function (a) { - var b, - c, - d = f.cache, - e = f.event.special, - g = f.support.deleteExpando; - for (var h = 0, i; (i = a[h]) != null; h++) { - if (i.nodeName && f.noData[i.nodeName.toLowerCase()]) continue; - c = i[f.expando]; - if (c) { - b = d[c]; - if (b && b.events) { - for (var j in b.events) - e[j] ? f.event.remove(i, j) : f.removeEvent(i, j, b.handle); - b.handle && (b.handle.elem = null); - } - g - ? delete i[f.expando] - : i.removeAttribute && i.removeAttribute(f.expando), - delete d[c]; - } - } - }, - }); - var bp = /alpha\([^)]*\)/i, - bq = /opacity=([^)]*)/, - br = /([A-Z]|^ms)/g, - bs = /^[\-+]?(?:\d*\.)?\d+$/i, - bt = /^-?(?:\d*\.)?\d+(?!px)[^\d\s]+$/i, - bu = /^([\-+])=([\-+.\de]+)/, - bv = /^margin/, - bw = { position: "absolute", visibility: "hidden", display: "block" }, - bx = ["Top", "Right", "Bottom", "Left"], - by, - bz, - bA; - (f.fn.css = function (a, c) { - return f.access( - this, - function (a, c, d) { - return d !== b ? f.style(a, c, d) : f.css(a, c); - }, - a, - c, - arguments.length > 1, - ); - }), - f.extend({ - cssHooks: { - opacity: { - get: function (a, b) { - if (b) { - var c = by(a, "opacity"); - return c === "" ? "1" : c; - } - return a.style.opacity; - }, - }, - }, - cssNumber: { - fillOpacity: !0, - fontWeight: !0, - lineHeight: !0, - opacity: !0, - orphans: !0, - widows: !0, - zIndex: !0, - zoom: !0, - }, - cssProps: { float: f.support.cssFloat ? "cssFloat" : "styleFloat" }, - style: function (a, c, d, e) { - if (!!a && a.nodeType !== 3 && a.nodeType !== 8 && !!a.style) { - var g, - h, - i = f.camelCase(c), - j = a.style, - k = f.cssHooks[i]; - c = f.cssProps[i] || i; - if (d === b) { - if (k && "get" in k && (g = k.get(a, !1, e)) !== b) return g; - return j[c]; - } - (h = typeof d), - h === "string" && - (g = bu.exec(d)) && - ((d = +(g[1] + 1) * +g[2] + parseFloat(f.css(a, c))), - (h = "number")); - if (d == null || (h === "number" && isNaN(d))) return; - h === "number" && !f.cssNumber[i] && (d += "px"); - if (!k || !("set" in k) || (d = k.set(a, d)) !== b) - try { - j[c] = d; - } catch (l) {} - } - }, - css: function (a, c, d) { - var e, g; - (c = f.camelCase(c)), - (g = f.cssHooks[c]), - (c = f.cssProps[c] || c), - c === "cssFloat" && (c = "float"); - if (g && "get" in g && (e = g.get(a, !0, d)) !== b) return e; - if (by) return by(a, c); - }, - swap: function (a, b, c) { - var d = {}, - e, - f; - for (f in b) (d[f] = a.style[f]), (a.style[f] = b[f]); - e = c.call(a); - for (f in b) a.style[f] = d[f]; - return e; - }, - }), - (f.curCSS = f.css), - c.defaultView && - c.defaultView.getComputedStyle && - (bz = function (a, b) { - var c, - d, - e, - g, - h = a.style; - (b = b.replace(br, "-$1").toLowerCase()), - (d = a.ownerDocument.defaultView) && - (e = d.getComputedStyle(a, null)) && - ((c = e.getPropertyValue(b)), - c === "" && - !f.contains(a.ownerDocument.documentElement, a) && - (c = f.style(a, b))), - !f.support.pixelMargin && - e && - bv.test(b) && - bt.test(c) && - ((g = h.width), (h.width = c), (c = e.width), (h.width = g)); - return c; - }), - c.documentElement.currentStyle && - (bA = function (a, b) { - var c, - d, - e, - f = a.currentStyle && a.currentStyle[b], - g = a.style; - f == null && g && (e = g[b]) && (f = e), - bt.test(f) && - ((c = g.left), - (d = a.runtimeStyle && a.runtimeStyle.left), - d && (a.runtimeStyle.left = a.currentStyle.left), - (g.left = b === "fontSize" ? "1em" : f), - (f = g.pixelLeft + "px"), - (g.left = c), - d && (a.runtimeStyle.left = d)); - return f === "" ? "auto" : f; - }), - (by = bz || bA), - f.each(["height", "width"], function (a, b) { - f.cssHooks[b] = { - get: function (a, c, d) { - if (c) - return a.offsetWidth !== 0 - ? bB(a, b, d) - : f.swap(a, bw, function () { - return bB(a, b, d); - }); - }, - set: function (a, b) { - return bs.test(b) ? b + "px" : b; - }, - }; - }), - f.support.opacity || - (f.cssHooks.opacity = { - get: function (a, b) { - return bq.test( - (b && a.currentStyle ? a.currentStyle.filter : a.style.filter) || - "", - ) - ? parseFloat(RegExp.$1) / 100 + "" - : b - ? "1" - : ""; - }, - set: function (a, b) { - var c = a.style, - d = a.currentStyle, - e = f.isNumeric(b) ? "alpha(opacity=" + b * 100 + ")" : "", - g = (d && d.filter) || c.filter || ""; - c.zoom = 1; - if (b >= 1 && f.trim(g.replace(bp, "")) === "") { - c.removeAttribute("filter"); - if (d && !d.filter) return; - } - c.filter = bp.test(g) ? g.replace(bp, e) : g + " " + e; - }, - }), - f(function () { - f.support.reliableMarginRight || - (f.cssHooks.marginRight = { - get: function (a, b) { - return f.swap(a, { display: "inline-block" }, function () { - return b ? by(a, "margin-right") : a.style.marginRight; - }); - }, - }); - }), - f.expr && - f.expr.filters && - ((f.expr.filters.hidden = function (a) { - var b = a.offsetWidth, - c = a.offsetHeight; - return ( - (b === 0 && c === 0) || - (!f.support.reliableHiddenOffsets && - ((a.style && a.style.display) || f.css(a, "display")) === "none") - ); - }), - (f.expr.filters.visible = function (a) { - return !f.expr.filters.hidden(a); - })), - f.each({ margin: "", padding: "", border: "Width" }, function (a, b) { - f.cssHooks[a + b] = { - expand: function (c) { - var d, - e = typeof c == "string" ? c.split(" ") : [c], - f = {}; - for (d = 0; d < 4; d++) f[a + bx[d] + b] = e[d] || e[d - 2] || e[0]; - return f; - }, - }; - }); - var bC = /%20/g, - bD = /\[\]$/, - bE = /\r?\n/g, - bF = /#.*$/, - bG = /^(.*?):[ \t]*([^\r\n]*)\r?$/gm, - bH = - /^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i, - bI = /^(?:about|app|app\-storage|.+\-extension|file|res|widget):$/, - bJ = /^(?:GET|HEAD)$/, - bK = /^\/\//, - bL = /\?/, - bM = /)<[^<]*)*<\/script>/gi, - bN = /^(?:select|textarea)/i, - bO = /\s+/, - bP = /([?&])_=[^&]*/, - bQ = /^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+))?)?/, - bR = f.fn.load, - bS = {}, - bT = {}, - bU, - bV, - bW = ["*/"] + ["*"]; - try { - bU = e.href; - } catch (bX) { - (bU = c.createElement("a")), (bU.href = ""), (bU = bU.href); - } - (bV = bQ.exec(bU.toLowerCase()) || []), - f.fn.extend({ - load: function (a, c, d) { - if (typeof a != "string" && bR) return bR.apply(this, arguments); - if (!this.length) return this; - var e = a.indexOf(" "); - if (e >= 0) { - var g = a.slice(e, a.length); - a = a.slice(0, e); - } - var h = "GET"; - c && - (f.isFunction(c) - ? ((d = c), (c = b)) - : typeof c == "object" && - ((c = f.param(c, f.ajaxSettings.traditional)), (h = "POST"))); - var i = this; - f.ajax({ - url: a, - type: h, - dataType: "html", - data: c, - complete: function (a, b, c) { - (c = a.responseText), - a.isResolved() && - (a.done(function (a) { - c = a; - }), - i.html(g ? f("
").append(c.replace(bM, "")).find(g) : c)), - d && i.each(d, [c, b, a]); - }, - }); - return this; - }, - serialize: function () { - return f.param(this.serializeArray()); - }, - serializeArray: function () { - return this.map(function () { - return this.elements ? f.makeArray(this.elements) : this; - }) - .filter(function () { - return ( - this.name && - !this.disabled && - (this.checked || bN.test(this.nodeName) || bH.test(this.type)) - ); - }) - .map(function (a, b) { - var c = f(this).val(); - return c == null - ? null - : f.isArray(c) - ? f.map(c, function (a, c) { - return { name: b.name, value: a.replace(bE, "\r\n") }; - }) - : { name: b.name, value: c.replace(bE, "\r\n") }; - }) - .get(); - }, - }), - f.each( - "ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split( - " ", - ), - function (a, b) { - f.fn[b] = function (a) { - return this.on(b, a); - }; - }, - ), - f.each(["get", "post"], function (a, c) { - f[c] = function (a, d, e, g) { - f.isFunction(d) && ((g = g || e), (e = d), (d = b)); - return f.ajax({ type: c, url: a, data: d, success: e, dataType: g }); - }; - }), - f.extend({ - getScript: function (a, c) { - return f.get(a, b, c, "script"); - }, - getJSON: function (a, b, c) { - return f.get(a, b, c, "json"); - }, - ajaxSetup: function (a, b) { - b ? b$(a, f.ajaxSettings) : ((b = a), (a = f.ajaxSettings)), b$(a, b); - return a; - }, - ajaxSettings: { - url: bU, - isLocal: bI.test(bV[1]), - global: !0, - type: "GET", - contentType: "application/x-www-form-urlencoded; charset=UTF-8", - processData: !0, - async: !0, - accepts: { - xml: "application/xml, text/xml", - html: "text/html", - text: "text/plain", - json: "application/json, text/javascript", - "*": bW, - }, - contents: { xml: /xml/, html: /html/, json: /json/ }, - responseFields: { xml: "responseXML", text: "responseText" }, - converters: { - "* text": a.String, - "text html": !0, - "text json": f.parseJSON, - "text xml": f.parseXML, - }, - flatOptions: { context: !0, url: !0 }, - }, - ajaxPrefilter: bY(bS), - ajaxTransport: bY(bT), - ajax: function (a, c) { - function w(a, c, l, m) { - if (s !== 2) { - (s = 2), - q && clearTimeout(q), - (p = b), - (n = m || ""), - (v.readyState = a > 0 ? 4 : 0); - var o, - r, - u, - w = c, - x = l ? ca(d, v, l) : b, - y, - z; - if ((a >= 200 && a < 300) || a === 304) { - if (d.ifModified) { - if ((y = v.getResponseHeader("Last-Modified"))) - f.lastModified[k] = y; - if ((z = v.getResponseHeader("Etag"))) f.etag[k] = z; - } - if (a === 304) (w = "notmodified"), (o = !0); - else - try { - (r = cb(d, x)), (w = "success"), (o = !0); - } catch (A) { - (w = "parsererror"), (u = A); - } - } else { - u = w; - if (!w || a) (w = "error"), a < 0 && (a = 0); - } - (v.status = a), - (v.statusText = "" + (c || w)), - o ? h.resolveWith(e, [r, w, v]) : h.rejectWith(e, [v, w, u]), - v.statusCode(j), - (j = b), - t && - g.trigger("ajax" + (o ? "Success" : "Error"), [ - v, - d, - o ? r : u, - ]), - i.fireWith(e, [v, w]), - t && - (g.trigger("ajaxComplete", [v, d]), - --f.active || f.event.trigger("ajaxStop")); - } - } - typeof a == "object" && ((c = a), (a = b)), (c = c || {}); - var d = f.ajaxSetup({}, c), - e = d.context || d, - g = e !== d && (e.nodeType || e instanceof f) ? f(e) : f.event, - h = f.Deferred(), - i = f.Callbacks("once memory"), - j = d.statusCode || {}, - k, - l = {}, - m = {}, - n, - o, - p, - q, - r, - s = 0, - t, - u, - v = { - readyState: 0, - setRequestHeader: function (a, b) { - if (!s) { - var c = a.toLowerCase(); - (a = m[c] = m[c] || a), (l[a] = b); - } - return this; - }, - getAllResponseHeaders: function () { - return s === 2 ? n : null; - }, - getResponseHeader: function (a) { - var c; - if (s === 2) { - if (!o) { - o = {}; - while ((c = bG.exec(n))) o[c[1].toLowerCase()] = c[2]; - } - c = o[a.toLowerCase()]; - } - return c === b ? null : c; - }, - overrideMimeType: function (a) { - s || (d.mimeType = a); - return this; - }, - abort: function (a) { - (a = a || "abort"), p && p.abort(a), w(0, a); - return this; - }, - }; - h.promise(v), - (v.success = v.done), - (v.error = v.fail), - (v.complete = i.add), - (v.statusCode = function (a) { - if (a) { - var b; - if (s < 2) for (b in a) j[b] = [j[b], a[b]]; - else (b = a[v.status]), v.then(b, b); - } - return this; - }), - (d.url = ((a || d.url) + "") - .replace(bF, "") - .replace(bK, bV[1] + "//")), - (d.dataTypes = f - .trim(d.dataType || "*") - .toLowerCase() - .split(bO)), - d.crossDomain == null && - ((r = bQ.exec(d.url.toLowerCase())), - (d.crossDomain = !( - !r || - (r[1] == bV[1] && - r[2] == bV[2] && - (r[3] || (r[1] === "http:" ? 80 : 443)) == - (bV[3] || (bV[1] === "http:" ? 80 : 443))) - ))), - d.data && - d.processData && - typeof d.data != "string" && - (d.data = f.param(d.data, d.traditional)), - bZ(bS, d, c, v); - if (s === 2) return !1; - (t = d.global), - (d.type = d.type.toUpperCase()), - (d.hasContent = !bJ.test(d.type)), - t && f.active++ === 0 && f.event.trigger("ajaxStart"); - if (!d.hasContent) { - d.data && - ((d.url += (bL.test(d.url) ? "&" : "?") + d.data), delete d.data), - (k = d.url); - if (d.cache === !1) { - var x = f.now(), - y = d.url.replace(bP, "$1_=" + x); - d.url = - y + (y === d.url ? (bL.test(d.url) ? "&" : "?") + "_=" + x : ""); - } - } - ((d.data && d.hasContent && d.contentType !== !1) || c.contentType) && - v.setRequestHeader("Content-Type", d.contentType), - d.ifModified && - ((k = k || d.url), - f.lastModified[k] && - v.setRequestHeader("If-Modified-Since", f.lastModified[k]), - f.etag[k] && v.setRequestHeader("If-None-Match", f.etag[k])), - v.setRequestHeader( - "Accept", - d.dataTypes[0] && d.accepts[d.dataTypes[0]] - ? d.accepts[d.dataTypes[0]] + - (d.dataTypes[0] !== "*" ? ", " + bW + "; q=0.01" : "") - : d.accepts["*"], - ); - for (u in d.headers) v.setRequestHeader(u, d.headers[u]); - if (d.beforeSend && (d.beforeSend.call(e, v, d) === !1 || s === 2)) { - v.abort(); - return !1; - } - for (u in { success: 1, error: 1, complete: 1 }) v[u](d[u]); - p = bZ(bT, d, c, v); - if (!p) w(-1, "No Transport"); - else { - (v.readyState = 1), - t && g.trigger("ajaxSend", [v, d]), - d.async && - d.timeout > 0 && - (q = setTimeout(function () { - v.abort("timeout"); - }, d.timeout)); - try { - (s = 1), p.send(l, w); - } catch (z) { - if (s < 2) w(-1, z); - else throw z; - } - } - return v; - }, - param: function (a, c) { - var d = [], - e = function (a, b) { - (b = f.isFunction(b) ? b() : b), - (d[d.length] = - encodeURIComponent(a) + "=" + encodeURIComponent(b)); - }; - c === b && (c = f.ajaxSettings.traditional); - if (f.isArray(a) || (a.jquery && !f.isPlainObject(a))) - f.each(a, function () { - e(this.name, this.value); - }); - else for (var g in a) b_(g, a[g], c, e); - return d.join("&").replace(bC, "+"); - }, - }), - f.extend({ active: 0, lastModified: {}, etag: {} }); - var cc = f.now(), - cd = /(\=)\?(&|$)|\?\?/i; - f.ajaxSetup({ - jsonp: "callback", - jsonpCallback: function () { - return f.expando + "_" + cc++; - }, - }), - f.ajaxPrefilter("json jsonp", function (b, c, d) { - var e = - typeof b.data == "string" && - /^application\/x\-www\-form\-urlencoded/.test(b.contentType); - if ( - b.dataTypes[0] === "jsonp" || - (b.jsonp !== !1 && (cd.test(b.url) || (e && cd.test(b.data)))) - ) { - var g, - h = (b.jsonpCallback = f.isFunction(b.jsonpCallback) - ? b.jsonpCallback() - : b.jsonpCallback), - i = a[h], - j = b.url, - k = b.data, - l = "$1" + h + "$2"; - b.jsonp !== !1 && - ((j = j.replace(cd, l)), - b.url === j && - (e && (k = k.replace(cd, l)), - b.data === k && - (j += (/\?/.test(j) ? "&" : "?") + b.jsonp + "=" + h))), - (b.url = j), - (b.data = k), - (a[h] = function (a) { - g = [a]; - }), - d.always(function () { - (a[h] = i), g && f.isFunction(i) && a[h](g[0]); - }), - (b.converters["script json"] = function () { - g || f.error(h + " was not called"); - return g[0]; - }), - (b.dataTypes[0] = "json"); - return "script"; - } - }), - f.ajaxSetup({ - accepts: { - script: - "text/javascript, application/javascript, application/ecmascript, application/x-ecmascript", - }, - contents: { script: /javascript|ecmascript/ }, - converters: { - "text script": function (a) { - f.globalEval(a); - return a; - }, - }, - }), - f.ajaxPrefilter("script", function (a) { - a.cache === b && (a.cache = !1), - a.crossDomain && ((a.type = "GET"), (a.global = !1)); - }), - f.ajaxTransport("script", function (a) { - if (a.crossDomain) { - var d, - e = c.head || c.getElementsByTagName("head")[0] || c.documentElement; - return { - send: function (f, g) { - (d = c.createElement("script")), - (d.async = "async"), - a.scriptCharset && (d.charset = a.scriptCharset), - (d.src = a.url), - (d.onload = d.onreadystatechange = - function (a, c) { - if ( - c || - !d.readyState || - /loaded|complete/.test(d.readyState) - ) - (d.onload = d.onreadystatechange = null), - e && d.parentNode && e.removeChild(d), - (d = b), - c || g(200, "success"); - }), - e.insertBefore(d, e.firstChild); - }, - abort: function () { - d && d.onload(0, 1); - }, - }; - } - }); - var ce = a.ActiveXObject - ? function () { - for (var a in cg) cg[a](0, 1); - } - : !1, - cf = 0, - cg; - (f.ajaxSettings.xhr = a.ActiveXObject - ? function () { - return (!this.isLocal && ch()) || ci(); - } - : ch), - (function (a) { - f.extend(f.support, { ajax: !!a, cors: !!a && "withCredentials" in a }); - })(f.ajaxSettings.xhr()), - f.support.ajax && - f.ajaxTransport(function (c) { - if (!c.crossDomain || f.support.cors) { - var d; - return { - send: function (e, g) { - var h = c.xhr(), - i, - j; - c.username - ? h.open(c.type, c.url, c.async, c.username, c.password) - : h.open(c.type, c.url, c.async); - if (c.xhrFields) for (j in c.xhrFields) h[j] = c.xhrFields[j]; - c.mimeType && - h.overrideMimeType && - h.overrideMimeType(c.mimeType), - !c.crossDomain && - !e["X-Requested-With"] && - (e["X-Requested-With"] = "XMLHttpRequest"); - try { - for (j in e) h.setRequestHeader(j, e[j]); - } catch (k) {} - h.send((c.hasContent && c.data) || null), - (d = function (a, e) { - var j, k, l, m, n; - try { - if (d && (e || h.readyState === 4)) { - (d = b), - i && - ((h.onreadystatechange = f.noop), ce && delete cg[i]); - if (e) h.readyState !== 4 && h.abort(); - else { - (j = h.status), - (l = h.getAllResponseHeaders()), - (m = {}), - (n = h.responseXML), - n && n.documentElement && (m.xml = n); - try { - m.text = h.responseText; - } catch (a) {} - try { - k = h.statusText; - } catch (o) { - k = ""; - } - !j && c.isLocal && !c.crossDomain - ? (j = m.text ? 200 : 404) - : j === 1223 && (j = 204); - } - } - } catch (p) { - e || g(-1, p); - } - m && g(j, k, m, l); - }), - !c.async || h.readyState === 4 - ? d() - : ((i = ++cf), - ce && (cg || ((cg = {}), f(a).unload(ce)), (cg[i] = d)), - (h.onreadystatechange = d)); - }, - abort: function () { - d && d(0, 1); - }, - }; - } - }); - var cj = {}, - ck, - cl, - cm = /^(?:toggle|show|hide)$/, - cn = /^([+\-]=)?([\d+.\-]+)([a-z%]*)$/i, - co, - cp = [ - ["height", "marginTop", "marginBottom", "paddingTop", "paddingBottom"], - ["width", "marginLeft", "marginRight", "paddingLeft", "paddingRight"], - ["opacity"], - ], - cq; - f.fn.extend({ - show: function (a, b, c) { - var d, e; - if (a || a === 0) return this.animate(ct("show", 3), a, b, c); - for (var g = 0, h = this.length; g < h; g++) - (d = this[g]), - d.style && - ((e = d.style.display), - !f._data(d, "olddisplay") && - e === "none" && - (e = d.style.display = ""), - ((e === "" && f.css(d, "display") === "none") || - !f.contains(d.ownerDocument.documentElement, d)) && - f._data(d, "olddisplay", cu(d.nodeName))); - for (g = 0; g < h; g++) { - d = this[g]; - if (d.style) { - e = d.style.display; - if (e === "" || e === "none") - d.style.display = f._data(d, "olddisplay") || ""; - } - } - return this; - }, - hide: function (a, b, c) { - if (a || a === 0) return this.animate(ct("hide", 3), a, b, c); - var d, - e, - g = 0, - h = this.length; - for (; g < h; g++) - (d = this[g]), - d.style && - ((e = f.css(d, "display")), - e !== "none" && - !f._data(d, "olddisplay") && - f._data(d, "olddisplay", e)); - for (g = 0; g < h; g++) this[g].style && (this[g].style.display = "none"); - return this; - }, - _toggle: f.fn.toggle, - toggle: function (a, b, c) { - var d = typeof a == "boolean"; - f.isFunction(a) && f.isFunction(b) - ? this._toggle.apply(this, arguments) - : a == null || d - ? this.each(function () { - var b = d ? a : f(this).is(":hidden"); - f(this)[b ? "show" : "hide"](); - }) - : this.animate(ct("toggle", 3), a, b, c); - return this; - }, - fadeTo: function (a, b, c, d) { - return this.filter(":hidden") - .css("opacity", 0) - .show() - .end() - .animate({ opacity: b }, a, c, d); - }, - animate: function (a, b, c, d) { - function g() { - e.queue === !1 && f._mark(this); - var b = f.extend({}, e), - c = this.nodeType === 1, - d = c && f(this).is(":hidden"), - g, - h, - i, - j, - k, - l, - m, - n, - o, - p, - q; - b.animatedProperties = {}; - for (i in a) { - (g = f.camelCase(i)), i !== g && ((a[g] = a[i]), delete a[i]); - if ((k = f.cssHooks[g]) && "expand" in k) { - (l = k.expand(a[g])), delete a[g]; - for (i in l) i in a || (a[i] = l[i]); - } - } - for (g in a) { - (h = a[g]), - f.isArray(h) - ? ((b.animatedProperties[g] = h[1]), (h = a[g] = h[0])) - : (b.animatedProperties[g] = - (b.specialEasing && b.specialEasing[g]) || - b.easing || - "swing"); - if ((h === "hide" && d) || (h === "show" && !d)) - return b.complete.call(this); - c && - (g === "height" || g === "width") && - ((b.overflow = [ - this.style.overflow, - this.style.overflowX, - this.style.overflowY, - ]), - f.css(this, "display") === "inline" && - f.css(this, "float") === "none" && - (!f.support.inlineBlockNeedsLayout || - cu(this.nodeName) === "inline" - ? (this.style.display = "inline-block") - : (this.style.zoom = 1))); - } - b.overflow != null && (this.style.overflow = "hidden"); - for (i in a) - (j = new f.fx(this, b, i)), - (h = a[i]), - cm.test(h) - ? ((q = - f._data(this, "toggle" + i) || - (h === "toggle" ? (d ? "show" : "hide") : 0)), - q - ? (f._data( - this, - "toggle" + i, - q === "show" ? "hide" : "show", - ), - j[q]()) - : j[h]()) - : ((m = cn.exec(h)), - (n = j.cur()), - m - ? ((o = parseFloat(m[2])), - (p = m[3] || (f.cssNumber[i] ? "" : "px")), - p !== "px" && - (f.style(this, i, (o || 1) + p), - (n = ((o || 1) / j.cur()) * n), - f.style(this, i, n + p)), - m[1] && (o = (m[1] === "-=" ? -1 : 1) * o + n), - j.custom(n, o, p)) - : j.custom(n, h, "")); - return !0; - } - var e = f.speed(b, c, d); - if (f.isEmptyObject(a)) return this.each(e.complete, [!1]); - a = f.extend({}, a); - return e.queue === !1 ? this.each(g) : this.queue(e.queue, g); - }, - stop: function (a, c, d) { - typeof a != "string" && ((d = c), (c = a), (a = b)), - c && a !== !1 && this.queue(a || "fx", []); - return this.each(function () { - function h(a, b, c) { - var e = b[c]; - f.removeData(a, c, !0), e.stop(d); - } - var b, - c = !1, - e = f.timers, - g = f._data(this); - d || f._unmark(!0, this); - if (a == null) - for (b in g) - g[b] && - g[b].stop && - b.indexOf(".run") === b.length - 4 && - h(this, g, b); - else g[(b = a + ".run")] && g[b].stop && h(this, g, b); - for (b = e.length; b--; ) - e[b].elem === this && - (a == null || e[b].queue === a) && - (d ? e[b](!0) : e[b].saveState(), (c = !0), e.splice(b, 1)); - (!d || !c) && f.dequeue(this, a); - }); - }, - }), - f.each( - { - slideDown: ct("show", 1), - slideUp: ct("hide", 1), - slideToggle: ct("toggle", 1), - fadeIn: { opacity: "show" }, - fadeOut: { opacity: "hide" }, - fadeToggle: { opacity: "toggle" }, - }, - function (a, b) { - f.fn[a] = function (a, c, d) { - return this.animate(b, a, c, d); - }; - }, - ), - f.extend({ - speed: function (a, b, c) { - var d = - a && typeof a == "object" - ? f.extend({}, a) - : { - complete: c || (!c && b) || (f.isFunction(a) && a), - duration: a, - easing: (c && b) || (b && !f.isFunction(b) && b), - }; - d.duration = f.fx.off - ? 0 - : typeof d.duration == "number" - ? d.duration - : d.duration in f.fx.speeds - ? f.fx.speeds[d.duration] - : f.fx.speeds._default; - if (d.queue == null || d.queue === !0) d.queue = "fx"; - (d.old = d.complete), - (d.complete = function (a) { - f.isFunction(d.old) && d.old.call(this), - d.queue ? f.dequeue(this, d.queue) : a !== !1 && f._unmark(this); - }); - return d; - }, - easing: { - linear: function (a) { - return a; - }, - swing: function (a) { - return -Math.cos(a * Math.PI) / 2 + 0.5; - }, - }, - timers: [], - fx: function (a, b, c) { - (this.options = b), - (this.elem = a), - (this.prop = c), - (b.orig = b.orig || {}); - }, - }), - (f.fx.prototype = { - update: function () { - this.options.step && this.options.step.call(this.elem, this.now, this), - (f.fx.step[this.prop] || f.fx.step._default)(this); - }, - cur: function () { - if ( - this.elem[this.prop] != null && - (!this.elem.style || this.elem.style[this.prop] == null) - ) - return this.elem[this.prop]; - var a, - b = f.css(this.elem, this.prop); - return isNaN((a = parseFloat(b))) ? (!b || b === "auto" ? 0 : b) : a; - }, - custom: function (a, c, d) { - function h(a) { - return e.step(a); - } - var e = this, - g = f.fx; - (this.startTime = cq || cr()), - (this.end = c), - (this.now = this.start = a), - (this.pos = this.state = 0), - (this.unit = d || this.unit || (f.cssNumber[this.prop] ? "" : "px")), - (h.queue = this.options.queue), - (h.elem = this.elem), - (h.saveState = function () { - f._data(e.elem, "fxshow" + e.prop) === b && - (e.options.hide - ? f._data(e.elem, "fxshow" + e.prop, e.start) - : e.options.show && f._data(e.elem, "fxshow" + e.prop, e.end)); - }), - h() && - f.timers.push(h) && - !co && - (co = setInterval(g.tick, g.interval)); - }, - show: function () { - var a = f._data(this.elem, "fxshow" + this.prop); - (this.options.orig[this.prop] = a || f.style(this.elem, this.prop)), - (this.options.show = !0), - a !== b - ? this.custom(this.cur(), a) - : this.custom( - this.prop === "width" || this.prop === "height" ? 1 : 0, - this.cur(), - ), - f(this.elem).show(); - }, - hide: function () { - (this.options.orig[this.prop] = - f._data(this.elem, "fxshow" + this.prop) || - f.style(this.elem, this.prop)), - (this.options.hide = !0), - this.custom(this.cur(), 0); - }, - step: function (a) { - var b, - c, - d, - e = cq || cr(), - g = !0, - h = this.elem, - i = this.options; - if (a || e >= i.duration + this.startTime) { - (this.now = this.end), - (this.pos = this.state = 1), - this.update(), - (i.animatedProperties[this.prop] = !0); - for (b in i.animatedProperties) - i.animatedProperties[b] !== !0 && (g = !1); - if (g) { - i.overflow != null && - !f.support.shrinkWrapBlocks && - f.each(["", "X", "Y"], function (a, b) { - h.style["overflow" + b] = i.overflow[a]; - }), - i.hide && f(h).hide(); - if (i.hide || i.show) - for (b in i.animatedProperties) - f.style(h, b, i.orig[b]), - f.removeData(h, "fxshow" + b, !0), - f.removeData(h, "toggle" + b, !0); - (d = i.complete), d && ((i.complete = !1), d.call(h)); - } - return !1; - } - i.duration == Infinity - ? (this.now = e) - : ((c = e - this.startTime), - (this.state = c / i.duration), - (this.pos = f.easing[i.animatedProperties[this.prop]]( - this.state, - c, - 0, - 1, - i.duration, - )), - (this.now = this.start + (this.end - this.start) * this.pos)), - this.update(); - return !0; - }, - }), - f.extend(f.fx, { - tick: function () { - var a, - b = f.timers, - c = 0; - for (; c < b.length; c++) - (a = b[c]), !a() && b[c] === a && b.splice(c--, 1); - b.length || f.fx.stop(); - }, - interval: 13, - stop: function () { - clearInterval(co), (co = null); - }, - speeds: { slow: 600, fast: 200, _default: 400 }, - step: { - opacity: function (a) { - f.style(a.elem, "opacity", a.now); - }, - _default: function (a) { - a.elem.style && a.elem.style[a.prop] != null - ? (a.elem.style[a.prop] = a.now + a.unit) - : (a.elem[a.prop] = a.now); - }, - }, - }), - f.each(cp.concat.apply([], cp), function (a, b) { - b.indexOf("margin") && - (f.fx.step[b] = function (a) { - f.style(a.elem, b, Math.max(0, a.now) + a.unit); - }); - }), - f.expr && - f.expr.filters && - (f.expr.filters.animated = function (a) { - return f.grep(f.timers, function (b) { - return a === b.elem; - }).length; - }); - var cv, - cw = /^t(?:able|d|h)$/i, - cx = /^(?:body|html)$/i; - "getBoundingClientRect" in c.documentElement - ? (cv = function (a, b, c, d) { - try { - d = a.getBoundingClientRect(); - } catch (e) {} - if (!d || !f.contains(c, a)) - return d ? { top: d.top, left: d.left } : { top: 0, left: 0 }; - var g = b.body, - h = cy(b), - i = c.clientTop || g.clientTop || 0, - j = c.clientLeft || g.clientLeft || 0, - k = - h.pageYOffset || (f.support.boxModel && c.scrollTop) || g.scrollTop, - l = - h.pageXOffset || - (f.support.boxModel && c.scrollLeft) || - g.scrollLeft, - m = d.top + k - i, - n = d.left + l - j; - return { top: m, left: n }; - }) - : (cv = function (a, b, c) { - var d, - e = a.offsetParent, - g = a, - h = b.body, - i = b.defaultView, - j = i ? i.getComputedStyle(a, null) : a.currentStyle, - k = a.offsetTop, - l = a.offsetLeft; - while ((a = a.parentNode) && a !== h && a !== c) { - if (f.support.fixedPosition && j.position === "fixed") break; - (d = i ? i.getComputedStyle(a, null) : a.currentStyle), - (k -= a.scrollTop), - (l -= a.scrollLeft), - a === e && - ((k += a.offsetTop), - (l += a.offsetLeft), - f.support.doesNotAddBorder && - (!f.support.doesAddBorderForTableAndCells || - !cw.test(a.nodeName)) && - ((k += parseFloat(d.borderTopWidth) || 0), - (l += parseFloat(d.borderLeftWidth) || 0)), - (g = e), - (e = a.offsetParent)), - f.support.subtractsBorderForOverflowNotVisible && - d.overflow !== "visible" && - ((k += parseFloat(d.borderTopWidth) || 0), - (l += parseFloat(d.borderLeftWidth) || 0)), - (j = d); - } - if (j.position === "relative" || j.position === "static") - (k += h.offsetTop), (l += h.offsetLeft); - f.support.fixedPosition && - j.position === "fixed" && - ((k += Math.max(c.scrollTop, h.scrollTop)), - (l += Math.max(c.scrollLeft, h.scrollLeft))); - return { top: k, left: l }; - }), - (f.fn.offset = function (a) { - if (arguments.length) - return a === b - ? this - : this.each(function (b) { - f.offset.setOffset(this, a, b); - }); - var c = this[0], - d = c && c.ownerDocument; - if (!d) return null; - if (c === d.body) return f.offset.bodyOffset(c); - return cv(c, d, d.documentElement); - }), - (f.offset = { - bodyOffset: function (a) { - var b = a.offsetTop, - c = a.offsetLeft; - f.support.doesNotIncludeMarginInBodyOffset && - ((b += parseFloat(f.css(a, "marginTop")) || 0), - (c += parseFloat(f.css(a, "marginLeft")) || 0)); - return { top: b, left: c }; - }, - setOffset: function (a, b, c) { - var d = f.css(a, "position"); - d === "static" && (a.style.position = "relative"); - var e = f(a), - g = e.offset(), - h = f.css(a, "top"), - i = f.css(a, "left"), - j = - (d === "absolute" || d === "fixed") && - f.inArray("auto", [h, i]) > -1, - k = {}, - l = {}, - m, - n; - j - ? ((l = e.position()), (m = l.top), (n = l.left)) - : ((m = parseFloat(h) || 0), (n = parseFloat(i) || 0)), - f.isFunction(b) && (b = b.call(a, c, g)), - b.top != null && (k.top = b.top - g.top + m), - b.left != null && (k.left = b.left - g.left + n), - "using" in b ? b.using.call(a, k) : e.css(k); - }, - }), - f.fn.extend({ - position: function () { - if (!this[0]) return null; - var a = this[0], - b = this.offsetParent(), - c = this.offset(), - d = cx.test(b[0].nodeName) ? { top: 0, left: 0 } : b.offset(); - (c.top -= parseFloat(f.css(a, "marginTop")) || 0), - (c.left -= parseFloat(f.css(a, "marginLeft")) || 0), - (d.top += parseFloat(f.css(b[0], "borderTopWidth")) || 0), - (d.left += parseFloat(f.css(b[0], "borderLeftWidth")) || 0); - return { top: c.top - d.top, left: c.left - d.left }; - }, - offsetParent: function () { - return this.map(function () { - var a = this.offsetParent || c.body; - while (a && !cx.test(a.nodeName) && f.css(a, "position") === "static") - a = a.offsetParent; - return a; - }); - }, - }), - f.each( - { scrollLeft: "pageXOffset", scrollTop: "pageYOffset" }, - function (a, c) { - var d = /Y/.test(c); - f.fn[a] = function (e) { - return f.access( - this, - function (a, e, g) { - var h = cy(a); - if (g === b) - return h - ? c in h - ? h[c] - : (f.support.boxModel && h.document.documentElement[e]) || - h.document.body[e] - : a[e]; - h - ? h.scrollTo( - d ? f(h).scrollLeft() : g, - d ? g : f(h).scrollTop(), - ) - : (a[e] = g); - }, - a, - e, - arguments.length, - null, - ); - }; - }, - ), - f.each({ Height: "height", Width: "width" }, function (a, c) { - var d = "client" + a, - e = "scroll" + a, - g = "offset" + a; - (f.fn["inner" + a] = function () { - var a = this[0]; - return a - ? a.style - ? parseFloat(f.css(a, c, "padding")) - : this[c]() - : null; - }), - (f.fn["outer" + a] = function (a) { - var b = this[0]; - return b - ? b.style - ? parseFloat(f.css(b, c, a ? "margin" : "border")) - : this[c]() - : null; - }), - (f.fn[c] = function (a) { - return f.access( - this, - function (a, c, h) { - var i, j, k, l; - if (f.isWindow(a)) { - (i = a.document), (j = i.documentElement[d]); - return (f.support.boxModel && j) || (i.body && i.body[d]) || j; - } - if (a.nodeType === 9) { - i = a.documentElement; - if (i[d] >= i[e]) return i[d]; - return Math.max(a.body[e], i[e], a.body[g], i[g]); - } - if (h === b) { - (k = f.css(a, c)), (l = parseFloat(k)); - return f.isNumeric(l) ? l : k; - } - f(a).css(c, h); - }, - c, - a, - arguments.length, - null, - ); - }); - }), - (a.jQuery = a.$ = f), - typeof define == "function" && - define.amd && - define.amd.jQuery && - define("jquery", [], function () { - return f; - }); -})(window); diff --git a/pygraz_website/urls.py b/pygraz_website/urls.py index 89d15a8..0bd3cd5 100644 --- a/pygraz_website/urls.py +++ b/pygraz_website/urls.py @@ -1,18 +1,23 @@ -from django.conf import settings -from django.conf.urls.static import static +""" +URL configuration for pygraz_website project. + +The `urlpatterns` list routes URLs to views. For more information please see: + https://docs.djangoproject.com/en/4.2/topics/http/urls/ +Examples: +Function views + 1. Add an import: from my_app import views + 2. Add a URL to urlpatterns: path('', views.home, name='home') +Class-based views + 1. Add an import: from other_app.views import Home + 2. Add a URL to urlpatterns: path('', Home.as_view(), name='home') +Including another URLconf + 1. Import the include() function: from django.urls import include, path + 2. Add a URL to urlpatterns: path('blog/', include('blog.urls')) +""" from django.contrib import admin from django.urls import include, path -from . import views - -admin.autodiscover() - urlpatterns = [ - path("", views.index, name="index"), - # Overwrites for userena - path("accounts/", include("pygraz_website.apps.accounts.urls")), - path("accounts/", include("userena.urls")), - path("meetups/", include("pygraz_website.apps.meetups.urls")), - path("companies/", include("pygraz_website.apps.companies.urls")), path("admin/", admin.site.urls), -] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) + path("", include("core.urls")), +] diff --git a/pygraz_website/views.py b/pygraz_website/views.py deleted file mode 100644 index 2cb9eee..0000000 --- a/pygraz_website/views.py +++ /dev/null @@ -1,36 +0,0 @@ -from django.shortcuts import render -from django.urls import reverse -from django.utils.timezone import now - -from .apps.meetups import forms as meetup_forms -from .apps.meetups import models as meetup_models - - -def index(request): - """ - Frontpage view listing all session proposals, past meetups and the next meetup. - """ - today = now() - try: - next_meetup = ( - meetup_models.Meetup.objects.get_future_meetups(now=today) - .order_by("-start_date") - .prefetch_related("sessions", "sessions__speaker") - .select_related("location")[0] - ) - except: - next_meetup = None - past_meetups = meetup_models.Meetup.objects.get_past_meetups(now=today) - session_proposals = meetup_models.Session.objects.get_proposals().select_related("speaker") - submission_form = meetup_forms.get_session_submission_form_class(request)() - submission_form.helper.form_action = reverse("submit-session") + "?next=/" - return render( - request, - "meetups/index.html", - { - "next_meetup": next_meetup, - "past_meetups": past_meetups, - "session_proposals": session_proposals, - "submission_form": submission_form, - }, - ) diff --git a/pygraz_website/wsgi.py b/pygraz_website/wsgi.py index 2a2973b..1a67ae9 100644 --- a/pygraz_website/wsgi.py +++ b/pygraz_website/wsgi.py @@ -1,29 +1,16 @@ """ WSGI config for pygraz_website project. -This module contains the WSGI application used by Django's development server -and any production WSGI deployments. It should expose a module-level variable -named ``application``. Django's ``runserver`` and ``runfcgi`` commands discover -this application via the ``WSGI_APPLICATION`` setting. - -Usually you will have the standard Django WSGI application here, but it also -might make sense to replace the whole Django WSGI application with a custom one -that later delegates to the Django one. For example, you could introduce WSGI -middleware here, or combine a Django application with an application of another -framework. +It exposes the WSGI callable as a module-level variable named ``application``. +For more information on this file, see +https://docs.djangoproject.com/en/4.2/howto/deployment/wsgi/ """ + import os -os.environ.setdefault("DJANGO_SETTINGS_MODULE", "pygraz_website.settings") +from django.core.wsgi import get_wsgi_application -# This application object is used by any WSGI server configured to use this -# file. This includes Django's development server, if the WSGI_APPLICATION -# setting points here. -from django.core.wsgi import get_wsgi_application # noqa: E402 +os.environ.setdefault("DJANGO_SETTINGS_MODULE", "pygraz_website.settings") application = get_wsgi_application() - -# Apply WSGI middleware here. -# from helloworld.wsgi import HelloWorldApplication -# application = HelloWorldApplication(application) diff --git a/pyproject.toml b/pyproject.toml index ae03967..c62516a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -2,7 +2,7 @@ max-line-length = 120 [tool.black] -target-version = ['py38'] +target-version = ['py310'] line-length = 120 include = '\.pyi?$' exclude = ''' @@ -20,6 +20,22 @@ default_section = "THIRDPARTY" known_first_party = "pygraz_website" skip_glob = "venv" +[tool.poetry] +name = "pygraz_website" +version = "2.0.0" +description = "Website of the Python user group Graz" +authors = ["Dorian Santner", "Horst Gutmann", "Thomas Aglassinger"] +license = "License :: OSI Approved :: BSD License" + +[tool.poetry.dependencies] +python = ">=3.10, <4" +django = "^4.2.6" +pillow = "^10.1.0" + +[tool.poetry.group.dev.dependencies] +pytest = "^7.4.3" +pytest-django = "^4.5.2" + [tool.pytest.ini_options] addopts = """\ --strict-config @@ -33,4 +49,8 @@ minversion = "7.2" testpaths = [ "tests", ] -DJANGO_SETTINGS_MODULE = "pygraz_website.settings.testing" +DJANGO_SETTINGS_MODULE = "pygraz_website.settings" + +[build-system] +requires = ["poetry-core>=1.0.0"] +build-backend = "poetry.core.masonry.api" diff --git a/requirements/base.txt b/requirements/base.txt deleted file mode 100644 index 6087a00..0000000 --- a/requirements/base.txt +++ /dev/null @@ -1,16 +0,0 @@ -Django>=4.0.9, <4.1 -psycopg2-binary==2.9.9 -pytz==2023.3.post1 -django-crispy-forms==1.14.0 -django-extensions==3.2.3 -django-flat-theme==1.1.4 -django-guardian==2.4.0 -django-userena-ce==7.0.3 -easy-thumbnails==2.8.5 -python-postmark==0.6.0 -Markdown==3.5 -Pillow==10.1.0 -raven==6.10.0 -icalendar==5.0.10 -requests==2.31.0 -arrow==1.3.0 diff --git a/requirements/development.txt b/requirements/development.txt deleted file mode 100644 index a911ecc..0000000 --- a/requirements/development.txt +++ /dev/null @@ -1,4 +0,0 @@ --r base.txt - -django-debug-toolbar==4.2.0 -pre-commit==3.5.0 diff --git a/requirements/live.txt b/requirements/live.txt deleted file mode 100644 index 66d735a..0000000 --- a/requirements/live.txt +++ /dev/null @@ -1,4 +0,0 @@ --r base.txt - -uWSGI==2.0.22 -opbeat==3.6.1 diff --git a/requirements/stage.txt b/requirements/stage.txt deleted file mode 100644 index a3b0eb3..0000000 --- a/requirements/stage.txt +++ /dev/null @@ -1,3 +0,0 @@ --r base.txt - -uWSGI==2.0.22 diff --git a/requirements/testing.txt b/requirements/testing.txt deleted file mode 100644 index bd6e30f..0000000 --- a/requirements/testing.txt +++ /dev/null @@ -1,8 +0,0 @@ --r base.txt - -coverage==7.3.2 -pytest-django==4.5.2 -pytest-xdist==3.3.1 -pytest-cov==4.1.0 -pytest-order==1.1.0 -requests_mock==1.11.0 diff --git a/scripts/build_migrations.sh b/scripts/build_migrations.sh new file mode 100755 index 0000000..4a55a15 --- /dev/null +++ b/scripts/build_migrations.sh @@ -0,0 +1,7 @@ +#!/bin/sh +set -ex +# TODO: Once the data model is reasonably stable, remove "rm" in order to preserve the data model. +rm -rf core/migrations/00*.py +rm -f pygraz.sqlite +poetry run python manage.py makemigrations --no-header +poetry run python manage.py make_demo diff --git a/tests/demo/test_demo.py b/tests/demo/test_demo.py new file mode 100644 index 0000000..a0dd5b7 --- /dev/null +++ b/tests/demo/test_demo.py @@ -0,0 +1,11 @@ +import pytest + +from demo.demo import build_demo, purge_demo + + +@pytest.mark.django_db +def test_can_build_demo(): + build_demo() + build_demo() + purge_demo() + build_demo() diff --git a/tox.ini b/tox.ini deleted file mode 100644 index b018c74..0000000 --- a/tox.ini +++ /dev/null @@ -1,12 +0,0 @@ -[tox] -skipsdist=true -envlist= - py38 - -[testenv] -deps = - -rrequirements/testing.txt -commands= - coverage run manage-testing.py test pygraz_website.apps.accounts pygraz_website.apps.companies pygraz_website.apps.core pygraz_website.apps.meetups - coverage html - coverage report