├── .bowerrc
├── .gitignore
├── .travis.yml
├── README.md
├── bower.json
├── build-test.txt
├── fabfile.py
├── manage.py
├── pyconkr
├── __init__.py
├── actions.py
├── admin.py
├── context_processors.py
├── fixtures
│ └── flatpages.json
├── forms.py
├── helper.py
├── locale
│ ├── __init__.py
│ ├── en
│ │ └── LC_MESSAGES
│ │ │ └── django.po
│ └── ko
│ │ └── LC_MESSAGES
│ │ └── django.po
├── migrations
│ ├── 0001_initial.py
│ ├── 0002_proposal_language.py
│ ├── 0003_auto_20160328_1611.py
│ ├── 0004_banner.py
│ ├── 0005_profile_nationality.py
│ ├── 0006_matching_profile.py
│ ├── 0007_auto_20160625_1618.py
│ ├── 0007_tutorialproposal.py
│ ├── 0008_merge.py
│ ├── 0009_auto_20160630_1359.py
│ ├── 0010_tutorialproposal_type.py
│ ├── 0011_auto_20160719_2118.py
│ ├── 0012_auto_20160727_2244.py
│ ├── 0013_auto_20170428_0007.py
│ ├── 0014_auto_20170630_1453.py
│ ├── 0015_auto_20170630_1534.py
│ ├── 0016_auto_20170701_1757.py
│ ├── 0017_programtime_day.py
│ ├── 0018_program_is_breaktime.py
│ ├── 0019_auto_20170712_2128.py
│ ├── 0020_auto_20180611_2132.py
│ ├── 0021_tutorialproposal_option.py
│ └── __init__.py
├── models.py
├── settings.py
├── static
│ ├── css
│ │ ├── pyconkr-media.css
│ │ ├── pyconkr-summernote.css
│ │ ├── pyconkr-teaser.css
│ │ ├── pyconkr.css
│ │ └── young-coder.css
│ ├── image
│ │ ├── anonymous.png
│ │ ├── dashed-logo.png
│ │ ├── dotted-fill-logo.png
│ │ ├── dotted-logo.png
│ │ ├── etc-badge1.png
│ │ ├── etc-badge2.png
│ │ ├── favicon.ico
│ │ ├── favicon2017.ico
│ │ ├── favicon2018.ico
│ │ ├── incline-logo.png
│ │ ├── naver-d2.png
│ │ ├── pycon2018-logo.png
│ │ ├── pycon_profile.png
│ │ ├── pyconkr-2018-cover.jpg
│ │ ├── pyconkr-2018-cover.png
│ │ ├── pyconkr-2018-slogan.png
│ │ ├── pyconkr-badge.png
│ │ ├── pyconkr2017-logo.png
│ │ ├── python-white.png
│ │ └── stripe-logo.png
│ └── js
│ │ ├── jquery.quickfit.js
│ │ ├── jquery.shuffle.js
│ │ ├── rgb-hsv.js
│ │ ├── teaser.js
│ │ └── young-coder.js
├── templates
│ ├── badge
│ │ ├── all.html
│ │ ├── facebook.html
│ │ ├── googleplus.html
│ │ └── twitter.html
│ ├── banner.html
│ ├── base.html
│ ├── child_care.html
│ ├── dev-robots.txt
│ ├── disqus.html
│ ├── facebook_script.html
│ ├── flatpages
│ │ └── default.html
│ ├── footer.html
│ ├── ga.html
│ ├── index.html
│ ├── login.html
│ ├── login_mailsent.html
│ ├── login_notvalidtoken.html
│ ├── mail
│ │ ├── ticket_registered_html.html
│ │ ├── ticket_registered_text.html
│ │ ├── token_html.html
│ │ └── token_text.html
│ ├── nav.html
│ ├── pyconkr
│ │ ├── announcement_detail.html
│ │ ├── announcement_list.html
│ │ ├── jobfair_list.html
│ │ ├── patron_list.html
│ │ ├── profile_detail.html
│ │ ├── profile_form.html
│ │ ├── program_detail.html
│ │ ├── program_form.html
│ │ ├── program_list.html
│ │ ├── program_preference.html
│ │ ├── proposal_detail.html
│ │ ├── proposal_form.html
│ │ ├── room_detail.html
│ │ ├── speaker_detail.html
│ │ ├── speaker_form.html
│ │ ├── speaker_list.html
│ │ ├── sponsor_detail.html
│ │ ├── sponsor_list.html
│ │ ├── sprintproposal_detail.html
│ │ ├── sprintproposal_list.html
│ │ ├── tutorialproposal_detail.html
│ │ └── tutorialproposal_list.html
│ ├── robots.txt
│ ├── schedule.html
│ ├── sponsors.html
│ ├── submenu.html
│ └── youngcoder.html
├── tests.py
├── translation.py
├── urls.py
├── views.py
└── wsgi.py
├── registration
├── __init__.py
├── admin.py
├── apps.py
├── forms.py
├── iamporter
│ ├── __init__.py
│ └── iamporter.py
├── locale
│ ├── en
│ │ └── LC_MESSAGES
│ │ │ └── django.po
│ └── ko
│ │ └── LC_MESSAGES
│ │ └── django.po
├── management
│ ├── __init__.py
│ └── commands
│ │ ├── __init__.py
│ │ ├── calculation_attendee.py
│ │ ├── delete_login_token.py
│ │ └── payment_reconciliation.py
├── migrations
│ ├── 0001_initial.py
│ ├── 0002_auto_20160323_1428.py
│ ├── 0003_option_has_additional_price.py
│ ├── 0004_registration_additional_price.py
│ ├── 0005_option_total.py
│ ├── 0006_auto_20160416_1202.py
│ ├── 0007_auto_20160416_1217.py
│ ├── 0008_auto_20160418_2250.py
│ ├── 0009_auto_20160501_2332.py
│ ├── 0010_auto_20170428_0007.py
│ ├── 0011_auto_20170515_2228.py
│ ├── 0012_registration_top_size.py
│ ├── 0013_auto_20170616_1446.py
│ ├── 0014_auto_20170619_1138.py
│ ├── 0015_auto_20170619_1151.py
│ ├── 0016_auto_20170619_1155.py
│ ├── 0017_auto_20170619_1458.py
│ ├── 0018_auto_20170619_1514.py
│ ├── 0019_auto_20170630_1534.py
│ ├── 0020_auto_20170701_1757.py
│ ├── 0021_auto_20170713_1341.py
│ ├── 0022_manualpayment.py
│ ├── 0023_issue_manager.py
│ ├── 0024_add_extra_fields_option.py
│ ├── 0025_auto_20180601_0214.py
│ ├── 0026_auto_20180607_1241.py
│ ├── 0027_auto_20180708_2058.py
│ ├── 0027_auto_20180715_2205.py
│ ├── 0028_merge_20180723_2159.py
│ └── __init__.py
├── models.py
├── static
│ ├── js
│ │ └── payment.js
│ └── stamp.jpg
├── templates
│ └── registration
│ │ ├── cancellation_result.html
│ │ ├── certificates.html
│ │ ├── certificates_not_registered.html
│ │ ├── certificates_not_visited.html
│ │ ├── certificates_sprint.html
│ │ ├── certificates_sprint_not_registered.html
│ │ ├── certificates_tutorial.html
│ │ ├── certificates_tutorial_not_registered.html
│ │ ├── certificates_tutorial_not_visited.html
│ │ ├── checkin_list.html
│ │ ├── info.html
│ │ ├── issue_print.html
│ │ ├── issue_ticket.html
│ │ ├── manual_payment.html
│ │ ├── payment.html
│ │ ├── payment_babycare.html
│ │ ├── payment_youngcoder.html
│ │ ├── registration_detail.html
│ │ ├── registration_list.html
│ │ ├── sprint_checkin.html
│ │ ├── sprint_print.html
│ │ └── status.html
├── tests.py
├── urls.py
└── views.py
├── requirements-dev.txt
├── requirements-prod.txt
└── requirements.txt
/.bowerrc:
--------------------------------------------------------------------------------
1 | {
2 | "directory" : "pyconkr/static/components"
3 | }
4 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Byte-compiled / optimized / DLL files
2 | __pycache__/
3 | *.py[cod]
4 | *$py.class
5 |
6 | # C extensions
7 | *.so
8 |
9 | # Distribution / packaging
10 | .Python
11 | env/
12 | build/
13 | develop-eggs/
14 | dist/
15 | downloads/
16 | eggs/
17 | .eggs/
18 | lib/
19 | lib64/
20 | parts/
21 | sdist/
22 | var/
23 | wheels/
24 | *.egg-info/
25 | .installed.cfg
26 | *.egg
27 |
28 | # PyInstaller
29 | # Usually these files are written by a python script from a template
30 | # before PyInstaller builds the exe, so as to inject date/other infos into it.
31 | *.manifest
32 | *.spec
33 |
34 | # Installer logs
35 | pip-log.txt
36 | pip-delete-this-directory.txt
37 |
38 | # Unit test / coverage reports
39 | htmlcov/
40 | .tox/
41 | .coverage
42 | .coverage.*
43 | .cache
44 | nosetests.xml
45 | coverage.xml
46 | *,cover
47 | .hypothesis/
48 |
49 | # Translations
50 | *.mo
51 | *.pot
52 |
53 | # Django stuff:
54 | *.log
55 | local_settings.py
56 |
57 | # Flask stuff:
58 | instance/
59 | .webassets-cache
60 |
61 | # Scrapy stuff:
62 | .scrapy
63 |
64 | # Sphinx documentation
65 | docs/_build/
66 |
67 | # PyBuilder
68 | target/
69 |
70 | # Jupyter Notebook
71 | .ipynb_checkpoints
72 |
73 | # pyenv
74 | .python-version
75 |
76 | # celery beat schedule file
77 | celerybeat-schedule
78 |
79 | # dotenv
80 | .env
81 |
82 | # virtualenv
83 | .venv/
84 | venv/
85 | ENV/
86 |
87 | # Spyder project settings
88 | .spyderproject
89 |
90 | # Rope project settings
91 | .ropeproject
92 |
93 | # IntelliJ
94 | *.iml
95 | .idea/
96 |
97 | # Bower
98 | pyconkr/static/components/*
99 |
100 | # TEST db
101 | db.sqlite3
102 |
103 | # macOS
104 | .DS_Store
105 |
106 | # Visual studio code configurations
107 | .vscode/
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: python
2 | python:
3 | - "3.6.1"
4 |
5 | # command to install dependencies
6 | install:
7 | - "pip install flake8"
8 | - "pip install -r requirements-dev.txt"
9 |
10 | before_script:
11 | - "export DISPLAY=:99.0"
12 | - "sh -e /etc/init.d/xvfb start"
13 | - sleep 3 # give xvfb some time to start
14 | - python manage.py makemigrations
15 |
16 | # command to run tests
17 | script:
18 | - python manage.py migrate --noinput
19 | - python manage.py test -v 3
20 |
21 | after_success:
22 | - codecov
23 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # A git repository for PyCon Korea 2018
2 | ## Version 11-August-2017
3 |
4 | [](https://travis-ci.org/pythonkr/pyconkr-2018)
5 |
6 | ## Requiremensts
7 | - Python 3.6
8 |
9 | ## Getting started
10 |
11 | ```bash
12 | $ git clone git@github.com:pythonkr/pyconkr-2018.git
13 | $ cd pyconkr-2018
14 | $ pip install -r requirements.txt
15 | $ python manage.py compilemessages
16 | $ python manage.py makemigrations # flatpages
17 | $ python manage.py migrate
18 | $ python manage.py loaddata ./pyconkr/fixtures/flatpages.json
19 | $ bower install
20 | $ python manage.py runserver
21 | ```
22 |
23 | ## ETC
24 | - 빌드 자동 테스트
25 |
--------------------------------------------------------------------------------
/bower.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "pyconkr",
3 | "dependencies": {
4 | "jquery": "~3.2.1",
5 | "jquery-ui": "~1.12.1",
6 | "select2-bootstrap-css": "~1.4.6",
7 | "html5shiv": "~3.7.2",
8 | "respond": "~1.4.2",
9 | "datetimepicker": "~2.2.4",
10 | "bootstrap": "~3.3.7",
11 | "font-awesome": "~4.7.0",
12 | "select2": "~3.5.4",
13 | "bootstrap-social": "~5.1.1",
14 | "typed.js": "~1.1.1",
15 | "bootstrap-side-navbar": "^1.0.1",
16 | "montserrat-webfont": "^1.0.3",
17 | "datatables.net": "^1.10.15",
18 | "datatables.net-bs": "^2.1.1",
19 | "datatables.net-rowreorder": "^1.2.0",
20 | "datatables.net-rowreorder-bs": "^1.2.0",
21 | "handlebars": "^4.0.10",
22 | "js-cookie": "^2.1.4",
23 | "slick-carousel": "^1.8.1"
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/build-test.txt:
--------------------------------------------------------------------------------
1 | 빌드 자동화 확인
2 |
--------------------------------------------------------------------------------
/fabfile.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | import os
3 |
4 | from fabric.api import local, run, cd, prefix, env, sudo, settings, shell_env
5 |
6 | env.use_ssh_config = True
7 | env.user = 'pyconkr'
8 | env.hosts = ['pythonkorea1']
9 |
10 | def deploy(target='dev', sha1=None):
11 | if sha1 is None:
12 | # get current working git sha1
13 | sha1 = local('git rev-parse HEAD', capture=True)
14 | # server code reset to current working sha1
15 | home_dir = '/home/pyconkr/{target}.pycon.kr/pyconkr-2017'.format(target=target)
16 |
17 | if target == 'dev':
18 | python_env = '/home/pyconkr/.pyenv/versions/pyconkr-2017-dev'
19 | else:
20 | python_env = '/home/pyconkr/.pyenv/versions/pyconkr-2017'
21 |
22 | with settings(cd(home_dir), shell_env(DJANGO_SETTINGS_MODULE='pyconkr.settings_prod')):
23 | run('git fetch --all -p')
24 | run('git reset --hard ' + sha1)
25 | run('bower install')
26 | run('%s/bin/pip install -r requirements.txt' % python_env)
27 | run('%s/bin/python manage.py compilemessages' % python_env)
28 | run('%s/bin/python manage.py migrate' % python_env)
29 | run('%s/bin/python manage.py collectstatic --noinput' % python_env)
30 | # worker reload
31 | run('echo r > /var/run/pyconkr-2017-%s.fifo' % target)
32 |
33 |
--------------------------------------------------------------------------------
/manage.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | import os
3 | import sys
4 |
5 | if __name__ == "__main__":
6 | os.environ.setdefault("DJANGO_SETTINGS_MODULE", "pyconkr.settings")
7 |
8 | from django.core.management import execute_from_command_line
9 |
10 | execute_from_command_line(sys.argv)
11 |
--------------------------------------------------------------------------------
/pyconkr/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonkr/pyconkr-2018/d2fe3b41d487875a6616319adddf8ee3d28dc7a2/pyconkr/__init__.py
--------------------------------------------------------------------------------
/pyconkr/actions.py:
--------------------------------------------------------------------------------
1 | from .models import (Program, Speaker)
2 |
3 |
4 | def convert_proposal_to_program(modeladmin, request, queryset):
5 | # prepare speaker
6 | for proposal in queryset:
7 | speaker, _ = Speaker.objects.get_or_create(email=proposal.user.email)
8 | program, _ = Program.objects.get_or_create(name=proposal.title)
9 |
10 | # Set initial data
11 | speaker.slug = proposal.user.email
12 | speaker.name = proposal.user.profile.name
13 | speaker.desc = proposal.user.profile.bio
14 | speaker.organization = proposal.user.profile.organization
15 | speaker.save()
16 |
17 | program.brief = proposal.brief
18 | program.desc = proposal.desc
19 | program.difficulty = proposal.difficulty
20 | program.duration = proposal.duration
21 | program.language = proposal.language
22 | program.speakers.clear()
23 | program.speakers.add(speaker)
24 | program.save()
25 |
26 | print(program, speaker)
27 |
--------------------------------------------------------------------------------
/pyconkr/context_processors.py:
--------------------------------------------------------------------------------
1 | from collections import OrderedDict
2 |
3 | from django.utils import timezone
4 | from django.conf import settings
5 | from django.contrib.flatpages.models import FlatPage
6 | from django.db.models import Count
7 | from django.utils.translation import ugettext_lazy as _
8 |
9 | from .models import SponsorLevel, Speaker, Banner
10 |
11 |
12 | def default(request):
13 | title = None
14 | # remove i18n_patterns prefix for flatpage
15 | url = request.path.replace('/' + request.LANGUAGE_CODE, '')
16 | if settings.FORCE_SCRIPT_NAME:
17 | url = url[len(settings.FORCE_SCRIPT_NAME):]
18 | base_content = FlatPage.objects.filter(url=url).first()
19 |
20 | submenu = None
21 | menu = OrderedDict([
22 | ('about', {
23 | 'title': _('About'),
24 | 'icon': 'python',
25 | 'submenu': OrderedDict([
26 | ('pyconkr', {'title': _('About PyCon Korea 2018')}),
27 | ('coc', {'title': _('Code of Conduct')}),
28 | ('blog', {'title': _('PyCon Korea Blog')}),
29 | ('announcements', {'title': _('Announcements')}),
30 | ('sponsor', {'title': _('Sponsors')}),
31 | ('patron', {'title': _('Patrons')}),
32 | ('sponsorship', {'title': _('Sponsorship')}),
33 | ('staff', {'title': _('Staff')}),
34 | ('contact', {'title': _('Contact')}),
35 | ]),
36 | }),
37 | ('program', {
38 | 'title': _('Programs'),
39 | 'icon': 'calendar',
40 | 'submenu': OrderedDict([
41 | ('schedule', {'title': _('Schedule')}),
42 | ('list', {'title': _('Program list')}),
43 | ('keynote', {'title': _('Keynotes')}),
44 | ('speaker', {'title': _('Speakers')}),
45 | ('tutorial', {'title': _('Tutorial')}),
46 | ('sprint', {'title': _('Sprint')}),
47 | ('youngcoder', {'title': _('Young Coder')}),
48 | ('child_care', {'title': _('Child Care')}),
49 | ('lightning_talk', {'title': _('Lightning talk')}),
50 | ('ost', {'title': _('Open Spaces')}),
51 | ('health', {'title': _('Health')}),
52 | ]),
53 | }),
54 | ('venue', {
55 | 'title': _('Venue'),
56 | 'icon': 'map-marker',
57 | 'submenu': OrderedDict([
58 | ('map', {'title': _('Venue Map')}),
59 | ('transportation', {'title': _('Transportation')}),
60 | ]),
61 | }),
62 | ('cfp', {
63 | 'title': _('Proposal'),
64 | 'icon': 'edit',
65 | 'submenu': OrderedDict([
66 | ('cfp', {'title': _('Call for proposals')}),
67 | ('howto', {'title': _('How to propose')}),
68 | ]),
69 | }),
70 | ('registration', {
71 | 'title': _('Registration'),
72 | 'icon': 'book',
73 | 'submenu': OrderedDict([
74 | ('information', {'title': _('Information')}),
75 | ('purchase', {'title': _('Purchase a ticket')}),
76 | ('finacial-aid', {'title': _('Financial Aid')}),
77 | ('visa', {'title': _('Visa Sponsing')}),
78 | ]),
79 | }),
80 | ])
81 |
82 | for k, v in menu.items():
83 | path = '/{}/'.format(k)
84 |
85 | if url.startswith(path):
86 | v['active'] = True
87 | title = v['title']
88 |
89 | if 'submenu' in v:
90 | submenu = v['submenu']
91 |
92 | for sk, sv in v['submenu'].items():
93 | sv['path'] = '{}{}/'.format(path, sk)
94 | subpath = sv['path']
95 |
96 | if url == subpath:
97 | sv['active'] = True
98 | title = sv['title']
99 |
100 | now = timezone.now()
101 | banners = Banner.objects.filter(begin__lte=now, end__gte=now)
102 |
103 | c = {
104 | 'menu': menu,
105 | 'submenu': submenu,
106 | 'banners': banners,
107 | 'title': title,
108 | 'domain': settings.DOMAIN,
109 | 'base_content': base_content.content if base_content else '',
110 | }
111 | return c
112 |
113 |
114 | def profile(request):
115 | speaker = None
116 | programs = None
117 |
118 | if request.user.is_authenticated():
119 | speaker = Speaker.objects.filter(email=request.user.email).first()
120 | if speaker:
121 | programs = speaker.program_set.all()
122 |
123 | return {
124 | 'my_speaker': speaker,
125 | 'my_programs': programs,
126 | }
127 |
128 |
129 | def sponsors(request):
130 | levels = SponsorLevel.objects.annotate(
131 | num_sponsors=Count('sponsor')).filter(num_sponsors__gt=0)
132 |
133 | return {
134 | 'levels': levels,
135 | }
136 |
--------------------------------------------------------------------------------
/pyconkr/helper.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | import json
3 |
4 | from django.core.mail import EmailMultiAlternatives
5 | from django.http import HttpResponse
6 | from django.template.loader import render_to_string
7 | from django.utils.translation import ugettext_lazy as _
8 |
9 |
10 | def sendEmailToken(request, token):
11 | title = _('PyCon Korea 2018 one-time login token')
12 | sender = _('PyCon Korea 2018') + ''
13 | html = render_to_string('mail/token_html.html', {'token': token}, request)
14 | text = render_to_string('mail/token_text.html', {'token': token}, request)
15 |
16 | msg = EmailMultiAlternatives(
17 | title,
18 | text,
19 | sender,
20 | [token.email])
21 | msg.attach_alternative(html, "text/html")
22 | msg.send(fail_silently=False)
23 |
24 |
25 | def is_pycon_user(email):
26 | return str.endswith(email, '@pycon.kr')
27 |
28 |
29 | def render_json(data_dict):
30 | return HttpResponse(json.dumps(data_dict),
31 | 'application/javascript')
32 |
33 |
34 | def render_template_json(template, context):
35 | return HttpResponse(render_to_string(template, context),
36 | 'application/javascript')
37 |
38 |
39 | def render_io_error(reason):
40 | response = HttpResponse(reason)
41 | response.status_code = 406
42 | return response
43 |
--------------------------------------------------------------------------------
/pyconkr/locale/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonkr/pyconkr-2018/d2fe3b41d487875a6616319adddf8ee3d28dc7a2/pyconkr/locale/__init__.py
--------------------------------------------------------------------------------
/pyconkr/migrations/0002_proposal_language.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # Generated by Django 1.9.4 on 2016-03-28 13:35
3 | from __future__ import unicode_literals
4 |
5 | from django.db import migrations, models
6 |
7 |
8 | class Migration(migrations.Migration):
9 |
10 | dependencies = [
11 | ('pyconkr', '0001_initial'),
12 | ]
13 |
14 | operations = [
15 | migrations.AddField(
16 | model_name='proposal',
17 | name='language',
18 | field=models.CharField(choices=[(b'E', 'English'), (b'K', 'Korean')], default=b'E', max_length=1),
19 | ),
20 | ]
21 |
--------------------------------------------------------------------------------
/pyconkr/migrations/0003_auto_20160328_1611.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # Generated by Django 1.9.4 on 2016-03-28 16:11
3 | from __future__ import unicode_literals
4 |
5 | from django.conf import settings
6 | from django.db import migrations, models
7 | import django.db.models.deletion
8 |
9 |
10 | class Migration(migrations.Migration):
11 |
12 | dependencies = [
13 | ('pyconkr', '0002_proposal_language'),
14 | ]
15 |
16 | operations = [
17 | migrations.AlterField(
18 | model_name='proposal',
19 | name='user',
20 | field=models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL),
21 | ),
22 | ]
23 |
--------------------------------------------------------------------------------
/pyconkr/migrations/0004_banner.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # Generated by Django 1.9.2 on 2016-04-02 01:43
3 | from __future__ import unicode_literals
4 |
5 | from django.db import migrations, models
6 | import sorl.thumbnail.fields
7 |
8 |
9 | class Migration(migrations.Migration):
10 |
11 | dependencies = [
12 | ('pyconkr', '0003_auto_20160328_1611'),
13 | ]
14 |
15 | operations = [
16 | migrations.CreateModel(
17 | name='Banner',
18 | fields=[
19 | ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
20 | ('name', models.CharField(max_length=100)),
21 | ('url', models.CharField(blank=True, max_length=255, null=True)),
22 | ('image', sorl.thumbnail.fields.ImageField(upload_to=b'banner')),
23 | ('desc', models.TextField(blank=True, null=True)),
24 | ('desc_ko', models.TextField(blank=True, null=True)),
25 | ('desc_en', models.TextField(blank=True, null=True)),
26 | ('begin', models.DateTimeField(blank=True, null=True)),
27 | ('end', models.DateTimeField(blank=True, null=True)),
28 | ],
29 | ),
30 | ]
31 |
--------------------------------------------------------------------------------
/pyconkr/migrations/0005_profile_nationality.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # Generated by Django 1.9.4 on 2016-05-01 14:38
3 | from __future__ import unicode_literals
4 |
5 | from django.db import migrations, models
6 |
7 |
8 | class Migration(migrations.Migration):
9 |
10 | dependencies = [
11 | ('pyconkr', '0004_banner'),
12 | ]
13 |
14 | operations = [
15 | migrations.AddField(
16 | model_name='profile',
17 | name='nationality',
18 | field=models.CharField(blank=True, max_length=100, null=True),
19 | ),
20 | ]
21 |
--------------------------------------------------------------------------------
/pyconkr/migrations/0006_matching_profile.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # Generated by Django 1.9.2 on 2016-06-18 01:09
3 | from __future__ import unicode_literals
4 |
5 | from django.db import migrations, models
6 |
7 |
8 | class Migration(migrations.Migration):
9 |
10 | dependencies = [
11 | ('pyconkr', '0005_profile_nationality'),
12 | ]
13 |
14 | operations = [
15 | migrations.AddField(
16 | model_name='program',
17 | name='brief',
18 | field=models.TextField(blank=True, null=True),
19 | ),
20 | migrations.AddField(
21 | model_name='program',
22 | name='difficulty',
23 | field=models.CharField(choices=[(b'B', 'Beginner'), (b'I', 'Intermediate'), (b'E', 'Experienced')], default=b'B', max_length=1),
24 | ),
25 | migrations.AddField(
26 | model_name='program',
27 | name='duration',
28 | field=models.CharField(choices=[(b'S', '25 mins'), (b'L', '40 mins')], default=b'S', max_length=1),
29 | ),
30 | migrations.AddField(
31 | model_name='speaker',
32 | name='organization',
33 | field=models.CharField(blank=True, max_length=100, null=True),
34 | ),
35 | migrations.AlterField(
36 | model_name='program',
37 | name='language',
38 | field=models.CharField(choices=[(b'E', 'English'), (b'K', 'Korean')], default=b'E', max_length=1),
39 | ),
40 | migrations.AlterField(
41 | model_name='program',
42 | name='name',
43 | field=models.CharField(db_index=True, max_length=255),
44 | ),
45 | migrations.AlterField(
46 | model_name='program',
47 | name='name_en',
48 | field=models.CharField(db_index=True, max_length=255, null=True),
49 | ),
50 | migrations.AlterField(
51 | model_name='program',
52 | name='name_ko',
53 | field=models.CharField(db_index=True, max_length=255, null=True),
54 | ),
55 | ]
56 |
--------------------------------------------------------------------------------
/pyconkr/migrations/0007_auto_20160625_1618.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # Generated by Django 1.9.2 on 2016-06-25 07:18
3 | from __future__ import unicode_literals
4 |
5 | from django.conf import settings
6 | from django.db import migrations, models
7 | import django.db.models.deletion
8 |
9 |
10 | class Migration(migrations.Migration):
11 |
12 | dependencies = [
13 | migrations.swappable_dependency(settings.AUTH_USER_MODEL),
14 | ('pyconkr', '0006_matching_profile'),
15 | ]
16 |
17 | operations = [
18 | migrations.CreateModel(
19 | name='Preference',
20 | fields=[
21 | ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
22 | ('program', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='pyconkr.Program')),
23 | ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
24 | ],
25 | ),
26 | migrations.AlterUniqueTogether(
27 | name='preference',
28 | unique_together=set([('user', 'program')]),
29 | ),
30 | ]
31 |
--------------------------------------------------------------------------------
/pyconkr/migrations/0007_tutorialproposal.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # Generated by Django 1.9.5 on 2016-06-25 06:41
3 | from __future__ import unicode_literals
4 |
5 | from django.conf import settings
6 | from django.db import migrations, models
7 | import django.db.models.deletion
8 |
9 |
10 | class Migration(migrations.Migration):
11 |
12 | dependencies = [
13 | migrations.swappable_dependency(settings.AUTH_USER_MODEL),
14 | ('pyconkr', '0006_matching_profile'),
15 | ]
16 |
17 | operations = [
18 | migrations.CreateModel(
19 | name='TutorialProposal',
20 | fields=[
21 | ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
22 | ('title', models.CharField(max_length=255)),
23 | ('brief', models.TextField(max_length=1000)),
24 | ('desc', models.TextField(max_length=4000)),
25 | ('comment', models.TextField(blank=True, max_length=4000, null=True)),
26 | ('difficulty', models.CharField(choices=[(b'B', 'Beginner'), (b'I', 'Intermediate'), (b'E', 'Experienced')], max_length=1)),
27 | ('duration', models.CharField(choices=[(b'S', '1 hour'), (b'M', '2 hours'), (b'L', '4 hours')], max_length=1)),
28 | ('language', models.CharField(choices=[(b'E', 'English'), (b'K', 'Korean')], default=b'E', max_length=1)),
29 | ('capacity', models.CharField(choices=[(b'S', '10 people'), (b'M', '45 people'), (b'L', '100 people')], max_length=1)),
30 | ('user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
31 | ],
32 | ),
33 | ]
34 |
--------------------------------------------------------------------------------
/pyconkr/migrations/0008_merge.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # Generated by Django 1.9.2 on 2016-06-25 08:38
3 | from __future__ import unicode_literals
4 |
5 | from django.db import migrations
6 |
7 |
8 | class Migration(migrations.Migration):
9 |
10 | dependencies = [
11 | ('pyconkr', '0007_auto_20160625_1618'),
12 | ('pyconkr', '0007_tutorialproposal'),
13 | ]
14 |
15 | operations = [
16 | ]
17 |
--------------------------------------------------------------------------------
/pyconkr/migrations/0009_auto_20160630_1359.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # Generated by Django 1.9.2 on 2016-06-30 04:59
3 | from __future__ import unicode_literals
4 |
5 | from django.db import migrations, models
6 |
7 |
8 | class Migration(migrations.Migration):
9 |
10 | dependencies = [
11 | ('pyconkr', '0008_merge'),
12 | ]
13 |
14 | operations = [
15 | migrations.AddField(
16 | model_name='programcategory',
17 | name='show_in_list',
18 | field=models.BooleanField(default=True),
19 | ),
20 | migrations.AddField(
21 | model_name='programcategory',
22 | name='show_in_mobile',
23 | field=models.BooleanField(default=True),
24 | ),
25 | ]
26 |
--------------------------------------------------------------------------------
/pyconkr/migrations/0010_tutorialproposal_type.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # Generated by Django 1.9.2 on 2016-07-19 11:28
3 | from __future__ import unicode_literals
4 |
5 | from django.db import migrations, models
6 |
7 |
8 | class Migration(migrations.Migration):
9 |
10 | dependencies = [
11 | ('pyconkr', '0009_auto_20160630_1359'),
12 | ]
13 |
14 | operations = [
15 | migrations.AddField(
16 | model_name='tutorialproposal',
17 | name='type',
18 | field=models.CharField(choices=[(b'T', 'Tutorial'), (b'S', 'Sprint')], default=b'T', max_length=1),
19 | ),
20 | ]
21 |
--------------------------------------------------------------------------------
/pyconkr/migrations/0011_auto_20160719_2118.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # Generated by Django 1.9.2 on 2016-07-19 12:18
3 | from __future__ import unicode_literals
4 |
5 | from django.conf import settings
6 | from django.db import migrations, models
7 | import django.db.models.deletion
8 |
9 |
10 | class Migration(migrations.Migration):
11 |
12 | dependencies = [
13 | migrations.swappable_dependency(settings.AUTH_USER_MODEL),
14 | ('pyconkr', '0010_tutorialproposal_type'),
15 | ]
16 |
17 | operations = [
18 | migrations.CreateModel(
19 | name='TutorialCheckin',
20 | fields=[
21 | ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
22 | ('tutorial', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='pyconkr.TutorialProposal')),
23 | ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
24 | ],
25 | ),
26 | migrations.AlterUniqueTogether(
27 | name='tutorialcheckin',
28 | unique_together=set([('user', 'tutorial')]),
29 | ),
30 | ]
31 |
--------------------------------------------------------------------------------
/pyconkr/migrations/0012_auto_20160727_2244.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # Generated by Django 1.9.4 on 2016-07-27 13:44
3 | from __future__ import unicode_literals
4 |
5 | from django.db import migrations, models
6 |
7 |
8 | class Migration(migrations.Migration):
9 |
10 | dependencies = [
11 | ('pyconkr', '0011_auto_20160719_2118'),
12 | ]
13 |
14 | operations = [
15 | migrations.AlterField(
16 | model_name='tutorialproposal',
17 | name='desc',
18 | field=models.TextField(),
19 | ),
20 | ]
21 |
--------------------------------------------------------------------------------
/pyconkr/migrations/0013_auto_20170428_0007.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # Generated by Django 1.11 on 2017-04-27 15:07
3 | from __future__ import unicode_literals
4 |
5 | from django.db import migrations, models
6 | import sorl.thumbnail.fields
7 |
8 |
9 | class Migration(migrations.Migration):
10 |
11 | dependencies = [
12 | ('pyconkr', '0012_auto_20160727_2244'),
13 | ]
14 |
15 | operations = [
16 | migrations.AlterField(
17 | model_name='banner',
18 | name='image',
19 | field=sorl.thumbnail.fields.ImageField(upload_to='banner'),
20 | ),
21 | migrations.AlterField(
22 | model_name='profile',
23 | name='image',
24 | field=sorl.thumbnail.fields.ImageField(blank=True, null=True, upload_to='profile'),
25 | ),
26 | migrations.AlterField(
27 | model_name='program',
28 | name='difficulty',
29 | field=models.CharField(choices=[('B', 'Beginner'), ('I', 'Intermediate'), ('E', 'Experienced')], default='B', max_length=1),
30 | ),
31 | migrations.AlterField(
32 | model_name='program',
33 | name='duration',
34 | field=models.CharField(choices=[('S', '25 mins'), ('L', '40 mins')], default='S', max_length=1),
35 | ),
36 | migrations.AlterField(
37 | model_name='program',
38 | name='language',
39 | field=models.CharField(choices=[('E', 'English'), ('K', 'Korean')], default='E', max_length=1),
40 | ),
41 | migrations.AlterField(
42 | model_name='proposal',
43 | name='difficulty',
44 | field=models.CharField(choices=[('B', 'Beginner'), ('I', 'Intermediate'), ('E', 'Experienced')], max_length=1),
45 | ),
46 | migrations.AlterField(
47 | model_name='proposal',
48 | name='duration',
49 | field=models.CharField(choices=[('S', '25 mins'), ('L', '40 mins')], max_length=1),
50 | ),
51 | migrations.AlterField(
52 | model_name='proposal',
53 | name='language',
54 | field=models.CharField(choices=[('E', 'English'), ('K', 'Korean')], default='E', max_length=1),
55 | ),
56 | migrations.AlterField(
57 | model_name='speaker',
58 | name='image',
59 | field=models.ImageField(blank=True, null=True, upload_to='speaker'),
60 | ),
61 | migrations.AlterField(
62 | model_name='sponsor',
63 | name='image',
64 | field=models.ImageField(blank=True, null=True, upload_to='sponsor'),
65 | ),
66 | migrations.AlterField(
67 | model_name='tutorialproposal',
68 | name='capacity',
69 | field=models.CharField(choices=[('S', '10 people'), ('M', '45 people'), ('L', '100 people')], max_length=1),
70 | ),
71 | migrations.AlterField(
72 | model_name='tutorialproposal',
73 | name='difficulty',
74 | field=models.CharField(choices=[('B', 'Beginner'), ('I', 'Intermediate'), ('E', 'Experienced')], max_length=1),
75 | ),
76 | migrations.AlterField(
77 | model_name='tutorialproposal',
78 | name='duration',
79 | field=models.CharField(choices=[('S', '1 hour'), ('M', '2 hours'), ('L', '4 hours')], max_length=1),
80 | ),
81 | migrations.AlterField(
82 | model_name='tutorialproposal',
83 | name='language',
84 | field=models.CharField(choices=[('E', 'English'), ('K', 'Korean')], default='E', max_length=1),
85 | ),
86 | migrations.AlterField(
87 | model_name='tutorialproposal',
88 | name='type',
89 | field=models.CharField(choices=[('T', 'Tutorial'), ('S', 'Sprint')], default='T', max_length=1),
90 | ),
91 | ]
92 |
--------------------------------------------------------------------------------
/pyconkr/migrations/0014_auto_20170630_1453.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # Generated by Django 1.11 on 2017-06-30 05:53
3 | from __future__ import unicode_literals
4 |
5 | from django.conf import settings
6 | from django.db import migrations, models
7 | import django.db.models.deletion
8 |
9 |
10 | class Migration(migrations.Migration):
11 |
12 | dependencies = [
13 | migrations.swappable_dependency(settings.AUTH_USER_MODEL),
14 | ('pyconkr', '0013_auto_20170428_0007'),
15 | ]
16 |
17 | operations = [
18 | migrations.CreateModel(
19 | name='SprintCheckin',
20 | fields=[
21 | ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
22 | ],
23 | ),
24 | migrations.CreateModel(
25 | name='SprintProposal',
26 | fields=[
27 | ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
28 | ('title', models.CharField(max_length=255)),
29 | ('language', models.CharField(max_length=255)),
30 | ('project_url', models.CharField(max_length=1024)),
31 | ('project_brief', models.TextField(max_length=1000)),
32 | ('contribution_desc', models.TextField()),
33 | ('comment', models.TextField(blank=True, max_length=4000, null=True)),
34 | ('confirmed', models.BooleanField(default=False)),
35 | ('user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
36 | ],
37 | ),
38 | migrations.RemoveField(
39 | model_name='tutorialproposal',
40 | name='type',
41 | ),
42 | migrations.AddField(
43 | model_name='tutorialproposal',
44 | name='confirmed',
45 | field=models.BooleanField(default=False),
46 | ),
47 | migrations.AddField(
48 | model_name='sprintcheckin',
49 | name='sprint',
50 | field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='pyconkr.SprintProposal'),
51 | ),
52 | migrations.AddField(
53 | model_name='sprintcheckin',
54 | name='user',
55 | field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL),
56 | ),
57 | migrations.AlterUniqueTogether(
58 | name='sprintcheckin',
59 | unique_together=set([('user', 'sprint')]),
60 | ),
61 | ]
62 |
--------------------------------------------------------------------------------
/pyconkr/migrations/0015_auto_20170630_1534.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # Generated by Django 1.11 on 2017-06-30 06:34
3 | from __future__ import unicode_literals
4 |
5 | from django.db import migrations, models
6 |
7 |
8 | class Migration(migrations.Migration):
9 |
10 | dependencies = [
11 | ('pyconkr', '0014_auto_20170630_1453'),
12 | ]
13 |
14 | operations = [
15 | migrations.AlterUniqueTogether(
16 | name='sprintcheckin',
17 | unique_together=set([]),
18 | ),
19 | migrations.RemoveField(
20 | model_name='sprintcheckin',
21 | name='sprint',
22 | ),
23 | migrations.RemoveField(
24 | model_name='sprintcheckin',
25 | name='user',
26 | ),
27 | migrations.RemoveField(
28 | model_name='sprintproposal',
29 | name='user',
30 | ),
31 | migrations.RemoveField(
32 | model_name='tutorialproposal',
33 | name='confirmed',
34 | ),
35 | migrations.AddField(
36 | model_name='tutorialproposal',
37 | name='type',
38 | field=models.CharField(choices=[('T', 'Tutorial'), ('S', 'Sprint')], default='T', max_length=1),
39 | ),
40 | migrations.DeleteModel(
41 | name='SprintCheckin',
42 | ),
43 | migrations.DeleteModel(
44 | name='SprintProposal',
45 | ),
46 | ]
47 |
--------------------------------------------------------------------------------
/pyconkr/migrations/0016_auto_20170701_1757.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # Generated by Django 1.11.1 on 2017-07-01 08:57
3 | from __future__ import unicode_literals
4 |
5 | from django.conf import settings
6 | from django.db import migrations, models
7 | import django.db.models.deletion
8 |
9 |
10 | class Migration(migrations.Migration):
11 |
12 | dependencies = [
13 | migrations.swappable_dependency(settings.AUTH_USER_MODEL),
14 | ('pyconkr', '0015_auto_20170630_1534'),
15 | ]
16 |
17 | operations = [
18 | migrations.CreateModel(
19 | name='SprintCheckin',
20 | fields=[
21 | ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
22 | ],
23 | ),
24 | migrations.CreateModel(
25 | name='SprintProposal',
26 | fields=[
27 | ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
28 | ('title', models.CharField(max_length=255)),
29 | ('language', models.CharField(max_length=255)),
30 | ('project_url', models.CharField(max_length=1024)),
31 | ('project_brief', models.TextField(max_length=1000)),
32 | ('contribution_desc', models.TextField()),
33 | ('comment', models.TextField(blank=True, max_length=4000, null=True)),
34 | ('confirmed', models.BooleanField(default=False)),
35 | ('user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
36 | ],
37 | ),
38 | migrations.RemoveField(
39 | model_name='tutorialproposal',
40 | name='type',
41 | ),
42 | migrations.AddField(
43 | model_name='tutorialproposal',
44 | name='confirmed',
45 | field=models.BooleanField(default=False),
46 | ),
47 | migrations.AddField(
48 | model_name='sprintcheckin',
49 | name='sprint',
50 | field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='pyconkr.SprintProposal'),
51 | ),
52 | migrations.AddField(
53 | model_name='sprintcheckin',
54 | name='user',
55 | field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL),
56 | ),
57 | migrations.AlterUniqueTogether(
58 | name='sprintcheckin',
59 | unique_together=set([('user', 'sprint')]),
60 | ),
61 | ]
62 |
--------------------------------------------------------------------------------
/pyconkr/migrations/0017_programtime_day.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # Generated by Django 1.11 on 2017-07-12 10:14
3 | from __future__ import unicode_literals
4 |
5 | from django.db import migrations, models
6 | import django.db.models.deletion
7 |
8 |
9 | class Migration(migrations.Migration):
10 |
11 | dependencies = [
12 | ('pyconkr', '0016_auto_20170701_1757'),
13 | ]
14 |
15 | operations = [
16 | migrations.AddField(
17 | model_name='programtime',
18 | name='day',
19 | field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='pyconkr.ProgramDate'),
20 | ),
21 | ]
22 |
--------------------------------------------------------------------------------
/pyconkr/migrations/0018_program_is_breaktime.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # Generated by Django 1.11 on 2017-07-12 12:26
3 | from __future__ import unicode_literals
4 |
5 | from django.db import migrations, models
6 |
7 |
8 | class Migration(migrations.Migration):
9 |
10 | dependencies = [
11 | ('pyconkr', '0017_programtime_day'),
12 | ]
13 |
14 | operations = [
15 | migrations.AddField(
16 | model_name='program',
17 | name='is_breaktime',
18 | field=models.BooleanField(default=True),
19 | ),
20 | ]
21 |
--------------------------------------------------------------------------------
/pyconkr/migrations/0019_auto_20170712_2128.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # Generated by Django 1.11 on 2017-07-12 12:28
3 | from __future__ import unicode_literals
4 |
5 | from django.db import migrations, models
6 |
7 |
8 | class Migration(migrations.Migration):
9 |
10 | dependencies = [
11 | ('pyconkr', '0018_program_is_breaktime'),
12 | ]
13 |
14 | operations = [
15 | migrations.AlterField(
16 | model_name='program',
17 | name='is_breaktime',
18 | field=models.BooleanField(default=False),
19 | ),
20 | ]
21 |
--------------------------------------------------------------------------------
/pyconkr/migrations/0020_auto_20180611_2132.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # Generated by Django 1.11.13 on 2018-06-11 12:32
3 | from __future__ import unicode_literals
4 |
5 | from django.db import migrations, models
6 |
7 |
8 | class Migration(migrations.Migration):
9 |
10 | dependencies = [
11 | ('pyconkr', '0019_auto_20170712_2128'),
12 | ]
13 |
14 | operations = [
15 | migrations.AlterModelOptions(
16 | name='sponsor',
17 | options={'ordering': ['deposit_time', 'id']},
18 | ),
19 | migrations.AddField(
20 | model_name='sponsor',
21 | name='deposit_time',
22 | field=models.DateTimeField(blank=True, null=True),
23 | ),
24 | ]
25 |
--------------------------------------------------------------------------------
/pyconkr/migrations/0021_tutorialproposal_option.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # Generated by Django 1.11.11 on 2018-07-20 06:20
3 | from __future__ import unicode_literals
4 |
5 | from django.db import migrations, models
6 | import django.db.models.deletion
7 |
8 |
9 | class Migration(migrations.Migration):
10 |
11 | dependencies = [
12 | ('registration', '0027_auto_20180708_2058'),
13 | ('pyconkr', '0020_auto_20180611_2132'),
14 | ]
15 |
16 | operations = [
17 | migrations.AddField(
18 | model_name='tutorialproposal',
19 | name='begin_date',
20 | field=models.DateField(blank=True, null=True),
21 | ),
22 | migrations.AddField(
23 | model_name='tutorialproposal',
24 | name='begin_time',
25 | field=models.TimeField(blank=True, null=True),
26 | ),
27 | migrations.AddField(
28 | model_name='tutorialproposal',
29 | name='end_date',
30 | field=models.DateField(blank=True, null=True),
31 | ),
32 | migrations.AddField(
33 | model_name='tutorialproposal',
34 | name='end_time',
35 | field=models.TimeField(blank=True, null=True),
36 | ),
37 | migrations.AddField(
38 | model_name='tutorialproposal',
39 | name='option',
40 | field=models.ForeignKey(blank=True, default=None, null=True, on_delete=django.db.models.deletion.CASCADE, to='registration.Option', verbose_name='구매 티켓 종류'),
41 | ),
42 | ]
43 |
--------------------------------------------------------------------------------
/pyconkr/migrations/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonkr/pyconkr-2018/d2fe3b41d487875a6616319adddf8ee3d28dc7a2/pyconkr/migrations/__init__.py
--------------------------------------------------------------------------------
/pyconkr/static/css/pyconkr-media.css:
--------------------------------------------------------------------------------
1 | @media (max-width: 767px) {
2 | .navbar {
3 | top: 0px;
4 | width: 100%;
5 | z-index: 50;
6 | }
7 | .navbar-nav {
8 | margin-top: 4px;
9 | }
10 | .navbar .navbar-toggle {
11 | position: fixed;
12 | z-index: 100;
13 | top: 12px;
14 | right: 12px;
15 | margin: 0;
16 | background: rgba(255,255,255,0.95);
17 | }
18 | .navbar .navbar-collapse {
19 | background: rgba(255,255,255,0.98);
20 | top: 0px;
21 | position: fixed;
22 | width: 100%;
23 | min-height: 1024px;
24 | max-height: 1024px;
25 | }
26 |
27 | .navbar .navbar-nav>.active>a,
28 | .navbar .navbar-nav>.active>a:hover,
29 | .navbar .navbar-nav>.active>a:focus {
30 | border-bottom: none;
31 | background-color: #aaa;
32 | }
33 |
34 | .navbar-translucent {
35 | }
36 | .navbar-translucent .navbar-toggle{
37 | position: absolute;
38 | background: rgba(0,0,0,0.5);
39 | }
40 | .navbar-translucent .navbar-collapse {
41 | z-index: 10;
42 | background: rgba(0,0,0,0.9);
43 | }
44 | .navbar-translucent .dropdown-menu>li>a {
45 | color: #fff;
46 | }
47 | .navbar-translucent .nav>li>a:hover,
48 | .navbar-translucent .nav>li>a:focus,
49 | .navbar-translucent .dropdown-menu>li>a:hover,
50 | .navbar-translucent .dropdown-menu>li>a:focus {
51 | background-color: #555;
52 | }
53 | .navbar-nav>li>a {
54 | padding: 10px 0 15px 15px;
55 | font-size: 1.5rem;
56 | line-height: 30px;
57 | }
58 | .navbar-nav .open .dropdown-menu>li>a {
59 | font-size: 1.2rem;
60 | line-height: 30px;
61 | }
62 | .frontpage .sky {
63 | height: 425px;
64 | }
65 | .footer .col {
66 | text-align: center;
67 | }
68 | .titlebar h1 {
69 | font-size: 2rem;
70 | }
71 | .sponsor img {
72 | max-width: 100%;
73 | }
74 | }
75 |
76 | @media (max-width: 640px) {
77 | .frontpage .slogan h1 {
78 | font-size: 4rem;
79 | }
80 | .frontpage .slogan h3 {
81 | font-size: 1.5rem;
82 | }
83 | }
84 |
85 | @media (max-width: 480px) {
86 | .frontpage .sky {
87 | height: 340px;
88 | }
89 | .container {
90 | padding-left: 20px;
91 | padding-right: 20px;
92 | }
93 | .container>.navbar-header,
94 | .container>.navbar-collapse {
95 | margin-left: -5px;
96 | margin-right: -5px;
97 | }
98 |
99 | .frontpage .slogan h1 {
100 | font-size: 3rem;
101 | margin-top: 30px;
102 | }
103 | .frontpage .slogan h3 {
104 | font-size: 1rem;
105 | }
106 |
107 | .well {
108 | margin: 14px -12px;
109 | }
110 |
111 | .jobfair dt img {
112 | width: auto;
113 | height: 32px;
114 | }
115 |
116 | .box-slick {
117 | width: 100%;
118 | padding: 30px 20px;
119 | }
120 |
121 | .box-section {
122 | padding: 10px;
123 | font-size: 14px;
124 | }
125 |
126 | .ticket-left {
127 | width: 10em;
128 | }
129 | }
130 |
131 | @media (min-width: 768px) {
132 | .container {
133 | width: auto;
134 | }
135 | }
136 |
137 | @media (min-width: 992px) {
138 | .container {
139 | width: 970px;
140 | }
141 | }
142 |
143 | @media (min-width: 1280px) {
144 | .container {
145 | width: 970px;
146 | }
147 | }
148 |
--------------------------------------------------------------------------------
/pyconkr/static/css/pyconkr-summernote.css:
--------------------------------------------------------------------------------
1 | body {
2 | padding-bottom: 0;
3 | }
4 |
--------------------------------------------------------------------------------
/pyconkr/static/css/young-coder.css:
--------------------------------------------------------------------------------
1 | .board {
2 | width: 90%;
3 | margin: 60px auto;
4 | height: 2500px;
5 | background: #fff;
6 | }
7 |
8 | .board .nav-tabs {
9 | position: relative;
10 | margin: 40px auto;
11 | margin-bottom: 0;
12 | box-sizing: border-box;
13 |
14 | }
15 |
16 | .board > div.board-inner {
17 | /*background-size: 30%;*/
18 | }
19 |
20 | p.narrow {
21 | width: 60%;
22 | margin: 10px auto;
23 | }
24 |
25 | .liner {
26 | height: 2px;
27 | background: #ddd;
28 | position: absolute;
29 | width: 80%;
30 | margin: 0 auto;
31 | left: 0;
32 | right: 0;
33 | top: 50%;
34 | z-index: 1;
35 | }
36 |
37 | .nav-tabs > li.active > a, .nav-tabs > li.active > a:hover, .nav-tabs > li.active > a:focus {
38 | color: #555555;
39 | cursor: default;
40 | border: 0;
41 | border-bottom-color: transparent;
42 | }
43 |
44 | span.round-tabs {
45 | width: 70px;
46 | height: 70px;
47 | line-height: 70px;
48 | display: inline-block;
49 | border-radius: 100px;
50 | background: white;
51 | z-index: 2;
52 | position: absolute;
53 | left: 0;
54 | text-align: center;
55 | font-size: 25px;
56 | }
57 |
58 | span.round-tabs.one {
59 | color: rgb(34, 194, 34);
60 | border: 2px solid rgb(34, 194, 34);
61 | }
62 |
63 | li.active span.round-tabs.one {
64 | background: #fff !important;
65 | border: 2px solid #ddd;
66 | color: rgb(34, 194, 34);
67 | }
68 |
69 | span.round-tabs.two {
70 | color: #febe29;
71 | border: 2px solid #febe29;
72 | }
73 |
74 | li.active span.round-tabs.two {
75 | background: #fff !important;
76 | border: 2px solid #ddd;
77 | color: #febe29;
78 | }
79 |
80 | span.round-tabs.three {
81 | color: #3e5e9a;
82 | border: 2px solid #3e5e9a;
83 | }
84 |
85 | li.active span.round-tabs.three {
86 | background: #fff !important;
87 | border: 2px solid #ddd;
88 | color: #3e5e9a;
89 | }
90 |
91 | span.round-tabs.four {
92 | color: #f1685e;
93 | border: 2px solid #f1685e;
94 | }
95 |
96 | li.active span.round-tabs.four {
97 | background: #fff !important;
98 | border: 2px solid #ddd;
99 | color: #f1685e;
100 | }
101 |
102 | span.round-tabs.five {
103 | color: #999;
104 | border: 2px solid #999;
105 | }
106 |
107 | li.active span.round-tabs.five {
108 | background: #fff !important;
109 | border: 2px solid #ddd;
110 | color: #999;
111 | }
112 |
113 | .nav-tabs > li.active > a span.round-tabs {
114 | background: #fafafa;
115 | }
116 |
117 | .nav-tabs > li {
118 | width: 25%;
119 | }
120 |
121 | li:after {
122 | content: " ";
123 | position: absolute;
124 | left: 45%;
125 | opacity: 0;
126 | margin: 0 auto;
127 | bottom: 0px;
128 | border: 5px solid transparent;
129 | border-bottom-color: #ddd;
130 | transition: 0.1s ease-in-out;
131 |
132 | }
133 |
134 | li.active:after {
135 | content: " ";
136 | position: absolute;
137 | left: 45%;
138 | opacity: 1;
139 | margin: 0 auto;
140 | bottom: 0px;
141 | border: 10px solid transparent;
142 | border-bottom-color: #ddd;
143 |
144 | }
145 |
146 | .nav-tabs > li a {
147 | width: 70px;
148 | height: 70px;
149 | margin: 20px auto;
150 | border-radius: 100%;
151 | padding: 0;
152 | }
153 |
154 | .nav-tabs > li a:hover {
155 | background: transparent;
156 | }
157 |
158 | .tab-content {
159 | }
160 |
161 | .tab-pane {
162 | position: relative;
163 | padding-top: 50px;
164 | }
165 |
166 | .tab-content .head {
167 | font-family: 'Roboto Condensed', sans-serif;
168 | font-size: 25px;
169 | text-transform: uppercase;
170 | padding-bottom: 10px;
171 | }
172 |
173 | .btn-outline-rounded {
174 | padding: 10px 40px;
175 | margin: 20px 0;
176 | border: 2px solid transparent;
177 | border-radius: 25px;
178 | }
179 |
180 | .youngcoder-logo {
181 | height: 100px;
182 | }
183 |
184 | @media ( max-width: 585px ) {
185 | .board {
186 | width: 90%;
187 | height: auto !important;
188 | }
189 |
190 | span.round-tabs {
191 | font-size: 16px;
192 | width: 50px;
193 | height: 50px;
194 | line-height: 50px;
195 | }
196 |
197 | .tab-content .head {
198 | font-size: 20px;
199 | }
200 |
201 | .nav-tabs > li a {
202 | width: 50px;
203 | height: 50px;
204 | line-height: 50px;
205 | }
206 |
207 | li.active:after {
208 | content: " ";
209 | position: absolute;
210 | left: 35%;
211 | }
212 |
213 | .btn-outline-rounded {
214 | padding: 12px 20px;
215 | }
216 | }
--------------------------------------------------------------------------------
/pyconkr/static/image/anonymous.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonkr/pyconkr-2018/d2fe3b41d487875a6616319adddf8ee3d28dc7a2/pyconkr/static/image/anonymous.png
--------------------------------------------------------------------------------
/pyconkr/static/image/dashed-logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonkr/pyconkr-2018/d2fe3b41d487875a6616319adddf8ee3d28dc7a2/pyconkr/static/image/dashed-logo.png
--------------------------------------------------------------------------------
/pyconkr/static/image/dotted-fill-logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonkr/pyconkr-2018/d2fe3b41d487875a6616319adddf8ee3d28dc7a2/pyconkr/static/image/dotted-fill-logo.png
--------------------------------------------------------------------------------
/pyconkr/static/image/dotted-logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonkr/pyconkr-2018/d2fe3b41d487875a6616319adddf8ee3d28dc7a2/pyconkr/static/image/dotted-logo.png
--------------------------------------------------------------------------------
/pyconkr/static/image/etc-badge1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonkr/pyconkr-2018/d2fe3b41d487875a6616319adddf8ee3d28dc7a2/pyconkr/static/image/etc-badge1.png
--------------------------------------------------------------------------------
/pyconkr/static/image/etc-badge2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonkr/pyconkr-2018/d2fe3b41d487875a6616319adddf8ee3d28dc7a2/pyconkr/static/image/etc-badge2.png
--------------------------------------------------------------------------------
/pyconkr/static/image/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonkr/pyconkr-2018/d2fe3b41d487875a6616319adddf8ee3d28dc7a2/pyconkr/static/image/favicon.ico
--------------------------------------------------------------------------------
/pyconkr/static/image/favicon2017.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonkr/pyconkr-2018/d2fe3b41d487875a6616319adddf8ee3d28dc7a2/pyconkr/static/image/favicon2017.ico
--------------------------------------------------------------------------------
/pyconkr/static/image/favicon2018.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonkr/pyconkr-2018/d2fe3b41d487875a6616319adddf8ee3d28dc7a2/pyconkr/static/image/favicon2018.ico
--------------------------------------------------------------------------------
/pyconkr/static/image/incline-logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonkr/pyconkr-2018/d2fe3b41d487875a6616319adddf8ee3d28dc7a2/pyconkr/static/image/incline-logo.png
--------------------------------------------------------------------------------
/pyconkr/static/image/naver-d2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonkr/pyconkr-2018/d2fe3b41d487875a6616319adddf8ee3d28dc7a2/pyconkr/static/image/naver-d2.png
--------------------------------------------------------------------------------
/pyconkr/static/image/pycon2018-logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonkr/pyconkr-2018/d2fe3b41d487875a6616319adddf8ee3d28dc7a2/pyconkr/static/image/pycon2018-logo.png
--------------------------------------------------------------------------------
/pyconkr/static/image/pycon_profile.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonkr/pyconkr-2018/d2fe3b41d487875a6616319adddf8ee3d28dc7a2/pyconkr/static/image/pycon_profile.png
--------------------------------------------------------------------------------
/pyconkr/static/image/pyconkr-2018-cover.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonkr/pyconkr-2018/d2fe3b41d487875a6616319adddf8ee3d28dc7a2/pyconkr/static/image/pyconkr-2018-cover.jpg
--------------------------------------------------------------------------------
/pyconkr/static/image/pyconkr-2018-cover.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonkr/pyconkr-2018/d2fe3b41d487875a6616319adddf8ee3d28dc7a2/pyconkr/static/image/pyconkr-2018-cover.png
--------------------------------------------------------------------------------
/pyconkr/static/image/pyconkr-2018-slogan.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonkr/pyconkr-2018/d2fe3b41d487875a6616319adddf8ee3d28dc7a2/pyconkr/static/image/pyconkr-2018-slogan.png
--------------------------------------------------------------------------------
/pyconkr/static/image/pyconkr-badge.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonkr/pyconkr-2018/d2fe3b41d487875a6616319adddf8ee3d28dc7a2/pyconkr/static/image/pyconkr-badge.png
--------------------------------------------------------------------------------
/pyconkr/static/image/pyconkr2017-logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonkr/pyconkr-2018/d2fe3b41d487875a6616319adddf8ee3d28dc7a2/pyconkr/static/image/pyconkr2017-logo.png
--------------------------------------------------------------------------------
/pyconkr/static/image/python-white.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonkr/pyconkr-2018/d2fe3b41d487875a6616319adddf8ee3d28dc7a2/pyconkr/static/image/python-white.png
--------------------------------------------------------------------------------
/pyconkr/static/image/stripe-logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonkr/pyconkr-2018/d2fe3b41d487875a6616319adddf8ee3d28dc7a2/pyconkr/static/image/stripe-logo.png
--------------------------------------------------------------------------------
/pyconkr/static/js/jquery.quickfit.js:
--------------------------------------------------------------------------------
1 | (function ($) {
2 | var Quickfit, QuickfitHelper, defaults, pluginName;
3 |
4 | pluginName = 'quickfit';
5 |
6 | defaults = {
7 | min: 8,
8 | max: 12,
9 | tolerance: 0.02,
10 | truncate: false,
11 | width: null,
12 | sampleNumberOfLetters: 10,
13 | sampleFontSize: 12
14 | };
15 | QuickfitHelper = (function () {
16 |
17 | var sharedInstance = null;
18 |
19 | QuickfitHelper.instance = function (options) {
20 | if (!sharedInstance) {
21 | sharedInstance = new QuickfitHelper(options);
22 | }
23 | return sharedInstance;
24 | };
25 |
26 | function QuickfitHelper(options) {
27 | this.options = options;
28 |
29 | this.item = $(' ');
30 | this.item.css({
31 | position: 'absolute',
32 | left: '-1000px',
33 | top: '-1000px',
34 | 'font-size': "" + this.options.sampleFontSize + "px"
35 | });
36 | $('body').append(this.item);
37 |
38 | this.meassures = {};
39 | }
40 |
41 | QuickfitHelper.prototype.getMeassure = function (letter) {
42 | var currentMeassure;
43 | currentMeassure = this.meassures[letter];
44 | if (!currentMeassure) {
45 | currentMeassure = this.setMeassure(letter);
46 | }
47 | return currentMeassure;
48 | };
49 |
50 | QuickfitHelper.prototype.setMeassure = function (letter) {
51 | var currentMeassure, index, sampleLetter, text, _ref;
52 |
53 | text = '';
54 | sampleLetter = letter === ' ' ? ' ' : letter;
55 |
56 | for (index = 0, _ref = this.options.sampleNumberOfLetters - 1; 0 <= _ref ? index <= _ref : index >= _ref; 0 <= _ref ? index++ : index--) {
57 | text += sampleLetter;
58 | }
59 |
60 | this.item.html(text);
61 | currentMeassure = this.item.width() / this.options.sampleNumberOfLetters / this.options.sampleFontSize;
62 | this.meassures[letter] = currentMeassure;
63 |
64 | return currentMeassure;
65 | };
66 |
67 | return QuickfitHelper;
68 |
69 | })();
70 |
71 | Quickfit = (function () {
72 |
73 | function Quickfit(element, options) {
74 | this.$element = element;
75 | this.options = $.extend({}, defaults, options);
76 | this.$element = $(this.$element);
77 | this._defaults = defaults;
78 | this._name = pluginName;
79 | this.quickfitHelper = QuickfitHelper.instance(this.options);
80 | }
81 |
82 | Quickfit.prototype.fit = function () {
83 | var elementWidth;
84 | if (!this.options.width) {
85 | elementWidth = this.$element.width();
86 | this.options.width = elementWidth - this.options.tolerance * elementWidth;
87 | }
88 | if (this.text = this.$element.attr('data-quickfit')) {
89 | this.previouslyTruncated = true;
90 | } else {
91 | this.text = this.$element.text();
92 | }
93 | this.calculateFontSize();
94 |
95 | if (this.options.truncate) this.truncate();
96 |
97 | return {
98 | $element: this.$element,
99 | size: this.fontSize
100 | };
101 | };
102 |
103 | Quickfit.prototype.calculateFontSize = function () {
104 | var letter, textWidth, i;
105 |
106 | textWidth = 0;
107 | for (i = 0; i < this.text.length; ++i) {
108 | letter = this.text.charAt(i);
109 | textWidth += this.quickfitHelper.getMeassure(letter);
110 | }
111 |
112 | this.targetFontSize = parseInt(this.options.width / textWidth);
113 | return this.fontSize = Math.max(this.options.min, Math.min(this.options.max, this.targetFontSize));
114 | };
115 |
116 | Quickfit.prototype.truncate = function () {
117 | var index, lastLetter, letter, textToAdd, textWidth;
118 |
119 | if (this.fontSize > this.targetFontSize) {
120 | textToAdd = '';
121 | textWidth = 3 * this.quickfitHelper.getMeassure('.') * this.fontSize;
122 |
123 | index = 0;
124 | while (textWidth < this.options.width && index < this.text.length) {
125 | letter = this.text[index++];
126 | if (lastLetter) textToAdd += lastLetter;
127 | textWidth += this.fontSize * this.quickfitHelper.getMeassure(letter);
128 | lastLetter = letter;
129 | }
130 |
131 | if (textToAdd.length + 1 === this.text.length) {
132 | textToAdd = this.text;
133 | } else {
134 | textToAdd += '...';
135 | }
136 | this.textWasTruncated = true;
137 |
138 | return this.$element.attr('data-quickfit', this.text).html(textToAdd);
139 |
140 | } else {
141 | if (this.previouslyTruncated) {
142 | return this.$element.html(this.text);
143 | }
144 | }
145 | };
146 |
147 | return Quickfit;
148 |
149 | })();
150 |
151 | return $.fn.quickfit = function (options) {
152 | var measurements = [];
153 |
154 | // Separate measurements from repaints
155 | // First calculate all measurements...
156 | var $elements = this.each(function () {
157 | var measurement = new Quickfit(this, options).fit();
158 | measurements.push(measurement);
159 | return measurement.$element;
160 | });
161 |
162 | // ... then apply the measurements.
163 | for (var i = 0; i < measurements.length; i++) {
164 | var measurement = measurements[i];
165 |
166 | measurement.$element.css({ fontSize: measurement.size + 'px' });
167 | }
168 |
169 | return $elements;
170 | };
171 |
172 | })(jQuery, window);
173 |
--------------------------------------------------------------------------------
/pyconkr/static/js/jquery.shuffle.js:
--------------------------------------------------------------------------------
1 | (function($){
2 | $.fn.shuffle = function() {
3 | var allElems = this.get(),
4 | getRandom = function(max) {
5 | return Math.floor(Math.random() * max);
6 | },
7 | shuffled = $.map(allElems, function(){
8 | var random = getRandom(allElems.length),
9 | randEl = $(allElems[random]).clone(true)[0];
10 | allElems.splice(random, 1);
11 | return randEl;
12 | });
13 |
14 | this.each(function(i){
15 | $(this).replaceWith($(shuffled[i]));
16 | });
17 |
18 | return $(shuffled);
19 | };
20 | })(jQuery);
21 |
--------------------------------------------------------------------------------
/pyconkr/static/js/rgb-hsv.js:
--------------------------------------------------------------------------------
1 | function RgbToHsv(rgb) {
2 | var min = Math.min(rgb.r, rgb.g, rgb.b),
3 | max = Math.max(rgb.r, rgb.g, rgb.b),
4 | delta = max - min,
5 | h, s, v = max;
6 |
7 | v = Math.floor(max / 255 * 100);
8 | if (max == 0) return {h:0, s:0, v:0, a:rgb.a};
9 | s = Math.floor(delta / max * 100);
10 | var deltadiv = delta == 0 ? 1 : delta;
11 | if( rgb.r == max ) h = (rgb.g - rgb.b) / deltadiv;
12 | else if(rgb.g == max) h = 2 + (rgb.b - rgb.r) / deltadiv;
13 | else h = 4 + (rgb.r - rgb.g) / deltadiv;
14 | h = Math.floor(h * 60);
15 | if( h < 0 ) h += 360;
16 | return { h: h, s:s, v:v, a:rgb.a }
17 | }
18 |
19 | function HsvToRgb(hsv) {
20 | h = hsv.h / 360;
21 | s = hsv.s / 100;
22 | v = hsv.v / 100;
23 |
24 | if (s == 0)
25 | {
26 | var val = Math.round(v * 255);
27 | return {r:val,g:val,b:val,a:hsv.a};
28 | }
29 | hPos = h * 6;
30 | hPosBase = Math.floor(hPos);
31 | base1 = v * (1 - s);
32 | base2 = v * (1 - s * (hPos - hPosBase));
33 | base3 = v * (1 - s * (1 - (hPos - hPosBase)));
34 | if (hPosBase == 0) {red = v; green = base3; blue = base1}
35 | else if (hPosBase == 1) {red = base2; green = v; blue = base1}
36 | else if (hPosBase == 2) {red = base1; green = v; blue = base3}
37 | else if (hPosBase == 3) {red = base1; green = base2; blue = v}
38 | else if (hPosBase == 4) {red = base3; green = base1; blue = v}
39 | else {red = v; green = base1; blue = base2};
40 |
41 | red = Math.round(red * 255);
42 | green = Math.round(green * 255);
43 | blue = Math.round(blue * 255);
44 | return {r:red,g:green,b:blue,a:hsv.a};
45 | }
46 |
47 | function mixRgb(color1, color2, amount)
48 | {
49 | var hsv1 = RgbToHsv(color1);
50 | var hsv2 = RgbToHsv(color2);
51 |
52 | var h = amount * hsv2.h + (1.0 - amount) * hsv1.h;
53 | var s = amount * hsv2.s + (1.0 - amount) * hsv1.s;
54 | var v = amount * hsv2.v + (1.0 - amount) * hsv1.v;
55 | var a = amount * hsv2.a + (1.0 - amount) * hsv1.a;
56 |
57 | return HsvToRgb({h:h, s:s, v:v, a:a});
58 | }
59 |
60 | function getSkyColorAt(hour, minute)
61 | {
62 | var skyCode = [
63 | [{r: 38, g: 37, b: 51, a: 0.9}, {r: 0, g: 0, b: 0, a: 1.0}],
64 | [{r: 0, g: 0, b: 0, a: 0.5}, {r: 0, g: 0, b: 0, a: 0.9}],
65 | [{r: 75, g: 83, b: 92, a: 1.0}, {r:131, g:177, b:224, a: 1.0}],
66 | [{r:130, g:175, b:224, a: 1.0}, {r: 60, g:203, b:226, a: 1.0}],
67 | [{r:112, g:216, b:239, a: 1.0}, {r:198, g:180, b:220, a: 1.0}],
68 | [{r:112, g:163, b:239, a: 1.0}, {r:202, g:142, b:198, a: 1.0}],
69 | [{r: 88, g: 81, b:197, a: 1.0}, {r:230, g:105, b:145, a: 1.0}],
70 | [{r: 43, g: 28, b: 58, a: 1.0}, {r: 84, g: 18, b: 39, a: 1.0}]
71 | ];
72 |
73 | var begin = Math.floor(hour/3);
74 | var end = (begin + 1) % 8;
75 | var mix = (hour - begin * 3) * 0.33 + (minute / 60.0 / 3.0);
76 |
77 | var color = skyCode[begin][0];
78 | var from = mixRgb(skyCode[begin][0], skyCode[end][0], mix);
79 | var to = mixRgb(skyCode[begin][1], skyCode[end][1], mix);
80 |
81 | var css = "linear-gradient(to bottom, "
82 | + "rgba("+from.r+","+from.g+","+from.b+","+from.a+") 0%, "
83 | + "rgba("+to.r+","+to.g+","+to.b+","+to.a+") 100%)";
84 |
85 | return css
86 | }
87 |
--------------------------------------------------------------------------------
/pyconkr/static/js/teaser.js:
--------------------------------------------------------------------------------
1 | $(document).ready(function(){
2 | var mapOptions = {
3 | center: new naver.maps.LatLng(37.5117731, 127.0592041),
4 | zoom: 10,
5 | zoomControl: true
6 | };
7 |
8 | var map = new naver.maps.Map('map', mapOptions);
9 |
10 | var marker = new naver.maps.Marker({
11 | position: new naver.maps.LatLng(37.5117731, 127.0592041),
12 | map: map
13 | });
14 |
15 | var Slickconfig = {
16 | dots: true,
17 | prevArrow: false,
18 | nextArrow: false,
19 | autoplay: true,
20 | autoplaySpeed: 5000
21 | };
22 |
23 | $('.js_slick').slick(Slickconfig);
24 | });
--------------------------------------------------------------------------------
/pyconkr/static/js/young-coder.js:
--------------------------------------------------------------------------------
1 | $(document).ready(function () {
2 | var url = document.location.toString();
3 | if (url.match('#')) {
4 | $(".nav-tabs a[href='#" + url.split('#')[1] + "']").tab('show');
5 | }
6 |
7 | // Change hash for page-reload
8 | $('.nav-tabs a').on('shown.bs.tab', function (e) {
9 | e.preventDefault();
10 | history.pushState({}, '', this.href);
11 | });
12 | });
--------------------------------------------------------------------------------
/pyconkr/templates/badge/all.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | {% include "badge/twitter.html" %}
4 |
5 |
6 | {% include "badge/facebook.html" %}
7 |
8 |
9 | {% include "badge/googleplus.html" %}
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/pyconkr/templates/badge/facebook.html:
--------------------------------------------------------------------------------
1 |
5 |
--------------------------------------------------------------------------------
/pyconkr/templates/badge/googleplus.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/pyconkr/templates/badge/twitter.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/pyconkr/templates/banner.html:
--------------------------------------------------------------------------------
1 |
2 | {% for banner in banners %}
3 |
4 |
5 |
6 |
7 | {{ banner.desc|safe }}
8 |
9 | {% endfor %}
10 |
11 |
--------------------------------------------------------------------------------
/pyconkr/templates/base.html:
--------------------------------------------------------------------------------
1 |
2 | {% load staticfiles %}
3 | {% load i18n %}
4 | {% if LANGUAGE_CODE == 'en' %}
5 |
6 | {% else %}
7 |
8 | {% endif %}
9 |
10 |
11 | {% block head-title %}{% trans "PyCon Korea 2018" %}{% endblock %}
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 | {% block head-include %}
39 | {% endblock %}
40 |
41 |
42 | {% block nav %}{% include "nav.html" %}{% endblock %}
43 | {% if index %}
44 |
45 |
46 |
47 |
48 |
72 | {% endif %}
73 |
74 |
75 |
76 | {% if not index %}
77 |
{% block title %}{{ title }}{% endblock %}
78 | {% endif %}
79 | {{ base_content | safe }}
80 | {% block content %}{% endblock %}
81 |
82 |
83 | {% block sponsors %}
84 |
85 |
89 |
90 | {% endblock %}
91 |
92 |
93 | {% block unboxed_content %} {# for index ^^ #}
94 | {% endblock %}
95 |
96 |
97 | {% include "footer.html" %}
98 |
99 |
100 |
101 |
--------------------------------------------------------------------------------
/pyconkr/templates/child_care.html:
--------------------------------------------------------------------------------
1 | {% extends "base.html" %}
2 | {% load staticfiles %}
3 | {% load i18n %}
4 | {% load thumbnail %}
5 |
6 |
7 |
--------------------------------------------------------------------------------
/pyconkr/templates/dev-robots.txt:
--------------------------------------------------------------------------------
1 | User-agent: *
2 | Disallow: /
3 |
--------------------------------------------------------------------------------
/pyconkr/templates/disqus.html:
--------------------------------------------------------------------------------
1 | {% load i18n %}
2 | {% trans "Comments" %}
3 |
4 |
12 | Please enable JavaScript to view the comments powered by Disqus.
13 | blog comments powered by
14 |
--------------------------------------------------------------------------------
/pyconkr/templates/facebook_script.html:
--------------------------------------------------------------------------------
1 |
2 |
9 |
--------------------------------------------------------------------------------
/pyconkr/templates/flatpages/default.html:
--------------------------------------------------------------------------------
1 | {% extends "base.html" %}
2 |
3 | {% block og-title %}{{ block.super }} {{ flatpage.title }}{% endblock %}
4 | {% block og-desc %}{{ flatpage.content|striptags|truncatechars:300 }}{% endblock %}
5 | {% block head-title %}{{ block.super }} {{ flatpage.title }}{% endblock %}
6 | {% block title %}{{ flatpage.title }}{% endblock %}
7 |
--------------------------------------------------------------------------------
/pyconkr/templates/footer.html:
--------------------------------------------------------------------------------
1 | {% load staticfiles %}
2 | {% load i18n %}
3 |
4 |
5 |
6 |
Dive into Diversity, {% trans "PyCon Korea 2018" %}
7 |
{% trans "PyCon Korea 2018 is a product of PyCon Korea Organizing Team" %}
8 |
9 | {% trans "Powered by Django" %} | {% trans "Hosted on Naver D2" %}
10 |
11 |
12 |
29 |
30 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/pyconkr/templates/ga.html:
--------------------------------------------------------------------------------
1 |
11 |
--------------------------------------------------------------------------------
/pyconkr/templates/index.html:
--------------------------------------------------------------------------------
1 | {% extends "base.html" %}
2 |
3 | {% load staticfiles %}
4 |
5 |
6 | {% block head-include %}
7 |
8 |
9 |
10 | {% endblock %}
11 |
12 | {% block content_wrapper %}
13 | {% endblock %}
14 |
15 | {% block content %}
16 |
17 | {% if recent_announcements %}
18 |
19 |
20 | {% for announcement in recent_announcements %}
21 |
22 |
23 |
{{ announcement }}
24 |
25 | {{ announcement.desc|safe }}
26 |
27 |
자세히 보기
28 |
29 |
30 | {% endfor %}
31 |
32 |
33 | {% endif %}
34 |
35 |
36 | 행사 상세
37 |
38 | 파이콘 한국은 한국의 파이썬 개발자들이 지식을 공유하고 만남을 갖기 위한 장입니다.
39 |
40 |
스프린트 (8/15, 8/17)
41 | 관심있는 오픈소스 프로젝트를 같은 장소에 모여 집중적으로 개발하는 자리입니다
42 | 스프린트 참가하기
43 |
44 | 튜토리얼 (8/17)
45 | 초보자들을 위해, 또는 새로운 것을 접하는 사람들을 위해 진행하는 교육 프로그램입니다.
46 | 튜토리얼 참가하기
47 |
48 | 컨퍼런스 (8/18 - 8/19)
49 | 파이썬 사용 사례, 지식 공유를 위한 행사입니다. 컨퍼런스의 자세한 시간표는 프로그램 > 세부일정 에서 확인하실 수 있습니다.
50 | 컨퍼런스 티켓 구매하기
51 |
52 | 이 외의 모든 공지사항은 공식 페이스북 과 이곳을 통해 공지될 예정입니다.
53 |
54 |
55 |
56 |
57 | 슬로건
58 | "Dive into Diversity - 다양성에 빠지다"
59 |
60 | 파이콘 한국 2018은 "Dive into Diversity 다양성에 빠지다" 라는 슬로건으로 진행됩니다.
61 | 파이썬 커뮤니티는 다양한 기술, 개성 및 경험을 갖추고 있는 전세계 구성원들이 서로의 차이를 존중하고,
62 | 다른 견해에 귀를 기울이며, 올바른 상호작용을 통해 성장하는 커뮤니티를 지향해왔습니다.
63 | 파이콘 한국 2018에서는 다양한 사람들이 다양한 상황과 분야에서 다양한 의도를 가지고 파이썬과 만났던 사례를 공유합니다.
64 | 또한 우리가 원하는 것을 이루고 문제를 해결하는 도구로서, 파이썬이 어떻게 쓰이고 있는지 조명하려고 합니다.
65 | 파이콘 한국 2018을 통해 서로 다른 견해와 경험을 접하며, 생각의 경계를 허물고 새로운 아이디어를 발견하는 계기가 되었으면 합니다.
66 |
67 |
68 |
69 |
70 | 장소
71 | 서울 코엑스 그랜드볼룸
72 |
76 |
77 |
78 |
85 | {% endblock %}
--------------------------------------------------------------------------------
/pyconkr/templates/login.html:
--------------------------------------------------------------------------------
1 | {% extends "base.html" %}
2 | {% load socialaccount %}
3 | {% load i18n %}
4 | {% load crispy_forms_tags %}
5 |
6 | {% block content %}
7 | {% trans "Login via mail" %}
8 |
9 | {% trans "We store your mail address only. Never store password or any personal information." %}
10 |
11 | {% crispy form %}
12 |
22 | {% endblock %}
23 |
--------------------------------------------------------------------------------
/pyconkr/templates/login_mailsent.html:
--------------------------------------------------------------------------------
1 | {% extends "base.html" %}
2 | {% load i18n %}
3 |
4 | {% block content %}
5 | {% trans "One-time login token url was sent to your mail. Please check your mailbox." %}
6 | {% trans "Login token valid for only 1 hour." %} {% trans "If you lost token mail or be lated, please login again." %}
7 | {% trans "Back to home" %}
8 | {% endblock %}
9 |
--------------------------------------------------------------------------------
/pyconkr/templates/login_notvalidtoken.html:
--------------------------------------------------------------------------------
1 | {% extends "base.html" %}
2 | {% load i18n %}
3 |
4 | {% block content %}
5 | {% trans "Requested token is not found or invalid." %}
6 | {% trans "If you lost token mail or be lated, please login again." %}
7 | {% trans "Login" %}
8 | {% endblock %}
9 |
--------------------------------------------------------------------------------
/pyconkr/templates/mail/ticket_registered_html.html:
--------------------------------------------------------------------------------
1 | {% load i18n %}
2 | {% trans "PyCon Korea Registration confirmation" %}
3 | PyCon Korea 2015 참가신청이 완료 되었습니다.
4 | 안녕하세요 {{payment_info.name}}님
5 |
6 | 본 메일은 PyCon Korea 2015 등록완료 확인 메일입니다.
7 |
8 | PyCon Korea 2015에 등록해주셔 감사합니다.
9 | PyCon Korea 2015 는 8월 29~30일 서울시 상암동 누리꿈 스퀘어에서 개최됩니다.
10 |
11 | 장소 : 누리꿈 스퀘어
12 | 주소 : 서울특별시 마포구 상암동 1605
13 | 도로명 주소 : 서울특별시 마포구 월드컵북로 396
14 | 안내 : http://nuri.nipa.kr/rt/
15 |
16 | 행사와 관련된 정보는 http://www.pycon.kr/2015/ 에서 확인하실 수 있습니다.
17 |
18 |
19 | {% trans '결제 정보' %}
20 |
21 |
22 | 이메일 {{payment_info.email}}
23 |
24 |
25 | 이름 {{payment_info.name}}
26 |
27 |
28 | 상의 사이즈 {{payment_info.top_size}}
29 |
30 |
31 | 전화번호 {{payment_info.phone_number}}
32 |
33 |
34 | 소속 {{payment_info.company}}
35 |
36 |
37 | 금액 {{amount}}원 ({{payment_info.payment_method}})
38 |
39 |
40 | 거래번호 {{payment_info.merchant_uid}}
41 |
42 |
43 | 등록완료일 {{payment_info.modified}}
44 |
45 |
46 | 결제와 관련된 정보는 http://www.pycon.kr{% url 'registration_status' %} 에서도 확인이 가능합니다.
47 |
48 | PyCon Korea 2015 에서 뵙겠습니다.
49 |
50 |
--------------------------------------------------------------------------------
/pyconkr/templates/mail/ticket_registered_text.html:
--------------------------------------------------------------------------------
1 | {% load i18n %}
2 | {% trans "PyCon Korea Registration confirmation" %}
3 |
4 | PyCon Korea 2015 참가신청이 완료 되었습니다.
5 |
6 | 안녕하세요 {{payment_info.name}}님
7 |
8 | 본 메일은 PyCon Korea 2015 등록완료 확인 메일입니다.
9 |
10 | PyCon Korea 2015에 등록해주셔 감사합니다.
11 | PyCon Korea 2015 는 8월 29~30일 서울시 상암동 누리꿈 스퀘어에서 개최됩니다.
12 |
13 | - 장소 : 누리꿈 스퀘어
14 | - 주소 : 서울특별시 마포구 상암동 1605
15 | - 도로명 주소 : 서울특별시 마포구 월드컵북로 396
16 | - 안내 : http://nuri.nipa.kr/rt/
17 |
18 | 행사와 관련된 정보는 http://www.pycon.kr/2015/ 에서 확인하실 수 있습니다.
19 |
20 | 결제 정보
21 |
22 | 이메일 : {{payment_info.email}}
23 | 이름 : {{payment_info.name}}
24 | 상의 사이즈 : {{payment_info.top_size}}
25 | 전화번호 : {{payment_info.phone_number}}
26 | 소속 : {{payment_info.company}}
27 | 거래번호 : {{payment_info.merchant_uid}}
28 | 금액 : {{amount}}원 ({{payment_info.payment_method}})
29 | 등록완료일 : {{payment_info.modified}}
30 |
31 |
32 | 결제와 관련된 정보는 http://www.pycon.kr{% url 'registration_status' %} 에서도 확인이 가능합니다.
33 |
34 | PyCon Korea 2015 에서 뵙겠습니다.
--------------------------------------------------------------------------------
/pyconkr/templates/mail/token_html.html:
--------------------------------------------------------------------------------
1 | {% load i18n %}
2 | {% trans "PyCon Korea 2018" %}
3 | {% trans "You can login to PyCon Korea 2018 homepage via below url." %}
4 | {% trans "Link" %}:
5 |
6 | http://{{ request.get_host }}{% url "login_req" token.token %}
7 |
8 |
9 |
--------------------------------------------------------------------------------
/pyconkr/templates/mail/token_text.html:
--------------------------------------------------------------------------------
1 | {% load i18n %}
2 | {% trans "You can login to PyCon Korea 2018 homepage via below url." %}
3 | http://{{ request.get_host }}{% url "login_req" token.token %}
4 |
--------------------------------------------------------------------------------
/pyconkr/templates/nav.html:
--------------------------------------------------------------------------------
1 | {% load staticfiles %}
2 | {% load i18n %}
3 |
4 |
5 |
6 |
17 |
18 |
19 |
20 |
21 | {% for k, v in menu.items %}
22 | {% if v.submenu %}
23 |
24 |
25 | {{ v.title }}
26 |
33 |
34 | {% else %}
35 |
36 | {{ v.title }}
37 |
38 | {% endif %}
39 | {% endfor %}
40 |
41 |
42 |
85 |
86 |
87 |
88 |
89 | {##}
103 |
104 |
--------------------------------------------------------------------------------
/pyconkr/templates/pyconkr/announcement_detail.html:
--------------------------------------------------------------------------------
1 | {% extends "base.html" %}
2 | {% load i18n %}
3 |
4 | {% block og-title %}{{ block.super }} {{ object.title }}{% endblock %}
5 | {% block og-desc %}{{ object.desc|striptags|truncatechars:300 }}{% endblock %}
6 | {% block head-title %}{{ object.title }}{% endblock %}
7 |
8 | {% block content %}
9 | {{ object.desc|safe }}
10 | {{ object.at }}
11 |
12 |
13 | {% trans "Back to list" %}
14 |
15 | {% endblock %}
16 |
--------------------------------------------------------------------------------
/pyconkr/templates/pyconkr/announcement_list.html:
--------------------------------------------------------------------------------
1 | {% extends "base.html" %}
2 | {% load i18n %}
3 |
4 | {% block content %}
5 | {% if not object_list %}
6 | {% trans "Ready for content" %}
7 | {% endif %}
8 |
9 | {% for announcement in object_list %}
10 |
11 |
12 |
13 | {{ announcement }}
14 | {{ announcement.at|date:"Y-m-d" }}
15 |
16 |
17 |
18 | {{ announcement.desc|striptags|truncatechars:300|safe }}
19 |
20 | {% trans "Read more" %}
21 |
22 |
23 |
24 | {% endfor %}
25 | {% endblock %}
26 |
--------------------------------------------------------------------------------
/pyconkr/templates/pyconkr/jobfair_list.html:
--------------------------------------------------------------------------------
1 | {% extends "base.html" %}
2 | {% load i18n %}
3 |
4 | {% block content %}
5 | {% for obj in object_list %}
6 |
7 |
8 |
15 |
16 |
17 |
18 | {{ obj.desc|safe }}
19 |
20 |
21 | {% endfor %}
22 | {% endblock %}
23 |
--------------------------------------------------------------------------------
/pyconkr/templates/pyconkr/patron_list.html:
--------------------------------------------------------------------------------
1 | {% extends "base.html" %}
2 | {% load staticfiles %}
3 | {% load thumbnail %}
4 | {% load i18n %}
5 |
6 | {% block content %}
7 |
8 |
파이콘 한국 2018 을 후원해주신 개인 후원자 분들의 명단입니다. 후원해주셔서 감사합니다.
9 |
41 |
42 | {% endblock %}
43 |
--------------------------------------------------------------------------------
/pyconkr/templates/pyconkr/profile_form.html:
--------------------------------------------------------------------------------
1 | {% extends "base.html" %}
2 | {% load i18n %}
3 | {% load crispy_forms_tags %}
4 |
5 | {% block title %}{% trans "Profile" %}{% endblock %}
6 |
7 | {% block content %}
8 | {% crispy form %}
9 | {% endblock %}
10 |
--------------------------------------------------------------------------------
/pyconkr/templates/pyconkr/program_detail.html:
--------------------------------------------------------------------------------
1 | {% extends "base.html" %}
2 | {% load i18n %}
3 |
4 | {% block head-title %}{{ block.super }} {% trans "Program" %} | {{ program.name }}{% endblock %}
5 | {% block og-title %}{{ program.name }}{% endblock %}
6 | {% block og-desc %}{{ program.desc|striptags|safe }}{% endblock %}
7 | {% block nav %}{% include "nav.html" with title=program.name %}{% endblock %}
8 | {% block title %}{{ program.name }}{% endblock %}
9 |
10 | {% block content %}
11 | {% include "badge/all.html" %}
12 |
13 | {% if program.category %}
14 |
15 | {{ program.category }}
16 |
17 | {% endif %}
18 | {% if program.difficulty %}
19 |
20 |
21 | {% if program.difficulty == 'B' %}{% trans "Difficulty Beginner" %}
22 | {% elif program.difficulty == 'I' %}{% trans "Difficulty Intermediate" %}
23 | {% elif program.difficulty == 'E' %}{% trans "Difficulty Experienced" %}
24 | {% endif %}
25 |
26 | {% endif %}
27 | {% if program.date %}
28 |
29 | {{ program.date }} {{ program.get_times }}
30 |
31 | {% endif %}
32 |
33 | {{ program.get_language_display }}
34 |
35 | {% if program.room %}
36 |
37 | {{ program.room }}
38 |
39 | {% endif %}
40 | {% if program.get_speakers %}
41 |
42 | {% for speaker in program.speakers.all %}
43 |
49 | {% endfor %}
50 |
51 | {% endif %}
52 |
53 | {% if program.is_recordable %}
54 | {% trans "Photography and recording is allowed" %}
55 | {% else %}
56 | {% trans "Photography and recording is not allowed" %}
57 | {% endif %}
58 |
59 |
60 | {% if program.get_slide_url_by_begin_time %}
61 | {% trans "Slide" %}
62 | {{ program.get_slide_url_by_begin_time|urlize }}
63 | {% endif %}
64 | {% if program.video_url %}
65 | {% trans "Video" %}
66 | {{ program.video_url|urlize }}
67 | {% endif %}
68 | {% if program.pdf_url %}
69 | {% trans "PDF" %}
70 | {{ program.pdf_url|urlize }}
71 | {% endif %}
72 | {% if program.desc %}
73 | {% trans "Description" %}
74 | {{ program.desc|safe }}
75 | {% endif %}
76 | {% if editable %}
77 |
78 | {% trans "Edit" %}
79 | {% endif %}
80 | {% include "disqus.html" %}
81 | {% endblock %}
82 |
--------------------------------------------------------------------------------
/pyconkr/templates/pyconkr/program_form.html:
--------------------------------------------------------------------------------
1 | {% extends "base.html" %}
2 | {% load crispy_forms_tags %}
3 |
4 | {% block head-include %}
5 | {{ form.media }}
6 | {% endblock %}
7 |
8 | {% block head-title %}{{ program }}{% endblock %}
9 | {% block title %}{{ program }}{% endblock %}
10 |
11 | {% block content %}
12 | {% crispy form %}
13 | {% endblock %}
14 |
--------------------------------------------------------------------------------
/pyconkr/templates/pyconkr/program_list.html:
--------------------------------------------------------------------------------
1 | {% extends "base.html" %}
2 | {% load i18n %}
3 |
4 | {% block content %}
5 | {% if not object_list %}
6 | {% trans "Ready for content" %}
7 | {% endif %}
8 |
9 | {% for obj in object_list %}
10 |
11 |
12 | {{ obj.name }}
13 |
14 |
15 |
31 | {% endfor %}
32 | {% endblock %}
33 |
--------------------------------------------------------------------------------
/pyconkr/templates/pyconkr/program_preference.html:
--------------------------------------------------------------------------------
1 | {% extends "base.html" %}
2 | {% load i18n %}
3 |
4 | {% block content %}
5 |
17 |
28 | {% endblock %}
29 |
--------------------------------------------------------------------------------
/pyconkr/templates/pyconkr/proposal_detail.html:
--------------------------------------------------------------------------------
1 | {% extends "base.html" %}
2 | {% load i18n %}
3 | {% load thumbnail %}
4 | {% load crispy_forms_tags %}
5 |
6 | {% block content %}
7 |
8 | {% if request.user.proposal %}
9 |
10 | {{ proposal.title }}
11 |
12 |
13 |
14 | {{ proposal.get_difficulty_display }}
15 | {{ proposal.get_duration_display }}
16 | {{ proposal.get_language_display }}
17 |
18 |
{{ proposal.brief|linebreaks }}
19 |
20 |
21 |
{% trans "Detailed description" %}
22 | {{ proposal.desc|safe }}
23 |
24 |
25 |
26 |
{% trans "Comment to reviewers" %}
27 | {{ proposal.comment|safe }}
28 |
29 |
30 | {% endif %}
31 |
32 | {% endblock %}
33 |
--------------------------------------------------------------------------------
/pyconkr/templates/pyconkr/proposal_form.html:
--------------------------------------------------------------------------------
1 | {% extends "base.html" %}
2 | {% load crispy_forms_tags i18n %}
3 |
4 | {% block head-include %}
5 | {{ form.media }}
6 | {% endblock %}
7 |
8 | {% block content %}
9 |
10 | {% crispy form %}
11 |
12 | {% endblock %}
13 |
--------------------------------------------------------------------------------
/pyconkr/templates/pyconkr/room_detail.html:
--------------------------------------------------------------------------------
1 | {% extends "base.html" %}
2 |
3 | {% block head-title %}{{ object.name }}{% endblock %}
4 |
5 | {% block content %}
6 | {{ object }}
7 | {% endblock %}
8 |
--------------------------------------------------------------------------------
/pyconkr/templates/pyconkr/speaker_detail.html:
--------------------------------------------------------------------------------
1 | {% extends "base.html" %}
2 | {% load i18n %}
3 |
4 | {% block head-title %}{{ block.super }} {% trans "Speaker" %} | {{ speaker.name }}{% endblock %}
5 | {% block og-title %}{{ speaker.name }}{% endblock %}
6 | {% block og-image %}{{ speaker.get_image_url }}{% endblock %}
7 | {% block og-desc %}{{ speaker.desc|striptags }}{% endblock %}
8 | {% block nav %}{% include "nav.html" with title=speaker.name %}{% endblock %}
9 | {% block title %}{{ speaker.name }}{% endblock %}
10 |
11 | {% block content %}
12 | {% include "badge/all.html" %}
13 |
14 |
15 | {{ speaker.get_badges|safe }}
16 | {% if speaker.desc %}
17 |
{% trans "Profile" %}
18 |
19 | {{ speaker.desc|safe }}
20 |
21 | {% endif %}
22 |
{% trans "Program" %}
23 |
24 | {% for program in speaker.program_set.all %}
25 | {{ program.name }}
26 | {% endfor %}
27 |
28 |
29 | {% if editable %}
30 |
31 | {% trans "Edit" %}
32 | {% endif %}
33 | {% endblock %}
34 |
--------------------------------------------------------------------------------
/pyconkr/templates/pyconkr/speaker_form.html:
--------------------------------------------------------------------------------
1 | {% extends "base.html" %}
2 | {% load crispy_forms_tags %}
3 |
4 | {% block head-include %}
5 | {{ form.media }}
6 | {% endblock %}
7 |
8 | {% block head-title %}{{ speaker }}{% endblock %}
9 | {% block title %}{{ speaker }}{% endblock %}
10 |
11 | {% block content %}
12 | {% crispy form %}
13 | {% endblock %}
14 |
--------------------------------------------------------------------------------
/pyconkr/templates/pyconkr/speaker_list.html:
--------------------------------------------------------------------------------
1 | {% extends "base.html" %}
2 | {% load staticfiles %}
3 | {% load i18n %}
4 | {% load thumbnail %}
5 |
6 | {% block content %}
7 |
33 | {% endblock %}
34 |
--------------------------------------------------------------------------------
/pyconkr/templates/pyconkr/sponsor_detail.html:
--------------------------------------------------------------------------------
1 | {% extends "base.html" %}
2 | {% load i18n %}
3 |
4 | {% block head-title %}{{ block.super }} {% trans "Sponsor" %} | {{ sponsor.name }}{% endblock %}
5 | {% block og-title %}{{ block.super }} {% trans "Sponsor" %} | {{ sponsor.name }}{% endblock %}
6 | {% block og-image %}{{ sponsor.image.url }}{% endblock %}
7 | {% block nav %}{% include "nav.html" with title=sponsor.name %}{% endblock %}
8 | {% block title %}{{ sponsor.name }}{% endblock %}
9 |
10 | {% block content %}
11 |
27 | {% endblock %}
28 |
--------------------------------------------------------------------------------
/pyconkr/templates/pyconkr/sponsor_list.html:
--------------------------------------------------------------------------------
1 | {% extends "base.html" %}
2 | {% load i18n %}
3 |
4 | {% block title %}{% trans "Sponsors" %}{% endblock %}
5 | {% block content %}
6 |
7 |
8 | {% include "sponsors.html" with detail="True" %}
9 |
10 |
11 | {% endblock %}
12 | {% block sponsors %}
13 | {% endblock %}
14 |
--------------------------------------------------------------------------------
/pyconkr/templates/pyconkr/sprintproposal_detail.html:
--------------------------------------------------------------------------------
1 | {% extends "base.html" %}
2 | {% load i18n %}
3 | {% load thumbnail %}
4 | {% load crispy_forms_tags %}
5 |
6 | {% block head-title %}{{ sprint.title }} — {{ block.super }}{% endblock %}
7 | {% block og-title %}{{ sprint.title }}{% endblock %}
8 | {% block og-desc %}{{ sprint.project_brief }}{% endblock %}
9 |
10 | {% block title %}
11 |
12 | {{ sprint.title }}
13 | {% if sprint.user == request.user %}
14 |
15 | {% trans "Edit" %}
16 |
17 | {% endif %}
18 |
19 | {% endblock %}
20 | {% block content %}
21 |
22 |
{% trans "Sprinter" %}
23 |
24 | {{ sprint.user.profile.name }}
25 | {% if sprint.user.profile.organization %}
26 | {{ sprint.user.profile.organization }}
27 | {% endif %}
28 |
29 |
30 | {{ sprint.user.profile.bio|safe }}
31 |
32 |
33 |
34 |
{% trans "Tutorial Information" %}
35 | {{ sprint.comment|safe }}
36 |
37 |
38 |
39 |
{% trans "Sprint Language" %}
40 |
{{ sprint.language|linebreaks }}
41 |
{% trans "Project brief" %}
42 |
{{ sprint.project_brief|urlize|linebreaks }}
43 |
{% trans "Detailed description" %}
44 |
{{ sprint.contribution_desc|safe }}
45 |
46 |
47 |
48 |
49 |
{% trans "Project URL" %}
50 |
{{ sprint.project_url|urlize|linebreaks }}
51 |
52 |
53 |
54 |
55 |
56 |
57 | {% trans "Back to list" %}
58 |
59 | {% if joined %}
60 |
61 | {% trans "Leave this event" %}
62 |
63 | {% else %}
64 |
65 | {% trans "Join this event" %}
66 |
67 | {% endif %}
68 |
69 |
70 | {% trans "Attendees" %}
71 | {% if not attendees %}
72 | {% trans "No attendees, yet." %}
73 | {% else %}
74 |
75 | {% for attend in attendees %}
76 |
77 | {% if attend.picture %}
78 |
79 | {% else %}
80 |
81 | {% endif %}
82 | {{ attend.name }}
83 |
84 | {% if attend.waiting %}
85 | {% trans "Waiting" %}
86 | {% else %}
87 | {% trans "Checked in" %}
88 | {% endif %}
89 |
90 | {% endfor %}
91 |
92 |
93 | {% endif %}
94 | {% endblock %}
95 |
--------------------------------------------------------------------------------
/pyconkr/templates/pyconkr/sprintproposal_list.html:
--------------------------------------------------------------------------------
1 | {% extends "base.html" %}
2 | {% load i18n %}
3 |
4 | {% block content %}
5 | Sprints
6 |
7 | {% for sprint in sprints %}
8 |
9 | {{ sprint.get_type_display }}
10 | {{ sprint.title }}
11 | {% if sprint.id in joined_sprints %}
12 | {% trans "Joined" %}
13 | {% endif %}
14 |
15 | {% endfor %}
16 |
17 | {% endblock %}
18 |
--------------------------------------------------------------------------------
/pyconkr/templates/pyconkr/tutorialproposal_detail.html:
--------------------------------------------------------------------------------
1 | {% extends "base.html" %}
2 | {% load i18n %}
3 | {% load thumbnail %}
4 | {% load crispy_forms_tags %}
5 |
6 | {% block head-title %}{{ tutorial.title }} — {{ block.super }}{% endblock %}
7 | {% block og-title %}{{ tutorial.title }}{% endblock %}
8 | {% block og-desc %}{{ tutorial.brief }}{% endblock %}
9 |
10 | {% block title %}
11 |
12 | {{ tutorial.title }}
13 | {% if tutorial.user == request.user %}
14 |
15 | {% trans "Edit" %}
16 |
17 | {% endif %}
18 |
19 | {% endblock %}
20 | {% block content %}
21 |
22 |
23 | {{ tutorial.get_type_display }}
24 | {{ tutorial.get_difficulty_display }}
25 | {{ tutorial.get_duration_display }}
26 | {{ tutorial.get_language_display }}
27 | {{ tutorial.capacity }} 명
28 |
29 |
30 | {{ tutorial.user.profile.name }}
31 | {% if tutorial.user.profile.organization %}
32 | {{ tutorial.user.profile.organization }}
33 | {% endif %}
34 |
35 |
36 | {{ tutorial.user.profile.bio|safe }}
37 |
38 |
39 |
40 | {% if option %}
41 | {% if is_registered %}
42 |
43 | 이미 등록하셨습니다.
44 |
45 | {% elif option.is_sold_out %}
46 |
47 | 등록 마감
48 |
49 | {% else %}
50 |
51 | 참가신청하기
52 |
53 | {% endif %}
54 | {% endif %}
55 |
56 |
57 |
{% trans "Tutorial Information" %}
58 | 일시 : {{ tutorial.begin_at|date:'Y-m-d H:i:s' }} ~ {{ tutorial.end_at|date:'Y-m-d H:i:s' }}
59 | {{ tutorial.comment|safe }}
60 |
61 |
62 |
63 |
{% trans "Brief" %}
64 |
{{ tutorial.brief|linebreaks }}
65 |
66 |
67 |
68 |
{% trans "Detailed description" %}
69 | {{ tutorial.desc|safe }}
70 |
71 |
72 |
73 |
74 | {% trans "Back to list" %}
75 |
76 |
77 |
78 | {% endblock %}
79 |
--------------------------------------------------------------------------------
/pyconkr/templates/pyconkr/tutorialproposal_list.html:
--------------------------------------------------------------------------------
1 | {% extends "base.html" %}
2 | {% load i18n %}
3 |
4 | {% block content %}
5 | Tutorials
6 |
7 | {% for tutorial in tutorials %}
8 |
9 | {{ tutorial.get_type_display }}
10 | {{ tutorial.title }}
11 | {% if tutorial.id in joined_tutorials %}
12 | {% trans "Joined" %}
13 | {% endif %}
14 |
15 | {% endfor %}
16 |
17 | {% endblock %}
18 |
--------------------------------------------------------------------------------
/pyconkr/templates/robots.txt:
--------------------------------------------------------------------------------
1 | User-agent: *
2 | Disallow: /media/speaker/*.jpg$
3 |
--------------------------------------------------------------------------------
/pyconkr/templates/sponsors.html:
--------------------------------------------------------------------------------
1 | {% load i18n %}
2 |
25 |
--------------------------------------------------------------------------------
/pyconkr/templates/submenu.html:
--------------------------------------------------------------------------------
1 |
6 |
--------------------------------------------------------------------------------
/pyconkr/tests.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | from django.test import TestCase
4 | from django.http import HttpResponse
5 | from django.test import Client
6 | from django.core.urlresolvers import reverse_lazy, reverse
7 | from django.contrib.auth import get_user_model
8 | from django_dynamic_fixture import G
9 |
10 | from pyconkr.models import TutorialCheckin, TutorialProposal
11 | from pyconkr.helper import render_io_error
12 | from registration.models import Registration
13 |
14 | User = get_user_model()
15 |
16 |
17 | class HelperFunctionTestCase(TestCase):
18 | def setUp(self):
19 | pass
20 |
21 | def tearDown(self):
22 | pass
23 |
24 | def test_render_io_error(self):
25 | a = render_io_error("test reason")
26 | self.assertEqual(a.status_code, 406, "render io error status code must be 406")
27 |
28 |
29 | class PaymentTestCase(TestCase):
30 | def setUp(self):
31 | self.client = Client()
32 | self.user = User.objects.create_user('testname', 'test@test.com', 'testpassword')
33 | self.client.login(username='testname', password='testpassword')
34 |
35 | def tearDown(self):
36 | pass
37 |
38 | def test_view_registration_payment(self):
39 | url = reverse('registration_payment')
40 | response = self.client.post(url, {'test': 1})
41 | self.assertEqual(response['content-type'], 'application/json', 'Result has to be JSON')
42 |
43 |
44 | class ProfileTest(TestCase):
45 | def test_profile_is_created_when_user_save(self):
46 | user = User.objects.create_user('test', 'test@email.com', 'password')
47 | self.assertNotEqual(user.profile, None)
48 |
49 | def test_redirect_to_profile_edit_page_when_user_has_not_profile(self):
50 | User.objects.create_user('test', 'test@email.com', 'password')
51 | client = Client()
52 | client.login(username='test', password='password')
53 | response = client.get(reverse('profile'))
54 | self.assertEqual(response.status_code, 302)
55 | self.assertEqual(response['location'], reverse('profile_edit'))
56 |
57 |
58 | class ProposeTest(TestCase):
59 | def test_redirect_to_profile_when_propose_without_profile(self):
60 | user = User.objects.create_user('test', 'test@email.com', 'password')
61 | client = Client()
62 | client.login(username='test', password='password')
63 | response = client.get(reverse('propose'))
64 | self.assertEqual(response.status_code, 302)
65 | self.assertEqual(response['location'], reverse('profile_edit'))
66 |
67 | class TutorialTest(TestCase):
68 | def test_tutorial_detail_attendees(self):
69 | # set capacity for test waiting flag
70 | tutorial = G(TutorialProposal, capacity='S')
71 | first_user = G(User, email='first@email.com')
72 | second_user = G(User, email='second@email.com')
73 | G(Registration, user=second_user, payment_status='paid')
74 | many_users = [G(User, email=str(x)+'@email.com') for x in range(9)]
75 | first_checkin = G(TutorialCheckin, tutorial=tutorial, user=first_user)
76 | second_checkin = G(TutorialCheckin, tutorial=tutorial, user=second_user)
77 | many_checkins = [G(TutorialCheckin, tutorial=tutorial, user=x) for x in
78 | many_users]
79 | response = self.client.get(reverse('tutorial', kwargs={'pk': tutorial.pk}))
80 | attendees = response.context['attendees']
81 | self.assertEqual(len(attendees), 11)
82 | # user email head?
83 | self.assertEqual(attendees[0]['name'], 'first')
84 | self.assertEqual(attendees[0]['registered'], False)
85 | self.assertEqual(attendees[1]['registered'], True)
86 | # waiting order by pk
87 | self.assertEqual(attendees[0]['waiting'], False)
88 | self.assertEqual(attendees[10]['waiting'], True)
89 |
--------------------------------------------------------------------------------
/pyconkr/translation.py:
--------------------------------------------------------------------------------
1 | from modeltranslation.translator import translator, TranslationOptions
2 | from django.contrib.flatpages.models import FlatPage
3 | from .models import (
4 | Room,
5 | ProgramCategory, ProgramTime,
6 | Sponsor, SponsorLevel,
7 | Speaker, Program,
8 | Announcement, Banner
9 | )
10 |
11 |
12 | class FlatPageTranslationOptions(TranslationOptions):
13 | fields = ('title', 'content',)
14 | translator.register(FlatPage, FlatPageTranslationOptions)
15 |
16 |
17 | class RoomTranslationOptions(TranslationOptions):
18 | fields = ('name', 'desc',)
19 | translator.register(Room, RoomTranslationOptions)
20 |
21 |
22 | class ProgramCategoryTranslationOptions(TranslationOptions):
23 | fields = ('name',)
24 | translator.register(ProgramCategory, ProgramCategoryTranslationOptions)
25 |
26 |
27 | class ProgramTimeTranslationOptions(TranslationOptions):
28 | fields = ('name',)
29 | translator.register(ProgramTime, ProgramTimeTranslationOptions)
30 |
31 |
32 | class SponsorTranslationOptions(TranslationOptions):
33 | fields = ('name', 'desc',)
34 | translator.register(Sponsor, SponsorTranslationOptions)
35 |
36 |
37 | class SponsorLevelTranslationOptions(TranslationOptions):
38 | fields = ('name', 'desc',)
39 | translator.register(SponsorLevel, SponsorLevelTranslationOptions)
40 |
41 |
42 | class SpeakerTranslationOptions(TranslationOptions):
43 | fields = ('name', 'desc',)
44 | translator.register(Speaker, SpeakerTranslationOptions)
45 |
46 |
47 | class ProgramTranslationOptions(TranslationOptions):
48 | fields = ('name', 'desc',)
49 | translator.register(Program, ProgramTranslationOptions)
50 |
51 |
52 | class AnnouncementTranslationOptions(TranslationOptions):
53 | fields = ('title', 'desc',)
54 | translator.register(Announcement, AnnouncementTranslationOptions)
55 |
56 |
57 | class BannerTranslationOptions(TranslationOptions):
58 | fields = ('desc',)
59 | translator.register(Banner, BannerTranslationOptions)
60 |
--------------------------------------------------------------------------------
/pyconkr/urls.py:
--------------------------------------------------------------------------------
1 | from django.conf import settings
2 | from django.conf.urls import include, url
3 | from django.conf.urls.i18n import i18n_patterns
4 | from django.conf.urls.static import static
5 | from django.contrib.flatpages import views
6 | from django.contrib.staticfiles.urls import staticfiles_urlpatterns
7 | from django.contrib.auth.decorators import login_required
8 | from django.views.generic.base import TemplateView
9 | from pyconkr.views import TutorialProposalCreate, TutorialProposalDetail, \
10 | TutorialProposalUpdate, TutorialProposalList, SprintProposalList, tutorial_join,\
11 | SprintProposalCreate, SprintProposalDetail, sprint_join, SprintProposalUpdate
12 |
13 | from .views import index, schedule, robots, youngcoder, child_care
14 | from .views import RoomDetail
15 | from .views import AnnouncementList, AnnouncementDetail
16 | from .views import SpeakerList, SpeakerDetail, SpeakerUpdate
17 | from .views import SponsorList, SponsorDetail, PatronList
18 | from .views import ProgramList, ProgramDetail, ProgramUpdate, PreferenceList
19 | from .views import ProposalCreate, ProposalUpdate, ProposalDetail
20 | from .views import ProfileDetail, ProfileUpdate
21 | from .views import login, login_req, login_mailsent, logout
22 |
23 | from django.contrib import admin
24 | admin.autodiscover()
25 |
26 | urlpatterns = [
27 | url(r'^robots.txt$', robots, name='robots'),
28 | url(r'^summernote/', include('django_summernote.urls')),
29 | url(r'^admin/', include(admin.site.urls)),
30 |
31 | url(r'^accounts/', include('allauth.urls')),
32 | url(r'^i18n/', include('django.conf.urls.i18n')),
33 | ]
34 |
35 | urlpatterns += i18n_patterns(
36 | url(r'^$', index, name='index'),
37 | url(r'^room/(?P\d+)$',
38 | RoomDetail.as_view(), name='room'),
39 |
40 | url(r'^about/announcements/$',
41 | AnnouncementList.as_view(), name='announcements'),
42 | url(r'^about/announcement/(?P\d+)$',
43 | AnnouncementDetail.as_view(), name='announcement'),
44 | url(r'^about/sponsor/$',
45 | SponsorList.as_view(), name='sponsors'),
46 | url(r'^about/patron/$',
47 | PatronList.as_view(), name='patrons'),
48 | url(r'^about/sponsor/(?P[\w|-]+)$',
49 | SponsorDetail.as_view(), name='sponsor'),
50 |
51 | url(r'^programs?/list/$',
52 | ProgramList.as_view(), name='programs'),
53 | url(r'^programs?/preference/$',
54 | login_required(PreferenceList.as_view()), name='program_preference'),
55 | url(r'^program/(?P\d+)$',
56 | ProgramDetail.as_view(), name='program'),
57 | url(r'^program/(?P\d+)/edit$',
58 | ProgramUpdate.as_view(), name='program_edit'),
59 | url(r'^programs?/speakers?/$',
60 | SpeakerList.as_view(), name='speakers'),
61 | url(r'^programs?/speakers?/(?P\w+)$',
62 | SpeakerDetail.as_view(), name='speaker'),
63 | url(r'^programs?/speakers?/(?P\w+)/edit$',
64 | SpeakerUpdate.as_view(), name='speaker_edit'),
65 | url(r'^programs?/schedule/$',
66 | schedule, name='schedule'),
67 | url(r'^programs?/youngcoder/$',
68 | youngcoder, name='youngcoder'),
69 | url(r'^programs?/child_care/$',
70 | child_care, name='child_care'),
71 | url(r'^programs?/tutorial/$',
72 | TutorialProposalList.as_view(), name='tutorial'),
73 | url(r'^programs?/sprint/$',
74 | SprintProposalList.as_view(), name='sprint'),
75 | url(r'^programs?/tutorial/(?P\d+)$',
76 | TutorialProposalDetail.as_view(), name='tutorial'),
77 | url(r'^programs?/tutorial/(?P\d+)/join/$',
78 | login_required(tutorial_join), name='tutorial-join'),
79 | url(r'^programs?/sprint/(?P\d+)$',
80 | SprintProposalDetail.as_view(), name='sprint'),
81 | url(r'^programs?/sprint/(?P\d+)/join/$',
82 | login_required(sprint_join), name='sprint-join'),
83 |
84 | url(r'^cfp/propose/$',
85 | login_required(ProposalCreate.as_view()), name='propose'),
86 | url(r'^cfp/tutorial-propose/$',
87 | login_required(TutorialProposalCreate.as_view()), name='tutorial-propose'),
88 | url(r'^profile/proposal/$',
89 | login_required(ProposalDetail.as_view()), name='proposal'),
90 | url(r'^cfp/sprint-propose/$',
91 | login_required(SprintProposalCreate.as_view()), name='sprint-propose'),
92 |
93 | url(r'^profile/proposal/edit$',
94 | login_required(ProposalUpdate.as_view()), name='proposal-update'),
95 | url(r'^profile/tutorial-proposal/edit$',
96 | login_required(TutorialProposalUpdate.as_view()), name='tutorial-proposal-update'),
97 | url(r'^profile/sprint-proposal/edit$',
98 | login_required(SprintProposalUpdate.as_view()), name='sprint-proposal-update'),
99 | url(r'^profile$',
100 | login_required(ProfileDetail.as_view()), name='profile'),
101 | url(r'^profile/edit$',
102 | login_required(ProfileUpdate.as_view()), name='profile_edit'),
103 |
104 | url(r'^login/$', login, name='login'),
105 | url(r'^login/req/(?P[a-z0-9\-]+)$', login_req, name='login_req'),
106 | url(r'^login/mailsent/$', login_mailsent, name='login_mailsent'),
107 | url(r'^logout/$', logout, name='logout'),
108 |
109 | url(r'^registration/', include('registration.urls')),
110 |
111 | # for rosetta
112 | url(r'^rosetta/', include('rosetta.urls')),
113 |
114 | # for flatpages
115 | url(r'^pages/', include('django.contrib.flatpages.urls')),
116 | url(r'^(?P.*/)$', views.flatpage, name='flatpage'),
117 |
118 | prefix_default_language=False
119 | )
120 |
121 | # for development
122 | if settings.DEBUG:
123 | urlpatterns += staticfiles_urlpatterns()
124 | urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
125 |
--------------------------------------------------------------------------------
/pyconkr/wsgi.py:
--------------------------------------------------------------------------------
1 | """
2 | WSGI config for pyconkr project.
3 |
4 | It exposes the WSGI callable as a module-level variable named ``application``.
5 |
6 | For more information on this file, see
7 | https://docs.djangoproject.com/en/1.9/howto/deployment/wsgi/
8 | """
9 |
10 | import os
11 |
12 | from django.core.wsgi import get_wsgi_application
13 |
14 | os.environ.setdefault("DJANGO_SETTINGS_MODULE", "pyconkr.settings")
15 |
16 | application = get_wsgi_application()
17 |
--------------------------------------------------------------------------------
/registration/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonkr/pyconkr-2018/d2fe3b41d487875a6616319adddf8ee3d28dc7a2/registration/__init__.py
--------------------------------------------------------------------------------
/registration/apps.py:
--------------------------------------------------------------------------------
1 | from __future__ import unicode_literals
2 |
3 | from django.apps import AppConfig
4 |
5 |
6 | class RegistrationConfig(AppConfig):
7 | name = 'registration'
8 |
--------------------------------------------------------------------------------
/registration/forms.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | from crispy_forms.helper import FormHelper
3 | from crispy_forms.layout import Submit
4 | from django import forms
5 | from django.utils.translation import ugettext_lazy as _
6 |
7 | from .models import Registration, ManualPayment
8 |
9 |
10 | class RegistrationForm(forms.ModelForm):
11 | base_price = forms.IntegerField(label=_('Base Price KRW'))
12 |
13 | def __init__(self, *args, **kwargs):
14 | super(RegistrationForm, self).__init__(*args, **kwargs)
15 | self.fields['email'].widget.attrs['readonly'] = True
16 | self.fields['base_price'].widget.attrs['readonly'] = True
17 | self.fields['option'].widget.attrs['disabled'] = True
18 | self.helper = FormHelper()
19 | self.helper.form_id = 'registration-form'
20 | self.helper.form_method = 'post'
21 | self.helper.add_input(Submit('submit', _('Submit'), disabled='disabled'))
22 |
23 | class Meta:
24 | model = Registration
25 | fields = ('email', 'option', 'base_price', 'name', 'top_size', 'company', 'phone_number', 'payment_method')
26 | labels = {
27 | 'name': _('Name'),
28 | 'option': _('Option'),
29 | 'top_size': _('Top Size'),
30 | 'email': _('E-Mail'),
31 | 'company': _('Company or Organization'),
32 | 'phone_number': _('Phone Number'),
33 | 'payment_method': _('Payment Method'),
34 | }
35 |
36 |
37 | class RegistrationFormWithoutTopSize(RegistrationForm):
38 | def __init__(self, *args, **kwargs):
39 | super(RegistrationFormWithoutTopSize, self).__init__(*args, **kwargs)
40 | self.fields.pop('top_size')
41 |
42 |
43 | class RegistrationAdditionalPriceForm(RegistrationForm):
44 | additional_price = forms.IntegerField(min_value=0)
45 |
46 | class Meta:
47 | model = Registration
48 | fields = ('email', 'option', 'base_price', 'additional_price', 'name', 'top_size', 'company', 'phone_number',
49 | 'payment_method')
50 | labels = {
51 | 'name': _('Name'),
52 | 'option': _('Option'),
53 | 'top_size': _('Top Size'),
54 | 'additional_price': _('Additional Funding KRW'),
55 | 'email': _('E-Mail'),
56 | 'company': _('Company or Organization'),
57 | 'phone_number': _('Phone Number'),
58 | 'payment_method': _('Payment Method')
59 | }
60 |
61 |
62 | class ManualPaymentForm(forms.ModelForm):
63 | email = forms.EmailField()
64 | base_price = forms.IntegerField(label=_('Base Price KRW'))
65 |
66 | def __init__(self, *args, **kwargs):
67 | super(ManualPaymentForm, self).__init__(*args, **kwargs)
68 | self.fields['title'].widget.attrs['readonly'] = True
69 | self.fields['email'].widget.attrs['readonly'] = True
70 | self.fields['base_price'].widget.attrs['readonly'] = True
71 | self.fields['payment_method'].widget.attrs['readonly'] = True
72 | self.helper = FormHelper()
73 | self.helper.form_id = 'manual-payment-form'
74 | self.helper.form_method = 'post'
75 | self.helper.add_input(Submit('submit', _('Submit'), disabled='disabled'))
76 |
77 | class Meta:
78 | model = ManualPayment
79 | fields = ('title', 'email', 'base_price', 'payment_method')
80 | labels = {
81 | 'title': _('Title'),
82 | 'email': _('Email'),
83 | 'payment_method': _('Payment Method'),
84 | }
85 |
86 |
87 | class IssueSubmitForm(forms.Form):
88 | user_id = forms.IntegerField()
89 |
--------------------------------------------------------------------------------
/registration/iamporter/__init__.py:
--------------------------------------------------------------------------------
1 | from .iamporter import Iamporter, IamporterError, get_access_token
2 |
--------------------------------------------------------------------------------
/registration/iamporter/iamporter.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | import requests
3 | import datetime
4 |
5 |
6 | class IamporterError(Exception):
7 | def __init__(self, code=None, message=None):
8 | self.code = code
9 | self.message = message
10 | return super(IamporterError, self).__init__('{code}: {message}'.format(code=code, message=message))
11 |
12 | def get_access_token(api_key, api_secret):
13 | url = 'https://api.iamport.kr/users/getToken'
14 | response = requests.post(url, data=dict(
15 | imp_key=api_key,
16 | imp_secret=api_secret,
17 | ))
18 |
19 | if response.status_code != 200:
20 | raise IamporterError(response.status_code, response.content)
21 |
22 | # TODO : validate expire time
23 | result = response.json()
24 |
25 | if result['code'] is not 0:
26 | raise IamporterError(result['code'], result['message'])
27 |
28 | return result['response']['access_token']
29 |
30 |
31 | class Iamporter(object):
32 | TOKEN_HEADER = 'X-ImpTokenHeader'
33 |
34 | def __init__(self, access_token):
35 | self._access_code = access_token
36 |
37 | def _set_default(self, data, headers):
38 | if not data:
39 | data = {}
40 |
41 | if not headers:
42 | headers = {}
43 | headers[self.TOKEN_HEADER] = self._access_code
44 |
45 | return data, headers
46 |
47 | def _parse_response(self, response):
48 | if response.status_code != 200 or not response.content:
49 | raise IamporterError(response.status_code, response.content)
50 |
51 | result = response.json()
52 |
53 | if result['code'] is not 0:
54 | raise IamporterError(result['code'], result['message'])
55 |
56 | return result['response']
57 |
58 | def _get(self, url, data=None, headers=None):
59 | data, headers = self._set_default(data, headers)
60 | response = requests.get(url, headers=headers, params=data)
61 |
62 | return self._parse_response(response)
63 |
64 | def _post(self, url, data=None, headers=None):
65 | data, headers = self._set_default(data, headers)
66 | response = requests.post(url, headers=headers, data=data)
67 |
68 | return self._parse_response(response)
69 |
70 | def onetime(self, **params):
71 | url = 'https://api.iamport.kr/subscribe/payments/onetime/'
72 | keys = ['token', 'merchant_uid', 'amount', 'vat', 'card_number', 'expiry', 'birth', 'pwd_2digit',
73 | 'name', 'remember_me', 'buyer_name', 'buyer_email', ]
74 | data = {k: v for k, v in params.items() if k in keys}
75 | return self._post(url, data)
76 |
77 | def foreign(self, **params):
78 | url = 'https://api.iamport.kr/subscribe/payments/foreign/'
79 | keys = ['token', 'merchant_uid', 'amount', 'vat', 'card_number', 'expiry',
80 | 'name', 'buyer_name', 'buyer_email', ]
81 | data = {k: v for k, v in params.items() if k in keys}
82 | return self._post(url, data)
83 |
84 | def cancel(self, **params):
85 | url = 'https://api.iamport.kr/payments/cancel/'
86 | keys = ['merchant_uid', 'reason', ]
87 | data = {k: v for k, v in params.items() if k in keys}
88 | return self._post(url, data)
89 |
90 | def find_by_merchant_uid(self, merchant_uid):
91 | url = 'https://api.iamport.kr/payments/find/{merchant_uid}'.format(merchant_uid=merchant_uid)
92 | return self._get(url)
93 |
94 | def get_paid_list(self, since, until=datetime.datetime.now()):
95 | url = 'https://api.iamport.kr/payments/status/{payment_status}'.format(payment_status='paid')
96 | since = int(since.strftime('%s'))
97 | until = int(until.strftime('%s'))
98 | data = {
99 | 'from': since,
100 | 'to': until,
101 | 'page': 1,
102 | }
103 | full_list = []
104 | while True:
105 | result = self._get(url, data)
106 | full_list.extend(result['list'])
107 | if result['next'] != 0:
108 | data['page'] += 1
109 | continue
110 | else:
111 | break
112 | return full_list
113 |
--------------------------------------------------------------------------------
/registration/locale/en/LC_MESSAGES/django.po:
--------------------------------------------------------------------------------
1 | # SOME DESCRIPTIVE TITLE.
2 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
3 | # This file is distributed under the same license as the PACKAGE package.
4 | # FIRST AUTHOR , YEAR.
5 | #
6 | #, fuzzy
7 | msgid ""
8 | msgstr ""
9 | "Project-Id-Version: PACKAGE VERSION\n"
10 | "Report-Msgid-Bugs-To: \n"
11 | "POT-Creation-Date: 2018-08-09 17:29+0900\n"
12 | "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
13 | "Last-Translator: FULL NAME \n"
14 | "Language-Team: LANGUAGE \n"
15 | "Language: \n"
16 | "MIME-Version: 1.0\n"
17 | "Content-Type: text/plain; charset=UTF-8\n"
18 | "Content-Transfer-Encoding: 8bit\n"
19 |
20 | #: registration/forms.py:11 registration/forms.py:64
21 | msgid "Base Price KRW"
22 | msgstr ""
23 |
24 | #: registration/forms.py:21 registration/forms.py:75
25 | msgid "Submit"
26 | msgstr ""
27 |
28 | #: registration/forms.py:27 registration/forms.py:51
29 | #: registration/templates/registration/status.html:16
30 | #: registration/templates/registration/status.html:90
31 | msgid "Name"
32 | msgstr ""
33 |
34 | #: registration/forms.py:28 registration/forms.py:52
35 | #: registration/templates/registration/status.html:49
36 | msgid "Option"
37 | msgstr ""
38 |
39 | #: registration/forms.py:29 registration/forms.py:53
40 | #: registration/templates/registration/status.html:27
41 | #: registration/templates/registration/status.html:32
42 | msgid "Top Size"
43 | msgstr ""
44 |
45 | #: registration/forms.py:30 registration/forms.py:55
46 | msgid "E-Mail"
47 | msgstr ""
48 |
49 | #: registration/forms.py:31 registration/forms.py:56
50 | #: registration/templates/registration/status.html:41
51 | msgid "Company or Organization"
52 | msgstr ""
53 |
54 | #: registration/forms.py:32 registration/forms.py:57
55 | msgid "Phone Number"
56 | msgstr ""
57 |
58 | #: registration/forms.py:33 registration/forms.py:58 registration/forms.py:83
59 | msgid "Payment Method"
60 | msgstr ""
61 |
62 | #: registration/forms.py:54
63 | msgid "Additional Funding KRW"
64 | msgstr ""
65 |
66 | #: registration/forms.py:81
67 | msgid "Title"
68 | msgstr ""
69 |
70 | #: registration/forms.py:82
71 | msgid "Email"
72 | msgstr ""
73 |
74 | #: registration/models.py:137
75 | msgid "Credit Card only for Korean"
76 | msgstr ""
77 |
78 | #: registration/models.py:138
79 | msgid "Credit Card for Foreign"
80 | msgstr ""
81 |
82 | #: registration/templates/registration/manual_payment.html:6
83 | msgid "Manual Payment"
84 | msgstr ""
85 |
86 | #: registration/templates/registration/payment.html:28
87 | #: registration/templates/registration/status.html:143
88 | #: registration/views.py:110 registration/views.py:359
89 | msgid "Registration"
90 | msgstr ""
91 |
92 | #: registration/templates/registration/registration_detail.html:14
93 | msgid "PyCon Korea 2018"
94 | msgstr ""
95 |
96 | #: registration/templates/registration/status.html:7
97 | msgid "Registration status"
98 | msgstr ""
99 |
100 | #: registration/templates/registration/status.html:9
101 | msgid "Registration is completed"
102 | msgstr ""
103 |
104 | #: registration/templates/registration/status.html:11
105 | msgid "Your registration is completed without any problems"
106 | msgstr ""
107 |
108 | #: registration/templates/registration/status.html:20
109 | #: registration/templates/registration/status.html:94
110 | msgid "E-mail"
111 | msgstr ""
112 |
113 | #: registration/templates/registration/status.html:45
114 | msgid "Phone number"
115 | msgstr ""
116 |
117 | #: registration/templates/registration/status.html:53
118 | #: registration/templates/registration/status.html:98
119 | msgid "Price"
120 | msgstr ""
121 |
122 | #: registration/templates/registration/status.html:58
123 | #: registration/templates/registration/status.html:103
124 | msgid "Additional Funding"
125 | msgstr ""
126 |
127 | #: registration/templates/registration/status.html:63
128 | #: registration/templates/registration/status.html:108
129 | msgid "Transaction ID"
130 | msgstr ""
131 |
132 | #: registration/templates/registration/status.html:67
133 | msgid "Registration datetime"
134 | msgstr ""
135 |
136 | #: registration/templates/registration/status.html:71
137 | msgid "Cancelable Date"
138 | msgstr ""
139 |
140 | #: registration/templates/registration/status.html:83
141 | msgid "Check Registration Receipt"
142 | msgstr ""
143 |
144 | #: registration/templates/registration/status.html:87
145 | msgid "Payment Information"
146 | msgstr ""
147 |
148 | #: registration/templates/registration/status.html:112
149 | msgid "Bank to transfer"
150 | msgstr ""
151 |
152 | #: registration/templates/registration/status.html:116
153 | msgid "Account number to transafer"
154 | msgstr ""
155 |
156 | #: registration/templates/registration/status.html:120
157 | msgid "Account owner name"
158 | msgstr ""
159 |
160 | #: registration/templates/registration/status.html:124
161 | msgid "Payment deadline"
162 | msgstr ""
163 |
164 | #: registration/templates/registration/status.html:128
165 | msgid "Payment check"
166 | msgstr ""
167 |
168 | #: registration/templates/registration/status.html:131
169 | msgid "Not checked yet"
170 | msgstr ""
171 |
172 | #: registration/templates/registration/status.html:133
173 | msgid "Payment checked"
174 | msgstr ""
175 |
176 | #: registration/templates/registration/status.html:140
177 | msgid "There is no registration record"
178 | msgstr ""
179 |
180 | #: registration/views.py:55
181 | msgid "Registration Status"
182 | msgstr ""
183 |
184 | #: registration/views.py:450
185 | msgid "Registration Receipt"
186 | msgstr ""
187 |
188 | #: registration/views.py:469
189 | msgid "Issue Ticket System"
190 | msgstr ""
191 |
192 | #: registration/views.py:486
193 | msgid "Ticket Print"
194 | msgstr ""
195 |
--------------------------------------------------------------------------------
/registration/management/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonkr/pyconkr-2018/d2fe3b41d487875a6616319adddf8ee3d28dc7a2/registration/management/__init__.py
--------------------------------------------------------------------------------
/registration/management/commands/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonkr/pyconkr-2018/d2fe3b41d487875a6616319adddf8ee3d28dc7a2/registration/management/commands/__init__.py
--------------------------------------------------------------------------------
/registration/management/commands/calculation_attendee.py:
--------------------------------------------------------------------------------
1 | from datetime import datetime
2 |
3 | from django.core.management.base import BaseCommand
4 |
5 | from registration.models import IssueTicket, Registration
6 |
7 |
8 | class Command(BaseCommand):
9 | help = 'Calculating attendee count per Option'
10 |
11 | def handle(self, *args, **options):
12 | all_tickets = IssueTicket.objects.all()
13 | categorized_tickets = {}
14 |
15 | for ticket in all_tickets:
16 | if ticket.registration.option.name in categorized_tickets:
17 | if ticket.registration not in categorized_tickets[ticket.registration.option.name]:
18 | categorized_tickets[ticket.registration.option.name].append(ticket.registration)
19 | else:
20 | categorized_tickets[ticket.registration.option.name] = [ticket.registration]
21 |
22 | all_registration = Registration.objects.all()
23 |
24 | print(datetime.now())
25 |
26 | for key in categorized_tickets.keys():
27 | print('{} - {}/{}'.format(key, len(categorized_tickets[key]),
28 | all_registration.filter(option__name=key).count()))
29 |
--------------------------------------------------------------------------------
/registration/management/commands/delete_login_token.py:
--------------------------------------------------------------------------------
1 | from datetime import datetime, timedelta
2 |
3 | from django.core.management.base import BaseCommand
4 |
5 | from pyconkr.models import EmailToken
6 |
7 |
8 | class Command(BaseCommand):
9 | help = 'Delete token 10 mins past'
10 |
11 | def handle(self, *args, **options):
12 | filtering_time = datetime.now() - timedelta(minutes=10)
13 | all_email_token = EmailToken.objects.filter(created__lt=filtering_time).all()
14 | all_email_token.delete()
15 |
--------------------------------------------------------------------------------
/registration/management/commands/payment_reconciliation.py:
--------------------------------------------------------------------------------
1 | import datetime
2 | from django.core.management.base import BaseCommand, CommandError
3 | from registration.models import Registration, Option
4 | from registration.iamporter import Iamporter, get_access_token
5 | from constance import config
6 |
7 | class Command(BaseCommand):
8 | help = 'Cross check paid and registration consistency'
9 |
10 | def handle(self, *args, **options):
11 | eary_bird = Option.objects.get(name='Early Bird')
12 | paid_registrations = \
13 | Registration.objects.filter(payment_status='paid').exclude(payment_method='bank', option=eary_bird).values_list('merchant_uid',
14 | 'email')
15 | paid_registrations = dict(list(paid_registrations))
16 | access_token = get_access_token(config.IMP_API_KEY, config.IMP_API_SECRET)
17 | imp_client = Iamporter(access_token)
18 | # Use hard coded date only for pycon 2016.
19 | paid_pg = imp_client.get_paid_list(since=datetime.datetime(2017, 1, 1))
20 | paid_pg = map(lambda x: (x['merchant_uid'], x['buyer_email']), paid_pg)
21 | paid_pg = dict(paid_pg)
22 | print('registered but not paid')
23 | for registration in paid_registrations:
24 | if registration not in paid_pg:
25 | print(registration)
26 | print(paid_registrations[registration])
27 | print('paid but not registered')
28 | for pg in paid_pg:
29 | if pg not in paid_registrations:
30 | print(pg)
31 | print(paid_pg[pg])
32 |
--------------------------------------------------------------------------------
/registration/migrations/0001_initial.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # Generated by Django 1.9.4 on 2016-03-23 12:29
3 | from __future__ import unicode_literals
4 |
5 | from django.conf import settings
6 | from django.db import migrations, models
7 | import django.db.models.deletion
8 |
9 |
10 | class Migration(migrations.Migration):
11 |
12 | initial = True
13 |
14 | dependencies = [
15 | migrations.swappable_dependency(settings.AUTH_USER_MODEL),
16 | ]
17 |
18 | operations = [
19 | migrations.CreateModel(
20 | name='Option',
21 | fields=[
22 | ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
23 | ('name', models.CharField(max_length=50)),
24 | ('description', models.TextField()),
25 | ('is_active', models.BooleanField(default=False)),
26 | ('price', models.IntegerField()),
27 | ],
28 | ),
29 | migrations.CreateModel(
30 | name='Registration',
31 | fields=[
32 | ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
33 | ('merchant_uid', models.CharField(max_length=32)),
34 | ('name', models.CharField(max_length=100)),
35 | ('email', models.EmailField(max_length=255)),
36 | ('company', models.CharField(blank=True, max_length=100)),
37 | ('phone_number', models.CharField(max_length=20)),
38 | ('transaction_code', models.CharField(max_length=36)),
39 | ('payment_method', models.CharField(choices=[('card', '\uc2e0\uc6a9\uce74\ub4dc')], default='card', max_length=20)),
40 | ('payment_status', models.CharField(max_length=10)),
41 | ('payment_message', models.CharField(max_length=255, null=True)),
42 | ('vbank_num', models.CharField(blank=True, max_length=255, null=True)),
43 | ('vbank_name', models.CharField(blank=True, max_length=20, null=True)),
44 | ('vbank_date', models.CharField(blank=True, max_length=50, null=True)),
45 | ('vbank_holder', models.CharField(blank=True, max_length=20, null=True)),
46 | ('created', models.DateTimeField(auto_now_add=True)),
47 | ('modified', models.DateTimeField(auto_now=True)),
48 | ('option', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='registration.Option')),
49 | ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
50 | ],
51 | ),
52 | ]
53 |
--------------------------------------------------------------------------------
/registration/migrations/0002_auto_20160323_1428.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # Generated by Django 1.9.4 on 2016-03-23 14:28
3 | from __future__ import unicode_literals
4 |
5 | from django.db import migrations, models
6 | import django.db.models.deletion
7 |
8 |
9 | class Migration(migrations.Migration):
10 |
11 | dependencies = [
12 | ('registration', '0001_initial'),
13 | ]
14 |
15 | operations = [
16 | migrations.AlterField(
17 | model_name='registration',
18 | name='option',
19 | field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='registration.Option'),
20 | ),
21 | ]
22 |
--------------------------------------------------------------------------------
/registration/migrations/0003_option_has_additional_price.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # Generated by Django 1.9.4 on 2016-03-31 14:51
3 | from __future__ import unicode_literals
4 |
5 | from django.db import migrations, models
6 |
7 |
8 | class Migration(migrations.Migration):
9 |
10 | dependencies = [
11 | ('registration', '0002_auto_20160323_1428'),
12 | ]
13 |
14 | operations = [
15 | migrations.AddField(
16 | model_name='option',
17 | name='has_additional_price',
18 | field=models.BooleanField(default=False),
19 | ),
20 | ]
21 |
--------------------------------------------------------------------------------
/registration/migrations/0004_registration_additional_price.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # Generated by Django 1.9.4 on 2016-04-04 12:56
3 | from __future__ import unicode_literals
4 |
5 | from django.db import migrations, models
6 |
7 |
8 | class Migration(migrations.Migration):
9 |
10 | dependencies = [
11 | ('registration', '0003_option_has_additional_price'),
12 | ]
13 |
14 | operations = [
15 | migrations.AddField(
16 | model_name='registration',
17 | name='additional_price',
18 | field=models.IntegerField(default=0),
19 | ),
20 | ]
21 |
--------------------------------------------------------------------------------
/registration/migrations/0005_option_total.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # Generated by Django 1.9.4 on 2016-04-12 18:27
3 | from __future__ import unicode_literals
4 |
5 | from django.db import migrations, models
6 |
7 |
8 | class Migration(migrations.Migration):
9 |
10 | dependencies = [
11 | ('registration', '0004_registration_additional_price'),
12 | ]
13 |
14 | operations = [
15 | migrations.AddField(
16 | model_name='option',
17 | name='total',
18 | field=models.IntegerField(default=500),
19 | ),
20 | ]
21 |
--------------------------------------------------------------------------------
/registration/migrations/0006_auto_20160416_1202.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # Generated by Django 1.9.2 on 2016-04-16 03:02
3 | from __future__ import unicode_literals
4 |
5 | from django.db import migrations, models
6 |
7 |
8 | class Migration(migrations.Migration):
9 |
10 | dependencies = [
11 | ('registration', '0005_option_total'),
12 | ]
13 |
14 | operations = [
15 | migrations.AddField(
16 | model_name='registration',
17 | name='canceled',
18 | field=models.DateTimeField(blank=True, null=True),
19 | ),
20 | migrations.AddField(
21 | model_name='registration',
22 | name='confirmed',
23 | field=models.DateTimeField(blank=True, null=True),
24 | ),
25 | migrations.AlterField(
26 | model_name='registration',
27 | name='payment_method',
28 | field=models.CharField(choices=[('card', 'Credit Card'), ('bank', 'Bank Transfer')], default='card', max_length=20),
29 | ),
30 | ]
31 |
--------------------------------------------------------------------------------
/registration/migrations/0007_auto_20160416_1217.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # Generated by Django 1.9.2 on 2016-04-16 03:17
3 | from __future__ import unicode_literals
4 |
5 | from django.db import migrations, models
6 |
7 |
8 | class Migration(migrations.Migration):
9 |
10 | dependencies = [
11 | ('registration', '0006_auto_20160416_1202'),
12 | ]
13 |
14 | operations = [
15 | migrations.AlterField(
16 | model_name='registration',
17 | name='payment_message',
18 | field=models.CharField(blank=True, max_length=255, null=True),
19 | ),
20 | ]
21 |
--------------------------------------------------------------------------------
/registration/migrations/0008_auto_20160418_2250.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # Generated by Django 1.9.4 on 2016-04-18 13:50
3 | from __future__ import unicode_literals
4 |
5 | from django.db import migrations, models
6 |
7 |
8 | class Migration(migrations.Migration):
9 |
10 | dependencies = [
11 | ('registration', '0007_auto_20160416_1217'),
12 | ]
13 |
14 | operations = [
15 | migrations.AlterField(
16 | model_name='registration',
17 | name='payment_status',
18 | field=models.CharField(choices=[('ready', 'Ready'), ('paid', 'Paid'), ('deleted', 'Deleted')], default='ready', max_length=10),
19 | ),
20 | migrations.AlterField(
21 | model_name='registration',
22 | name='transaction_code',
23 | field=models.CharField(blank=True, max_length=36),
24 | ),
25 | ]
26 |
--------------------------------------------------------------------------------
/registration/migrations/0009_auto_20160501_2332.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # Generated by Django 1.9.4 on 2016-05-01 14:32
3 | from __future__ import unicode_literals
4 |
5 | from django.db import migrations, models
6 |
7 |
8 | class Migration(migrations.Migration):
9 |
10 | dependencies = [
11 | ('registration', '0008_auto_20160418_2250'),
12 | ]
13 |
14 | operations = [
15 | migrations.AlterField(
16 | model_name='registration',
17 | name='payment_status',
18 | field=models.CharField(choices=[('ready', 'Ready'), ('paid', 'Paid'), ('deleted', 'Deleted'), ('cancelled', 'Cancelled')], default='ready', max_length=10),
19 | ),
20 | ]
21 |
--------------------------------------------------------------------------------
/registration/migrations/0010_auto_20170428_0007.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # Generated by Django 1.11 on 2017-04-27 15:07
3 | from __future__ import unicode_literals
4 |
5 | from django.db import migrations, models
6 |
7 |
8 | class Migration(migrations.Migration):
9 |
10 | dependencies = [
11 | ('registration', '0009_auto_20160501_2332'),
12 | ]
13 |
14 | operations = [
15 | migrations.AlterField(
16 | model_name='registration',
17 | name='payment_method',
18 | field=models.CharField(choices=[('card', 'Credit Card'), ('bank', 'Bank Transfer'), ('vbank', 'Virtual Bank Transfer')], default='card', max_length=20),
19 | ),
20 | ]
21 |
--------------------------------------------------------------------------------
/registration/migrations/0011_auto_20170515_2228.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # Generated by Django 1.11.1 on 2017-05-15 13:28
3 | from __future__ import unicode_literals
4 |
5 | from django.db import migrations, models
6 |
7 |
8 | class Migration(migrations.Migration):
9 |
10 | dependencies = [
11 | ('registration', '0010_auto_20170428_0007'),
12 | ]
13 |
14 | operations = [
15 | migrations.AlterField(
16 | model_name='registration',
17 | name='payment_method',
18 | field=models.CharField(choices=[('card', 'Credit Card'), ('vbank', 'Virtual Bank Transfer')], default='card', max_length=20),
19 | ),
20 | ]
21 |
--------------------------------------------------------------------------------
/registration/migrations/0012_registration_top_size.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # Generated by Django 1.11.2 on 2017-06-12 09:33
3 | from __future__ import unicode_literals
4 |
5 | from django.db import migrations, models
6 |
7 |
8 | class Migration(migrations.Migration):
9 |
10 | dependencies = [
11 | ('registration', '0011_auto_20170515_2228'),
12 | ]
13 |
14 | operations = [
15 | migrations.AddField(
16 | model_name='registration',
17 | name='top_size',
18 | field=models.CharField(choices=[('small', 'S(85)'), ('medium', 'M(90)'), ('large', 'L(95)'), ('xlarge', 'XL(100)'), ('2xlarge', '2XL(105)'), ('3xlarge', '3XL(110)'), ('4xlarge', '3XL(115)')], default='L', max_length=20),
19 | ),
20 | ]
21 |
--------------------------------------------------------------------------------
/registration/migrations/0013_auto_20170616_1446.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # Generated by Django 1.11.2 on 2017-06-16 05:46
3 | from __future__ import unicode_literals
4 |
5 | from django.db import migrations, models
6 |
7 |
8 | class Migration(migrations.Migration):
9 |
10 | dependencies = [
11 | ('registration', '0012_registration_top_size'),
12 | ]
13 |
14 | operations = [
15 | migrations.AlterField(
16 | model_name='registration',
17 | name='top_size',
18 | field=models.CharField(choices=[('small', 'S(85)'), ('medium', 'M(90)'), ('large', 'L(95)'), ('xlarge', 'XL(100)'), ('2xlarge', '2XL(105)'), ('3xlarge', '3XL(110)'), ('4xlarge', '3XL(115)')], max_length=20, null=True),
19 | ),
20 | ]
21 |
--------------------------------------------------------------------------------
/registration/migrations/0014_auto_20170619_1138.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # Generated by Django 1.11.2 on 2017-06-19 02:38
3 | from __future__ import unicode_literals
4 |
5 | from django.db import migrations, models
6 |
7 |
8 | class Migration(migrations.Migration):
9 |
10 | dependencies = [
11 | ('registration', '0013_auto_20170616_1446'),
12 | ]
13 |
14 | operations = [
15 | migrations.AlterField(
16 | model_name='registration',
17 | name='top_size',
18 | field=models.CharField(choices=[('small', 'S(85)'), ('medium', 'M(90)'), ('large', 'L(95)'), ('xlarge', 'XL(100)'), ('2xlarge', '2XL(105)'), ('3xlarge', '3XL(110)'), ('4xlarge', '3XL(115)')], default=None, max_length=20, null=True),
19 | ),
20 | ]
21 |
--------------------------------------------------------------------------------
/registration/migrations/0015_auto_20170619_1151.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # Generated by Django 1.11.2 on 2017-06-19 02:51
3 | from __future__ import unicode_literals
4 |
5 | from django.db import migrations, models
6 |
7 |
8 | class Migration(migrations.Migration):
9 |
10 | dependencies = [
11 | ('registration', '0014_auto_20170619_1138'),
12 | ]
13 |
14 | operations = [
15 | migrations.AlterField(
16 | model_name='registration',
17 | name='top_size',
18 | field=models.CharField(choices=[('small', 'S(85)'), ('medium', 'M(90)'), ('large', 'L(95)'), ('xlarge', 'XL(100)'), ('2xlarge', '2XL(105)'), ('3xlarge', '3XL(110)'), ('4xlarge', '3XL(115)')], default='', max_length=20, null=True),
19 | ),
20 | ]
21 |
--------------------------------------------------------------------------------
/registration/migrations/0016_auto_20170619_1155.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # Generated by Django 1.11.2 on 2017-06-19 02:55
3 | from __future__ import unicode_literals
4 |
5 | from django.db import migrations, models
6 |
7 |
8 | class Migration(migrations.Migration):
9 |
10 | dependencies = [
11 | ('registration', '0015_auto_20170619_1151'),
12 | ]
13 |
14 | operations = [
15 | migrations.AlterField(
16 | model_name='registration',
17 | name='top_size',
18 | field=models.CharField(choices=[('small', 'S(85)'), ('medium', 'M(90)'), ('large', 'L(95)'), ('xlarge', 'XL(100)'), ('2xlarge', '2XL(105)'), ('3xlarge', '3XL(110)'), ('4xlarge', '3XL(115)')], default='', max_length=20),
19 | ),
20 | ]
21 |
--------------------------------------------------------------------------------
/registration/migrations/0017_auto_20170619_1458.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # Generated by Django 1.11.2 on 2017-06-19 05:58
3 | from __future__ import unicode_literals
4 |
5 | from django.db import migrations, models
6 |
7 |
8 | class Migration(migrations.Migration):
9 |
10 | dependencies = [
11 | ('registration', '0016_auto_20170619_1155'),
12 | ]
13 |
14 | operations = [
15 | migrations.AlterField(
16 | model_name='registration',
17 | name='top_size',
18 | field=models.CharField(choices=[('small', 'S(85)'), ('medium', 'M(90)'), ('large', 'L(95)'), ('xlarge', 'XL(100)'), ('2xlarge', '2XL(105)'), ('3xlarge', '3XL(110)'), ('4xlarge', '3XL(115)')], default=None, max_length=20, null=True),
19 | ),
20 | ]
21 |
--------------------------------------------------------------------------------
/registration/migrations/0018_auto_20170619_1514.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # Generated by Django 1.11 on 2017-06-19 06:14
3 | from __future__ import unicode_literals
4 |
5 | from django.db import migrations, models
6 |
7 |
8 | class Migration(migrations.Migration):
9 |
10 | dependencies = [
11 | ('registration', '0017_auto_20170619_1458'),
12 | ]
13 |
14 | operations = [
15 | migrations.AlterField(
16 | model_name='registration',
17 | name='top_size',
18 | field=models.CharField(blank=True, choices=[('small', 'S(85)'), ('medium', 'M(90)'), ('large', 'L(95)'), ('xlarge', 'XL(100)'), ('2xlarge', '2XL(105)'), ('3xlarge', '3XL(110)'), ('4xlarge', '3XL(115)')], default=None, max_length=20, null=True),
19 | ),
20 | ]
21 |
--------------------------------------------------------------------------------
/registration/migrations/0019_auto_20170630_1534.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # Generated by Django 1.11 on 2017-06-30 06:34
3 | from __future__ import unicode_literals
4 |
5 | from django.db import migrations, models
6 |
7 |
8 | class Migration(migrations.Migration):
9 |
10 | dependencies = [
11 | ('registration', '0018_auto_20170619_1514'),
12 | ]
13 |
14 | operations = [
15 | migrations.AlterField(
16 | model_name='registration',
17 | name='top_size',
18 | field=models.CharField(blank=True, choices=[('small', 'S(85)'), ('medium', 'M(90)'), ('large', 'L(95)'), ('xlarge', 'XL(100)'), ('2xlarge', '2XL(105)'), ('3xlarge', '3XL(110)'), ('4xlarge', '4XL(115)')], default=None, max_length=20, null=True),
19 | ),
20 | ]
21 |
--------------------------------------------------------------------------------
/registration/migrations/0020_auto_20170701_1757.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # Generated by Django 1.11.1 on 2017-07-01 08:57
3 | from __future__ import unicode_literals
4 |
5 | from django.db import migrations
6 |
7 |
8 | class Migration(migrations.Migration):
9 |
10 | dependencies = [
11 | ('registration', '0019_auto_20170630_1534'),
12 | ]
13 |
14 | operations = [
15 | migrations.AlterModelOptions(
16 | name='option',
17 | options={'ordering': ['price']},
18 | ),
19 | ]
20 |
--------------------------------------------------------------------------------
/registration/migrations/0021_auto_20170713_1341.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # Generated by Django 1.11.1 on 2017-07-13 04:41
3 | from __future__ import unicode_literals
4 |
5 | from django.db import migrations, models
6 |
7 |
8 | class Migration(migrations.Migration):
9 |
10 | dependencies = [
11 | ('registration', '0020_auto_20170701_1757'),
12 | ]
13 |
14 | operations = [
15 | migrations.AddField(
16 | model_name='option',
17 | name='cancelable_date',
18 | field=models.DateTimeField(null=True),
19 | ),
20 | migrations.AddField(
21 | model_name='option',
22 | name='is_cancelable',
23 | field=models.BooleanField(default=False),
24 | ),
25 | ]
26 |
--------------------------------------------------------------------------------
/registration/migrations/0022_manualpayment.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # Generated by Django 1.11.3 on 2017-07-15 04:51
3 | from __future__ import unicode_literals
4 |
5 | from django.conf import settings
6 | from django.db import migrations, models
7 | import django.db.models.deletion
8 |
9 |
10 | class Migration(migrations.Migration):
11 |
12 | dependencies = [
13 | migrations.swappable_dependency(settings.AUTH_USER_MODEL),
14 | ('registration', '0021_auto_20170713_1341'),
15 | ]
16 |
17 | operations = [
18 | migrations.CreateModel(
19 | name='ManualPayment',
20 | fields=[
21 | ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
22 | ('title', models.CharField(max_length=100)),
23 | ('price', models.PositiveIntegerField()),
24 | ('merchant_uid', models.CharField(blank=True, db_index=True, max_length=32)),
25 | ('imp_uid', models.CharField(blank=True, max_length=32, null=True)),
26 | ('transaction_code', models.CharField(blank=True, max_length=36)),
27 | ('payment_method', models.CharField(choices=[('card', 'Credit Card')], default='card', max_length=20)),
28 | ('payment_status', models.CharField(choices=[('ready', 'Ready'), ('paid', 'Paid'), ('cancelled', 'Cancelled')], default='ready', max_length=10)),
29 | ('payment_message', models.CharField(blank=True, max_length=255, null=True)),
30 | ('description', models.TextField(blank=True)),
31 | ('created', models.DateTimeField(auto_now_add=True)),
32 | ('modified', models.DateTimeField(auto_now=True)),
33 | ('confirmed', models.DateTimeField(blank=True, null=True)),
34 | ('canceled', models.DateTimeField(blank=True, null=True)),
35 | ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
36 | ],
37 | ),
38 | ]
39 |
--------------------------------------------------------------------------------
/registration/migrations/0023_issue_manager.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # Generated by Django 1.11 on 2017-08-01 11:33
3 | from __future__ import unicode_literals
4 |
5 | from django.conf import settings
6 | from django.db import migrations, models
7 | import django.db.models.deletion
8 | import django.utils.timezone
9 |
10 |
11 | class Migration(migrations.Migration):
12 |
13 | dependencies = [
14 | migrations.swappable_dependency(settings.AUTH_USER_MODEL),
15 | ('registration', '0022_manualpayment'),
16 | ]
17 |
18 | operations = [
19 | migrations.CreateModel(
20 | name='IssueTicket',
21 | fields=[
22 | ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
23 | ('issue_date', models.DateTimeField(default=django.utils.timezone.now)),
24 | ('issuer', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
25 | ('registration', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='registration.Registration')),
26 | ],
27 | ),
28 | ]
29 |
--------------------------------------------------------------------------------
/registration/migrations/0024_add_extra_fields_option.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # Generated by Django 1.11.11 on 2018-05-17 19:00
3 | from __future__ import unicode_literals
4 |
5 | from django.db import migrations, models
6 |
7 |
8 | class Migration(migrations.Migration):
9 |
10 | dependencies = [
11 | ('registration', '0023_issue_manager'),
12 | ]
13 |
14 | operations = [
15 | migrations.AddField(
16 | model_name='option',
17 | name='begin_at',
18 | field=models.DateTimeField(null=True),
19 | ),
20 | migrations.AddField(
21 | model_name='option',
22 | name='closed_at',
23 | field=models.DateTimeField(null=True),
24 | ),
25 | migrations.AddField(
26 | model_name='option',
27 | name='conference_type',
28 | field=models.CharField(blank=True, choices=[('earlybird', '얼리버드'), ('regular', '일반'), ('company', '법인'), ('patron', '개인후원')], max_length=15, null=True),
29 | ),
30 | migrations.AddField(
31 | model_name='option',
32 | name='event_type',
33 | field=models.CharField(choices=[('conference', '컨퍼런스'), ('tuturial', '튜토리얼'), ('young', '영코더'), ('babycare', '아이돌봄')], default='conference', max_length=15),
34 | ),
35 | migrations.AlterField(
36 | model_name='option',
37 | name='price',
38 | field=models.PositiveIntegerField(),
39 | ),
40 | migrations.AlterUniqueTogether(
41 | name='option',
42 | unique_together=set([('event_type', 'conference_type')]),
43 | ),
44 | ]
45 |
--------------------------------------------------------------------------------
/registration/migrations/0025_auto_20180601_0214.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # Generated by Django 1.11.13 on 2018-05-31 17:14
3 | from __future__ import unicode_literals
4 |
5 | from django.db import migrations, models
6 |
7 |
8 | class Migration(migrations.Migration):
9 |
10 | dependencies = [
11 | ('registration', '0024_add_extra_fields_option'),
12 | ]
13 |
14 | operations = [
15 | migrations.AlterField(
16 | model_name='registration',
17 | name='payment_method',
18 | field=models.CharField(choices=[('card-korean', 'Credit Card only for Korean'), ('card-foreign', 'Credit Card for Foreign'), ('vbank', 'Virtual Bank Transfer')], default='card-korean', max_length=20),
19 | ),
20 | ]
21 |
--------------------------------------------------------------------------------
/registration/migrations/0026_auto_20180607_1241.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # Generated by Django 1.11.13 on 2018-06-07 03:41
3 | from __future__ import unicode_literals
4 |
5 | from django.db import migrations, models
6 |
7 |
8 | class Migration(migrations.Migration):
9 |
10 | dependencies = [
11 | ('registration', '0025_auto_20180601_0214'),
12 | ]
13 |
14 | operations = [
15 | migrations.AlterField(
16 | model_name='registration',
17 | name='additional_price',
18 | field=models.PositiveIntegerField(default=0),
19 | ),
20 | ]
21 |
--------------------------------------------------------------------------------
/registration/migrations/0027_auto_20180708_2058.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # Generated by Django 1.11.13 on 2018-07-08 11:58
3 | from __future__ import unicode_literals
4 |
5 | from django.db import migrations
6 |
7 |
8 | class Migration(migrations.Migration):
9 |
10 | dependencies = [
11 | ('registration', '0026_auto_20180607_1241'),
12 | ]
13 |
14 | operations = [
15 | migrations.AlterUniqueTogether(
16 | name='option',
17 | unique_together=set([]),
18 | ),
19 | ]
20 |
--------------------------------------------------------------------------------
/registration/migrations/0027_auto_20180715_2205.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # Generated by Django 1.11.11 on 2018-07-15 13:05
3 | from __future__ import unicode_literals
4 |
5 | from django.db import migrations, models
6 |
7 |
8 | class Migration(migrations.Migration):
9 |
10 | dependencies = [
11 | ('registration', '0026_auto_20180607_1241'),
12 | ]
13 |
14 | operations = [
15 | migrations.AlterField(
16 | model_name='option',
17 | name='event_type',
18 | field=models.CharField(choices=[('conference', '컨퍼런스'), ('tutorial', '튜토리얼'), ('young', '영코더'), ('babycare', '아이돌봄')], default='conference', max_length=15),
19 | ),
20 | ]
21 |
--------------------------------------------------------------------------------
/registration/migrations/0028_merge_20180723_2159.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # Generated by Django 1.11.13 on 2018-07-23 12:59
3 | from __future__ import unicode_literals
4 |
5 | from django.db import migrations
6 |
7 |
8 | class Migration(migrations.Migration):
9 |
10 | dependencies = [
11 | ('registration', '0027_auto_20180715_2205'),
12 | ('registration', '0027_auto_20180708_2058'),
13 | ]
14 |
15 | operations = [
16 | ]
17 |
--------------------------------------------------------------------------------
/registration/migrations/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonkr/pyconkr-2018/d2fe3b41d487875a6616319adddf8ee3d28dc7a2/registration/migrations/__init__.py
--------------------------------------------------------------------------------
/registration/static/js/payment.js:
--------------------------------------------------------------------------------
1 | // TODO : i18n
2 | var payment = {
3 | config: {},
4 | setConfig: function (config) {
5 | this.config = config;
6 | },
7 | handleResponse: function (response) {
8 | var payment = this;
9 | var $additionalPrice = $('#id_additional_price');
10 |
11 | response['csrfmiddlewaretoken'] = payment.config.csrf_token;
12 | response['name'] = $('#id_name').val();
13 | response['email'] = $('#id_email').val();
14 | response['base_price'] = parseInt(this.config.amount);
15 | response['additional_price'] = parseInt($additionalPrice.val()) ? parseInt($additionalPrice.val()) : 0;
16 | response['company'] = $('#id_company').val();
17 | response['top_size'] = $('#id_top_size').val();
18 | response['phone_number'] = $('#id_phone_number').val();
19 | response['payment_method'] = $('#id_payment_method').val();
20 | response['option'] = $('#id_option').val();
21 |
22 | $.ajax({
23 | method: 'POST',
24 | url: payment.config.payment_url,
25 | data: response,
26 | dataType: 'json'
27 | }).done(function (result) {
28 | if (!result.success) {
29 | alert('결제에 실패했습니다. ' + result.code + ' ' + result.message);
30 | window.location.reload();
31 | return;
32 | }
33 | alert('결제가 완료되었습니다.');
34 | window.location.href = payment.config.status_url;
35 | }.bind(this)).fail(function (xhr, status, error) {
36 | alert('결제에 실패했습니다. 다시 시도해 주세요.' + error);
37 | window.location.reload();
38 | }.bind(this));
39 | },
40 | iamportCard: function (initCode, uid, amount) {
41 | var payment = this;
42 |
43 | IMP.SBCR.init(initCode);
44 | IMP.SBCR.onetime({
45 | merchant_uid: uid,
46 | amount: amount,
47 | vat: 0
48 | }, function (response) {
49 | if (!response.token) {
50 | alert(response.message);
51 | return false;
52 | }
53 | payment.handleResponse(response);
54 | }.bind(this));
55 | },
56 | init: function (config) {
57 | this.setConfig(config);
58 | var payment = this;
59 |
60 | $('#submit-id-submit').attr('disabled', false);
61 | $('#registration-form').submit(function (e) {
62 | e.preventDefault();
63 | var $additionalPrice = $('#id_additional_price');
64 | var additionalPrice = parseInt($additionalPrice.val()) ? parseInt($additionalPrice.val()) : 0;
65 | var paymentMethod = $('#id_payment_method').val();
66 | var totalPrice = parseInt(payment.config.amount) + additionalPrice;
67 |
68 | if (paymentMethod === 'card-korean') {
69 | payment.iamportCard(payment.config.IMP_DOM_USER_CODE, payment.config.uid, totalPrice);
70 | } else if (paymentMethod === 'card-foreign') {
71 | payment.iamportCard(payment.config.IMP_INTL_USER_CODE, payment.config.uid, totalPrice);
72 | } else if (paymentMethod === 'vbank') {
73 | IMP.init(payment.config.IMP_DOM_USER_CODE);
74 | IMP.request_pay({
75 | pg: 'nice',
76 | pay_method: 'vbank',
77 | merchant_uid: payment.config.uid,
78 | name: $('#id_option').val(),
79 | amount: totalPrice,
80 | buyer_email: $('#id_email').val(),
81 | buyer_name: $('#id_name').val(),
82 | buyer_tel: $('#id_phone_number').val(),
83 | buyer_addr: '',
84 | buyer_postcode: ''
85 | }, function (rsp) {
86 | if (rsp.success) {
87 | payment.handleResponse(rsp);
88 | } else {
89 | var msg = '결제에 실패하였습니다.';
90 | msg += '에러내용 : ' + rsp.error_msg;
91 | alert(msg);
92 | }
93 | });
94 | } else {
95 | // ?????
96 | }
97 | });
98 | }
99 | };
100 |
--------------------------------------------------------------------------------
/registration/static/stamp.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonkr/pyconkr-2018/d2fe3b41d487875a6616319adddf8ee3d28dc7a2/registration/static/stamp.jpg
--------------------------------------------------------------------------------
/registration/templates/registration/cancellation_result.html:
--------------------------------------------------------------------------------
1 | {% extends "admin/base_site.html" %}
2 | {% load i18n l10n %}
3 | {% load admin_urls %}
4 |
5 | {% block content %}
6 |
7 |
8 |
9 | ID
10 | 이름
11 | 이메일
12 | 옵션
13 | Merchant UID
14 | 취소 여부
15 | 비고
16 |
17 |
18 |
19 | {% for obj in results %}
20 |
21 | {{ obj.id }}
22 | {{ obj.name }}
23 | {{ obj.email }}
24 | {{ obj.option }}
25 | {{ obj.merchant_uid }}
26 | {{ obj.cancel_status }}
27 | {{ obj.cancel_reason }}
28 |
29 | {% endfor %}
30 |
31 |
32 |
33 | Back to list
34 |
35 | {% endblock %}
36 |
--------------------------------------------------------------------------------
/registration/templates/registration/certificates.html:
--------------------------------------------------------------------------------
1 | {% load staticfiles %}
2 |
3 |
4 |
29 |
30 |
31 |
32 |
참석 확인증 (Confirmation of the attendance)
33 |
34 |
35 |
36 | 성 명 (Name) : {{ registration.name }}
37 | 소 속 (Organization) : {{ registration.company }}
38 |
39 |
40 |
41 |
42 | 위 사람은 파이콘 한국에서 주최하는 파이콘 한국 2018에 참가하였음을 확인합니다.
43 | This is to certify that the above-mentioned person has visited the conference for 2 days at PyCon Korea 2018
44 |
45 |
46 |
47 |
48 | 1. 일시 (Date) : 2018년 8월 18일, 19일 (August 18th and 19th, 2018)
49 |
50 | 2. 장소 (Venue) : 서울특별시 강남구 영동대로 513 코엑스 (COEX, Yeongdong-daero 513, Gangnam-gu, Seoul)
51 |
52 | 3. 주최 (Hosted by) : 파이콘 한국 준비위원회 (PyCon Korea Organizing Team)
53 |
54 |
55 |
56 |
{{ year }}. {{ month }}. {{ day }}
57 |
58 |
59 | 사단법인 파이썬사용자모임 대표 배권한 (Kwon-Han Bae, President of Python User Group)
61 |
62 |
63 |
64 |
65 |
66 |
67 |
--------------------------------------------------------------------------------
/registration/templates/registration/certificates_not_registered.html:
--------------------------------------------------------------------------------
1 | {% load staticfiles %}
2 |
3 |
4 |
7 |
8 |
9 |
10 |
파이콘 한국 2018에 등록하지 않았습니다. (Not Registered)
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/registration/templates/registration/certificates_not_visited.html:
--------------------------------------------------------------------------------
1 | {% load staticfiles %}
2 |
3 |
4 |
7 |
8 |
9 |
10 |
파이콘 한국 2018에 참석하지 않았습니다. (Not Visited)
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/registration/templates/registration/certificates_sprint.html:
--------------------------------------------------------------------------------
1 | {% load staticfiles %}
2 |
3 |
4 |
29 |
30 |
31 |
32 |
참석 확인증 (Confirmation of the attendance)
33 |
34 |
35 |
36 | 성 명 (Name) : {{ user.profile.name }}
37 | 소 속 (Organization) : {{ user.profile.organization }}
38 |
39 |
40 |
41 |
42 | 위 사람은 파이콘 한국에서 주최하는 파이콘 한국 2018 스프린트 프로그램에 참가하였음을 확인합니다.
43 | This is to certify that the above-mentioned person has visited the Sprint program at PyCon Korea 2018
44 |
45 |
46 |
47 |
48 | 1. 일시 (Date) : 2018년 8월 15일, 17일 (August 15th and 17th, 2018)
49 |
50 | 2. 장소 (Venue) : 서울특별시 강남구 영동대로 513 코엑스 (COEX, Yeongdong-daero 513, Gangnam-gu, Seoul)
51 |
52 | 3. 주최 (Hosted by) : 파이콘 한국 준비위원회 (PyCon Korea Organizing Team)
53 |
54 |
55 |
56 |
{{ year }}. {{ month }}. {{ day }}
57 |
58 |
59 | 사단법인 파이썬사용자모임 대표 배권한 (Kwon-Han Bae, President of Python User Group)
61 |
62 |
63 |
64 |
65 |
66 |
67 |
--------------------------------------------------------------------------------
/registration/templates/registration/certificates_sprint_not_registered.html:
--------------------------------------------------------------------------------
1 | {% load staticfiles %}
2 |
3 |
4 |
7 |
8 |
9 |
10 |
파이콘 한국 2018 스프린트 프로그램에 등록하지 않았습니다. (Not Registered)
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/registration/templates/registration/certificates_tutorial.html:
--------------------------------------------------------------------------------
1 | {% load staticfiles %}
2 |
3 |
4 |
29 |
30 |
31 |
32 |
참석 확인증 (Confirmation of the attendance)
33 |
34 |
35 |
36 | 성 명 (Name) : {{ registration.name }}
37 | 소 속 (Organization) : {{ registration.company }}
38 |
39 |
40 |
41 |
42 | 위 사람은 파이콘 한국에서 주최하는 파이콘 한국 2018 튜토리얼 프로그램에 참가하였음을 확인합니다.
43 | This is to certify that the above-mentioned person has visited the Tutorial program at PyCon Korea 2018
44 |
45 |
46 |
47 |
48 | 1. 일시 (Date) : 2018년 8월 15일 (August 15th, 2018)
49 |
50 | 2. 장소 (Venue) : 서울특별시 강남구 영동대로 513 코엑스 (COEX, Yeongdong-daero 513, Gangnam-gu, Seoul)
51 |
52 | 3. 주최 (Hosted by) : 파이콘 한국 준비위원회 (PyCon Korea Organizing Team)
53 |
54 |
55 |
56 |
{{ year }}. {{ month }}. {{ day }}
57 |
58 |
59 | 사단법인 파이썬사용자모임 대표 배권한 (Kwon-Han Bae, President of Python User Group)
61 |
62 |
63 |
64 |
65 |
66 |
67 |
--------------------------------------------------------------------------------
/registration/templates/registration/certificates_tutorial_not_registered.html:
--------------------------------------------------------------------------------
1 | {% load staticfiles %}
2 |
3 |
4 |
7 |
8 |
9 |
10 |
파이콘 한국 2018 튜토리얼 프로그램에 등록하지 않았습니다. (Not Registered)
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/registration/templates/registration/certificates_tutorial_not_visited.html:
--------------------------------------------------------------------------------
1 | {% load staticfiles %}
2 |
3 |
4 |
7 |
8 |
9 |
10 |
파이콘 한국 2018 튜토리얼 프로그램에 참석하지 않았습니다. (Not Visited)
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/registration/templates/registration/checkin_list.html:
--------------------------------------------------------------------------------
1 | {% extends "base.html" %}
2 | {% load i18n humanize %}
3 |
4 | {% block head-include %}
5 |
6 |
7 |
8 |
13 | {% endblock %}
14 |
15 | {% block content %}
16 |
17 | 스프린트명 : {{ sprint.title }}
18 |
19 |
20 |
21 |
22 |
23 |
24 | email
25 | name
26 | created_at
27 |
28 |
29 |
30 | {% for checkin in checkins %}
31 |
32 | {{ checkin.user.email }}
33 | {{ checkin.user.profile.name }}
34 | {{ checkin.created }}
35 |
36 | {% endfor %}
37 |
38 |
39 |
40 | {% endblock %}
41 |
--------------------------------------------------------------------------------
/registration/templates/registration/info.html:
--------------------------------------------------------------------------------
1 | {% extends "base.html" %}
2 | {% load i18n humanize %}
3 |
4 | {% block content %}
5 |
6 | {% if is_registered %}
7 |
8 |
이미 등록되었습니다.
9 |
10 | 등록 확인하기
11 |
12 |
13 | {% else %}
14 | {% if not options %}
15 |
등록 기간이 아닙니다
16 | {% else %}
17 |
18 | {% for option in options %}
19 |
20 |
{{ option.name }}
21 |
{% autoescape off %}{{ option.description }}{% endautoescape %}
22 |
Price: {{ option.price|intcomma }} KRW
23 |
Cancelable Date :
24 | {% if option.is_cancelable %}
25 | {{ option.cancelable_date|date:"Y년 M d일 D a g시까지"}}
26 | {% else %}
27 | 환불 불가(Not Refundable)
28 | {% endif %}
29 |
30 |
31 | {% if option.is_sold_out %}
32 |
33 | {{ option.name }}-SOLD OUT
34 |
35 | {% elif option.is_opened %}
36 |
37 | {{ option.name }}
38 |
39 | {% else %}
40 |
41 | {{ option.begin_at|date:"Y년 M d일 D a g" }}시 오픈 예정
42 |
43 | {% endif %}
44 |
45 |
46 | {% endfor %}
47 |
48 | {% endif %}
49 | {% endif %}
50 |
51 | {% endblock %}
52 |
--------------------------------------------------------------------------------
/registration/templates/registration/issue_print.html:
--------------------------------------------------------------------------------
1 | {% load staticfiles %}
2 |
3 |
4 |
78 |
79 |
80 |
81 |
82 | 현재 발권횟수: {{ registration.issueticket_set.count }}
83 |
84 |
85 |
86 | 결제시 이름: {{ registration.name }}
87 | 프로필 이름: {{ registration.user.profile.name }}
88 |
89 |
90 |
발권
91 |
92 |
93 |
94 |
{{ name }}
95 |
{{ company }}
96 |
97 | {% if additional_ticket is not None %}
98 |
99 | {% if additional_ticket.patron %}
100 |
개인후원 기념품을 수령해가세요.
101 | {% endif %}
102 | {% if additional_ticket.speaker %}
103 |
발표자 기념품을 수령해가세요.
104 | {% endif %}
105 | {% if additional_ticket.baby_care %}
106 |
아이돌봄 명찰을 수령해주세요.
107 | {% endif %}
108 | {% if additional_ticket.young_coder %}
109 |
영코더 추가 등록 절차를 진행해주세요.
110 | {% endif %}
111 |
112 | {% endif %}
113 |
114 |
115 |
116 |
117 |
155 |
156 |
157 |
--------------------------------------------------------------------------------
/registration/templates/registration/issue_ticket.html:
--------------------------------------------------------------------------------
1 | {% extends "base.html" %}
2 | {% load i18n humanize %}
3 | {% load staticfiles %}
4 | {% load crispy_forms_tags %}
5 |
6 | {% block content %}
7 |
8 |
9 |
10 | 이름
11 | 이메일
12 | 셔츠사이즈
13 | 관리
14 |
15 |
16 |
17 | {% for user in registration %}
18 |
19 | {{ user.name }}
20 | {{ user.email }}
21 | {{ user.top_size }}
22 |
23 |
31 |
32 |
33 | {% endfor %}
34 |
35 |
36 |
37 |
38 | {% endblock %}
39 |
40 | {% block head-include %}
41 |
42 | {% endblock %}
43 |
44 | {% block script %}
45 |
46 |
47 |
48 |
60 |
61 | {% endblock %}
62 |
--------------------------------------------------------------------------------
/registration/templates/registration/manual_payment.html:
--------------------------------------------------------------------------------
1 | {% extends "base.html" %}
2 | {% load i18n %}
3 | {% load crispy_forms_tags %}
4 |
5 | {% block content %}
6 | {% trans 'Manual Payment' %}
7 |
8 |
{% crispy form %}
9 |
10 | {% endblock %}
11 |
12 | {% block head-include %}
13 |
14 |
15 |
68 | {% endblock %}
69 |
--------------------------------------------------------------------------------
/registration/templates/registration/payment.html:
--------------------------------------------------------------------------------
1 | {% extends "base.html" %}
2 | {% load staticfiles %}
3 | {% load i18n %}
4 | {% load crispy_forms_tags %}
5 |
6 | {% block head-include %}
7 |
8 |
9 |
10 |
25 | {% endblock %}
26 |
27 | {% block content %}
28 | {% trans 'Registration' %}
29 |
30 |
결제를 완료하시면 신청이 됩니다. (* ) 는 필수 입력 항목입니다.
31 |
{% crispy form %}
32 |
33 | {% endblock %}
34 |
--------------------------------------------------------------------------------
/registration/templates/registration/payment_babycare.html:
--------------------------------------------------------------------------------
1 | {% extends "base.html" %}
2 | {% load staticfiles %}
3 | {% load i18n %}
4 | {% load crispy_forms_tags %}
5 |
6 | {% block head-include %}
7 |
8 |
9 |
10 |
25 | {% endblock %}
26 |
27 | {% block content %}
28 | 아이돌봄 신청
29 |
30 | {% if sold_out %}
31 |
아이돌봄 프로그램이 모두 판매되었습니다.
32 | {% else %}
33 | {% if has_conference_ticket %}
34 |
아래의 모든 항목을 채워주세요. 구글 설문을 응해주시지 않으면 참여가 어려울 수 있습니다.
35 |
36 |
40 |
41 |
아래의 폼 입력 후 결제를 완료하시면 신청이 됩니다. (* ) 는 필수 입력 항목입니다.
42 |
{% crispy form %}
43 |
44 | {% else %}
45 |
아이돌봄은 파이콘 한국 2018 컨퍼런스 티켓 구매자에 한해 구매가 가능합니다.
46 | {% endif %}
47 | {% endif %}
48 |
49 | {% endblock %}
50 |
51 |
--------------------------------------------------------------------------------
/registration/templates/registration/payment_youngcoder.html:
--------------------------------------------------------------------------------
1 | {% extends "base.html" %}
2 | {% load staticfiles %}
3 | {% load i18n %}
4 | {% load crispy_forms_tags %}
5 |
6 | {% block head-include %}
7 |
8 |
9 |
10 |
25 | {% endblock %}
26 |
27 | {% block content %}
28 | 영코더 신청
29 |
30 | {% if sold_out %}
31 |
영코더 프로그램이 모두 판매되었습니다.
32 | {% else %}
33 |
아래의 모든 항목을 채워주세요. 구글 설문을 응해주시지 않으면 참여가 어려울 수 있습니다.
34 |
35 | {% if option_id == 17 %}
36 |
40 | {% else %}
41 |
42 |
46 | {% endif %}
47 |
48 |
아래의 폼 입력 후 결제를 완료하시면 신청이 됩니다. (* ) 는 필수 입력 항목입니다.
49 |
{% crispy form %}
50 |
51 | {% endif %}
52 |
53 | {% endblock %}
54 |
55 |
--------------------------------------------------------------------------------
/registration/templates/registration/registration_detail.html:
--------------------------------------------------------------------------------
1 | {% extends "base.html" %}
2 | {% load i18n humanize %}
3 | {% load thumbnail %}
4 | {% load crispy_forms_tags %}
5 | {% load staticfiles %}
6 |
7 | {% block content %}
8 |
9 |
10 |
11 | Name {{ registration.name }}
12 |
13 |
14 | Ticket Type {% trans "PyCon Korea 2018" %} - {{ registration.option.name }}
15 |
16 |
17 | Price {{ registration.option.price|add:registration.additional_price|intcomma }}
18 |
19 |
20 | Provider Python Korea Inc.Chair man. Kwon-Han, Bae
21 |
22 |
23 |
24 |
25 | Provider Company Number 338-82-00046
26 |
27 |
28 |
29 | {% endblock %}
30 |
31 |
--------------------------------------------------------------------------------
/registration/templates/registration/registration_list.html:
--------------------------------------------------------------------------------
1 | {% extends "base.html" %}
2 | {% load i18n humanize %}
3 |
4 | {% block head-include %}
5 |
6 |
7 |
8 |
13 | {% endblock %}
14 |
15 | {% block content %}
16 |
17 | 티켓 타입 : {{ option.event_type }}
18 | 티켓 옵션 : {{ option.name }}
19 | 티켓 가격 : {{ option.price }}
20 |
21 |
22 |
23 |
24 |
25 |
26 | email
27 | name
28 | created_at
29 |
30 |
31 |
32 | {% for regi in registrations %}
33 |
34 | {{ regi.email }}
35 | {{ regi.name }}
36 | {{ regi.created }}
37 |
38 | {% endfor %}
39 |
40 |
41 |
42 | {% endblock %}
43 |
--------------------------------------------------------------------------------
/registration/templates/registration/sprint_checkin.html:
--------------------------------------------------------------------------------
1 | {% extends "base.html" %}
2 | {% load i18n humanize %}
3 | {% load staticfiles %}
4 | {% load crispy_forms_tags %}
5 |
6 | {% block content %}
7 |
8 |
9 |
10 | 이름
11 | 이메일
12 | 관리
13 |
14 |
15 |
16 | {% for checkin in checkins %}
17 |
18 | {{ checkin.user.profile.name }}
19 | {{ checkin.user.email }}
20 |
21 |
29 |
30 |
31 | {% endfor %}
32 |
33 |
34 |
35 |
36 | {% endblock %}
37 |
38 | {% block head-include %}
39 |
40 | {% endblock %}
41 |
42 | {% block script %}
43 |
44 |
45 |
46 |
58 |
59 | {% endblock %}
60 |
--------------------------------------------------------------------------------
/registration/templates/registration/sprint_print.html:
--------------------------------------------------------------------------------
1 | {% load staticfiles %}
2 |
3 |
4 |
5 |
72 |
73 |
74 |
75 |
76 |
77 | 출력이름 이름: {{ name }}
78 | 출력이름 회사: {{ company }}
79 | 참여 스프린트: {{ sprint_title }}
80 |
81 |
82 |
발권
83 |
84 |
85 |
86 |
{{ name }}
87 |
{{ company }}
88 |
{{ sprint_title }}
89 |
90 |
91 |
92 |
93 |
101 |
102 |
103 |
--------------------------------------------------------------------------------
/registration/tests.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | import datetime
3 |
4 | from unittest import mock
5 | from django.test import TestCase
6 | from django.contrib.auth import get_user_model
7 | from django.contrib.auth.models import Group
8 | from django.core.urlresolvers import reverse
9 | from constance.test import override_config
10 | from django_dynamic_fixture import G
11 |
12 | from .models import Option, Registration, IssueTicket
13 |
14 | User = get_user_model()
15 |
16 |
17 | @override_config(REGISTRATION_OPEN=datetime.date.today()-datetime.timedelta(days=1), REGISTRATION_CLOSE=datetime.date.today()+datetime.timedelta(days=1))
18 | class RegistrationTest(TestCase):
19 | def test_patron_has_additional_price(self):
20 | option = Option.objects.create(name='patron', price=1000, has_additional_price=True, is_active=True)
21 | user = User.objects.create_user('testname', 'test@test.com', 'testpassword')
22 | self.client.login(username='testname', password='testpassword')
23 | response = self.client.get(reverse('registration_payment', args=[option.id]))
24 | self.assertIn('additional_price', response.context['form'].fields)
25 |
26 | def test_transaction_id_is_not_required(self):
27 | registration = G(Registration, transaction_code='')
28 | self.assertNotEqual(registration.id, None)
29 |
30 | @mock.patch('registration.views.get_access_token')
31 | @mock.patch('registration.views.Iamporter')
32 | def test_vbank_status_update_via_iamport_callback(self, Iamporter, get_access_token):
33 | get_access_token.return_value = 'test token'
34 | iamporter = Iamporter.return_value
35 | # make registration object for test
36 | registration = G(Registration, payment_method='vbank', payment_status='ready')
37 | iamporter.find_by_merchant_uid.return_value = dict(
38 | merchant_uid=registration.merchant_uid,
39 | status='paid' # yes i wanna make status to paid
40 | )
41 | # WOW it's so easy. I love ddf.
42 | # let's make a callback parameter
43 | callback_param = dict(
44 | merchant_uid=registration.merchant_uid,
45 | imp_uid='whatever... we dont care.',
46 | status='ready' # acctually i wanna make status to paid
47 | )
48 |
49 | response = self.client.post(reverse('registration_callback'), callback_param)
50 | self.assertEqual(response.status_code, 200)
51 | registration = Registration.objects.get(id=registration.id)
52 | self.assertEqual(registration.payment_status, 'paid')
53 |
54 |
55 | class IssueTicketTest(TestCase):
56 | def test_inner_group_only(self):
57 | response = self.client.get(reverse('registration_issue'))
58 | self.assertNotEqual(response.status_code, 200)
59 | login_user = User.objects.create_user('test@user.com', 'test@user.com',
60 | 'testpass')
61 | self.client.login(username='test@user.com', password='testpass')
62 | response = self.client.get(reverse('registration_issue'))
63 | self.assertNotEqual(response.status_code, 200)
64 | group = G(Group, name='volunteer')
65 | login_user.groups.add(group)
66 | response = self.client.get(reverse('registration_issue'))
67 | self.assertEqual(response.status_code, 200)
68 |
69 | def test_incr_issue_count(self):
70 | login_user = User.objects.create_user('test@user.com', 'test@user.com',
71 | 'testpass')
72 | G(Registration, payment_status='paid', user=login_user)
73 | group = G(Group, name='volunteer')
74 | login_user.groups.add(group)
75 | self.client.login(username='test@user.com', password='testpass')
76 | response = self.client.get(reverse('registration_issue_submit'))
77 | self.assertEqual(response.status_code, 405) # Because POST only
78 | response = self.client.post(reverse('registration_issue_submit'),
79 | {'user_id': login_user.id})
80 | issue_count = IssueTicket.objects.filter(registration__user=login_user).count()
81 | self.assertEqual(issue_count, 1)
82 |
--------------------------------------------------------------------------------
/registration/urls.py:
--------------------------------------------------------------------------------
1 | from django.conf.urls import url
2 | from django.contrib.auth.decorators import login_required
3 |
4 | from . import views
5 |
6 | urlpatterns = [
7 | url(r'^purchase/$', views.index, name='registration_index'),
8 | url(r'^status/(\d*)/$', views.status, name='registration_status'),
9 | url(r'^list/(\d*)/$', views.registrations, name='registration_list'),
10 | url(r'^checkins/(\d*)/$', views.checkins, name='registration_checkins'),
11 | url(r'^payment/(\d*)/$', views.payment, name='registration_payment'),
12 | url(r'^payment/$', views.payment_process, name='registration_payment'),
13 | url(r'^payment/callback/$', views.payment_callback, name='registration_callback'),
14 | url(r'^receipt/$',
15 | login_required(views.RegistrationReceiptDetail.as_view()), name='registration_receipt'),
16 | url(r'^payment/manual/(\d+)/$', views.manual_registration, name='manual_registration'),
17 | url(r'^payment/manual/payment/$', views.manual_payment_process, name='manual_payment'),
18 | url(r'^certificates/$', login_required(views.certificates), name='certificates'),
19 | url(r'^certificates_tutorial/$', login_required(views.certificates_tutorial), name='certificates_tutorial'),
20 | url(r'^certificates_sprint/$', login_required(views.certificates_sprint), name='certificates_sprint'),
21 | url(r'^issue/$', views.issue, name='registration_issue'),
22 | url(r'^issue/submit/$', views.issue_submit, name='registration_issue_submit'),
23 | url(r'^issue/print/(?P\d+)/$', views.issue_print, name='registration_issue_print'),
24 | url(r'^sprint/$', views.sprint, name='sprint_checkin'),
25 | url(r'^sprint/print/(?P\d+)/$', views.sprint_print, name='sprint_checkin_print'),
26 | ]
27 |
--------------------------------------------------------------------------------
/requirements-dev.txt:
--------------------------------------------------------------------------------
1 | -r requirements.txt
2 | sphinx
3 | pytest
4 | codecov
5 |
--------------------------------------------------------------------------------
/requirements-prod.txt:
--------------------------------------------------------------------------------
1 | -r requirements.txt
2 | uwsgi
3 | gevent
4 | psycopg2
5 | raven
6 |
--------------------------------------------------------------------------------
/requirements.txt:
--------------------------------------------------------------------------------
1 | appdirs==1.4.3
2 | defusedxml==0.5.0
3 | Django<1.12
4 | django-allauth==0.32.0
5 | django-constance==2.0.0
6 | django-crispy-forms==1.6.1
7 | django-csv-exports==1.0.3
8 | django-dynamic-fixture==1.9.5
9 | django-jsonfield==1.0.1
10 | django-modeltranslation==0.12.1
11 | django-picklefield==0.3.2
12 | django-rosetta==0.7.13
13 | django-summernote==0.8.7
14 | iamport-rest-client==0.7.0
15 | microsofttranslator==0.8
16 | oauthlib==2.0.2
17 | olefile==0.44
18 | packaging==16.8
19 | Pillow==4.1.0
20 | polib==1.0.8
21 | pyparsing==2.2.0
22 | python3-openid==3.1.0
23 | pytz==2017.2
24 | requests==2.13.0
25 | requests-oauthlib==0.8.0
26 | six==1.10.0
27 | sorl-thumbnail==12.3
28 |
--------------------------------------------------------------------------------