├── .github └── workflows │ └── ci_pipeline.yml ├── .gitignore ├── .mailmap ├── .python-version ├── .vscode └── launch.json ├── Dockerfile ├── LICENSE.bsd ├── Makefile ├── README.md ├── assets ├── css │ ├── Galyon-Bold.otf │ ├── Galyon-Italic.otf │ ├── Galyon-Regular.otf │ ├── bootstrap.min.css │ ├── bs-stepper.min.css │ ├── europython-bs-theme.css │ └── europython-customizations.css ├── img │ ├── ep2021-background-online.jpg │ ├── ep2021-favicon.png │ ├── ep2021-icon-logo-small.png │ ├── ep2021-icon-logo.png │ ├── ep2021-logo-white-1024px-alpha.png │ ├── ep2021-logo.png │ ├── ep2021-online-logo.png │ ├── ep2021-snake-wrangler.jpg │ ├── ep2021-social-online-card.jpg │ ├── ep2021-social-online-card.png │ ├── ep2021-white-logo-alpha.png │ ├── ep2022-background-ccd-original.jpg │ ├── ep2022-background-ccd.jpg │ ├── ep2022-conference-venue-from-above.jpg │ ├── ep2022-social-card.jpg │ ├── ep2022-social-card.png │ ├── epslogo.png │ ├── fitted-cut-size-guide.png │ └── straight-cut-size-guide.png └── js │ ├── bootstrap.min.js │ ├── bs-stepper.min.js │ ├── generate_toc_for_cms.js │ ├── jquery-3.2.1.slim.min.js │ ├── popper.min.js │ └── taggit_labels_customised_with_max_number_of_tags.js ├── assopy ├── __init__.py ├── admin.py ├── auth_backends.py ├── dataaccess.py ├── forms.py ├── management │ ├── __init__.py │ └── commands │ │ ├── __init__.py │ │ └── update_orders.py ├── migrations │ ├── 0001_initial.py │ ├── 0002_auto_20180408_2337.py │ ├── 0003_add_exrate_fields_to_invoice_model.py │ ├── 0004_add_order_payment_date.py │ ├── 0005_simplify_invoice_html_field_name.py │ ├── 0006_add_bank_to_payment_options.py │ ├── 0007_add_customer_to_invoice.py │ ├── 0008_remove_user_oauth_info_model.py │ ├── 0009_rename_assopy_user.py │ ├── 0010_add_uuid_to_Order.py │ ├── 0011_updated_vat_settings_for_swiss_vat.py │ ├── 0012_add_type_to_order.py │ ├── 0013_mystery_migrations_maybe_2_to_3_bytes_to_str.py │ ├── 0014_deprecate_paypal_20191124_2308.py │ ├── 0015_remove_refund_models.py │ ├── 0016_null_has_no_effect_on_vat_manytomay_relationship.py │ └── __init__.py ├── models.py ├── stats.py ├── templatetags │ ├── __init__.py │ └── assopy_tags.py ├── urls.py ├── utils.py └── views.py ├── cms_utils ├── __init__.py ├── cms_app.py ├── cms_plugins.py ├── migrations │ ├── 0001_initial.py │ ├── 0002_templatepluginmodel.py │ └── __init__.py ├── models.py ├── processors.py └── templates │ ├── djangocms_markitup │ └── markitup.html │ └── djangocms_template │ └── template_plugin.html ├── common ├── __init__.py ├── decorators.py ├── django_urls.py ├── http.py ├── jsonify.py └── tests │ ├── __init__.py │ └── test_jsonify.py ├── conference ├── __init__.py ├── accounts.py ├── admin.py ├── api.py ├── apps.py ├── cachef.py ├── cart.py ├── cfp.py ├── context_processors.py ├── currencies.py ├── dataaccess.py ├── debug_panel.py ├── decorators.py ├── fares.py ├── forms │ ├── __init__.py │ ├── auth.py │ ├── forms.py │ └── talks.py ├── gravatar.py ├── homepage.py ├── invoicing.py ├── listeners.py ├── management │ ├── __init__.py │ └── commands │ │ ├── __init__.py │ │ ├── add_invoices_for_zero_amount_orders.py │ │ ├── create_initial_data_for_dev.py │ │ ├── get_conference_speakers.py │ │ ├── make_speaker_profiles_public.py │ │ ├── pull_latest_exrates.py │ │ ├── ranking_of_talks.py │ │ └── upgrade_placeholder_invoices_for_2018.py ├── migrations │ ├── 0001_initial.py │ ├── 0002_talk_domain.py │ ├── 0003_add_domain_level_field.py │ ├── 0004_add_exchangerate_model.py │ ├── 0005_add_captcha_question.py │ ├── 0006_update_talk_model_fields.py │ ├── 0007_remove_special_place.py │ ├── 0008_add_news_model.py │ ├── 0009_add_field_created_by_and_modified_to_talk.py │ ├── 0010_add_gender_and_is_minor_fields.py │ ├── 0011_add_stripepayment_model.py │ ├── 0012_add_vototalk_timestamps.py │ ├── 0013_add_stripe_charge_id.py │ ├── 0014_stripe_charge_default_uuid.py │ ├── 0015_add_talk_url_fields.py │ ├── 0016_mystery_migrations_maybe_2_to_3_bytes_to_str.py │ ├── 0017_retire_more_unused_models.py │ ├── 0018_remove_unused_models.py │ ├── 0019_add_stripe_session_id.py │ ├── 0020_make_gender_field_required.py │ ├── 0021_alter_add_deletion_PROTECT.py │ ├── 0022_alter_sponsorincome_tags.py │ ├── 0023_update_field_descriptions.py │ ├── 0024_add_talk_status_declined.py │ ├── 0025_add_poster_45_type.py │ ├── 0026_auto_20201204_1130.py │ ├── 0027_auto_20201204_1539.py │ ├── 0028_changes_to_conferencetag_and_conferencetaggeditem.py │ ├── 0029_talk_availability.py │ ├── 0030_add_streamset.py │ ├── 0031_update_streamset_help_text.py │ └── __init__.py ├── models.py ├── news.py ├── orders.py ├── payments.py ├── profiles.py ├── schedule.py ├── social_card.py ├── static │ └── conference │ │ ├── images │ │ └── 500.jpg │ │ ├── init.js │ │ ├── jquery-flot │ │ ├── .gitignore │ │ ├── .travis.yml │ │ ├── API.md │ │ ├── CONTRIBUTING.md │ │ ├── FAQ.md │ │ ├── LICENSE.txt │ │ ├── Makefile │ │ ├── NEWS.md │ │ ├── PLUGINS.md │ │ ├── README.md │ │ ├── component.json │ │ ├── examples │ │ │ ├── ajax │ │ │ │ ├── data-eu-gdp-growth-1.json │ │ │ │ ├── data-eu-gdp-growth-2.json │ │ │ │ ├── data-eu-gdp-growth-3.json │ │ │ │ ├── data-eu-gdp-growth-4.json │ │ │ │ ├── data-eu-gdp-growth-5.json │ │ │ │ ├── data-eu-gdp-growth.json │ │ │ │ ├── data-japan-gdp-growth.json │ │ │ │ ├── data-usa-gdp-growth.json │ │ │ │ └── index.html │ │ │ ├── annotating │ │ │ │ └── index.html │ │ │ ├── axes-interacting │ │ │ │ └── index.html │ │ │ ├── axes-multiple │ │ │ │ └── index.html │ │ │ ├── axes-time-zones │ │ │ │ ├── date.js │ │ │ │ ├── index.html │ │ │ │ └── tz │ │ │ │ │ ├── africa │ │ │ │ │ ├── antarctica │ │ │ │ │ ├── asia │ │ │ │ │ ├── australasia │ │ │ │ │ ├── backward │ │ │ │ │ ├── etcetera │ │ │ │ │ ├── europe │ │ │ │ │ ├── factory │ │ │ │ │ ├── iso3166.tab │ │ │ │ │ ├── leapseconds │ │ │ │ │ ├── northamerica │ │ │ │ │ ├── pacificnew │ │ │ │ │ ├── solar87 │ │ │ │ │ ├── solar88 │ │ │ │ │ ├── solar89 │ │ │ │ │ ├── southamerica │ │ │ │ │ ├── systemv │ │ │ │ │ ├── yearistype.sh │ │ │ │ │ └── zone.tab │ │ │ ├── axes-time │ │ │ │ └── index.html │ │ │ ├── background.png │ │ │ ├── basic-options │ │ │ │ └── index.html │ │ │ ├── basic-usage │ │ │ │ └── index.html │ │ │ ├── canvas │ │ │ │ └── index.html │ │ │ ├── categories │ │ │ │ └── index.html │ │ │ ├── examples.css │ │ │ ├── image │ │ │ │ ├── hs-2004-27-a-large-web.jpg │ │ │ │ └── index.html │ │ │ ├── index.html │ │ │ ├── interacting │ │ │ │ └── index.html │ │ │ ├── navigate │ │ │ │ ├── arrow-down.gif │ │ │ │ ├── arrow-left.gif │ │ │ │ ├── arrow-right.gif │ │ │ │ ├── arrow-up.gif │ │ │ │ └── index.html │ │ │ ├── percentiles │ │ │ │ └── index.html │ │ │ ├── realtime │ │ │ │ └── index.html │ │ │ ├── resize │ │ │ │ └── index.html │ │ │ ├── selection │ │ │ │ └── index.html │ │ │ ├── series-errorbars │ │ │ │ └── index.html │ │ │ ├── series-pie │ │ │ │ └── index.html │ │ │ ├── series-toggle │ │ │ │ └── index.html │ │ │ ├── series-types │ │ │ │ └── index.html │ │ │ ├── shared │ │ │ │ └── jquery-ui │ │ │ │ │ └── jquery-ui.min.css │ │ │ ├── stacking │ │ │ │ └── index.html │ │ │ ├── symbols │ │ │ │ └── index.html │ │ │ ├── threshold │ │ │ │ └── index.html │ │ │ ├── tracking │ │ │ │ └── index.html │ │ │ ├── visitors │ │ │ │ └── index.html │ │ │ └── zooming │ │ │ │ └── index.html │ │ ├── excanvas.js │ │ ├── excanvas.min.js │ │ ├── flot.jquery.json │ │ ├── jquery.colorhelpers.js │ │ ├── jquery.flot.canvas.js │ │ ├── jquery.flot.categories.js │ │ ├── jquery.flot.crosshair.js │ │ ├── jquery.flot.errorbars.js │ │ ├── jquery.flot.fillbetween.js │ │ ├── jquery.flot.image.js │ │ ├── jquery.flot.js │ │ ├── jquery.flot.navigate.js │ │ ├── jquery.flot.pie.js │ │ ├── jquery.flot.resize.js │ │ ├── jquery.flot.selection.js │ │ ├── jquery.flot.stack.js │ │ ├── jquery.flot.symbol.js │ │ ├── jquery.flot.threshold.js │ │ ├── jquery.flot.time.js │ │ ├── jquery.js │ │ └── package.json │ │ ├── jquery-transit │ │ └── jquery-transit.js │ │ ├── jquery-ui │ │ ├── css │ │ │ └── flick │ │ │ │ ├── images │ │ │ │ ├── ui-bg_flat_0_aaaaaa_40x100.png │ │ │ │ ├── ui-bg_flat_0_eeeeee_40x100.png │ │ │ │ ├── ui-bg_flat_55_ffffff_40x100.png │ │ │ │ ├── ui-bg_flat_75_ffffff_40x100.png │ │ │ │ ├── ui-bg_glass_65_ffffff_1x400.png │ │ │ │ ├── ui-bg_highlight-soft_100_f6f6f6_1x100.png │ │ │ │ ├── ui-bg_highlight-soft_25_0073ea_1x100.png │ │ │ │ ├── ui-bg_highlight-soft_50_dddddd_1x100.png │ │ │ │ ├── ui-icons_0073ea_256x240.png │ │ │ │ ├── ui-icons_454545_256x240.png │ │ │ │ ├── ui-icons_666666_256x240.png │ │ │ │ ├── ui-icons_ff0084_256x240.png │ │ │ │ └── ui-icons_ffffff_256x240.png │ │ │ │ └── jquery-ui-1.8.17.custom.css │ │ ├── index.html │ │ └── js │ │ │ ├── jquery-1.7.1.min.js │ │ │ └── jquery-ui-1.8.17.custom.min.js │ │ └── jquery.form.js ├── talk_voting.py ├── talks.py ├── templatetags │ ├── __init__.py │ ├── conference.py │ └── template_tools.py ├── tickets.py ├── tools │ ├── __init__.py │ └── voteengine-0.99 │ │ ├── CHANGES │ │ ├── docs.html │ │ ├── input.txt │ │ ├── rob │ │ ├── rob2 │ │ ├── roy │ │ ├── test │ │ ├── test2 │ │ ├── test3 │ │ ├── test5 │ │ ├── ve.py │ │ ├── voteengine.py │ │ ├── votelib.py │ │ ├── votemain.py │ │ ├── votemethod.py │ │ └── zav ├── user_panel.py ├── users.py └── utils.py ├── docker-compose-vscode-debugger.yml ├── docker-compose.yml ├── email_template ├── __init__.py ├── admin.py ├── models.py ├── utils.py └── views.py ├── ep-social-ticket-search-app ├── CREDITS ├── README ├── css │ └── materialize.min.css ├── fonts │ └── roboto │ │ ├── Roboto-Bold.eot │ │ ├── Roboto-Bold.ttf │ │ ├── Roboto-Bold.woff │ │ ├── Roboto-Bold.woff2 │ │ ├── Roboto-Light.eot │ │ ├── Roboto-Light.ttf │ │ ├── Roboto-Light.woff │ │ ├── Roboto-Light.woff2 │ │ ├── Roboto-Medium.eot │ │ ├── Roboto-Medium.ttf │ │ ├── Roboto-Medium.woff │ │ ├── Roboto-Medium.woff2 │ │ ├── Roboto-Regular.eot │ │ ├── Roboto-Regular.ttf │ │ ├── Roboto-Regular.woff │ │ ├── Roboto-Regular.woff2 │ │ ├── Roboto-Thin.eot │ │ ├── Roboto-Thin.ttf │ │ ├── Roboto-Thin.woff │ │ └── Roboto-Thin.woff2 ├── js │ ├── jquery.min.js │ ├── list.fuzzysearch.js │ ├── list.js │ └── materialize.min.js ├── materialize │ ├── LICENSE │ ├── README.md │ └── font │ │ ├── material-design-icons │ │ ├── LICENSE.txt │ │ ├── Material-Design-Icons.eot │ │ ├── Material-Design-Icons.svg │ │ ├── Material-Design-Icons.ttf │ │ ├── Material-Design-Icons.woff │ │ └── Material-Design-Icons.woff2 │ │ └── roboto │ │ ├── Roboto-Bold.eot │ │ ├── Roboto-Bold.ttf │ │ ├── Roboto-Bold.woff │ │ ├── Roboto-Bold.woff2 │ │ ├── Roboto-Light.eot │ │ ├── Roboto-Light.ttf │ │ ├── Roboto-Light.woff │ │ ├── Roboto-Light.woff2 │ │ ├── Roboto-Medium.eot │ │ ├── Roboto-Medium.ttf │ │ ├── Roboto-Medium.woff │ │ ├── Roboto-Medium.woff2 │ │ ├── Roboto-Regular.eot │ │ ├── Roboto-Regular.ttf │ │ ├── Roboto-Regular.woff │ │ ├── Roboto-Regular.woff2 │ │ ├── Roboto-Thin.eot │ │ ├── Roboto-Thin.ttf │ │ ├── Roboto-Thin.woff │ │ └── Roboto-Thin.woff2 └── run.sh ├── ep-ticket-search-app ├── CREDITS ├── README ├── css │ └── materialize.min.css ├── fonts │ └── roboto │ │ ├── Roboto-Bold.eot │ │ ├── Roboto-Bold.ttf │ │ ├── Roboto-Bold.woff │ │ ├── Roboto-Bold.woff2 │ │ ├── Roboto-Light.eot │ │ ├── Roboto-Light.ttf │ │ ├── Roboto-Light.woff │ │ ├── Roboto-Light.woff2 │ │ ├── Roboto-Medium.eot │ │ ├── Roboto-Medium.ttf │ │ ├── Roboto-Medium.woff │ │ ├── Roboto-Medium.woff2 │ │ ├── Roboto-Regular.eot │ │ ├── Roboto-Regular.ttf │ │ ├── Roboto-Regular.woff │ │ ├── Roboto-Regular.woff2 │ │ ├── Roboto-Thin.eot │ │ ├── Roboto-Thin.ttf │ │ ├── Roboto-Thin.woff │ │ └── Roboto-Thin.woff2 ├── js │ ├── jquery.min.js │ ├── list.fuzzysearch.js │ ├── list.js │ └── materialize.min.js ├── materialize │ ├── LICENSE │ ├── README.md │ └── font │ │ ├── material-design-icons │ │ ├── LICENSE.txt │ │ ├── Material-Design-Icons.eot │ │ ├── Material-Design-Icons.svg │ │ ├── Material-Design-Icons.ttf │ │ ├── Material-Design-Icons.woff │ │ └── Material-Design-Icons.woff2 │ │ └── roboto │ │ ├── Roboto-Bold.eot │ │ ├── Roboto-Bold.ttf │ │ ├── Roboto-Bold.woff │ │ ├── Roboto-Bold.woff2 │ │ ├── Roboto-Light.eot │ │ ├── Roboto-Light.ttf │ │ ├── Roboto-Light.woff │ │ ├── Roboto-Light.woff2 │ │ ├── Roboto-Medium.eot │ │ ├── Roboto-Medium.ttf │ │ ├── Roboto-Medium.woff │ │ ├── Roboto-Medium.woff2 │ │ ├── Roboto-Regular.eot │ │ ├── Roboto-Regular.ttf │ │ ├── Roboto-Regular.woff │ │ ├── Roboto-Regular.woff2 │ │ ├── Roboto-Thin.eot │ │ ├── Roboto-Thin.ttf │ │ ├── Roboto-Thin.woff │ │ └── Roboto-Thin.woff2 └── run.sh ├── manage.py ├── media_public └── conference │ └── sponsor │ └── resized │ ├── continuum-analytics.jpg │ ├── github.jpg │ └── redhat.jpg ├── p3 ├── __init__.py ├── admin.py ├── apps.py ├── context_processors.py ├── dataaccess.py ├── listeners.py ├── management │ ├── __init__.py │ └── commands │ │ ├── __init__.py │ │ ├── accepted_talks.py │ │ ├── attendify_schedule_csv.py │ │ ├── attendify_schedule_xlsx.py │ │ ├── attendify_speakers_xlsx.py │ │ ├── build_social_ticket_search_app.py │ │ ├── build_ticket_search_app.py │ │ ├── check_schedule.py │ │ ├── create_bulk_coupons.py │ │ ├── create_community_coupons.py │ │ ├── create_conference_organizer_coupons.py │ │ ├── create_coupon_batch.py │ │ ├── create_speaker_coupons.py │ │ ├── create_trainer_training_pass_coupons.py │ │ ├── delete_spam_users.py │ │ ├── get_attendees_csv.py │ │ ├── guidebook_csv.py │ │ ├── partner_events.py │ │ ├── send_talk_verification_email.py │ │ ├── speaker_list.py │ │ ├── speakers_csv.py │ │ ├── sync_profiles.py │ │ ├── talk_abstracts.py │ │ ├── ticket_list.py │ │ ├── ticket_profiles.py │ │ ├── users.py │ │ ├── users_with_unassigned_tickets.py │ │ └── video_schedule_xlsx.py ├── migrations │ ├── 0001_initial.py │ ├── 0002_remove_unused_models.py │ ├── 0003_add_name_field_to_ticket_conference.py │ ├── 0004_mystery_migrations_maybe_2_to_3_bytes_to_str.py │ ├── 0005_auto_shirt_and_dietary_defaults.py │ ├── 0006_remove_p3talk.py │ ├── 0007_auto_20200217_1654.py │ ├── 0008_remove_ticketconference_name.py │ └── __init__.py ├── models.py ├── static │ ├── p5 │ │ └── images │ │ │ ├── close.png │ │ │ └── headshot-default.jpg │ └── p6 │ │ └── javascripts │ │ └── ckeditor.wysiwyg.js ├── stats.py ├── templatetags │ ├── __init__.py │ ├── meta.py │ └── sessions.py ├── urls.py ├── utils.py └── views.py ├── pycon ├── __init__.py ├── ci_settings.py ├── dev_settings.py ├── settings.py ├── test_settings.py ├── urls.py └── wsgi.py ├── pytest.ini ├── pytest_ci.ini ├── requirements-dev.in ├── requirements-dev.txt ├── requirements.in ├── requirements.txt ├── scripts ├── __init__.py ├── fix_names.py └── restore_epstage_data.py ├── setup.cfg ├── templates ├── 404.html ├── 500.html ├── admin │ ├── assopy │ │ ├── invoice │ │ │ └── change_form.html │ │ └── order │ │ │ ├── change_form.html │ │ │ └── change_list.html │ ├── auth │ │ └── user │ │ │ ├── change_form.html │ │ │ └── new_order.html │ ├── conference │ │ ├── conference │ │ │ ├── attendee_stats.html │ │ │ ├── attendee_stats_details.html │ │ │ ├── schedule_view.html │ │ │ ├── schedule_view_base.html │ │ │ └── schedule_view_schedule.html │ │ ├── conferencetag │ │ │ ├── change_form.html │ │ │ └── merge.html │ │ ├── schedule │ │ │ ├── change_form.html │ │ │ └── change_list.html │ │ ├── speaker │ │ │ ├── change_list.html │ │ │ └── stats_list.html │ │ └── ticket │ │ │ ├── change_form.html │ │ │ └── change_list.html │ └── inc │ │ └── extrahead.html ├── assopy │ ├── admin │ │ ├── edit_invoices.html │ │ └── order_stats.html │ ├── invoice.html │ └── invoices │ │ ├── _additional_text_for_2018.html │ │ ├── _additional_text_for_2019.html │ │ ├── _additional_text_for_2020.html │ │ ├── _additional_text_for_2021.html │ │ └── _additional_text_for_2022.html ├── cmsplugin_filer_image │ └── plugins │ │ └── image │ │ └── default.html ├── conference │ ├── README │ ├── _cookie_consent.html │ ├── _googleanalytics.html │ ├── accounts │ │ ├── _login_with_google.html │ │ ├── login.html │ │ ├── password_reset.html │ │ ├── password_reset_complete.html │ │ ├── password_reset_confirm.html │ │ ├── password_reset_done.html │ │ ├── signup.html │ │ └── signup_please_verify_email.html │ ├── admin │ │ ├── schedule_event.html │ │ └── schedule_tracks.html │ ├── base.html │ ├── cart │ │ ├── _order_summary.html │ │ ├── base.html │ │ ├── step_1_choose_type_of_order.html │ │ ├── step_2_pick_tickets.html │ │ ├── step_3_add_billing_info.html │ │ ├── step_4_payment.html │ │ └── step_5_congrats_order_complete.html │ ├── cfp │ │ ├── _steps.html │ │ ├── cfp_is_closed.html │ │ ├── preview.html │ │ ├── step1_talk_info.html │ │ ├── step2_add_speaker.html │ │ ├── step3_thanks.html │ │ ├── update_proposal.html │ │ └── update_speakers.html │ ├── conference │ │ └── talk_social_card.html │ ├── content │ │ ├── _breadcrumbs.html │ │ ├── _breadcrumbs_bar.html │ │ ├── _breadcrumbs_no_active.html │ │ ├── _menu.html │ │ ├── _messages.html │ │ ├── content_only_page.html │ │ ├── generic_content_page_with_sidebar.html │ │ └── wide_content_page.html │ ├── debugpanel │ │ ├── fares_setup.html │ │ ├── index.html │ │ ├── invoice_placeholders.html │ │ ├── invoices_export.html │ │ └── reissue_invoice.html │ ├── emails │ │ ├── order_confirmation_email.txt │ │ ├── password_reset_email.txt │ │ ├── password_reset_subject.txt │ │ └── signup_verification_email.txt │ ├── footer │ │ ├── _show_menu_in_footer.html │ │ └── footer.html │ ├── header │ │ ├── _homepage_jumbotron.html │ │ ├── _nav.html │ │ ├── _nav_menu.html │ │ ├── _regular.html │ │ └── _with_jumbotron.html │ ├── homepage.html │ ├── homepage │ │ ├── _schedule_overview.html │ │ ├── _sponsors.html │ │ ├── _venue.html │ │ ├── home.html │ │ └── home_template.html │ ├── news │ │ └── list.html │ ├── profiles │ │ ├── profile.html │ │ └── profile_unavailable.html │ ├── schedule │ │ └── schedule.html │ ├── signup.html │ ├── talk_voting │ │ ├── _voting_form.html │ │ ├── voting.html │ │ ├── voting_is_closed.html │ │ └── voting_is_unavailable.html │ ├── talks │ │ ├── talk.html │ │ └── update_talk.html │ └── user_panel │ │ ├── _invoices.html │ │ ├── _orders.html │ │ ├── _proposals.html │ │ ├── _tickets.html │ │ ├── assign_ticket.html │ │ ├── base.html │ │ ├── configure_ticket.html │ │ ├── dashboard.html │ │ ├── forms │ │ ├── privacy_settings_recruiting.html │ │ ├── privacy_settings_sms_messages.html │ │ ├── privacy_settings_user_messages.html │ │ └── profile_settings_picture.html │ │ ├── password_change.html │ │ ├── password_change_done.html │ │ ├── privacy_settings.html │ │ └── profile_settings.html ├── ep19 │ └── bs │ │ └── content │ │ └── generic_content_page_with_sidebar.html └── p3 │ └── admin │ └── index.html └── tests ├── __init__.py ├── common_tools.py ├── conftest.py ├── factories.py ├── test_accounts.py ├── test_assopy_admin.py ├── test_assopy_templates_paths.py ├── test_assopy_user.py ├── test_attendeeprofiles.py ├── test_avatar.py ├── test_cart.py ├── test_cfp.py ├── test_change_password.py ├── test_cmsplugins.py ├── test_conference_admin.py ├── test_debugpanel.py ├── test_exchangerates.py ├── test_homepage.py ├── test_invoices.py ├── test_management_commands.py ├── test_matrix_auth_api.py ├── test_models.py ├── test_new_talk_voting.py ├── test_p3_templatetags.py ├── test_profile.py ├── test_provisioning_script.py ├── test_reset_password.py ├── test_schedule.py ├── test_stats.py ├── test_streamset.py ├── test_talk_voting.py ├── test_talks.py ├── test_user_login_and_registration.py └── test_user_panel.py /.github/workflows/ci_pipeline.yml: -------------------------------------------------------------------------------- 1 | name: CI Pipeline 2 | 3 | on: 4 | push: 5 | branches: 6 | - master 7 | - dev/ep20* 8 | - ep20* 9 | pull_request: 10 | branches: 11 | - dev/ep20* 12 | - ep20* 13 | 14 | jobs: 15 | tests: 16 | runs-on: ubuntu-latest 17 | steps: 18 | - uses: actions/checkout@v2 19 | - name: Set up Python 3.9 20 | uses: actions/setup-python@v1 21 | with: 22 | python-version: 3.9 23 | - name: Install dependencies 24 | run: | 25 | sudo apt-get install -y libxml2-dev libxslt1-dev 26 | python -m pip install -U pip 27 | pip install -r requirements.txt 28 | pip install -r requirements-dev.txt 29 | - name: Run pytest 30 | env: 31 | SECRET_KEY: mysecret 32 | STRIPE_PUBLISHABLE_KEY: ${{ secrets.STRIPE_PUBLISHABLE_KEY }} 33 | STRIPE_SECRET_KEY: ${{ secrets.STRIPE_SECRET_KEY }} 34 | run: | 35 | pytest -c pytest_ci.ini 36 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # VIM 2 | .vimrc 3 | tags 4 | *.swp 5 | 6 | # py.test cache 7 | .pytest_cache/ 8 | 9 | # pipenv 10 | Pipfile* 11 | 12 | *.pyc 13 | settings_locale.py 14 | Session.vim 15 | penv/* 16 | data/ 17 | p3/static/p5/stylesheets/.sass-cache/* 18 | p3/static/p6/stylesheets/.sass-cache/* 19 | p3/static/p6/.sass-cache/* 20 | *.mo 21 | .bundle 22 | ._* 23 | .DS_Store 24 | *.db 25 | Thumbs.db 26 | *.tmproj 27 | *.mo 28 | .bzr 29 | *.egg-info 30 | .idea 31 | *.sqlite 32 | build/ 33 | *.bak 34 | *~ 35 | Makefile.local 36 | env.csh 37 | logs/ 38 | migrate-to-ep2017.sh 39 | pycon-env/ 40 | src/ 41 | .coverage 42 | htmlcov/ 43 | *.py,cover 44 | .cache/ 45 | coverage.xml 46 | prof/ 47 | .vagrant 48 | 49 | # virtualenvwrapper/zsh 50 | .venv 51 | .env 52 | env 53 | -------------------------------------------------------------------------------- /.python-version: -------------------------------------------------------------------------------- 1 | 3.6.9 2 | -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | { 8 | "name": "Attach", 9 | "type": "python", 10 | "request": "attach", 11 | "port": 3000, 12 | "host": "localhost", 13 | "django": true, // allows you to set breakpoints in Django template files. 14 | "pathMappings": [ 15 | { 16 | "localRoot": "${workspaceFolder}", 17 | "remoteRoot": "." // automatically maps to the remote cwd where your app is running 18 | } 19 | ], 20 | } 21 | ] 22 | } 23 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | # Base image 2 | FROM python:3.9 3 | 4 | # Update system 5 | RUN apt-get update && \ 6 | apt-get -y upgrade && \ 7 | apt-get -y autoremove 8 | 9 | # Install system dependencies 10 | RUN apt-get update && \ 11 | apt-get install -y --no-install-recommends \ 12 | build-essential \ 13 | sqlite3 14 | 15 | # Create main code folder 16 | RUN mkdir /code 17 | WORKDIR /code 18 | 19 | # Install dependencies (simulates `make install` in the live dockerfile) 20 | RUN pip install -U pip==19.3.1 21 | RUN pip install -U pip-tools 22 | COPY ./requirements*.txt /tmp/ 23 | RUN pip-sync /tmp/requirements.txt /tmp/requirements-dev.txt 24 | 25 | ENTRYPOINT ["/bin/bash", "-c"] 26 | -------------------------------------------------------------------------------- /LICENSE.bsd: -------------------------------------------------------------------------------- 1 | Copyright (c) 2009-2013, Python Italia APS 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 5 | 6 | 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 7 | 8 | 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 9 | 10 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 11 | -------------------------------------------------------------------------------- /assets/css/Galyon-Bold.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EuroPython/epcon/341c22649ff4ec858fc710821303cf3b78aa59e6/assets/css/Galyon-Bold.otf -------------------------------------------------------------------------------- /assets/css/Galyon-Italic.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EuroPython/epcon/341c22649ff4ec858fc710821303cf3b78aa59e6/assets/css/Galyon-Italic.otf -------------------------------------------------------------------------------- /assets/css/Galyon-Regular.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EuroPython/epcon/341c22649ff4ec858fc710821303cf3b78aa59e6/assets/css/Galyon-Regular.otf -------------------------------------------------------------------------------- /assets/img/ep2021-background-online.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EuroPython/epcon/341c22649ff4ec858fc710821303cf3b78aa59e6/assets/img/ep2021-background-online.jpg -------------------------------------------------------------------------------- /assets/img/ep2021-favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EuroPython/epcon/341c22649ff4ec858fc710821303cf3b78aa59e6/assets/img/ep2021-favicon.png -------------------------------------------------------------------------------- /assets/img/ep2021-icon-logo-small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EuroPython/epcon/341c22649ff4ec858fc710821303cf3b78aa59e6/assets/img/ep2021-icon-logo-small.png -------------------------------------------------------------------------------- /assets/img/ep2021-icon-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EuroPython/epcon/341c22649ff4ec858fc710821303cf3b78aa59e6/assets/img/ep2021-icon-logo.png -------------------------------------------------------------------------------- /assets/img/ep2021-logo-white-1024px-alpha.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EuroPython/epcon/341c22649ff4ec858fc710821303cf3b78aa59e6/assets/img/ep2021-logo-white-1024px-alpha.png -------------------------------------------------------------------------------- /assets/img/ep2021-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EuroPython/epcon/341c22649ff4ec858fc710821303cf3b78aa59e6/assets/img/ep2021-logo.png -------------------------------------------------------------------------------- /assets/img/ep2021-online-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EuroPython/epcon/341c22649ff4ec858fc710821303cf3b78aa59e6/assets/img/ep2021-online-logo.png -------------------------------------------------------------------------------- /assets/img/ep2021-snake-wrangler.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EuroPython/epcon/341c22649ff4ec858fc710821303cf3b78aa59e6/assets/img/ep2021-snake-wrangler.jpg -------------------------------------------------------------------------------- /assets/img/ep2021-social-online-card.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EuroPython/epcon/341c22649ff4ec858fc710821303cf3b78aa59e6/assets/img/ep2021-social-online-card.jpg -------------------------------------------------------------------------------- /assets/img/ep2021-social-online-card.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EuroPython/epcon/341c22649ff4ec858fc710821303cf3b78aa59e6/assets/img/ep2021-social-online-card.png -------------------------------------------------------------------------------- /assets/img/ep2021-white-logo-alpha.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EuroPython/epcon/341c22649ff4ec858fc710821303cf3b78aa59e6/assets/img/ep2021-white-logo-alpha.png -------------------------------------------------------------------------------- /assets/img/ep2022-background-ccd-original.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EuroPython/epcon/341c22649ff4ec858fc710821303cf3b78aa59e6/assets/img/ep2022-background-ccd-original.jpg -------------------------------------------------------------------------------- /assets/img/ep2022-background-ccd.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EuroPython/epcon/341c22649ff4ec858fc710821303cf3b78aa59e6/assets/img/ep2022-background-ccd.jpg -------------------------------------------------------------------------------- /assets/img/ep2022-conference-venue-from-above.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EuroPython/epcon/341c22649ff4ec858fc710821303cf3b78aa59e6/assets/img/ep2022-conference-venue-from-above.jpg -------------------------------------------------------------------------------- /assets/img/ep2022-social-card.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EuroPython/epcon/341c22649ff4ec858fc710821303cf3b78aa59e6/assets/img/ep2022-social-card.jpg -------------------------------------------------------------------------------- /assets/img/ep2022-social-card.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EuroPython/epcon/341c22649ff4ec858fc710821303cf3b78aa59e6/assets/img/ep2022-social-card.png -------------------------------------------------------------------------------- /assets/img/epslogo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EuroPython/epcon/341c22649ff4ec858fc710821303cf3b78aa59e6/assets/img/epslogo.png -------------------------------------------------------------------------------- /assets/img/fitted-cut-size-guide.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EuroPython/epcon/341c22649ff4ec858fc710821303cf3b78aa59e6/assets/img/fitted-cut-size-guide.png -------------------------------------------------------------------------------- /assets/img/straight-cut-size-guide.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EuroPython/epcon/341c22649ff4ec858fc710821303cf3b78aa59e6/assets/img/straight-cut-size-guide.png -------------------------------------------------------------------------------- /assets/js/generate_toc_for_cms.js: -------------------------------------------------------------------------------- 1 | // Build a table of contents based on the headers in the CMS section 2 | // of the page and place it into a
, if available. 3 | 4 | function addTOC() { 5 | var div_toc = $("#toc"); 6 | if (!div_toc) return; 7 | var toc = 8 | "

Table of contents

" + 10 | "" + "

"; 34 | div_toc.replaceWith(toc); 35 | $(document).scrollTop( $($(location).attr("hash")).offset().top ); 36 | } 37 | $(document).ready(addTOC); 38 | -------------------------------------------------------------------------------- /assopy/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EuroPython/epcon/341c22649ff4ec858fc710821303cf3b78aa59e6/assopy/__init__.py -------------------------------------------------------------------------------- /assopy/management/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EuroPython/epcon/341c22649ff4ec858fc710821303cf3b78aa59e6/assopy/management/__init__.py -------------------------------------------------------------------------------- /assopy/management/commands/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EuroPython/epcon/341c22649ff4ec858fc710821303cf3b78aa59e6/assopy/management/commands/__init__.py -------------------------------------------------------------------------------- /assopy/migrations/0003_add_exrate_fields_to_invoice_model.py: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | from django.db import migrations, models 5 | import datetime 6 | from decimal import Decimal 7 | 8 | 9 | class Migration(migrations.Migration): 10 | 11 | dependencies = [ 12 | ('assopy', '0002_auto_20180408_2337'), 13 | ] 14 | 15 | operations = [ 16 | migrations.AddField( 17 | model_name='invoice', 18 | name='exchange_rate', 19 | field=models.DecimalField(default=Decimal('1'), max_digits=10, decimal_places=5), 20 | ), 21 | migrations.AddField( 22 | model_name='invoice', 23 | name='exchange_rate_date', 24 | field=models.DateField(default=datetime.date(2000, 1, 1)), 25 | ), 26 | migrations.AddField( 27 | model_name='invoice', 28 | name='local_currency', 29 | field=models.CharField(default=b'EUR', max_length=3), 30 | ), 31 | migrations.AddField( 32 | model_name='invoice', 33 | name='vat_in_local_currency', 34 | field=models.DecimalField(default=Decimal('0'), max_digits=6, decimal_places=2), 35 | ), 36 | ] 37 | -------------------------------------------------------------------------------- /assopy/migrations/0004_add_order_payment_date.py: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | from django.db import migrations, models 5 | 6 | 7 | class Migration(migrations.Migration): 8 | 9 | dependencies = [ 10 | ('assopy', '0003_add_exrate_fields_to_invoice_model'), 11 | ] 12 | 13 | operations = [ 14 | migrations.AddField( 15 | model_name='order', 16 | name='payment_date', 17 | field=models.DateTimeField(help_text=b'Auto filled by the payments backend', null=True, blank=True), 18 | ), 19 | ] 20 | -------------------------------------------------------------------------------- /assopy/migrations/0005_simplify_invoice_html_field_name.py: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | from django.db import migrations, models 5 | 6 | 7 | class Migration(migrations.Migration): 8 | 9 | dependencies = [ 10 | ('assopy', '0004_add_order_payment_date'), 11 | ] 12 | 13 | operations = [ 14 | migrations.RenameField( 15 | model_name='invoice', 16 | old_name='invoice_copy_full_html', 17 | new_name='html', 18 | ), 19 | ] 20 | -------------------------------------------------------------------------------- /assopy/migrations/0006_add_bank_to_payment_options.py: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | from django.db import migrations, models 5 | 6 | 7 | class Migration(migrations.Migration): 8 | 9 | dependencies = [ 10 | ('assopy', '0005_simplify_invoice_html_field_name'), 11 | ] 12 | 13 | operations = [ 14 | migrations.AlterField( 15 | model_name='order', 16 | name='method', 17 | field=models.CharField(max_length=6, choices=[(b'cc', b'Credit Card'), (b'paypal', b'PayPal'), (b'bank', b'Bank')]), 18 | ), 19 | ] 20 | -------------------------------------------------------------------------------- /assopy/migrations/0007_add_customer_to_invoice.py: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | from django.db import migrations, models 5 | 6 | 7 | class Migration(migrations.Migration): 8 | 9 | dependencies = [ 10 | ('assopy', '0006_add_bank_to_payment_options'), 11 | ] 12 | 13 | operations = [ 14 | migrations.AddField( 15 | model_name='invoice', 16 | name='customer', 17 | field=models.TextField(default=''), 18 | preserve_default=False, 19 | ), 20 | ] 21 | -------------------------------------------------------------------------------- /assopy/migrations/0008_remove_user_oauth_info_model.py: -------------------------------------------------------------------------------- 1 | 2 | # Generated by Django 1.9.13 on 2018-10-15 12:28 3 | 4 | 5 | from django.db import migrations 6 | 7 | 8 | class Migration(migrations.Migration): 9 | 10 | dependencies = [ 11 | ('assopy', '0007_add_customer_to_invoice'), 12 | ] 13 | 14 | operations = [ 15 | migrations.RemoveField( 16 | model_name='useroauthinfo', 17 | name='user', 18 | ), 19 | migrations.DeleteModel( 20 | name='UserOAuthInfo', 21 | ), 22 | ] 23 | -------------------------------------------------------------------------------- /assopy/migrations/0009_rename_assopy_user.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 1.11.16 on 2018-10-27 10:51 2 | from __future__ import unicode_literals 3 | import sqlite3 4 | 5 | from django.db import migrations 6 | 7 | 8 | class Migration(migrations.Migration): 9 | # This was added because the pipelines in Github don't have a version of 10 | # SQLite>3.26 and this migration fails on versions before that. 11 | if sqlite3.sqlite_version_info[1] < 27: 12 | atomic = False 13 | 14 | dependencies = [ 15 | ('assopy', '0008_remove_user_oauth_info_model'), 16 | ('p3', '0002_remove_unused_models'), 17 | ] 18 | 19 | operations = [ 20 | migrations.RenameModel( 21 | old_name='User', 22 | new_name='AssopyUser', 23 | ), 24 | ] 25 | -------------------------------------------------------------------------------- /assopy/migrations/0010_add_uuid_to_Order.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Generated by Django 1.11.16 on 2019-02-17 11:31 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 | ('assopy', '0009_rename_assopy_user'), 12 | ] 13 | 14 | operations = [ 15 | migrations.AddField( 16 | model_name='order', 17 | name='uuid', 18 | field=models.CharField(blank=True, default='', max_length=40), 19 | ), 20 | ] 21 | -------------------------------------------------------------------------------- /assopy/migrations/0011_updated_vat_settings_for_swiss_vat.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Generated by Django 1.11.20 on 2019-05-07 19: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 | ('assopy', '0010_add_uuid_to_Order'), 12 | ] 13 | 14 | operations = [ 15 | migrations.AlterField( 16 | model_name='vat', 17 | name='value', 18 | field=models.DecimalField(decimal_places=2, max_digits=5), 19 | ), 20 | ] 21 | -------------------------------------------------------------------------------- /assopy/migrations/0012_add_type_to_order.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 1.11.20 on 2019-05-11 21:11 2 | 3 | from django.db import migrations, models 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [("assopy", "0011_updated_vat_settings_for_swiss_vat")] 9 | 10 | operations = [ 11 | migrations.AddField( 12 | model_name="order", 13 | name="order_type", 14 | field=models.CharField( 15 | blank=True, 16 | choices=[ 17 | ("company", "Company"), 18 | ("student", "Student"), 19 | ("personal", "Personal"), 20 | ], 21 | max_length=20, 22 | ), 23 | ) 24 | ] 25 | -------------------------------------------------------------------------------- /assopy/migrations/0014_deprecate_paypal_20191124_2308.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Generated by Django 1.11.26 on 2019-11-24 22:08 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 | ('assopy', '0013_mystery_migrations_maybe_2_to_3_bytes_to_str'), 12 | ] 13 | 14 | operations = [ 15 | migrations.AlterField( 16 | model_name='order', 17 | name='method', 18 | field=models.CharField(choices=[('cc', 'Credit Card'), ('paypal', 'PayPal (deprecated)'), ('bank', 'Bank')], max_length=6), 19 | ), 20 | ] 21 | -------------------------------------------------------------------------------- /assopy/migrations/0016_null_has_no_effect_on_vat_manytomay_relationship.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.19 on 2021-05-17 07:32 2 | 3 | from django.db import migrations, models 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('assopy', '0015_remove_refund_models'), 10 | ] 11 | 12 | operations = [ 13 | migrations.AlterField( 14 | model_name='vat', 15 | name='fares', 16 | field=models.ManyToManyField(blank=True, through='assopy.VatFare', to='conference.Fare'), 17 | ), 18 | ] 19 | -------------------------------------------------------------------------------- /assopy/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EuroPython/epcon/341c22649ff4ec858fc710821303cf3b78aa59e6/assopy/migrations/__init__.py -------------------------------------------------------------------------------- /assopy/templatetags/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EuroPython/epcon/341c22649ff4ec858fc710821303cf3b78aa59e6/assopy/templatetags/__init__.py -------------------------------------------------------------------------------- /assopy/templatetags/assopy_tags.py: -------------------------------------------------------------------------------- 1 | from django import template 2 | from django.core import paginator 3 | 4 | import urllib.request, urllib.parse, urllib.error 5 | 6 | register = template.Library() 7 | 8 | 9 | @register.simple_tag(takes_context=True) 10 | def paginate(context, qs, count=20): 11 | pages = paginator.Paginator(qs, int(count)) 12 | try: 13 | ix = int(context['request'].GET.get('page', 1)) 14 | except ValueError: 15 | ix = 1 16 | try: 17 | return pages.page(ix) 18 | except: 19 | ix = 1 if ix < 1 else pages.num_pages 20 | return pages.page(ix) 21 | 22 | 23 | @register.simple_tag(takes_context=True) 24 | def add_page_number_to_query(context, page, get=None): 25 | if get is None: 26 | get = context['request'].GET.copy() 27 | else: 28 | get = dict(get) 29 | get['page'] = page 30 | return urllib.parse.urlencode(get) 31 | -------------------------------------------------------------------------------- /assopy/urls.py: -------------------------------------------------------------------------------- 1 | from django.conf.urls import url as re_path 2 | 3 | from assopy import views 4 | 5 | 6 | urlpatterns = [ 7 | # Views below continue to be used as of EP2019/2020 8 | re_path( 9 | r"orders/(?P.+)/invoices/(?P.+).html$", 10 | views.invoice, 11 | name="assopy-invoice-html", 12 | kwargs={"mode": "html"}, 13 | ), 14 | re_path( 15 | r"orders/(?P.+)/invoices/(?P.+).pdf$", 16 | views.invoice, 17 | name="assopy-invoice-pdf", 18 | kwargs={"mode": "pdf"}, 19 | ), 20 | ] 21 | 22 | -------------------------------------------------------------------------------- /assopy/views.py: -------------------------------------------------------------------------------- 1 | import logging 2 | 3 | from django import http 4 | from django.contrib.admin.utils import unquote 5 | from django.contrib.auth.decorators import login_required 6 | from django.shortcuts import get_object_or_404 7 | 8 | from assopy import models 9 | from common.http import PdfResponse 10 | 11 | log = logging.getLogger('assopy.views') 12 | 13 | 14 | @login_required 15 | def invoice(request, order_code, code, mode='html'): 16 | if not request.user.is_staff: 17 | userfilter = { 18 | 'order__user__user': request.user, 19 | } 20 | else: 21 | userfilter = {} 22 | 23 | invoice = get_object_or_404( 24 | models.Invoice, 25 | code=unquote(code), 26 | order__code=unquote(order_code), 27 | **userfilter 28 | ) 29 | 30 | if mode == 'html': 31 | return http.HttpResponse(invoice.html) 32 | 33 | return PdfResponse(filename=invoice.get_invoice_filename(), 34 | content=invoice.html) 35 | -------------------------------------------------------------------------------- /cms_utils/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from django.utils.translation import ugettext_lazy as _ -------------------------------------------------------------------------------- /cms_utils/cms_app.py: -------------------------------------------------------------------------------- 1 | from cms.app_base import CMSApp 2 | from cms.apphook_pool import apphook_pool 3 | from django.utils.translation import ugettext_lazy as _ 4 | 5 | 6 | class AssopyApphook(CMSApp): 7 | name = _("Assopy") 8 | urls = ["assopy.urls"] 9 | 10 | 11 | class ConferenceApphook(CMSApp): 12 | name = _("Conference") 13 | urls = ["conference.urls"] 14 | 15 | 16 | class P3Apphook(CMSApp): 17 | name = _("P3") 18 | urls = ["p3.urls"] 19 | 20 | 21 | apphook_pool.register(AssopyApphook) 22 | apphook_pool.register(ConferenceApphook) 23 | apphook_pool.register(P3Apphook) 24 | -------------------------------------------------------------------------------- /cms_utils/cms_plugins.py: -------------------------------------------------------------------------------- 1 | from cms.plugin_base import CMSPluginBase 2 | from cms.plugin_pool import plugin_pool 3 | from django.utils.translation import ugettext_lazy as _ 4 | 5 | from .models import MarkitUpPluginModel, TemplatePluginModel 6 | 7 | 8 | @plugin_pool.register_plugin 9 | class MarkItUpPlugin(CMSPluginBase): 10 | name = _('MarkItUp') 11 | model = MarkitUpPluginModel 12 | render_template = 'djangocms_markitup/markitup.html' 13 | 14 | 15 | @plugin_pool.register_plugin 16 | class TemplatePlugin(CMSPluginBase): 17 | name = _('Template Plugin') 18 | model = TemplatePluginModel 19 | render_template = 'djangocms_template/template_plugin.html' 20 | -------------------------------------------------------------------------------- /cms_utils/migrations/0001_initial.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | 4 | from django.db import migrations, models 5 | import markitup.fields 6 | 7 | 8 | class Migration(migrations.Migration): 9 | 10 | dependencies = [ 11 | ('cms', '0016_auto_20160608_1535'), 12 | ] 13 | 14 | operations = [ 15 | migrations.CreateModel( 16 | name='MarkitUpPluginModel', 17 | fields=[ 18 | ('cmsplugin_ptr', models.OneToOneField(on_delete=models.deletion.CASCADE, parent_link=True, related_name='cms_utils_markituppluginmodel', auto_created=True, primary_key=True, serialize=False, to='cms.CMSPlugin')), 19 | ('body', markitup.fields.MarkupField(no_rendered_field=True)), 20 | ('_body_rendered', models.TextField(editable=False, blank=True)), 21 | ], 22 | options={ 23 | 'abstract': False, 24 | }, 25 | bases=('cms.cmsplugin',), 26 | ), 27 | ] 28 | -------------------------------------------------------------------------------- /cms_utils/migrations/0002_templatepluginmodel.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.23 on 2021-05-23 14:06 2 | 3 | from django.db import migrations, models 4 | import django.db.models.deletion 5 | 6 | 7 | class Migration(migrations.Migration): 8 | 9 | dependencies = [ 10 | ('cms', '0022_auto_20180620_1551'), 11 | ('cms_utils', '0001_initial'), 12 | ] 13 | 14 | operations = [ 15 | migrations.CreateModel( 16 | name='TemplatePluginModel', 17 | fields=[ 18 | ('cmsplugin_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, related_name='cms_utils_templatepluginmodel', serialize=False, to='cms.CMSPlugin')), 19 | ('body', models.TextField()), 20 | ], 21 | options={ 22 | 'abstract': False, 23 | }, 24 | bases=('cms.cmsplugin',), 25 | ), 26 | ] 27 | -------------------------------------------------------------------------------- /cms_utils/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EuroPython/epcon/341c22649ff4ec858fc710821303cf3b78aa59e6/cms_utils/migrations/__init__.py -------------------------------------------------------------------------------- /cms_utils/models.py: -------------------------------------------------------------------------------- 1 | from cms.models import CMSPlugin 2 | from django.db import models 3 | from markitup.fields import MarkupField 4 | 5 | 6 | class MarkitUpPluginModel(CMSPlugin): 7 | body = MarkupField() 8 | 9 | 10 | class TemplatePluginModel(CMSPlugin): 11 | body = models.TextField() 12 | -------------------------------------------------------------------------------- /cms_utils/processors.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from django.template import Template, Context 3 | 4 | 5 | def process_templatetags(instance, placeholder, rendered_content, original_context): 6 | """ 7 | This plugin processor render the resulting content to parse for templatetags 8 | in the plugin output 9 | """ 10 | context = Context(original_context) 11 | 12 | try: 13 | template = Template(rendered_content) 14 | except Exception as e: 15 | return '

Template Error: {}

{}'.format(str(e), rendered_content) 16 | return template.render(context) 17 | -------------------------------------------------------------------------------- /cms_utils/templates/djangocms_markitup/markitup.html: -------------------------------------------------------------------------------- 1 | {{ instance.body }} -------------------------------------------------------------------------------- /cms_utils/templates/djangocms_template/template_plugin.html: -------------------------------------------------------------------------------- 1 | {{ instance.body|safe }} -------------------------------------------------------------------------------- /common/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EuroPython/epcon/341c22649ff4ec858fc710821303cf3b78aa59e6/common/__init__.py -------------------------------------------------------------------------------- /common/decorators.py: -------------------------------------------------------------------------------- 1 | import functools 2 | from decorator import decorator 3 | 4 | from django import http 5 | from django.conf import settings 6 | from django.forms.utils import ErrorDict 7 | 8 | from common.jsonify import json_dumps 9 | 10 | 11 | def render_to_json(f): 12 | """ 13 | Decorator to be applied to a view to serialize json in the result. 14 | """ 15 | @functools.wraps(f) 16 | def wrapper(func, *args, **kw): 17 | if settings.DEBUG: 18 | ct = 'text/plain' 19 | j = lambda d: json_dumps(d, indent=2) 20 | else: 21 | ct = 'application/json' 22 | j = json_dumps 23 | 24 | try: 25 | result = func(*args, **kw) 26 | except Exception as e: 27 | result = j(str(e)) 28 | status = 500 29 | else: 30 | if isinstance(result, http.HttpResponse): 31 | return result 32 | else: 33 | result = j(result) 34 | status = 200 if not isinstance(result, ErrorDict) else 400 35 | return http.HttpResponse(content = result, content_type = ct, status = status) 36 | return decorator(wrapper, f) 37 | -------------------------------------------------------------------------------- /common/django_urls.py: -------------------------------------------------------------------------------- 1 | import urllib.parse 2 | 3 | from django.conf import settings 4 | 5 | 6 | class UrlMixin(object): 7 | """ 8 | DEPRECATED - DO NOT USE 9 | 10 | This is kept here for legacy reasons as migrations require it and in case 11 | we need to reffer to it. It was used in the Talk and Speaker models. 12 | """ 13 | def get_url(self): 14 | if hasattr(self.get_url_path, 'dont_recurse'): 15 | raise NotImplementedError 16 | 17 | try: 18 | path = self.get_url_path() 19 | except NotImplementedError: 20 | raise 21 | 22 | # Should we look up a related site? 23 | # if getattr(self._meta, 'url_by_site'): 24 | prefix = getattr(settings, 'DEFAULT_URL_PREFIX', 'http://localhost') 25 | return prefix + path 26 | 27 | get_url.dont_recurse = True 28 | 29 | def get_url_path(self): 30 | if hasattr(self.get_url, 'dont_recurse'): 31 | raise NotImplementedError 32 | try: 33 | url = self.get_url() 34 | except NotImplementedError: 35 | raise 36 | 37 | bits = urllib.parse.urlparse(url) 38 | return urllib.parse.urlunparse(('', '') + bits[2:]) 39 | 40 | get_url_path.dont_recurse = True 41 | -------------------------------------------------------------------------------- /common/http.py: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | 3 | from django.http import HttpResponse 4 | from weasyprint import HTML 5 | 6 | 7 | class PdfResponse(HttpResponse): 8 | 9 | def __init__(self, filename, content, **kwargs): 10 | disposition = 'filename="%s"' % filename 11 | pdf_content = self.convert_to_pdf(content) 12 | super(PdfResponse, self).__init__(content=pdf_content, **kwargs) 13 | self['Content-Type'] = 'application/pdf' 14 | self['Content-Disposition'] = disposition 15 | 16 | # return response 17 | 18 | def convert_to_pdf(self, content): 19 | return HTML(string=content).write_pdf() 20 | -------------------------------------------------------------------------------- /common/jsonify.py: -------------------------------------------------------------------------------- 1 | import datetime 2 | import json 3 | import functools 4 | 5 | 6 | class MyEncode(json.JSONEncoder): 7 | def default(self, obj): 8 | if isinstance(obj, datetime.datetime): 9 | return obj.strftime('%d/%m/%Y %H:%M:%S') 10 | elif isinstance(obj, datetime.date): 11 | return obj.strftime('%d/%m/%Y') 12 | elif isinstance(obj, datetime.time): 13 | return obj.strftime('%H:%M') 14 | elif isinstance(obj, set): 15 | return list(obj) 16 | 17 | return json.JSONEncoder.default(self, obj) 18 | 19 | 20 | json_dumps = functools.partial(json.dumps, cls=MyEncode) 21 | -------------------------------------------------------------------------------- /common/tests/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EuroPython/epcon/341c22649ff4ec858fc710821303cf3b78aa59e6/common/tests/__init__.py -------------------------------------------------------------------------------- /conference/__init__.py: -------------------------------------------------------------------------------- 1 | default_app_config = 'conference.apps.ConferenceConfig' 2 | -------------------------------------------------------------------------------- /conference/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | 4 | class ConferenceConfig(AppConfig): 5 | name = 'conference' 6 | 7 | def ready(self): 8 | import conference.listeners # noqa 9 | -------------------------------------------------------------------------------- /conference/context_processors.py: -------------------------------------------------------------------------------- 1 | from django.conf import settings 2 | 3 | 4 | def epcon_ctx(request): 5 | return { 6 | 'CURRENT_URL': settings.DEFAULT_URL_PREFIX + request.path, 7 | 'DEFAULT_URL_PREFIX': settings.DEFAULT_URL_PREFIX, 8 | 'CONFERENCE': settings.CONFERENCE_CONFERENCE, 9 | } 10 | -------------------------------------------------------------------------------- /conference/decorators.py: -------------------------------------------------------------------------------- 1 | import functools 2 | 3 | from django.contrib import messages 4 | from django.urls import reverse 5 | from django.shortcuts import redirect 6 | 7 | 8 | def full_profile_required(func): 9 | @functools.wraps(func) 10 | def wrapper(request, *args, **kwargs): 11 | if (request.user 12 | and request.user.id # FIXME test mocks mess with the above object so we have to check the id 13 | and (not request.user.attendeeprofile or not request.user.attendeeprofile.gender)): 14 | 15 | messages.warning( 16 | request, 17 | "Please update your profile to continue using the EuroPython website." 18 | ) 19 | 20 | return redirect(reverse('user_panel:profile_settings')) 21 | 22 | return func(request, *args, **kwargs) 23 | return wrapper 24 | -------------------------------------------------------------------------------- /conference/forms/__init__.py: -------------------------------------------------------------------------------- 1 | from .auth import * # noqa 2 | from .forms import * # noqa 3 | from .talks import * # noqa 4 | -------------------------------------------------------------------------------- /conference/forms/auth.py: -------------------------------------------------------------------------------- 1 | from django.contrib.auth import get_user_model 2 | from django.contrib.auth.forms import PasswordResetForm 3 | 4 | 5 | class CustomPasswordResetForm(PasswordResetForm): 6 | def get_users(self, email): 7 | """Given an email, return matching user(s) who should receive a reset. 8 | 9 | This allows subclasses to more easily customize the default policies 10 | that prevent inactive users and users with unusable passwords from 11 | resetting their password. 12 | """ 13 | user_model = get_user_model() 14 | active_users = user_model._default_manager.filter(**{ 15 | 'email__iexact': email, 16 | 'is_active': True, 17 | }) 18 | d = (u for u in active_users) 19 | return d 20 | -------------------------------------------------------------------------------- /conference/gravatar.py: -------------------------------------------------------------------------------- 1 | """ 2 | Gravatar-related functions. 3 | """ 4 | import hashlib 5 | import urllib.error 6 | import urllib.parse 7 | import urllib.request 8 | 9 | 10 | def gravatar(email, size=80, default='identicon', rating='r', 11 | protocol='https'): 12 | """Create a Gravatar URL given the user email address.""" 13 | 14 | if protocol == 'https': 15 | host = 'https://secure.gravatar.com' 16 | else: 17 | host = 'http://www.gravatar.com' 18 | 19 | # Remember: hash funcions expect bytes objects, not strings. 20 | lowercase_email = email.lower() 21 | if not isinstance(lowercase_email, bytes): 22 | # Encode it! 23 | lowercase_email = lowercase_email.encode('utf-8') 24 | 25 | gravatar_url = f'{host}/avatar/{hashlib.md5(lowercase_email).hexdigest()}?' 26 | gravatar_url += urllib.parse.urlencode({ 27 | 'default': default, 28 | 'size': size, 29 | 'rating': rating, 30 | }) 31 | return gravatar_url 32 | -------------------------------------------------------------------------------- /conference/management/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EuroPython/epcon/341c22649ff4ec858fc710821303cf3b78aa59e6/conference/management/__init__.py -------------------------------------------------------------------------------- /conference/management/commands/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EuroPython/epcon/341c22649ff4ec858fc710821303cf3b78aa59e6/conference/management/commands/__init__.py -------------------------------------------------------------------------------- /conference/management/commands/add_invoices_for_zero_amount_orders.py: -------------------------------------------------------------------------------- 1 | from django.core.management.base import BaseCommand 2 | from assopy import models as amodels 3 | 4 | 5 | def generate_invoices_for_zero_amount_orders_for_year(year): 6 | orders = amodels.Order.objects.filter( 7 | created__year=year, 8 | method='bank', 9 | ) 10 | 11 | for o in orders: 12 | if not o.complete(): 13 | continue 14 | if o.total() > 0: 15 | continue 16 | print('Creating invoice for order %r' % o) 17 | o.confirm_order(o.created) 18 | o.complete() 19 | 20 | 21 | class Command(BaseCommand): 22 | """ 23 | The system did not generate invoices for orders with a zero amount 24 | in 2018 (e.g. as result of using discounts). 25 | 26 | We have to add them after the fact. 27 | """ 28 | def handle(self, *args, **options): 29 | generate_invoices_for_zero_amount_orders_for_year(2018) 30 | -------------------------------------------------------------------------------- /conference/management/commands/pull_latest_exrates.py: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | from django.core.management.base import BaseCommand 6 | 7 | from conference.currencies import fetch_and_store_latest_ecb_exrates 8 | 9 | 10 | class Command(BaseCommand): 11 | """ 12 | Checks ECB API endpoint for the new exrates, if there are any updates it 13 | stores them in db. 14 | """ 15 | def handle(self, *args, **options): 16 | print("PULLING LATEST ECB RATES") 17 | fetch_and_store_latest_ecb_exrates() 18 | -------------------------------------------------------------------------------- /conference/migrations/0002_talk_domain.py: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | from django.db import migrations, models 5 | 6 | 7 | class Migration(migrations.Migration): 8 | 9 | dependencies = [ 10 | ('conference', '0001_initial'), 11 | ] 12 | 13 | operations = [ 14 | migrations.AddField( 15 | model_name='talk', 16 | name='domain', 17 | field=models.CharField(default=b'', max_length=20, choices=[(b'business_track', b'Business Track'), (b'devops', b'DevOps'), (b'django', b'Django Track'), (b'education', b'Educational Track'), (b'general', b'General Python'), (b'hw_iot', b'Hardware/IoT Track'), (b'pydata', b'PyData Track'), (b'science', b'Science Track'), (b'web', b'Web Track'), (b'', b'None of the above')]), 18 | ), 19 | ] 20 | -------------------------------------------------------------------------------- /conference/migrations/0003_add_domain_level_field.py: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | from django.db import migrations, models 5 | 6 | 7 | class Migration(migrations.Migration): 8 | 9 | dependencies = [ 10 | ('conference', '0002_talk_domain'), 11 | ] 12 | 13 | operations = [ 14 | migrations.AddField( 15 | model_name='talk', 16 | name='domain_level', 17 | field=models.CharField(default=b'beginner', max_length=12, verbose_name='Audience Domain Level', choices=[(b'beginner', 'Beginner'), (b'intermediate', 'Intermediate'), (b'advanced', 'Advanced')]), 18 | ), 19 | migrations.AlterField( 20 | model_name='talk', 21 | name='level', 22 | field=models.CharField(default=b'beginner', max_length=12, verbose_name='Audience Python level', choices=[(b'beginner', 'Beginner'), (b'intermediate', 'Intermediate'), (b'advanced', 'Advanced')]), 23 | ), 24 | ] 25 | -------------------------------------------------------------------------------- /conference/migrations/0004_add_exchangerate_model.py: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | from django.db import migrations, models 5 | 6 | 7 | class Migration(migrations.Migration): 8 | 9 | dependencies = [ 10 | ('conference', '0003_add_domain_level_field'), 11 | ] 12 | 13 | operations = [ 14 | migrations.CreateModel( 15 | name='ExchangeRate', 16 | fields=[ 17 | ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), 18 | ('datestamp', models.DateField()), 19 | ('currency', models.CharField(max_length=3)), 20 | ('rate', models.DecimalField(max_digits=10, decimal_places=5)), 21 | ], 22 | ), 23 | migrations.AlterField( 24 | model_name='talk', 25 | name='domain', 26 | field=models.CharField(default=b'', max_length=20, choices=[(b'business_track', b'Business Track'), (b'devops', b'DevOps'), (b'django', b'Django Track'), (b'education', b'Educational Track'), (b'general', b'General Python'), (b'hw_iot', b'Hardware/IoT Track'), (b'pydata', b'PyData Track'), (b'science', b'Science Track'), (b'web', b'Web Track'), (b'', b'Other')]), 27 | ), 28 | ] 29 | -------------------------------------------------------------------------------- /conference/migrations/0005_add_captcha_question.py: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | from django.db import migrations, models 5 | import django.utils.timezone 6 | import model_utils.fields 7 | 8 | 9 | class Migration(migrations.Migration): 10 | 11 | dependencies = [ 12 | ('conference', '0004_add_exchangerate_model'), 13 | ] 14 | 15 | operations = [ 16 | migrations.CreateModel( 17 | name='CaptchaQuestion', 18 | fields=[ 19 | ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), 20 | ('created', model_utils.fields.AutoCreatedField(default=django.utils.timezone.now, verbose_name='created', editable=False)), 21 | ('modified', model_utils.fields.AutoLastModifiedField(default=django.utils.timezone.now, verbose_name='modified', editable=False)), 22 | ('question', models.CharField(max_length=255)), 23 | ('answer', models.CharField(max_length=255)), 24 | ('enabled', models.BooleanField(default=True)), 25 | ], 26 | options={ 27 | 'abstract': False, 28 | }, 29 | ), 30 | ] 31 | -------------------------------------------------------------------------------- /conference/migrations/0007_remove_special_place.py: -------------------------------------------------------------------------------- 1 | 2 | # Generated by Django 1.11.16 on 2019-01-03 20:05 3 | from __future__ import unicode_literals 4 | 5 | from django.db import migrations 6 | 7 | 8 | class Migration(migrations.Migration): 9 | 10 | dependencies = [ 11 | ('conference', '0006_update_talk_model_fields'), 12 | ] 13 | 14 | operations = [ 15 | migrations.DeleteModel( 16 | name='SpecialPlace', 17 | ), 18 | ] 19 | -------------------------------------------------------------------------------- /conference/migrations/0009_add_field_created_by_and_modified_to_talk.py: -------------------------------------------------------------------------------- 1 | import uuid 2 | 3 | from django.conf import settings 4 | from django.db import migrations, models 5 | import django.db.models.deletion 6 | 7 | 8 | class Migration(migrations.Migration): 9 | 10 | dependencies = [ 11 | migrations.swappable_dependency(settings.AUTH_USER_MODEL), 12 | ("conference", "0008_add_news_model"), 13 | ] 14 | 15 | operations = [ 16 | migrations.AddField( 17 | model_name="talk", 18 | name="created_by", 19 | field=models.ForeignKey( 20 | blank=True, 21 | null=True, 22 | on_delete=django.db.models.deletion.CASCADE, 23 | to=settings.AUTH_USER_MODEL, 24 | ), 25 | ), 26 | migrations.AddField( 27 | model_name="talk", 28 | name="modified", 29 | field=models.DateTimeField(auto_now=True, null=True), 30 | ), 31 | migrations.AddField( 32 | model_name="talk", 33 | name="uuid", 34 | field=models.CharField( 35 | default=uuid.uuid4, max_length=40, unique=False, 36 | ), 37 | ), 38 | ] 39 | -------------------------------------------------------------------------------- /conference/migrations/0010_add_gender_and_is_minor_fields.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 1.11.20 on 2019-04-05 07:25 2 | 3 | from django.db import migrations, models 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ("conference", "0009_add_field_created_by_and_modified_to_talk") 10 | ] 11 | 12 | operations = [ 13 | migrations.AlterModelOptions( 14 | name="news", 15 | options={ 16 | "ordering": ["-published_date"], 17 | "verbose_name_plural": "News", 18 | }, 19 | ), 20 | migrations.AddField( 21 | model_name="attendeeprofile", 22 | name="gender", 23 | field=models.CharField(blank=True, max_length=32), 24 | ), 25 | migrations.AddField( 26 | model_name="attendeeprofile", 27 | name="is_minor", 28 | field=models.BooleanField(default=False), 29 | ), 30 | ] 31 | -------------------------------------------------------------------------------- /conference/migrations/0012_add_vototalk_timestamps.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Generated by Django 1.11.20 on 2019-05-14 08:23 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 | ('conference', '0011_add_stripepayment_model'), 12 | ] 13 | 14 | operations = [ 15 | migrations.AddField( 16 | model_name='vototalk', 17 | name='created', 18 | field=models.DateTimeField(auto_now_add=True), 19 | ), 20 | migrations.AddField( 21 | model_name='vototalk', 22 | name='modified', 23 | field=models.DateTimeField(auto_now=True, null=True), 24 | ), 25 | ] 26 | -------------------------------------------------------------------------------- /conference/migrations/0013_add_stripe_charge_id.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Generated by Django 1.11.20 on 2019-05-19 11:32 3 | from __future__ import unicode_literals 4 | 5 | import conference.models 6 | from django.db import migrations, models 7 | 8 | 9 | class Migration(migrations.Migration): 10 | 11 | dependencies = [ 12 | ('conference', '0012_add_vototalk_timestamps'), 13 | ] 14 | 15 | operations = [ 16 | migrations.AddField( 17 | model_name='stripepayment', 18 | name='charge_id', 19 | field=models.CharField(max_length=100, null=True), 20 | ), 21 | ] 22 | -------------------------------------------------------------------------------- /conference/migrations/0014_stripe_charge_default_uuid.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Generated by Django 1.11.20 on 2019-06-10 11:52 3 | from __future__ import unicode_literals 4 | 5 | import conference.models 6 | from django.db import migrations, models 7 | import uuid 8 | 9 | 10 | class Migration(migrations.Migration): 11 | 12 | dependencies = [ 13 | ('conference', '0013_add_stripe_charge_id'), 14 | ] 15 | 16 | operations = [ 17 | migrations.AlterField( 18 | model_name='stripepayment', 19 | name='uuid', 20 | field=models.CharField(default=uuid.uuid4, max_length=40, unique=True), 21 | ), 22 | ] 23 | -------------------------------------------------------------------------------- /conference/migrations/0015_add_talk_url_fields.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Generated by Django 1.11.21 on 2019-08-08 17:55 3 | from __future__ import unicode_literals 4 | 5 | import conference.models 6 | from django.conf import settings 7 | from django.db import migrations, models 8 | import django.db.models.deletion 9 | 10 | 11 | class Migration(migrations.Migration): 12 | 13 | dependencies = [ 14 | ('conference', '0014_stripe_charge_default_uuid'), 15 | ] 16 | 17 | operations = [ 18 | migrations.AddField( 19 | model_name='talk', 20 | name='repository_url', 21 | field=models.URLField(blank=True), 22 | ), 23 | migrations.AddField( 24 | model_name='talk', 25 | name='slides_url', 26 | field=models.URLField(blank=True), 27 | ), 28 | ] 29 | -------------------------------------------------------------------------------- /conference/migrations/0019_add_stripe_session_id.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from __future__ import unicode_literals 3 | 4 | import conference.models 5 | from django.db import migrations, models 6 | 7 | 8 | class Migration(migrations.Migration): 9 | 10 | dependencies = [ 11 | ('conference', '0018_remove_unused_models'), 12 | ] 13 | 14 | operations = [ 15 | migrations.AddField( 16 | model_name='stripepayment', 17 | name='session_id', 18 | field=models.CharField(max_length=100, null=True), 19 | ), 20 | ] 21 | -------------------------------------------------------------------------------- /conference/migrations/0020_make_gender_field_required.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Generated by Django 1.11.28 on 2020-03-02 21:15 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 | ('conference', '0019_add_stripe_session_id'), 12 | ] 13 | 14 | operations = [ 15 | migrations.AlterField( 16 | model_name='attendeeprofile', 17 | name='gender', 18 | field=models.CharField(choices=[('m', 'Male'), ('f', 'Female'), ('o', 'Other'), ('x', 'Prefer not to say')], help_text='We use this information for statistics related to conference attendance diversity.', max_length=1), 19 | ), 20 | migrations.AlterField( 21 | model_name='attendeeprofile', 22 | name='phone', 23 | field=models.CharField(blank=True, help_text='We require a mobile phone number for all speakers for last minute contacts and in case we need timely clarification (if no reponse to previous emails). Use the international format (e.g.: +44 123456789).', max_length=30, verbose_name='Phone'), 24 | ), 25 | ] 26 | -------------------------------------------------------------------------------- /conference/migrations/0022_alter_sponsorincome_tags.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Generated by Django 1.11.29 on 2020-03-04 20:48 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 | ('conference', '0021_alter_add_deletion_PROTECT'), 12 | ] 13 | 14 | operations = [ 15 | migrations.AlterField( 16 | model_name='sponsorincome', 17 | name='tags', 18 | field=models.CharField(blank=True, help_text='comma separated list of tags. Something like: special, break, keynote', max_length=200), 19 | ), 20 | ] 21 | -------------------------------------------------------------------------------- /conference/migrations/0023_update_field_descriptions.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Generated by Django 1.11.29 on 2020-05-20 14:15 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 | ('conference', '0022_alter_sponsorincome_tags'), 12 | ] 13 | 14 | operations = [ 15 | migrations.AlterField( 16 | model_name='schedule', 17 | name='conference', 18 | field=models.CharField(help_text='Name of the conference', max_length=20), 19 | ), 20 | migrations.AlterField( 21 | model_name='track', 22 | name='order', 23 | field=models.PositiveIntegerField(default=0), 24 | ), 25 | migrations.AlterField( 26 | model_name='track', 27 | name='title', 28 | field=models.TextField(help_text='HTML supported', verbose_name='Track title'), 29 | ), 30 | migrations.AlterField( 31 | model_name='track', 32 | name='track', 33 | field=models.CharField(max_length=20, verbose_name='Track name'), 34 | ), 35 | ] 36 | -------------------------------------------------------------------------------- /conference/migrations/0024_add_talk_status_declined.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Generated by Django 1.11.29 on 2020-05-27 08:45 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 | ('conference', '0023_update_field_descriptions'), 12 | ] 13 | 14 | operations = [ 15 | migrations.AlterField( 16 | model_name='talk', 17 | name='status', 18 | field=models.CharField(choices=[('proposed', 'Proposed'), ('accepted', 'Accepted'), ('canceled', 'Canceled'), ('waitlist', 'Waitlist'), ('declined', 'Declined')], default='proposed', max_length=8), 19 | ), 20 | ] 21 | -------------------------------------------------------------------------------- /conference/migrations/0025_add_poster_45_type.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Generated by Django 1.11.29 on 2020-06-17 12:53 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 | ('conference', '0024_add_talk_status_declined'), 12 | ] 13 | 14 | operations = [ 15 | migrations.AlterField( 16 | model_name='talk', 17 | name='type', 18 | field=models.CharField(choices=[('t_30', 'Talk (30 mins)'), ('t_45', 'Talk (45 mins)'), ('t_60', 'Talk (60 mins)'), ('i_60', 'Interactive (60 mins)'), ('r_180', 'Training (180 mins)'), ('p_45', 'Poster session (45 mins)'), ('p_180', 'Poster session (180 mins)'), ('n_60', 'Panel (60 mins)'), ('n_90', 'Panel (90 mins)'), ('h_180', 'Help desk (180 mins)')], default='t_30', max_length=5), 19 | ), 20 | ] 21 | -------------------------------------------------------------------------------- /conference/migrations/0026_auto_20201204_1130.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.17 on 2020-12-04 10:30 2 | 3 | from django.db import migrations, models 4 | import django.db.models.deletion 5 | 6 | 7 | class Migration(migrations.Migration): 8 | 9 | dependencies = [ 10 | ('conference', '0025_add_poster_45_type'), 11 | ] 12 | 13 | operations = [ 14 | migrations.AlterField( 15 | model_name='conferencetag', 16 | name='name', 17 | field=models.CharField(max_length=100, unique=True, verbose_name='name'), 18 | ), 19 | migrations.AlterField( 20 | model_name='conferencetag', 21 | name='slug', 22 | field=models.SlugField(max_length=100, unique=True, verbose_name='slug'), 23 | ), 24 | migrations.AlterField( 25 | model_name='conferencetaggeditem', 26 | name='content_type', 27 | field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='conference_conferencetaggeditem_tagged_items', to='contenttypes.ContentType', verbose_name='content type'), 28 | ), 29 | migrations.AlterField( 30 | model_name='conferencetaggeditem', 31 | name='object_id', 32 | field=models.IntegerField(db_index=True, verbose_name='object ID'), 33 | ), 34 | ] 35 | -------------------------------------------------------------------------------- /conference/migrations/0027_auto_20201204_1539.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.17 on 2020-12-04 14:39 2 | 3 | from django.db import migrations, models 4 | import django.db.models.deletion 5 | 6 | 7 | class Migration(migrations.Migration): 8 | 9 | dependencies = [ 10 | ('conference', '0026_auto_20201204_1130'), 11 | ] 12 | 13 | operations = [ 14 | migrations.AlterField( 15 | model_name='conferencetag', 16 | name='name', 17 | field=models.CharField(max_length=100, unique=True, verbose_name='Name'), 18 | ), 19 | migrations.AlterField( 20 | model_name='conferencetag', 21 | name='slug', 22 | field=models.SlugField(max_length=100, unique=True, verbose_name='Slug'), 23 | ), 24 | migrations.AlterField( 25 | model_name='conferencetaggeditem', 26 | name='content_type', 27 | field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='conference_conferencetaggeditem_tagged_items', to='contenttypes.ContentType', verbose_name='Content type'), 28 | ), 29 | migrations.AlterField( 30 | model_name='conferencetaggeditem', 31 | name='object_id', 32 | field=models.IntegerField(db_index=True, verbose_name='Object id'), 33 | ), 34 | ] 35 | -------------------------------------------------------------------------------- /conference/migrations/0029_talk_availability.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.19 on 2021-04-24 14:38 2 | 3 | from django.db import migrations, models 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('conference', '0028_changes_to_conferencetag_and_conferencetaggeditem'), 10 | ] 11 | 12 | operations = [ 13 | migrations.AddField( 14 | model_name='talk', 15 | name='availability', 16 | field=models.TextField(blank=True, default='', help_text='

Please enter your time availability.

', verbose_name='Timezone availability'), 17 | ), 18 | ] 19 | -------------------------------------------------------------------------------- /conference/migrations/0030_add_streamset.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.19 on 2021-05-22 13:40 2 | 3 | from django.db import migrations, models 4 | import django.db.models.deletion 5 | import django_extensions.db.fields.json 6 | 7 | 8 | class Migration(migrations.Migration): 9 | 10 | dependencies = [ 11 | ('conference', '0029_talk_availability'), 12 | ] 13 | 14 | operations = [ 15 | migrations.CreateModel( 16 | name='StreamSet', 17 | fields=[ 18 | ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), 19 | ('name', models.CharField(max_length=255)), 20 | ('enabled', models.BooleanField(default=True, help_text='Is this set visible to enduser?')), 21 | ('start_date', models.DateTimeField(blank=True, null=True)), 22 | ('end_date', models.DateTimeField(blank=True, null=True)), 23 | ('streams', django_extensions.db.fields.json.JSONField(blank=True, default=dict, help_text='Stream definitions as JSON list')), 24 | ('conference', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='conference.Conference')), 25 | ], 26 | ), 27 | ] 28 | -------------------------------------------------------------------------------- /conference/migrations/0031_update_streamset_help_text.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.19 on 2021-05-24 14:07 2 | 3 | from django.db import migrations 4 | import django_extensions.db.fields.json 5 | 6 | 7 | class Migration(migrations.Migration): 8 | 9 | dependencies = [ 10 | ('conference', '0030_add_streamset'), 11 | ] 12 | 13 | operations = [ 14 | migrations.AlterField( 15 | model_name='streamset', 16 | name='streams', 17 | field=django_extensions.db.fields.json.JSONField(blank=True, default=dict, help_text='Stream definitions as JSON list, with one entry per track in\nthe stream set. Order is important. The stream page will default to showing the first\ntrack. Example:\n[\n {\n "title": "Holy Grail",\n "fare_codes": ["TRCC", "TRCP", "TRSC", "TRSP", "TRVC", "TRVP"],\n "url": "https://www.youtube.com/embed/EEIk7gwjgIM"\n }\n]\n'), 18 | ), 19 | ] 20 | -------------------------------------------------------------------------------- /conference/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EuroPython/epcon/341c22649ff4ec858fc710821303cf3b78aa59e6/conference/migrations/__init__.py -------------------------------------------------------------------------------- /conference/news.py: -------------------------------------------------------------------------------- 1 | from django.views.generic import ListView 2 | 3 | from .models import News 4 | 5 | 6 | class NewsList(ListView): 7 | model = News 8 | paginate_by = 100 9 | template_name = "conference/news/list.html" 10 | context_object_name = "news" 11 | 12 | def get_context_data(self, **kwargs): 13 | context = super().get_context_data(**kwargs) 14 | context["title"] = "Latest News" 15 | return context 16 | 17 | def get_queryset(self): 18 | return News.objects.filter(status=News.STATUS.PUBLISHED) 19 | 20 | 21 | news_list = NewsList.as_view() 22 | -------------------------------------------------------------------------------- /conference/social_card.py: -------------------------------------------------------------------------------- 1 | from django import http 2 | from django.conf.urls import url as re_path 3 | from django.shortcuts import get_object_or_404 4 | from django.template.loader import render_to_string 5 | 6 | from weasyprint import HTML 7 | 8 | from conference.models import Talk 9 | 10 | 11 | def talk_social_card_png(request, slug): 12 | talk = get_object_or_404(Talk, slug=slug) 13 | 14 | subtitle = ", ".join( 15 | [ 16 | speaker.user.assopy_user.name() 17 | for speaker in talk.speakers.all().select_related( 18 | "user__assopy_user" 19 | ) 20 | ] 21 | ) 22 | 23 | content = render_to_string( 24 | "conference/conference/talk_social_card.html", 25 | {"title": talk.title, "subtitle": subtitle}, 26 | ) 27 | 28 | data = HTML( 29 | string=content, base_url=request.build_absolute_uri("/") 30 | ).write_png() 31 | 32 | return http.HttpResponse(data, content_type="image/png") 33 | 34 | 35 | urlpatterns = [ 36 | re_path( 37 | r"^talks/(?P[\w-]+)/social-card.png$", 38 | talk_social_card_png, 39 | name="conference-talk-social-card-png", 40 | ), 41 | ] 42 | -------------------------------------------------------------------------------- /conference/static/conference/images/500.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EuroPython/epcon/341c22649ff4ec858fc710821303cf3b78aa59e6/conference/static/conference/images/500.jpg -------------------------------------------------------------------------------- /conference/static/conference/jquery-flot/.gitignore: -------------------------------------------------------------------------------- 1 | *.min.js 2 | !excanvas.min.js 3 | node_modules/ 4 | -------------------------------------------------------------------------------- /conference/static/conference/jquery-flot/.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - 0.8 4 | -------------------------------------------------------------------------------- /conference/static/conference/jquery-flot/LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2007-2014 IOLA and Ole Laursen 2 | 3 | Permission is hereby granted, free of charge, to any person 4 | obtaining a copy of this software and associated documentation 5 | files (the "Software"), to deal in the Software without 6 | restriction, including without limitation the rights to use, 7 | copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the 9 | Software is furnished to do so, subject to the following 10 | conditions: 11 | 12 | The above copyright notice and this permission notice shall be 13 | included in all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 17 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 19 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 20 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 | OTHER DEALINGS IN THE SOFTWARE. 23 | -------------------------------------------------------------------------------- /conference/static/conference/jquery-flot/Makefile: -------------------------------------------------------------------------------- 1 | # Makefile for generating minified files 2 | 3 | .PHONY: all 4 | 5 | # we cheat and process all .js files instead of an exhaustive list 6 | all: $(patsubst %.js,%.min.js,$(filter-out %.min.js,$(wildcard *.js))) 7 | 8 | %.min.js: %.js 9 | yui-compressor $< -o $@ 10 | 11 | test: 12 | ./node_modules/.bin/jshint *jquery.flot.js 13 | -------------------------------------------------------------------------------- /conference/static/conference/jquery-flot/component.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Flot", 3 | "version": "0.8.3", 4 | "main": "jquery.flot.js", 5 | "dependencies": { 6 | "jquery": ">= 1.2.6" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /conference/static/conference/jquery-flot/examples/ajax/data-eu-gdp-growth-1.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "Europe (EU27)", 3 | "data": [[1999, 3.0], [2000, 3.9]] 4 | } 5 | -------------------------------------------------------------------------------- /conference/static/conference/jquery-flot/examples/ajax/data-eu-gdp-growth-2.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "Europe (EU27)", 3 | "data": [[1999, 3.0], [2000, 3.9], [2001, 2.0], [2002, 1.2]] 4 | } 5 | -------------------------------------------------------------------------------- /conference/static/conference/jquery-flot/examples/ajax/data-eu-gdp-growth-3.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "Europe (EU27)", 3 | "data": [[1999, 3.0], [2000, 3.9], [2001, 2.0], [2002, 1.2], [2003, 1.3], [2004, 2.5]] 4 | } 5 | -------------------------------------------------------------------------------- /conference/static/conference/jquery-flot/examples/ajax/data-eu-gdp-growth-4.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "Europe (EU27)", 3 | "data": [[1999, 3.0], [2000, 3.9], [2001, 2.0], [2002, 1.2], [2003, 1.3], [2004, 2.5], [2005, 2.0], [2006, 3.1]] 4 | } 5 | -------------------------------------------------------------------------------- /conference/static/conference/jquery-flot/examples/ajax/data-eu-gdp-growth-5.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "Europe (EU27)", 3 | "data": [[1999, 3.0], [2000, 3.9], [2001, 2.0], [2002, 1.2], [2003, 1.3], [2004, 2.5], [2005, 2.0], [2006, 3.1], [2007, 2.9], [2008, 0.9]] 4 | } 5 | -------------------------------------------------------------------------------- /conference/static/conference/jquery-flot/examples/ajax/data-eu-gdp-growth.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "Europe (EU27)", 3 | "data": [[1999, 3.0], [2000, 3.9], [2001, 2.0], [2002, 1.2], [2003, 1.3], [2004, 2.5], [2005, 2.0], [2006, 3.1], [2007, 2.9], [2008, 0.9]] 4 | } 5 | -------------------------------------------------------------------------------- /conference/static/conference/jquery-flot/examples/ajax/data-japan-gdp-growth.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "Japan", 3 | "data": [[1999, -0.1], [2000, 2.9], [2001, 0.2], [2002, 0.3], [2003, 1.4], [2004, 2.7], [2005, 1.9], [2006, 2.0], [2007, 2.3], [2008, -0.7]] 4 | } 5 | -------------------------------------------------------------------------------- /conference/static/conference/jquery-flot/examples/ajax/data-usa-gdp-growth.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "USA", 3 | "data": [[1999, 4.4], [2000, 3.7], [2001, 0.8], [2002, 1.6], [2003, 2.5], [2004, 3.6], [2005, 2.9], [2006, 2.8], [2007, 2.0], [2008, 1.1]] 4 | } 5 | -------------------------------------------------------------------------------- /conference/static/conference/jquery-flot/examples/axes-time-zones/tz/factory: -------------------------------------------------------------------------------- 1 | #
 2 | # This file is in the public domain, so clarified as of
 3 | # 2009-05-17 by Arthur David Olson.
 4 | 
 5 | # For companies who don't want to put time zone specification in
 6 | # their installation procedures.  When users run date, they'll get the message.
 7 | # Also useful for the "comp.sources" version.
 8 | 
 9 | # Zone	NAME	GMTOFF	RULES	FORMAT
10 | Zone	Factory	0	- "Local time zone must be set--see zic manual page"
11 | 


--------------------------------------------------------------------------------
/conference/static/conference/jquery-flot/examples/axes-time-zones/tz/southamerica:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EuroPython/epcon/341c22649ff4ec858fc710821303cf3b78aa59e6/conference/static/conference/jquery-flot/examples/axes-time-zones/tz/southamerica


--------------------------------------------------------------------------------
/conference/static/conference/jquery-flot/examples/axes-time-zones/tz/yearistype.sh:
--------------------------------------------------------------------------------
 1 | #! /bin/sh
 2 | 
 3 | : 'This file is in the public domain, so clarified as of'
 4 | : '2006-07-17 by Arthur David Olson.'
 5 | 
 6 | case $#-$1 in
 7 | 	2-|2-0*|2-*[!0-9]*)
 8 | 		echo "$0: wild year - $1" >&2
 9 | 		exit 1 ;;
10 | esac
11 | 
12 | case $#-$2 in
13 | 	2-even)
14 | 		case $1 in
15 | 			*[24680])			exit 0 ;;
16 | 			*)				exit 1 ;;
17 | 		esac ;;
18 | 	2-nonpres|2-nonuspres)
19 | 		case $1 in
20 | 			*[02468][048]|*[13579][26])	exit 1 ;;
21 | 			*)				exit 0 ;;
22 | 		esac ;;
23 | 	2-odd)
24 | 		case $1 in
25 | 			*[13579])			exit 0 ;;
26 | 			*)				exit 1 ;;
27 | 		esac ;;
28 | 	2-uspres)
29 | 		case $1 in
30 | 			*[02468][048]|*[13579][26])	exit 0 ;;
31 | 			*)				exit 1 ;;
32 | 		esac ;;
33 | 	2-*)
34 | 		echo "$0: wild type - $2" >&2 ;;
35 | esac
36 | 
37 | echo "$0: usage is $0 year even|odd|uspres|nonpres|nonuspres" >&2
38 | exit 1
39 | 


--------------------------------------------------------------------------------
/conference/static/conference/jquery-flot/examples/background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EuroPython/epcon/341c22649ff4ec858fc710821303cf3b78aa59e6/conference/static/conference/jquery-flot/examples/background.png


--------------------------------------------------------------------------------
/conference/static/conference/jquery-flot/examples/image/hs-2004-27-a-large-web.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EuroPython/epcon/341c22649ff4ec858fc710821303cf3b78aa59e6/conference/static/conference/jquery-flot/examples/image/hs-2004-27-a-large-web.jpg


--------------------------------------------------------------------------------
/conference/static/conference/jquery-flot/examples/navigate/arrow-down.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EuroPython/epcon/341c22649ff4ec858fc710821303cf3b78aa59e6/conference/static/conference/jquery-flot/examples/navigate/arrow-down.gif


--------------------------------------------------------------------------------
/conference/static/conference/jquery-flot/examples/navigate/arrow-left.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EuroPython/epcon/341c22649ff4ec858fc710821303cf3b78aa59e6/conference/static/conference/jquery-flot/examples/navigate/arrow-left.gif


--------------------------------------------------------------------------------
/conference/static/conference/jquery-flot/examples/navigate/arrow-right.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EuroPython/epcon/341c22649ff4ec858fc710821303cf3b78aa59e6/conference/static/conference/jquery-flot/examples/navigate/arrow-right.gif


--------------------------------------------------------------------------------
/conference/static/conference/jquery-flot/examples/navigate/arrow-up.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EuroPython/epcon/341c22649ff4ec858fc710821303cf3b78aa59e6/conference/static/conference/jquery-flot/examples/navigate/arrow-up.gif


--------------------------------------------------------------------------------
/conference/static/conference/jquery-flot/flot.jquery.json:
--------------------------------------------------------------------------------
 1 | {
 2 | 	"name": "flot",
 3 | 	"version": "0.8.3",
 4 | 	"title": "Flot",
 5 | 	"author": {
 6 | 		"name": "Ole Laursen",
 7 | 		"url": "https://github.com/OleLaursen"
 8 | 	},
 9 | 	"licenses": [{
10 | 		"type": "MIT",
11 | 		"url": "http://github.com/flot/flot/blob/master/LICENSE.txt"
12 | 	}],
13 | 	"dependencies": {
14 | 		"jquery": ">=1.2.6"
15 | 	},
16 | 	"description": "Flot is a pure JavaScript plotting library for jQuery, with a focus on simple usage, attractive looks and interactive features.",
17 | 	"keywords": ["plot", "chart", "graph", "visualization", "canvas", "graphics"],
18 | 	"homepage": "http://www.flotcharts.org",
19 | 	"docs": "http://github.com/flot/flot/blob/master/API.md",
20 | 	"demo": "http://www.flotcharts.org/flot/examples/",
21 | 	"bugs": "http://github.com/flot/flot/issues",
22 | 	"maintainers": [{
23 | 		"name": "David Schnur",
24 | 		"email": "dnschnur@gmail.com",
25 | 		"url": "http://github.com/dnschnur"
26 | 	}]
27 | }
28 | 


--------------------------------------------------------------------------------
/conference/static/conference/jquery-flot/package.json:
--------------------------------------------------------------------------------
 1 | {
 2 | 	"name": "Flot",
 3 | 	"version": "0.8.3",
 4 | 	"main": "jquery.flot.js",
 5 | 	"scripts": {
 6 | 		"test": "make test"
 7 | 	},
 8 | 	"devDependencies": {
 9 | 		"jshint": "0.9.1"
10 | 	}
11 | }
12 | 


--------------------------------------------------------------------------------
/conference/static/conference/jquery-ui/css/flick/images/ui-bg_flat_0_aaaaaa_40x100.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EuroPython/epcon/341c22649ff4ec858fc710821303cf3b78aa59e6/conference/static/conference/jquery-ui/css/flick/images/ui-bg_flat_0_aaaaaa_40x100.png


--------------------------------------------------------------------------------
/conference/static/conference/jquery-ui/css/flick/images/ui-bg_flat_0_eeeeee_40x100.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EuroPython/epcon/341c22649ff4ec858fc710821303cf3b78aa59e6/conference/static/conference/jquery-ui/css/flick/images/ui-bg_flat_0_eeeeee_40x100.png


--------------------------------------------------------------------------------
/conference/static/conference/jquery-ui/css/flick/images/ui-bg_flat_55_ffffff_40x100.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EuroPython/epcon/341c22649ff4ec858fc710821303cf3b78aa59e6/conference/static/conference/jquery-ui/css/flick/images/ui-bg_flat_55_ffffff_40x100.png


--------------------------------------------------------------------------------
/conference/static/conference/jquery-ui/css/flick/images/ui-bg_flat_75_ffffff_40x100.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EuroPython/epcon/341c22649ff4ec858fc710821303cf3b78aa59e6/conference/static/conference/jquery-ui/css/flick/images/ui-bg_flat_75_ffffff_40x100.png


--------------------------------------------------------------------------------
/conference/static/conference/jquery-ui/css/flick/images/ui-bg_glass_65_ffffff_1x400.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EuroPython/epcon/341c22649ff4ec858fc710821303cf3b78aa59e6/conference/static/conference/jquery-ui/css/flick/images/ui-bg_glass_65_ffffff_1x400.png


--------------------------------------------------------------------------------
/conference/static/conference/jquery-ui/css/flick/images/ui-bg_highlight-soft_100_f6f6f6_1x100.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EuroPython/epcon/341c22649ff4ec858fc710821303cf3b78aa59e6/conference/static/conference/jquery-ui/css/flick/images/ui-bg_highlight-soft_100_f6f6f6_1x100.png


--------------------------------------------------------------------------------
/conference/static/conference/jquery-ui/css/flick/images/ui-bg_highlight-soft_25_0073ea_1x100.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EuroPython/epcon/341c22649ff4ec858fc710821303cf3b78aa59e6/conference/static/conference/jquery-ui/css/flick/images/ui-bg_highlight-soft_25_0073ea_1x100.png


--------------------------------------------------------------------------------
/conference/static/conference/jquery-ui/css/flick/images/ui-bg_highlight-soft_50_dddddd_1x100.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EuroPython/epcon/341c22649ff4ec858fc710821303cf3b78aa59e6/conference/static/conference/jquery-ui/css/flick/images/ui-bg_highlight-soft_50_dddddd_1x100.png


--------------------------------------------------------------------------------
/conference/static/conference/jquery-ui/css/flick/images/ui-icons_0073ea_256x240.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EuroPython/epcon/341c22649ff4ec858fc710821303cf3b78aa59e6/conference/static/conference/jquery-ui/css/flick/images/ui-icons_0073ea_256x240.png


--------------------------------------------------------------------------------
/conference/static/conference/jquery-ui/css/flick/images/ui-icons_454545_256x240.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EuroPython/epcon/341c22649ff4ec858fc710821303cf3b78aa59e6/conference/static/conference/jquery-ui/css/flick/images/ui-icons_454545_256x240.png


--------------------------------------------------------------------------------
/conference/static/conference/jquery-ui/css/flick/images/ui-icons_666666_256x240.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EuroPython/epcon/341c22649ff4ec858fc710821303cf3b78aa59e6/conference/static/conference/jquery-ui/css/flick/images/ui-icons_666666_256x240.png


--------------------------------------------------------------------------------
/conference/static/conference/jquery-ui/css/flick/images/ui-icons_ff0084_256x240.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EuroPython/epcon/341c22649ff4ec858fc710821303cf3b78aa59e6/conference/static/conference/jquery-ui/css/flick/images/ui-icons_ff0084_256x240.png


--------------------------------------------------------------------------------
/conference/static/conference/jquery-ui/css/flick/images/ui-icons_ffffff_256x240.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EuroPython/epcon/341c22649ff4ec858fc710821303cf3b78aa59e6/conference/static/conference/jquery-ui/css/flick/images/ui-icons_ffffff_256x240.png


--------------------------------------------------------------------------------
/conference/templatetags/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EuroPython/epcon/341c22649ff4ec858fc710821303cf3b78aa59e6/conference/templatetags/__init__.py


--------------------------------------------------------------------------------
/conference/templatetags/template_tools.py:
--------------------------------------------------------------------------------
1 | from django import template
2 | 
3 | register = template.Library()
4 | 
5 | 
6 | @register.filter
7 | def get_item(dictionary, key):
8 |     return dictionary.get(key)
9 | 


--------------------------------------------------------------------------------
/conference/tools/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EuroPython/epcon/341c22649ff4ec858fc710821303cf3b78aa59e6/conference/tools/__init__.py


--------------------------------------------------------------------------------
/conference/tools/voteengine-0.99/CHANGES:
--------------------------------------------------------------------------------
 1 | CHANGELOG
 2 | 
 3 | 2021-05-25 MAL:
 4 | - partially ported to Python 3 -- only as far as was needed to make the
 5 |   tool run again
 6 | 
 7 | -----
 8 | 
 9 | 0.99 Feb 12 2001
10 |  Fixed some bugs introduced by 0.95.  Changed how method options
11 |  are done.
12 | 
13 | 0.95 Nov 14 2001
14 |  Fixed a bug, and made major internal changes
15 | 
16 | 0.94 Nov 10 2001
17 |  Windows compatability changes.
18 | 
19 | 0.93 Nov 10 2001
20 |  Added Nanson's original method. 
21 | 
22 | 0.92 Aug 23 2001
23 |  I changed the way multiple ballots per line are handled.  Instead of the
24 |  old "-each" command, I now use the colon.
25 | 
26 | 0.91 Aug 13 2001
27 |  Changed name of Nanson to borda-elim in a desperate 
28 |  attempt to avoid confusion
29 | 
30 | 0.90 Apr 23 2001
31 |  Changed RP tiebreaker to be the same as Zavist and Tideman's
32 |  
33 | 0.85-0.88 Feb 21 2001 - Mar 13 2001
34 |  Correction of RP algorithm
35 | 
36 | 0.8 Feb 04 2001
37 |  Some bug fixes/algorithm improvements
38 | 
39 | 0.11
40 |  Changed name of Tideman's method to Ranked Pairs.
41 | 
42 | 0.1
43 |  The introduction of version numbers
44 |  The introduction of a change log
45 |  Major internal revisions.  Introduction of some non-pairwise methods.
46 | 


--------------------------------------------------------------------------------
/conference/tools/voteengine-0.99/input.txt:
--------------------------------------------------------------------------------
1 | -m borda-elim
2 | -cands A B C D E -tie C B D A E
3 | A B C D E
4 | B C D E A
5 | C D E A B
6 | D E A B C
7 | E A B C D
8 | 


--------------------------------------------------------------------------------
/conference/tools/voteengine-0.99/rob:
--------------------------------------------------------------------------------
1 | -cands A B C D
2 | 110: B C A D
3 | 37: B C D A
4 | 161: B D C A
5 | 125: C A B D
6 | 190: C A D B
7 | 298: D A B C
8 | 
9 | 


--------------------------------------------------------------------------------
/conference/tools/voteengine-0.99/rob2:
--------------------------------------------------------------------------------
1 | -cands A B C D
2 | 12:  A>B>C>D
3 | 21:  B>A>C>D
4 | 12:  B>A>D>C
5 | 6:   B>D>A>C
6 | 21:  C>D>A>B
7 | 3:   D>A>C>B
8 | 25:  D>C>A>B
9 | 


--------------------------------------------------------------------------------
/conference/tools/voteengine-0.99/roy:
--------------------------------------------------------------------------------
1 | -cands A B C D X
2 | -table
3 | A  -   71  42  29  39 
4 | B  29  -   71  58  39
5 | C  58  29  -   87  39
6 | D  71  42  13  -   39
7 | X  61  61  61  61  -
8 | 


--------------------------------------------------------------------------------
/conference/tools/voteengine-0.99/test:
--------------------------------------------------------------------------------
1 | -cands A B C D E F
2 | -tie A F B E C D
3 | A B C D E F
4 | B C A E F D
5 | C A B F D E
6 | 


--------------------------------------------------------------------------------
/conference/tools/voteengine-0.99/test2:
--------------------------------------------------------------------------------
 1 | -cands A-F 
 2 | -table
 3 | #   A    B     C     D     E      F
 4 | A   X    6     0     0     0      0
 5 | B   0    X     5     0     0      0
 6 | C   4    0     X     0     7      0
 7 | D   0    0     0     X     9      0
 8 | E   0    0     0     0     X      10
 9 | F   0    0     0     8     0      X
10 | 


--------------------------------------------------------------------------------
/conference/tools/voteengine-0.99/test3:
--------------------------------------------------------------------------------
1 | -cands A B C D E -tie C B D A E
2 | A B C D E
3 | B C D E A
4 | C D E A B
5 | D E A B C
6 | E A B C D
7 | 


--------------------------------------------------------------------------------
/conference/tools/voteengine-0.99/test5:
--------------------------------------------------------------------------------
 1 | -m rp
 2 | -cands A B C D E
 3 | -table
 4 | #    A   B   C   D   E
 5 | A    X   3   2   7   0 
 6 | B    0   X   6   0   1
 7 | C    0   0   X   6   8
 8 | D    0   6   0   X   0
 9 | E    4   0   0   0   X
10 | 
11 | 


--------------------------------------------------------------------------------
/conference/tools/voteengine-0.99/ve.py:
--------------------------------------------------------------------------------
 1 | #!/usr/bin/python
 2 | 
 3 | """
 4 | Vote counter by Blake Cretney 
 5 | 
 6 | This work is distributed AS IS.  It is up to you to 
 7 | determine if it is useful and safe.  In particular, 
 8 | NO WARRANTY is expressed or implied.
 9 | 
10 | I permanently give everyone the rights to use, modify, 
11 | copy, distribute, re-distribute, and perform this work, 
12 | and all derived works, to the extent that I hold copyright 
13 | in them.  My intent is to have this work treated as 
14 | public domain.
15 | 
16 | This module is used to run the program where a proper console
17 | is not available.  I wrote it for Windows, but maybe it works
18 | on a Mac too.  I have no way of knowing.
19 | """
20 | 
21 | import votemain
22 | import sys
23 | 
24 | sys_stdin=sys.stdin
25 | sys_stdout=sys.stdout
26 | pause=1
27 | try:
28 | 	sys.stdin=open("input.txt")
29 | 	sys.stdout=open("output.txt","w")
30 | 	votemain.vote_main()
31 | 	pause=0
32 | except IOError as e:
33 | 	sys_stdout.write(str(e) + "\n")
34 | except RuntimeError as e:
35 | 	sys_stdout.write(e.args[0] + "\n")
36 | if pause:
37 | 	try:
38 | 		import msvcrt
39 | 		sys_stdout.write("Press any key to continue\n")
40 | 		c = msvcrt.getch()
41 | 		pause=0
42 | 	except: pass
43 | 
44 | 


--------------------------------------------------------------------------------
/conference/tools/voteengine-0.99/voteengine.py:
--------------------------------------------------------------------------------
 1 | #!/usr/bin/env python3
 2 | 
 3 | """
 4 | Vote counter by Blake Cretney
 5 | 
 6 | This work is distributed AS IS.  It is up to you to
 7 | determine if it is useful and safe.  In particular,
 8 | NO WARRANTY is expressed or implied.
 9 | 
10 | I permanently give everyone the rights to use, modify,
11 | copy, distribute, re-distribute, and perform this work,
12 | and all derived works, to the extent that I hold copyright
13 | in them.  My intent is to have this work treated as
14 | public domain.
15 | 
16 | This module actually starts the program.
17 | """
18 | 
19 | import votemain
20 | votemain.vote_engine()
21 | 


--------------------------------------------------------------------------------
/conference/tools/voteengine-0.99/zav:
--------------------------------------------------------------------------------
 1 | -cands a b b' c d e f
 2 | 
 3 | d e b b' f a c
 4 | e b b' f c a d
 5 | b b' f c a d e
 6 | c f a d e b b'
 7 | d c a e b b' f
 8 | a b' b c d e f
 9 | a c b' b d e f
10 | f e a c b' b d
11 | f e b' b d c a
12 | 


--------------------------------------------------------------------------------
/conference/users.py:
--------------------------------------------------------------------------------
 1 | """
 2 | This module takes care of a lot of user related things.
 3 | It's a good place to put validators and user management functions/classes
 4 | """
 5 | import os
 6 | 
 7 | 
 8 | RANDOM_USERNAME_LENGTH = 12
 9 | 
10 | 
11 | def generate_random_username():
12 |     """Returns random username of length set by RANDOM_USERNAME_LENGTH
13 |     
14 |        The generated names will always start with 'ep' to make sure that we
15 |        don't generate numeric only names.
16 |        
17 |     """
18 |     return 'ep' + os.urandom(100).hex()[:RANDOM_USERNAME_LENGTH-2]
19 | 


--------------------------------------------------------------------------------
/docker-compose-vscode-debugger.yml:
--------------------------------------------------------------------------------
1 | version: '3.7'
2 | 
3 | services:
4 |   epcon:
5 |     command: ["python -m ptvsd --host 0.0.0.0 --port 3000 --wait ./manage.py runserver --noreload --nothreading 0.0.0.0:8888"]
6 |     ports:
7 |       - "3000:3000"
8 | 


--------------------------------------------------------------------------------
/docker-compose.yml:
--------------------------------------------------------------------------------
 1 | version: '3.7'
 2 | 
 3 | services:
 4 |   epcon:
 5 |     stdin_open: true
 6 |     tty: true
 7 |     build:
 8 |       context: .
 9 |     environment:
10 |       PYTHONDONTWRITEBYTECODE: 1
11 |       DJANGO_SETTINGS_MODULE: "pycon.dev_settings"
12 |       SECRET_KEY: "secret"
13 |     command: ["./manage.py migrate --no-input && ./manage.py runserver 0.0.0.0:8888"]
14 |     volumes:
15 |       - .:/code
16 |     ports:
17 |       - "8888:8888"
18 | 


--------------------------------------------------------------------------------
/email_template/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EuroPython/epcon/341c22649ff4ec858fc710821303cf3b78aa59e6/email_template/__init__.py


--------------------------------------------------------------------------------
/email_template/admin.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | from django.contrib import admin
3 | from email_template import models
4 | 
5 | class EmailAdmin(admin.ModelAdmin):
6 |     list_display = ( 'code', 'subject', 'from_email', 'cc', 'bcc' )
7 | 
8 | admin.site.register(models.Email, EmailAdmin)
9 | 


--------------------------------------------------------------------------------
/email_template/models.py:
--------------------------------------------------------------------------------
 1 | # -*- coding: utf-8 -*-
 2 | from django.db import models
 3 | from django.template import Template, Context
 4 | from django.utils.safestring import mark_safe
 5 | 
 6 | 
 7 | class Email(models.Model):
 8 |     code = models.CharField('Codice', max_length = 30,
 9 |         unique = True,
10 |         help_text = 'codice testuale che identifica in maniera univoca questa email')
11 |     subject = models.CharField('Oggetto', max_length = 200)
12 |     text = models.TextField('Testo')
13 |     from_email = models.CharField('From address', max_length = 200, blank = True)
14 |     cc = models.TextField('Cc address', blank = True)
15 |     bcc = models.TextField('Bcc address', blank = True)
16 | 
17 |     def __str__(self):
18 |         return 'email_template: %s' % self.code
19 | 
20 |     def render(self, ctx, mark_safestring=True):
21 |         """
22 |         Restituisce subject e body dopo averci applicato il contesto
23 |         passato.
24 |         """
25 |         if mark_safestring:
26 |             ctx = dict(ctx)
27 |             for key, value in ctx.items():
28 |                 if isinstance(value, str):
29 |                     ctx[key] = mark_safe(value)
30 |         ctx = Context(ctx)
31 |         return Template(self.subject).render(ctx), Template(self.text).render(ctx)
32 | 


--------------------------------------------------------------------------------
/email_template/utils.py:
--------------------------------------------------------------------------------
 1 | # -*- coding: utf-8 -*-
 2 | from django.core.mail import EmailMessage
 3 | from django.shortcuts import get_object_or_404
 4 | from email_template import models
 5 | 
 6 | def email(code, ctx, mark_safestring=True, **kw):
 7 |     e = get_object_or_404(models.Email, code = code)
 8 |     subject, body = e.render(ctx, mark_safestring=mark_safestring)
 9 |     email = EmailMessage()
10 |     email.subject = subject
11 |     email.body = body
12 |     if e.from_email and 'from_email' not in kw:
13 |         kw['from_email'] = e.from_email
14 |     for key, value in kw.items():
15 |         setattr(email, key, value)
16 |     if e.bcc:
17 |         email.bcc += [ x.strip() for x in e.bcc.split(',') ]
18 |     if e.cc:
19 |         email.cc += [ x.strip() for x in e.cc.split(',') ]
20 |     return email
21 | 


--------------------------------------------------------------------------------
/email_template/views.py:
--------------------------------------------------------------------------------
1 | # Create your views here.
2 | 


--------------------------------------------------------------------------------
/ep-social-ticket-search-app/CREDITS:
--------------------------------------------------------------------------------
1 | Tools used for the app:
2 | 
3 |  * List.js: http://www.listjs.com/
4 |  * MaterializeCSS: http://materializecss.com/
5 |  * jQuery: https://jquery.com/
6 | 
7 | 


--------------------------------------------------------------------------------
/ep-social-ticket-search-app/README:
--------------------------------------------------------------------------------
 1 | Build Ticket Search App
 2 | -----------------------
 3 | 
 4 |     Creates a single-page fuzzy full text search list with all tickets
 5 |     and their ticket IDs.  Writes the single page to
 6 |     ep-ticket-search-app/index.html
 7 | 
 8 |     This can be used during registration to do quick search in the
 9 |     list of all tickets in order to find badges or find that no badge
10 |     exists.
11 | 
12 |     Usage:
13 | 
14 |     cd ..
15 |     ./manage.py build_ticket_search_app ep2016
16 |     cd ep-ticket-search-app
17 |     ./run.sh
18 | 
19 |     This will build the search app and start a web server running
20 |     on port 8000. Pointing a browser at http://localhost:8000/ will
21 |     then load the app into the browser.
22 | 


--------------------------------------------------------------------------------
/ep-social-ticket-search-app/fonts/roboto/Roboto-Bold.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EuroPython/epcon/341c22649ff4ec858fc710821303cf3b78aa59e6/ep-social-ticket-search-app/fonts/roboto/Roboto-Bold.eot


--------------------------------------------------------------------------------
/ep-social-ticket-search-app/fonts/roboto/Roboto-Bold.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EuroPython/epcon/341c22649ff4ec858fc710821303cf3b78aa59e6/ep-social-ticket-search-app/fonts/roboto/Roboto-Bold.ttf


--------------------------------------------------------------------------------
/ep-social-ticket-search-app/fonts/roboto/Roboto-Bold.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EuroPython/epcon/341c22649ff4ec858fc710821303cf3b78aa59e6/ep-social-ticket-search-app/fonts/roboto/Roboto-Bold.woff


--------------------------------------------------------------------------------
/ep-social-ticket-search-app/fonts/roboto/Roboto-Bold.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EuroPython/epcon/341c22649ff4ec858fc710821303cf3b78aa59e6/ep-social-ticket-search-app/fonts/roboto/Roboto-Bold.woff2


--------------------------------------------------------------------------------
/ep-social-ticket-search-app/fonts/roboto/Roboto-Light.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EuroPython/epcon/341c22649ff4ec858fc710821303cf3b78aa59e6/ep-social-ticket-search-app/fonts/roboto/Roboto-Light.eot


--------------------------------------------------------------------------------
/ep-social-ticket-search-app/fonts/roboto/Roboto-Light.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EuroPython/epcon/341c22649ff4ec858fc710821303cf3b78aa59e6/ep-social-ticket-search-app/fonts/roboto/Roboto-Light.ttf


--------------------------------------------------------------------------------
/ep-social-ticket-search-app/fonts/roboto/Roboto-Light.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EuroPython/epcon/341c22649ff4ec858fc710821303cf3b78aa59e6/ep-social-ticket-search-app/fonts/roboto/Roboto-Light.woff


--------------------------------------------------------------------------------
/ep-social-ticket-search-app/fonts/roboto/Roboto-Light.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EuroPython/epcon/341c22649ff4ec858fc710821303cf3b78aa59e6/ep-social-ticket-search-app/fonts/roboto/Roboto-Light.woff2


--------------------------------------------------------------------------------
/ep-social-ticket-search-app/fonts/roboto/Roboto-Medium.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EuroPython/epcon/341c22649ff4ec858fc710821303cf3b78aa59e6/ep-social-ticket-search-app/fonts/roboto/Roboto-Medium.eot


--------------------------------------------------------------------------------
/ep-social-ticket-search-app/fonts/roboto/Roboto-Medium.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EuroPython/epcon/341c22649ff4ec858fc710821303cf3b78aa59e6/ep-social-ticket-search-app/fonts/roboto/Roboto-Medium.ttf


--------------------------------------------------------------------------------
/ep-social-ticket-search-app/fonts/roboto/Roboto-Medium.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EuroPython/epcon/341c22649ff4ec858fc710821303cf3b78aa59e6/ep-social-ticket-search-app/fonts/roboto/Roboto-Medium.woff


--------------------------------------------------------------------------------
/ep-social-ticket-search-app/fonts/roboto/Roboto-Medium.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EuroPython/epcon/341c22649ff4ec858fc710821303cf3b78aa59e6/ep-social-ticket-search-app/fonts/roboto/Roboto-Medium.woff2


--------------------------------------------------------------------------------
/ep-social-ticket-search-app/fonts/roboto/Roboto-Regular.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EuroPython/epcon/341c22649ff4ec858fc710821303cf3b78aa59e6/ep-social-ticket-search-app/fonts/roboto/Roboto-Regular.eot


--------------------------------------------------------------------------------
/ep-social-ticket-search-app/fonts/roboto/Roboto-Regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EuroPython/epcon/341c22649ff4ec858fc710821303cf3b78aa59e6/ep-social-ticket-search-app/fonts/roboto/Roboto-Regular.ttf


--------------------------------------------------------------------------------
/ep-social-ticket-search-app/fonts/roboto/Roboto-Regular.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EuroPython/epcon/341c22649ff4ec858fc710821303cf3b78aa59e6/ep-social-ticket-search-app/fonts/roboto/Roboto-Regular.woff


--------------------------------------------------------------------------------
/ep-social-ticket-search-app/fonts/roboto/Roboto-Regular.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EuroPython/epcon/341c22649ff4ec858fc710821303cf3b78aa59e6/ep-social-ticket-search-app/fonts/roboto/Roboto-Regular.woff2


--------------------------------------------------------------------------------
/ep-social-ticket-search-app/fonts/roboto/Roboto-Thin.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EuroPython/epcon/341c22649ff4ec858fc710821303cf3b78aa59e6/ep-social-ticket-search-app/fonts/roboto/Roboto-Thin.eot


--------------------------------------------------------------------------------
/ep-social-ticket-search-app/fonts/roboto/Roboto-Thin.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EuroPython/epcon/341c22649ff4ec858fc710821303cf3b78aa59e6/ep-social-ticket-search-app/fonts/roboto/Roboto-Thin.ttf


--------------------------------------------------------------------------------
/ep-social-ticket-search-app/fonts/roboto/Roboto-Thin.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EuroPython/epcon/341c22649ff4ec858fc710821303cf3b78aa59e6/ep-social-ticket-search-app/fonts/roboto/Roboto-Thin.woff


--------------------------------------------------------------------------------
/ep-social-ticket-search-app/fonts/roboto/Roboto-Thin.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EuroPython/epcon/341c22649ff4ec858fc710821303cf3b78aa59e6/ep-social-ticket-search-app/fonts/roboto/Roboto-Thin.woff2


--------------------------------------------------------------------------------
/ep-social-ticket-search-app/materialize/LICENSE:
--------------------------------------------------------------------------------
 1 | The MIT License (MIT)
 2 | 
 3 | Copyright (c) 2014-2016 Materialize
 4 | 
 5 | Permission is hereby granted, free of charge, to any person obtaining a copy
 6 | of this software and associated documentation files (the "Software"), to deal
 7 | in the Software without restriction, including without limitation the rights
 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 | 
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 | 
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 | 


--------------------------------------------------------------------------------
/ep-social-ticket-search-app/materialize/font/material-design-icons/Material-Design-Icons.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EuroPython/epcon/341c22649ff4ec858fc710821303cf3b78aa59e6/ep-social-ticket-search-app/materialize/font/material-design-icons/Material-Design-Icons.eot


--------------------------------------------------------------------------------
/ep-social-ticket-search-app/materialize/font/material-design-icons/Material-Design-Icons.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EuroPython/epcon/341c22649ff4ec858fc710821303cf3b78aa59e6/ep-social-ticket-search-app/materialize/font/material-design-icons/Material-Design-Icons.ttf


--------------------------------------------------------------------------------
/ep-social-ticket-search-app/materialize/font/material-design-icons/Material-Design-Icons.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EuroPython/epcon/341c22649ff4ec858fc710821303cf3b78aa59e6/ep-social-ticket-search-app/materialize/font/material-design-icons/Material-Design-Icons.woff


--------------------------------------------------------------------------------
/ep-social-ticket-search-app/materialize/font/material-design-icons/Material-Design-Icons.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EuroPython/epcon/341c22649ff4ec858fc710821303cf3b78aa59e6/ep-social-ticket-search-app/materialize/font/material-design-icons/Material-Design-Icons.woff2


--------------------------------------------------------------------------------
/ep-social-ticket-search-app/materialize/font/roboto/Roboto-Bold.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EuroPython/epcon/341c22649ff4ec858fc710821303cf3b78aa59e6/ep-social-ticket-search-app/materialize/font/roboto/Roboto-Bold.eot


--------------------------------------------------------------------------------
/ep-social-ticket-search-app/materialize/font/roboto/Roboto-Bold.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EuroPython/epcon/341c22649ff4ec858fc710821303cf3b78aa59e6/ep-social-ticket-search-app/materialize/font/roboto/Roboto-Bold.ttf


--------------------------------------------------------------------------------
/ep-social-ticket-search-app/materialize/font/roboto/Roboto-Bold.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EuroPython/epcon/341c22649ff4ec858fc710821303cf3b78aa59e6/ep-social-ticket-search-app/materialize/font/roboto/Roboto-Bold.woff


--------------------------------------------------------------------------------
/ep-social-ticket-search-app/materialize/font/roboto/Roboto-Bold.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EuroPython/epcon/341c22649ff4ec858fc710821303cf3b78aa59e6/ep-social-ticket-search-app/materialize/font/roboto/Roboto-Bold.woff2


--------------------------------------------------------------------------------
/ep-social-ticket-search-app/materialize/font/roboto/Roboto-Light.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EuroPython/epcon/341c22649ff4ec858fc710821303cf3b78aa59e6/ep-social-ticket-search-app/materialize/font/roboto/Roboto-Light.eot


--------------------------------------------------------------------------------
/ep-social-ticket-search-app/materialize/font/roboto/Roboto-Light.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EuroPython/epcon/341c22649ff4ec858fc710821303cf3b78aa59e6/ep-social-ticket-search-app/materialize/font/roboto/Roboto-Light.ttf


--------------------------------------------------------------------------------
/ep-social-ticket-search-app/materialize/font/roboto/Roboto-Light.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EuroPython/epcon/341c22649ff4ec858fc710821303cf3b78aa59e6/ep-social-ticket-search-app/materialize/font/roboto/Roboto-Light.woff


--------------------------------------------------------------------------------
/ep-social-ticket-search-app/materialize/font/roboto/Roboto-Light.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EuroPython/epcon/341c22649ff4ec858fc710821303cf3b78aa59e6/ep-social-ticket-search-app/materialize/font/roboto/Roboto-Light.woff2


--------------------------------------------------------------------------------
/ep-social-ticket-search-app/materialize/font/roboto/Roboto-Medium.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EuroPython/epcon/341c22649ff4ec858fc710821303cf3b78aa59e6/ep-social-ticket-search-app/materialize/font/roboto/Roboto-Medium.eot


--------------------------------------------------------------------------------
/ep-social-ticket-search-app/materialize/font/roboto/Roboto-Medium.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EuroPython/epcon/341c22649ff4ec858fc710821303cf3b78aa59e6/ep-social-ticket-search-app/materialize/font/roboto/Roboto-Medium.ttf


--------------------------------------------------------------------------------
/ep-social-ticket-search-app/materialize/font/roboto/Roboto-Medium.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EuroPython/epcon/341c22649ff4ec858fc710821303cf3b78aa59e6/ep-social-ticket-search-app/materialize/font/roboto/Roboto-Medium.woff


--------------------------------------------------------------------------------
/ep-social-ticket-search-app/materialize/font/roboto/Roboto-Medium.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EuroPython/epcon/341c22649ff4ec858fc710821303cf3b78aa59e6/ep-social-ticket-search-app/materialize/font/roboto/Roboto-Medium.woff2


--------------------------------------------------------------------------------
/ep-social-ticket-search-app/materialize/font/roboto/Roboto-Regular.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EuroPython/epcon/341c22649ff4ec858fc710821303cf3b78aa59e6/ep-social-ticket-search-app/materialize/font/roboto/Roboto-Regular.eot


--------------------------------------------------------------------------------
/ep-social-ticket-search-app/materialize/font/roboto/Roboto-Regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EuroPython/epcon/341c22649ff4ec858fc710821303cf3b78aa59e6/ep-social-ticket-search-app/materialize/font/roboto/Roboto-Regular.ttf


--------------------------------------------------------------------------------
/ep-social-ticket-search-app/materialize/font/roboto/Roboto-Regular.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EuroPython/epcon/341c22649ff4ec858fc710821303cf3b78aa59e6/ep-social-ticket-search-app/materialize/font/roboto/Roboto-Regular.woff


--------------------------------------------------------------------------------
/ep-social-ticket-search-app/materialize/font/roboto/Roboto-Regular.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EuroPython/epcon/341c22649ff4ec858fc710821303cf3b78aa59e6/ep-social-ticket-search-app/materialize/font/roboto/Roboto-Regular.woff2


--------------------------------------------------------------------------------
/ep-social-ticket-search-app/materialize/font/roboto/Roboto-Thin.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EuroPython/epcon/341c22649ff4ec858fc710821303cf3b78aa59e6/ep-social-ticket-search-app/materialize/font/roboto/Roboto-Thin.eot


--------------------------------------------------------------------------------
/ep-social-ticket-search-app/materialize/font/roboto/Roboto-Thin.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EuroPython/epcon/341c22649ff4ec858fc710821303cf3b78aa59e6/ep-social-ticket-search-app/materialize/font/roboto/Roboto-Thin.ttf


--------------------------------------------------------------------------------
/ep-social-ticket-search-app/materialize/font/roboto/Roboto-Thin.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EuroPython/epcon/341c22649ff4ec858fc710821303cf3b78aa59e6/ep-social-ticket-search-app/materialize/font/roboto/Roboto-Thin.woff


--------------------------------------------------------------------------------
/ep-social-ticket-search-app/materialize/font/roboto/Roboto-Thin.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EuroPython/epcon/341c22649ff4ec858fc710821303cf3b78aa59e6/ep-social-ticket-search-app/materialize/font/roboto/Roboto-Thin.woff2


--------------------------------------------------------------------------------
/ep-social-ticket-search-app/run.sh:
--------------------------------------------------------------------------------
 1 | #!/bin/bash
 2 | #
 3 | # Run local web app install server
 4 | #
 5 | 
 6 | # Settings
 7 | WWWDIR=$PWD
 8 | PORT=8000
 9 | 
10 | version=`python -c 'import sys; print(sys.version_info[0])'`
11 | 
12 | if [ $version = 2 ]
13 | then
14 |     python -m SimpleHTTPServer $PORT
15 | else
16 |     python -m http.server $PORT
17 | fi
18 | 
19 | 


--------------------------------------------------------------------------------
/ep-ticket-search-app/CREDITS:
--------------------------------------------------------------------------------
1 | Tools used for the app:
2 | 
3 |  * List.js: http://www.listjs.com/
4 |  * MaterializeCSS: http://materializecss.com/
5 |  * jQuery: https://jquery.com/
6 | 
7 | 


--------------------------------------------------------------------------------
/ep-ticket-search-app/README:
--------------------------------------------------------------------------------
 1 | Build Ticket Search App
 2 | -----------------------
 3 | 
 4 |     Creates a single-page fuzzy full text search list with all tickets
 5 |     and their ticket IDs.  Writes the single page to
 6 |     ep-ticket-search-app/index.html
 7 | 
 8 |     This can be used during registration to do quick search in the
 9 |     list of all tickets in order to find badges or find that no badge
10 |     exists.
11 | 
12 |     Usage:
13 | 
14 |     cd ..
15 |     ./manage.py build_ticket_search_app ep2016
16 |     cd ep-ticket-search-app
17 |     ./run.sh
18 | 
19 |     This will build the search app and start a web server running
20 |     on port 8000. Pointing a browser at http://localhost:8000/ will
21 |     then load the app into the browser.
22 | 


--------------------------------------------------------------------------------
/ep-ticket-search-app/fonts/roboto/Roboto-Bold.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EuroPython/epcon/341c22649ff4ec858fc710821303cf3b78aa59e6/ep-ticket-search-app/fonts/roboto/Roboto-Bold.eot


--------------------------------------------------------------------------------
/ep-ticket-search-app/fonts/roboto/Roboto-Bold.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EuroPython/epcon/341c22649ff4ec858fc710821303cf3b78aa59e6/ep-ticket-search-app/fonts/roboto/Roboto-Bold.ttf


--------------------------------------------------------------------------------
/ep-ticket-search-app/fonts/roboto/Roboto-Bold.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EuroPython/epcon/341c22649ff4ec858fc710821303cf3b78aa59e6/ep-ticket-search-app/fonts/roboto/Roboto-Bold.woff


--------------------------------------------------------------------------------
/ep-ticket-search-app/fonts/roboto/Roboto-Bold.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EuroPython/epcon/341c22649ff4ec858fc710821303cf3b78aa59e6/ep-ticket-search-app/fonts/roboto/Roboto-Bold.woff2


--------------------------------------------------------------------------------
/ep-ticket-search-app/fonts/roboto/Roboto-Light.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EuroPython/epcon/341c22649ff4ec858fc710821303cf3b78aa59e6/ep-ticket-search-app/fonts/roboto/Roboto-Light.eot


--------------------------------------------------------------------------------
/ep-ticket-search-app/fonts/roboto/Roboto-Light.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EuroPython/epcon/341c22649ff4ec858fc710821303cf3b78aa59e6/ep-ticket-search-app/fonts/roboto/Roboto-Light.ttf


--------------------------------------------------------------------------------
/ep-ticket-search-app/fonts/roboto/Roboto-Light.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EuroPython/epcon/341c22649ff4ec858fc710821303cf3b78aa59e6/ep-ticket-search-app/fonts/roboto/Roboto-Light.woff


--------------------------------------------------------------------------------
/ep-ticket-search-app/fonts/roboto/Roboto-Light.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EuroPython/epcon/341c22649ff4ec858fc710821303cf3b78aa59e6/ep-ticket-search-app/fonts/roboto/Roboto-Light.woff2


--------------------------------------------------------------------------------
/ep-ticket-search-app/fonts/roboto/Roboto-Medium.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EuroPython/epcon/341c22649ff4ec858fc710821303cf3b78aa59e6/ep-ticket-search-app/fonts/roboto/Roboto-Medium.eot


--------------------------------------------------------------------------------
/ep-ticket-search-app/fonts/roboto/Roboto-Medium.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EuroPython/epcon/341c22649ff4ec858fc710821303cf3b78aa59e6/ep-ticket-search-app/fonts/roboto/Roboto-Medium.ttf


--------------------------------------------------------------------------------
/ep-ticket-search-app/fonts/roboto/Roboto-Medium.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EuroPython/epcon/341c22649ff4ec858fc710821303cf3b78aa59e6/ep-ticket-search-app/fonts/roboto/Roboto-Medium.woff


--------------------------------------------------------------------------------
/ep-ticket-search-app/fonts/roboto/Roboto-Medium.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EuroPython/epcon/341c22649ff4ec858fc710821303cf3b78aa59e6/ep-ticket-search-app/fonts/roboto/Roboto-Medium.woff2


--------------------------------------------------------------------------------
/ep-ticket-search-app/fonts/roboto/Roboto-Regular.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EuroPython/epcon/341c22649ff4ec858fc710821303cf3b78aa59e6/ep-ticket-search-app/fonts/roboto/Roboto-Regular.eot


--------------------------------------------------------------------------------
/ep-ticket-search-app/fonts/roboto/Roboto-Regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EuroPython/epcon/341c22649ff4ec858fc710821303cf3b78aa59e6/ep-ticket-search-app/fonts/roboto/Roboto-Regular.ttf


--------------------------------------------------------------------------------
/ep-ticket-search-app/fonts/roboto/Roboto-Regular.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EuroPython/epcon/341c22649ff4ec858fc710821303cf3b78aa59e6/ep-ticket-search-app/fonts/roboto/Roboto-Regular.woff


--------------------------------------------------------------------------------
/ep-ticket-search-app/fonts/roboto/Roboto-Regular.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EuroPython/epcon/341c22649ff4ec858fc710821303cf3b78aa59e6/ep-ticket-search-app/fonts/roboto/Roboto-Regular.woff2


--------------------------------------------------------------------------------
/ep-ticket-search-app/fonts/roboto/Roboto-Thin.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EuroPython/epcon/341c22649ff4ec858fc710821303cf3b78aa59e6/ep-ticket-search-app/fonts/roboto/Roboto-Thin.eot


--------------------------------------------------------------------------------
/ep-ticket-search-app/fonts/roboto/Roboto-Thin.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EuroPython/epcon/341c22649ff4ec858fc710821303cf3b78aa59e6/ep-ticket-search-app/fonts/roboto/Roboto-Thin.ttf


--------------------------------------------------------------------------------
/ep-ticket-search-app/fonts/roboto/Roboto-Thin.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EuroPython/epcon/341c22649ff4ec858fc710821303cf3b78aa59e6/ep-ticket-search-app/fonts/roboto/Roboto-Thin.woff


--------------------------------------------------------------------------------
/ep-ticket-search-app/fonts/roboto/Roboto-Thin.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EuroPython/epcon/341c22649ff4ec858fc710821303cf3b78aa59e6/ep-ticket-search-app/fonts/roboto/Roboto-Thin.woff2


--------------------------------------------------------------------------------
/ep-ticket-search-app/materialize/LICENSE:
--------------------------------------------------------------------------------
 1 | The MIT License (MIT)
 2 | 
 3 | Copyright (c) 2014-2016 Materialize
 4 | 
 5 | Permission is hereby granted, free of charge, to any person obtaining a copy
 6 | of this software and associated documentation files (the "Software"), to deal
 7 | in the Software without restriction, including without limitation the rights
 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 | 
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 | 
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 | 


--------------------------------------------------------------------------------
/ep-ticket-search-app/materialize/font/material-design-icons/Material-Design-Icons.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EuroPython/epcon/341c22649ff4ec858fc710821303cf3b78aa59e6/ep-ticket-search-app/materialize/font/material-design-icons/Material-Design-Icons.eot


--------------------------------------------------------------------------------
/ep-ticket-search-app/materialize/font/material-design-icons/Material-Design-Icons.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EuroPython/epcon/341c22649ff4ec858fc710821303cf3b78aa59e6/ep-ticket-search-app/materialize/font/material-design-icons/Material-Design-Icons.ttf


--------------------------------------------------------------------------------
/ep-ticket-search-app/materialize/font/material-design-icons/Material-Design-Icons.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EuroPython/epcon/341c22649ff4ec858fc710821303cf3b78aa59e6/ep-ticket-search-app/materialize/font/material-design-icons/Material-Design-Icons.woff


--------------------------------------------------------------------------------
/ep-ticket-search-app/materialize/font/material-design-icons/Material-Design-Icons.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EuroPython/epcon/341c22649ff4ec858fc710821303cf3b78aa59e6/ep-ticket-search-app/materialize/font/material-design-icons/Material-Design-Icons.woff2


--------------------------------------------------------------------------------
/ep-ticket-search-app/materialize/font/roboto/Roboto-Bold.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EuroPython/epcon/341c22649ff4ec858fc710821303cf3b78aa59e6/ep-ticket-search-app/materialize/font/roboto/Roboto-Bold.eot


--------------------------------------------------------------------------------
/ep-ticket-search-app/materialize/font/roboto/Roboto-Bold.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EuroPython/epcon/341c22649ff4ec858fc710821303cf3b78aa59e6/ep-ticket-search-app/materialize/font/roboto/Roboto-Bold.ttf


--------------------------------------------------------------------------------
/ep-ticket-search-app/materialize/font/roboto/Roboto-Bold.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EuroPython/epcon/341c22649ff4ec858fc710821303cf3b78aa59e6/ep-ticket-search-app/materialize/font/roboto/Roboto-Bold.woff


--------------------------------------------------------------------------------
/ep-ticket-search-app/materialize/font/roboto/Roboto-Bold.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EuroPython/epcon/341c22649ff4ec858fc710821303cf3b78aa59e6/ep-ticket-search-app/materialize/font/roboto/Roboto-Bold.woff2


--------------------------------------------------------------------------------
/ep-ticket-search-app/materialize/font/roboto/Roboto-Light.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EuroPython/epcon/341c22649ff4ec858fc710821303cf3b78aa59e6/ep-ticket-search-app/materialize/font/roboto/Roboto-Light.eot


--------------------------------------------------------------------------------
/ep-ticket-search-app/materialize/font/roboto/Roboto-Light.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EuroPython/epcon/341c22649ff4ec858fc710821303cf3b78aa59e6/ep-ticket-search-app/materialize/font/roboto/Roboto-Light.ttf


--------------------------------------------------------------------------------
/ep-ticket-search-app/materialize/font/roboto/Roboto-Light.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EuroPython/epcon/341c22649ff4ec858fc710821303cf3b78aa59e6/ep-ticket-search-app/materialize/font/roboto/Roboto-Light.woff


--------------------------------------------------------------------------------
/ep-ticket-search-app/materialize/font/roboto/Roboto-Light.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EuroPython/epcon/341c22649ff4ec858fc710821303cf3b78aa59e6/ep-ticket-search-app/materialize/font/roboto/Roboto-Light.woff2


--------------------------------------------------------------------------------
/ep-ticket-search-app/materialize/font/roboto/Roboto-Medium.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EuroPython/epcon/341c22649ff4ec858fc710821303cf3b78aa59e6/ep-ticket-search-app/materialize/font/roboto/Roboto-Medium.eot


--------------------------------------------------------------------------------
/ep-ticket-search-app/materialize/font/roboto/Roboto-Medium.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EuroPython/epcon/341c22649ff4ec858fc710821303cf3b78aa59e6/ep-ticket-search-app/materialize/font/roboto/Roboto-Medium.ttf


--------------------------------------------------------------------------------
/ep-ticket-search-app/materialize/font/roboto/Roboto-Medium.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EuroPython/epcon/341c22649ff4ec858fc710821303cf3b78aa59e6/ep-ticket-search-app/materialize/font/roboto/Roboto-Medium.woff


--------------------------------------------------------------------------------
/ep-ticket-search-app/materialize/font/roboto/Roboto-Medium.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EuroPython/epcon/341c22649ff4ec858fc710821303cf3b78aa59e6/ep-ticket-search-app/materialize/font/roboto/Roboto-Medium.woff2


--------------------------------------------------------------------------------
/ep-ticket-search-app/materialize/font/roboto/Roboto-Regular.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EuroPython/epcon/341c22649ff4ec858fc710821303cf3b78aa59e6/ep-ticket-search-app/materialize/font/roboto/Roboto-Regular.eot


--------------------------------------------------------------------------------
/ep-ticket-search-app/materialize/font/roboto/Roboto-Regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EuroPython/epcon/341c22649ff4ec858fc710821303cf3b78aa59e6/ep-ticket-search-app/materialize/font/roboto/Roboto-Regular.ttf


--------------------------------------------------------------------------------
/ep-ticket-search-app/materialize/font/roboto/Roboto-Regular.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EuroPython/epcon/341c22649ff4ec858fc710821303cf3b78aa59e6/ep-ticket-search-app/materialize/font/roboto/Roboto-Regular.woff


--------------------------------------------------------------------------------
/ep-ticket-search-app/materialize/font/roboto/Roboto-Regular.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EuroPython/epcon/341c22649ff4ec858fc710821303cf3b78aa59e6/ep-ticket-search-app/materialize/font/roboto/Roboto-Regular.woff2


--------------------------------------------------------------------------------
/ep-ticket-search-app/materialize/font/roboto/Roboto-Thin.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EuroPython/epcon/341c22649ff4ec858fc710821303cf3b78aa59e6/ep-ticket-search-app/materialize/font/roboto/Roboto-Thin.eot


--------------------------------------------------------------------------------
/ep-ticket-search-app/materialize/font/roboto/Roboto-Thin.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EuroPython/epcon/341c22649ff4ec858fc710821303cf3b78aa59e6/ep-ticket-search-app/materialize/font/roboto/Roboto-Thin.ttf


--------------------------------------------------------------------------------
/ep-ticket-search-app/materialize/font/roboto/Roboto-Thin.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EuroPython/epcon/341c22649ff4ec858fc710821303cf3b78aa59e6/ep-ticket-search-app/materialize/font/roboto/Roboto-Thin.woff


--------------------------------------------------------------------------------
/ep-ticket-search-app/materialize/font/roboto/Roboto-Thin.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EuroPython/epcon/341c22649ff4ec858fc710821303cf3b78aa59e6/ep-ticket-search-app/materialize/font/roboto/Roboto-Thin.woff2


--------------------------------------------------------------------------------
/ep-ticket-search-app/run.sh:
--------------------------------------------------------------------------------
 1 | #!/bin/bash
 2 | #
 3 | # Run local web app install server
 4 | #
 5 | 
 6 | # Settings
 7 | WWWDIR=$PWD
 8 | PORT=8000
 9 | 
10 | version=`python -c 'import sys; print(sys.version_info[0])'`
11 | 
12 | if [ $version = 2 ]
13 | then
14 |     python -m SimpleHTTPServer $PORT
15 | else
16 |     python -m http.server $PORT
17 | fi
18 | 
19 | 


--------------------------------------------------------------------------------
/manage.py:
--------------------------------------------------------------------------------
 1 | #!/usr/bin/env python3
 2 | import os
 3 | import sys
 4 | 
 5 | if __name__ == "__main__":
 6 |     os.environ.setdefault("DJANGO_SETTINGS_MODULE", "pycon.settings")
 7 |     from django.core.management import execute_from_command_line
 8 | 
 9 |     execute_from_command_line(sys.argv)
10 | 


--------------------------------------------------------------------------------
/media_public/conference/sponsor/resized/continuum-analytics.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EuroPython/epcon/341c22649ff4ec858fc710821303cf3b78aa59e6/media_public/conference/sponsor/resized/continuum-analytics.jpg


--------------------------------------------------------------------------------
/media_public/conference/sponsor/resized/github.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EuroPython/epcon/341c22649ff4ec858fc710821303cf3b78aa59e6/media_public/conference/sponsor/resized/github.jpg


--------------------------------------------------------------------------------
/media_public/conference/sponsor/resized/redhat.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EuroPython/epcon/341c22649ff4ec858fc710821303cf3b78aa59e6/media_public/conference/sponsor/resized/redhat.jpg


--------------------------------------------------------------------------------
/p3/__init__.py:
--------------------------------------------------------------------------------
1 | default_app_config = 'p3.apps.P3Config'
2 | 


--------------------------------------------------------------------------------
/p3/apps.py:
--------------------------------------------------------------------------------
1 | from django.apps import AppConfig
2 | 
3 | 
4 | class P3Config(AppConfig):
5 |     name = 'p3'
6 | 
7 |     def ready(self):
8 |         import p3.listeners  # noqa
9 | 


--------------------------------------------------------------------------------
/p3/context_processors.py:
--------------------------------------------------------------------------------
 1 | import django.conf
 2 | 
 3 | 
 4 | def settings(request):
 5 |     names = (
 6 |         'NEWSLETTER_SUBSCRIBE_URL',
 7 |         'TWITTER_USER',
 8 |         'GOOGLE_ANALYTICS',
 9 |     )
10 |     output = {}
11 |     for x in names:
12 |         output[x] = getattr(django.conf.settings, 'P3_' + x, None)
13 |     return output
14 | 


--------------------------------------------------------------------------------
/p3/management/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EuroPython/epcon/341c22649ff4ec858fc710821303cf3b78aa59e6/p3/management/__init__.py


--------------------------------------------------------------------------------
/p3/management/commands/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EuroPython/epcon/341c22649ff4ec858fc710821303cf3b78aa59e6/p3/management/commands/__init__.py


--------------------------------------------------------------------------------
/p3/management/commands/users.py:
--------------------------------------------------------------------------------
 1 | 
 2 | """ Print a json file with the users in the database."""
 3 | 
 4 | import json
 5 | import logging as log
 6 | from collections import OrderedDict
 7 | from django.core.management.base import BaseCommand
 8 | from assopy.models import AssopyUser
 9 | 
10 | 
11 | class Command(BaseCommand):
12 |     option_list = BaseCommand.option_list + (
13 | 
14 |     )
15 | 
16 |     def handle(self, *args, **options):
17 |         assopy_db_users = AssopyUser.objects.all()
18 |         users = OrderedDict()
19 |         for u in assopy_db_users:
20 |             try:
21 |                 user_name = u.name()
22 |                 user_id   = u.user.id
23 |             except:
24 |                 log.error('Error with user {}.'.format(u.id))
25 |                 users[u.id] = {'assopy_id': u.id, }
26 |             else:
27 |                 users[u.id] = {
28 |                     'name': user_name.encode('utf-8'),
29 |                     'assopy_id': u.id,
30 |                     'id': user_id,
31 |                     'username': u.user.get_username().encode('utf-8'),
32 |                     'email': u.user.email.encode('utf-8'),
33 |                     'date-joined': str(u.user.date_joined).encode('utf-8'),
34 |                 }
35 | 
36 |         print(json.dumps(users, indent=2, separators=(',', ': ')))
37 | 


--------------------------------------------------------------------------------
/p3/migrations/0002_remove_unused_models.py:
--------------------------------------------------------------------------------
 1 | 
 2 | # Generated by Django 1.9.13 on 2018-10-09 18:46
 3 | 
 4 | 
 5 | from django.db import migrations
 6 | 
 7 | 
 8 | class Migration(migrations.Migration):
 9 | 
10 |     dependencies = [
11 |         ('p3', '0001_initial'),
12 |     ]
13 | 
14 |     operations = [
15 |         migrations.RemoveField(
16 |             model_name='donation',
17 |             name='user',
18 |         ),
19 |         migrations.RemoveField(
20 |             model_name='sprint',
21 |             name='conference',
22 |         ),
23 |         migrations.RemoveField(
24 |             model_name='sprint',
25 |             name='user',
26 |         ),
27 |         migrations.RemoveField(
28 |             model_name='sprintpresence',
29 |             name='sprint',
30 |         ),
31 |         migrations.RemoveField(
32 |             model_name='sprintpresence',
33 |             name='user',
34 |         ),
35 |         migrations.DeleteModel(
36 |             name='Donation',
37 |         ),
38 |         migrations.DeleteModel(
39 |             name='Sprint',
40 |         ),
41 |         migrations.DeleteModel(
42 |             name='SprintPresence',
43 |         ),
44 |     ]
45 | 


--------------------------------------------------------------------------------
/p3/migrations/0003_add_name_field_to_ticket_conference.py:
--------------------------------------------------------------------------------
 1 | # Generated by Django 1.11.20 on 2019-05-05 09:59
 2 | from __future__ import unicode_literals
 3 | 
 4 | from django.db import migrations, models
 5 | 
 6 | 
 7 | class Migration(migrations.Migration):
 8 | 
 9 |     dependencies = [('p3', '0002_remove_unused_models')]
10 | 
11 |     operations = [
12 |         migrations.AddField(
13 |             model_name='ticketconference',
14 |             name='name',
15 |             field=models.CharField(
16 |                 default='',
17 |                 help_text='What name should appear on the badge?',
18 |                 max_length=255,
19 |             ),
20 |             preserve_default=False,
21 |         )
22 |     ]
23 | 


--------------------------------------------------------------------------------
/p3/migrations/0005_auto_shirt_and_dietary_defaults.py:
--------------------------------------------------------------------------------
 1 | # -*- coding: utf-8 -*-
 2 | # Generated by Django 1.11.22 on 2019-07-16 15: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 |         ('p3', '0004_mystery_migrations_maybe_2_to_3_bytes_to_str'),
12 |     ]
13 | 
14 |     operations = [
15 |         migrations.AlterField(
16 |             model_name='ticketconference',
17 |             name='diet',
18 |             field=models.CharField(choices=[(None, 'Please select your dietary preferences!'), ('omnivorous', 'Omnivorous'), ('vegetarian', 'Vegetarian'), ('other', 'Other')], default=None, max_length=10, null=True),
19 |         ),
20 |         migrations.AlterField(
21 |             model_name='ticketconference',
22 |             name='shirt_size',
23 |             field=models.CharField(choices=[(None, 'Please select your shirt size!'), ('fs', 'S (female)'), ('fm', 'M (female)'), ('fl', 'L (female)'), ('fxl', 'XL (female)'), ('fxxl', 'XXL (female)'), ('fxxxl', '3XL (female)'), ('s', 'S (male)'), ('m', 'M (male)'), ('l', 'L (male)'), ('xl', 'XL (male)'), ('xxl', 'XXL (male)'), ('xxxl', '3XL (male)'), ('xxxxl', '4XL (male)')], default=None, max_length=5, null=True),
24 |         ),
25 |     ]
26 | 


--------------------------------------------------------------------------------
/p3/migrations/0006_remove_p3talk.py:
--------------------------------------------------------------------------------
 1 | # -*- coding: utf-8 -*-
 2 | # Generated by Django 1.11.26 on 2020-01-11 16:20
 3 | from __future__ import unicode_literals
 4 | 
 5 | from django.db import migrations
 6 | 
 7 | 
 8 | class Migration(migrations.Migration):
 9 | 
10 |     dependencies = [
11 |         ('p3', '0005_auto_shirt_and_dietary_defaults'),
12 |     ]
13 | 
14 |     operations = [
15 |         migrations.RemoveField(
16 |             model_name='p3talk',
17 |             name='talk',
18 |         ),
19 |         migrations.DeleteModel(
20 |             name='P3Talk',
21 |         ),
22 |     ]
23 | 


--------------------------------------------------------------------------------
/p3/migrations/0007_auto_20200217_1654.py:
--------------------------------------------------------------------------------
 1 | # -*- coding: utf-8 -*-
 2 | # Generated by Django 1.11.28 on 2020-02-17 16:54
 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 |         ('p3', '0006_remove_p3talk'),
12 |     ]
13 | 
14 |     operations = [
15 |         migrations.AlterField(
16 |             model_name='ticketconference',
17 |             name='shirt_size',
18 |             field=models.CharField(choices=[(None, 'Please select your shirt size!'), ('fs', 'S (fitted cut)'), ('fm', 'M (fitted cut)'), ('fl', 'L (fitted cut)'), ('fxl', 'XL (fitted cut)'), ('fxxl', 'XXL (fitted cut)'), ('fxxxl', '3XL (fitted cut)'), ('s', 'S (straight cut)'), ('m', 'M (straight cut)'), ('l', 'L (straight cut)'), ('xl', 'XL (straight cut)'), ('xxl', 'XXL (straight cut)'), ('xxxl', '3XL (straight cut)'), ('xxxxl', '4XL (straight cut)')], default=None, max_length=5, null=True),
19 |         ),
20 |     ]
21 | 


--------------------------------------------------------------------------------
/p3/migrations/0008_remove_ticketconference_name.py:
--------------------------------------------------------------------------------
 1 | # -*- coding: utf-8 -*-
 2 | # Generated by Django 1.11.29 on 2020-06-17 12:53
 3 | from __future__ import unicode_literals
 4 | 
 5 | from django.db import migrations
 6 | 
 7 | 
 8 | class Migration(migrations.Migration):
 9 | 
10 |     dependencies = [
11 |         ('p3', '0007_auto_20200217_1654'),
12 |     ]
13 | 
14 |     operations = [
15 |         migrations.RemoveField(
16 |             model_name='ticketconference',
17 |             name='name',
18 |         ),
19 |     ]
20 | 


--------------------------------------------------------------------------------
/p3/migrations/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EuroPython/epcon/341c22649ff4ec858fc710821303cf3b78aa59e6/p3/migrations/__init__.py


--------------------------------------------------------------------------------
/p3/static/p5/images/close.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EuroPython/epcon/341c22649ff4ec858fc710821303cf3b78aa59e6/p3/static/p5/images/close.png


--------------------------------------------------------------------------------
/p3/static/p5/images/headshot-default.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EuroPython/epcon/341c22649ff4ec858fc710821303cf3b78aa59e6/p3/static/p5/images/headshot-default.jpg


--------------------------------------------------------------------------------
/p3/static/p6/javascripts/ckeditor.wysiwyg.js:
--------------------------------------------------------------------------------
 1 | /* Default CKEDITOR Styles
 2 |  * Added within src/settings.py CKEDITOR_SETTINGS.stylesSet
 3 |  */
 4 | 
 5 | CKEDITOR.stylesSet.add('default', [
 6 |     /* Block Styles */
 7 |     {'name': 'Title', 'element': ['h2'], 'attributes': {'class': 'border-title'}},
 8 |     {'name': 'Medium title', 'element': ['h3'], 'attributes': {'class': 'border-title'}},
 9 | 
10 |     /* Inline Styles */
11 | ]);
12 | 


--------------------------------------------------------------------------------
/p3/templatetags/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EuroPython/epcon/341c22649ff4ec858fc710821303cf3b78aa59e6/p3/templatetags/__init__.py


--------------------------------------------------------------------------------
/p3/urls.py:
--------------------------------------------------------------------------------
 1 | from django.conf.urls import url as re_path
 2 | 
 3 | from p3 import views as p3_views
 4 | 
 5 | 
 6 | urlpatterns = [
 7 |     re_path(
 8 |         r'^p/profile/(?P[\w-]+)/avatar$',
 9 |         p3_views.p3_profile_avatar,
10 |         name='p3-profile-avatar'
11 |     ),
12 | ]
13 | 


--------------------------------------------------------------------------------
/p3/views.py:
--------------------------------------------------------------------------------
 1 | import logging
 2 | import os.path
 3 | 
 4 | from django import http
 5 | from django.shortcuts import get_object_or_404
 6 | 
 7 | from conference import models as cmodels
 8 | 
 9 | log = logging.getLogger('p3.views')
10 | 
11 | 
12 | def p3_profile_avatar(request, slug):
13 |     p = get_object_or_404(cmodels.AttendeeProfile, slug=slug).p3_profile
14 |     from urllib.request import urlopen
15 |     try:
16 |         response = urlopen(p.profile_image_url())
17 |     except Exception:
18 |         import p3
19 |         from django.conf import settings
20 |         path = os.path.join(os.path.dirname(p3.__file__), 'static', settings.P3_ANONYMOUS_AVATAR)
21 |         with open(path, 'rb') as image_file:
22 |             image = image_file.read()
23 |         ct = 'image/jpg'
24 |     else:
25 |         headers = response.info()
26 |         image = response.read()
27 |         ct = headers.get('content-type')
28 |     return http.HttpResponse(image, content_type=ct)
29 | 


--------------------------------------------------------------------------------
/pycon/__init__.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | 


--------------------------------------------------------------------------------
/pycon/ci_settings.py:
--------------------------------------------------------------------------------
 1 | from .test_settings import *  # noqa
 2 | 
 3 | # DEBUG=True
 4 | 
 5 | # Disable all the caching
 6 | DISABLE_CACHING = {
 7 |     'default': {
 8 |         'BACKEND': 'django.core.cache.backends.dummy.DummyCache',
 9 |     }
10 | }
11 | 
12 | # however for some tests we *do* want to test caches, hence we're going to use
13 | # @override_settings(CACHES=settings.ENABLE_LOCMEM_CACHE)
14 | ENABLE_LOCMEM_CACHE = {
15 |     'default': {
16 |         'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',
17 |         'LOCATION': 'unique-snowflake',
18 |     }
19 | }
20 | 
21 | CACHES = DISABLE_CACHING
22 | 
23 | TEMPLATES[0]['OPTIONS']['debug'] = True  # noqa
24 | 
25 | DATABASES = {
26 |     'default': {
27 |         'ENGINE': 'django.db.backends.sqlite3',
28 |         'NAME': '/tmp/p3.db',
29 |     }
30 | }
31 | 


--------------------------------------------------------------------------------
/pycon/test_settings.py:
--------------------------------------------------------------------------------
1 | from .dev_settings import *  # noqa
2 | 
3 | DATABASES = {
4 |     'default': {
5 |         'ENGINE': 'django.db.backends.sqlite3',
6 |         'NAME': ':memory:',
7 |     }
8 | }
9 | 


--------------------------------------------------------------------------------
/pycon/wsgi.py:
--------------------------------------------------------------------------------
 1 | """
 2 | WSGI config for pycon project.
 3 | 
 4 | This module contains the WSGI application used by Django's development server
 5 | and any production WSGI deployments. It should expose a module-level variable
 6 | named ``application``. Django's ``runserver`` and ``runfcgi`` commands discover
 7 | this application via the ``WSGI_APPLICATION`` setting.
 8 | 
 9 | Usually you will have the standard Django WSGI application here, but it also
10 | might make sense to replace the whole Django WSGI application with a custom one
11 | that later delegates to the Django one. For example, you could introduce WSGI
12 | middleware here, or combine a Django application with an application of another
13 | framework.
14 | 
15 | """
16 | import os
17 | 
18 | os.environ.setdefault("DJANGO_SETTINGS_MODULE", "pycon.settings")
19 | 
20 | # This application object is used by any WSGI server configured to use this
21 | # file. This includes Django's development server, if the WSGI_APPLICATION
22 | # setting points here.
23 | from django.core.wsgi import get_wsgi_application
24 | application = get_wsgi_application()
25 | 
26 | # Apply WSGI middleware here.
27 | # from helloworld.wsgi import HelloWorldApplication
28 | # application = HelloWorldApplication(application)
29 | 


--------------------------------------------------------------------------------
/pytest.ini:
--------------------------------------------------------------------------------
 1 | [pytest]
 2 | DJANGO_SETTINGS_MODULE=pycon.ci_settings
 3 | 
 4 | testpaths =
 5 |     ./tests
 6 |     ./common/tests
 7 | 
 8 | python_files =
 9 |     tests.py
10 |     test_*.py
11 | 
12 | addopts =
13 |     # show all except passed
14 |     -ra
15 |     # disable output capturing
16 |     -s
17 |     # distributed testing
18 |     #-n auto
19 |     # increased verbosity
20 |     #-vvv
21 |     # coverage report
22 |     --cov-config .coveragerc --cov=./ --cov-report=term
23 |     # reuse database
24 |     --reuse-db
25 |     # no migrations
26 |     --nomigrations
27 |     # new first
28 |     --new-first
29 |     # failed first
30 |     --failed-first
31 |     # no coverage on fail
32 |     --no-cov-on-fail
33 |     # fail immediately
34 |     -x
35 | 


--------------------------------------------------------------------------------
/pytest_ci.ini:
--------------------------------------------------------------------------------
 1 | [pytest]
 2 | DJANGO_SETTINGS_MODULE=pycon.ci_settings
 3 | 
 4 | testpaths =
 5 |     ./tests
 6 |     ./common/tests
 7 | 
 8 | python_files =
 9 |     tests.py
10 |     test_*.py
11 | 
12 | addopts =
13 |     # show all except passed
14 |     -ra
15 |     # disable output capturing
16 |     -s
17 |     # distributed testing
18 |     -n auto
19 |     # increased verbosity
20 |     -vvv
21 |     # coverage report
22 |     --cov-config .coveragerc --cov=./ --cov-report=term
23 | 


--------------------------------------------------------------------------------
/requirements-dev.in:
--------------------------------------------------------------------------------
 1 | pytest
 2 | pytest-cov
 3 | pytest-django
 4 | pytest-mock
 5 | pytest-xdist
 6 | 
 7 | freezegun
 8 | responses
 9 | factory_boy
10 | 
11 | flake8
12 | black
13 | 
14 | django-pdb
15 | pdbpp
16 | ptvsd
17 | 
18 | pip-tools
19 | wheel
20 | certifi
21 | requests
22 | 


--------------------------------------------------------------------------------
/requirements.in:
--------------------------------------------------------------------------------
 1 | Django~=2.2
 2 | 
 3 | requests
 4 | requests-oauthlib
 5 | shortuuid
 6 | 
 7 | django-classy-tags
 8 | django_extensions
 9 | django-model-utils<4.0
10 | django-crispy-forms
11 | 
12 | django-taggit
13 | git+https://github.com/bennylope/django-taggit-labels#egg=django-taggit-labels
14 | 
15 | python3-openid
16 | python-social-auth
17 | social-auth-app-django
18 | # Fixes https://github.com/python-social-auth/social-app-django/issues/178
19 | social-auth-core[openidconnect]
20 | 
21 | markdown2
22 | 
23 | # 3.7 DjangoCMS LTS release
24 | # Please note that django-cms relies on django-treebeard and version 4.5.1 of 
25 | # that package is incompatible: https://stackoverflow.com/questions/66776994/
26 | django-cms<3.8
27 | django-treebeard<4.5.1
28 | djangocms-admin-style
29 | djangocms-text-ckeditor
30 | django-filer
31 | git+https://github.com/pawelmarkowski/cmsplugin-filer#egg=cmsplugin-filer
32 | 
33 | django-filebrowser-no-grappelli
34 | django-markitup
35 | 
36 | # django settings enhancements
37 | python-decouple
38 | dj-database-url
39 | 
40 | # phone numbers
41 | django-phonenumber-field
42 | phonenumbers
43 | 
44 | # payments
45 | stripe
46 | 
47 | WeasyPrint
48 | unicodecsv
49 | 
50 | openpyxl
51 | ipython
52 | decorator
53 | 
54 | lxml  # for currencies
55 | 
56 | gunicorn
57 | 
58 | anglicize
59 | 


--------------------------------------------------------------------------------
/scripts/__init__.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | 


--------------------------------------------------------------------------------
/templates/admin/assopy/invoice/change_form.html:
--------------------------------------------------------------------------------
 1 | {% extends "admin/change_form.html" %}
 2 | {% block object-tools %}
 3 |     
17 | {% endblock %}
18 | 


--------------------------------------------------------------------------------
/templates/admin/assopy/order/change_form.html:
--------------------------------------------------------------------------------
 1 | {% extends "admin/change_form.html" %}
 2 | {% block object-tools %}
 3 |     
11 | {% endblock %}
12 | 


--------------------------------------------------------------------------------
/templates/admin/assopy/order/change_list.html:
--------------------------------------------------------------------------------
 1 | {% extends "admin/change_list.html" %}
 2 | {% load i18n %}
 3 | {% block object-tools %}
 4 |     
16 | {% endblock %}
17 | 


--------------------------------------------------------------------------------
/templates/admin/conference/conference/schedule_view.html:
--------------------------------------------------------------------------------
 1 | {% extends "admin/conference/conference/schedule_view_base.html" %}
 2 | {% block extrahead %}
 3 | {{ block.super }}
 4 | 
21 | {% endblock %}
22 | 


--------------------------------------------------------------------------------
/templates/admin/conference/conference/schedule_view_schedule.html:
--------------------------------------------------------------------------------
 1 | {% load conference %}
 2 |     
3 | 4 |
5 | {% for track, events in timetable.iterOnTracks %} 6 | {% for e in events %} 7 |
21 |
22 | {{ e.time|date:"H:i" }} 23 | {% if e.id %} 24 | {{ e.name|safe }} 25 | {% endif %} 26 | {% if e.tracks|length > 1 %} 27 |
28 | {% endif %} 29 |
30 |
31 | {% endfor %} 32 | {% endfor %} 33 | -------------------------------------------------------------------------------- /templates/admin/conference/conferencetag/change_form.html: -------------------------------------------------------------------------------- 1 | {% extends "admin/change_form.html" %} 2 | {% load conference %} 3 | 4 | {% block content %} 5 | {{ block.super }} 6 |
7 |

Tagged items

8 | 9 | 10 | 11 | 12 | 13 | {% tagged_items original as objects %} 14 | {% for cid, o in objects %} 15 | {% with cid|content_type as ct %} 16 | 17 | 18 | 33 | 34 | {% endwith %} 35 | {% endfor %} 36 |
TypeObject
{{ ct.model }} 19 | {% admin_urlname_fromct ct "change" o as aurl %} 20 | {% if aurl %} 21 | 22 | {% if ct.model == "talk" %} 23 | {% talk_data o as t %} 24 | {{ t.title }} 25 | {% else %} 26 | {{ o }} 27 | {% endif %} 28 | 29 | {% else %} 30 | {{ o }} 31 | {% endif %} 32 |
37 |
38 | {% endblock %} 39 | -------------------------------------------------------------------------------- /templates/admin/conference/conferencetag/merge.html: -------------------------------------------------------------------------------- 1 | {% load conference %} 2 |
{% csrf_token %} 3 | 4 | 5 | 6 | 7 | 8 | 9 | {% for t in tags %} 10 | 11 | 12 | 13 | 14 | 15 | {% endfor %} 16 |
TagUsage
{{ t.name }}{{ t.usage }}
17 |
18 | -------------------------------------------------------------------------------- /templates/admin/conference/schedule/change_form.html: -------------------------------------------------------------------------------- 1 | {% extends "admin/change_form.html" %} 2 | {% block extrahead %} 3 | {{ block.super }} 4 | {% comment %} 5 | ridefinisco questo blocco per ridurre le textarea, 6 | lo schedule ne mostra troppe e la pagina diventa inutilizzabile. 7 | {% endcomment %} 8 | 13 | {% endblock %} 14 | -------------------------------------------------------------------------------- /templates/admin/conference/schedule/change_list.html: -------------------------------------------------------------------------------- 1 | {% extends "admin/change_list.html" %} 2 | {% load i18n %} 3 | {% block object-tools %} 4 | 13 | {% endblock %} 14 | -------------------------------------------------------------------------------- /templates/admin/conference/speaker/change_list.html: -------------------------------------------------------------------------------- 1 | {% extends "admin/change_list.html" %} 2 | {% load i18n %} 3 | {% block object-tools %} 4 | 14 | {% endblock %} 15 | -------------------------------------------------------------------------------- /templates/admin/conference/ticket/change_form.html: -------------------------------------------------------------------------------- 1 | {% extends "admin/change_form.html" %} 2 | {% block object-tools %} 3 | 14 | {% endblock %} 15 | -------------------------------------------------------------------------------- /templates/admin/inc/extrahead.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /templates/assopy/admin/edit_invoices.html: -------------------------------------------------------------------------------- 1 | {% extends "admin/base_site.html" %} 2 | 3 | {% block content %} 4 |

Please confirm the following orders:

5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | {% for o in orders %} 16 | {% with o.invoice as i %} 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | {% endwith %} 27 | {% endfor %} 28 |
CodeBuyer NameMethodDateTotalInvoiceInvoice date
{{ o.code }}{{ o.card_name }}{{ o.method }}{{ o.created|date:"d M Y" }}{{ o.total|floatformat:".2" }}{% if i %}Yes{% else %}No{% endif %}{% if i %}{{ i.invoice_date }}{% endif %}
29 |
30 |
{% csrf_token %} 31 | {{ form }} 32 |
33 | 34 |
35 |
36 | {% endblock %} 37 | -------------------------------------------------------------------------------- /templates/assopy/admin/order_stats.html: -------------------------------------------------------------------------------- 1 | {% extends "admin/base_site.html" %} 2 | 3 | {% block extrahead %} 4 | 26 | {% endblock %} 27 | {% block breadcrumbs %} 28 | 34 | {% endblock %}{% block content %} 35 | {% for conf, stats in conferences %} 36 |
37 |

{{ conf.code }}

38 | {% for name, doc, render in stats %} 39 |
40 |

{{ name }}

41 |

{{ doc }}

42 | {{ render }} 43 |
44 | {% endfor %} 45 |
46 | {% endfor %} 47 |
48 | {% endblock %} 49 | -------------------------------------------------------------------------------- /templates/assopy/invoices/_additional_text_for_2018.html: -------------------------------------------------------------------------------- 1 |

2 | The EuroPython 2018 conference is held in the UK. Accordingly, we have to charge UK VAT on the total amount. 3 |

4 | 5 |

6 | The EuroPython Society is registered for UK VAT under the VAT ID GB 297620469, with registered address "EuroPython Society, Unit 2, Block C, Arena Business Park, Poole, Dorset BH17 7FN" 7 |

8 | -------------------------------------------------------------------------------- /templates/assopy/invoices/_additional_text_for_2019.html: -------------------------------------------------------------------------------- 1 |

2 | The EuroPython 2019 conference is held in Switzerland. Accordingly, we have to charge Swiss VAT on the total amount. 3 |

4 | 5 |

6 | We are registered in Switzerland for VAT under VAT ID: CHE-195.676.403; 7 | EuroPython Society c/o Rhenuba Treuhand GmbH, Hardstrasse 127, 4052 Basel, Switzerland 8 |

9 | -------------------------------------------------------------------------------- /templates/assopy/invoices/_additional_text_for_2020.html: -------------------------------------------------------------------------------- 1 |

2 | The EuroPython 2020 conference is held online. Accordingly, we have to apply 3 | Swedish tax laws, since the EuroPython Society (EPS), as provider of the 4 | services, is registered as a non-profit organization in Sweden. We don't 5 | charge VAT on the total amount, since the EPS is VAT exempt. 6 |

7 | 8 |

9 |

10 | -------------------------------------------------------------------------------- /templates/assopy/invoices/_additional_text_for_2021.html: -------------------------------------------------------------------------------- 1 |

2 | The EuroPython 2021 conference is held online. Accordingly, we have to apply 3 | Swedish tax laws, since the EuroPython Society (EPS), as provider of the 4 | services, is registered as a non-profit organization in Sweden. We don't 5 | charge VAT on the total amount, since the EPS is VAT exempt. 6 |

7 | 8 |

9 |

10 | -------------------------------------------------------------------------------- /templates/assopy/invoices/_additional_text_for_2022.html: -------------------------------------------------------------------------------- 1 |

2 | The EuroPython 2022 conference is held in Ireland. Accordingly, we have to 3 | charge Irish VAT on the total amount. 4 |

5 | 6 |

7 | We are VAT registered in Ireland under the VAT ID: IE3673027HH
8 | Europython Society, Ramnebacken 45, 424 38 Agnesberg, Sweden 9 |

10 | 11 | -------------------------------------------------------------------------------- /templates/conference/README: -------------------------------------------------------------------------------- 1 | 2019-03-02 2 | ---------- 3 | 4 | This is a folder for a new bootstrp4 based version of templates. 5 | We've done some work towards material design, and those can be found outside of 6 | this directory. 7 | -------------------------------------------------------------------------------- /templates/conference/_cookie_consent.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 25 | -------------------------------------------------------------------------------- /templates/conference/_googleanalytics.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 9 | -------------------------------------------------------------------------------- /templates/conference/accounts/_login_with_google.html: -------------------------------------------------------------------------------- 1 |

... or use your existing Google account

2 |

3 | You will be able to specify billing and personal info later; e.g.: you can use 4 | your personal Google account to buy business tickets for your company and your 5 | Google name will not appear anywhere. 6 |

7 | 8 | 9 | Login with Google 10 | 11 | -------------------------------------------------------------------------------- /templates/conference/accounts/password_reset_complete.html: -------------------------------------------------------------------------------- 1 | 2 | {% extends "conference/base.html" %} 3 | 4 | {% load crispy_forms_tags %} 5 | 6 | 7 | {% block content %} 8 | 9 |
10 |
11 |
12 |
13 |

Password reset complete

14 |

Your password has been set. You may go ahead and log in now.

15 | 16 |

Log in

17 | 18 |

Cheers, EuroPython Team

19 |
20 |
21 | 22 |
23 |
24 | 25 | {% endblock %} 26 | -------------------------------------------------------------------------------- /templates/conference/accounts/password_reset_done.html: -------------------------------------------------------------------------------- 1 | 2 | {% extends "conference/base.html" %} 3 | 4 | {% load crispy_forms_tags %} 5 | 6 | 7 | {% block content %} 8 | 9 |
10 |
11 |
12 |
13 |

Password reset started

14 |

We sent you a link to reset your password to the email address you submitted.

15 |

If the account exists in our system you should receive the email shortly

16 |

Please find the link in your inbox (you might need to check the Spam folder) and use it to change your password.

17 |

Cheers, EuroPython Team

18 |
19 |
20 | 21 |
22 |
23 | 24 | {% endblock %} 25 | -------------------------------------------------------------------------------- /templates/conference/accounts/signup_please_verify_email.html: -------------------------------------------------------------------------------- 1 | {% extends "conference/base.html" %} 2 | 3 | {% load crispy_forms_tags %} 4 | 5 | 6 | {% block content %} 7 | 8 |
9 |
10 |
11 |
12 |

Thank you for creating your account

13 | 14 |

We sent you a link to verify your email address.

15 |

Please find the link in your inbox (you might need to check the Spam folder) and use it to fully activate the account

16 |

Cheers, EuroPython Team

17 | 18 |
19 |
20 | 21 |
22 |
23 | 24 | {% endblock %} 25 | -------------------------------------------------------------------------------- /templates/conference/admin/schedule_event.html: -------------------------------------------------------------------------------- 1 |
2 | {% csrf_token %} 3 | {{ form }}
4 |
5 | 6 | 7 | 8 | 9 |
10 |
-------------------------------------------------------------------------------- /templates/conference/admin/schedule_tracks.html: -------------------------------------------------------------------------------- 1 |
2 | {% csrf_token %} 3 | {{ form }}
4 |
5 | 6 |
7 |
-------------------------------------------------------------------------------- /templates/conference/cart/base.html: -------------------------------------------------------------------------------- 1 | {% extends "conference/base.html" %} 2 | 3 | {% load menu_tags %} 4 | 5 | {% block content %} 6 | {% endblock %} 7 | -------------------------------------------------------------------------------- /templates/conference/cart/step_3_add_billing_info.html: -------------------------------------------------------------------------------- 1 | {% extends "conference/cart/base.html" %} 2 | 3 | {% load crispy_forms_tags static %} 4 | 5 | {% block breadcrumbs %} 6 | {{ block.super }} 7 | » Step 3: Set billing info 8 | {% endblock %} 9 | 10 | {% block content %} 11 |
12 |
13 |
14 |

Step 3: Add billing info for {{ order.code }}

15 |
16 |
17 | 18 |
19 |
20 |
21 | {% csrf_token %} 22 | 23 | {{ form|crispy }} 24 |

To proceed with the purchase, we will need you to accept our terms & conditions for EuroPython 2021.

25 |

26 | 27 |

28 |
29 | 30 | 31 |
32 |
33 | {% include "conference/cart/_order_summary.html" %} 34 |
35 | 36 | 37 |
38 |
39 | {% endblock %} 40 | -------------------------------------------------------------------------------- /templates/conference/cart/step_5_congrats_order_complete.html: -------------------------------------------------------------------------------- 1 | {% extends "conference/cart/base.html" %} 2 | 3 | {% block breadcrumbs %} 4 | {{ block.super }} 5 | » Step 4: Confirmation and Payment 6 | {% endblock %} 7 | 8 | {% block content %} 9 | 10 |
11 |
12 |
13 |

Congrats! Order #{{ order.code }} complete.

14 | {% comment %} 15 |

Please take note of your ticket numbers below.
16 | You will need to provide them during at the registration desk to 17 | collect your badge.

18 | {% endcomment %} 19 | {% include "conference/cart/_order_summary.html" %} 20 |
21 |
22 |
23 | 24 | 25 | {% endblock %} 26 | -------------------------------------------------------------------------------- /templates/conference/cfp/cfp_is_closed.html: -------------------------------------------------------------------------------- 1 | {% extends "conference/base.html" %} 2 | 3 | {% block content %} 4 | 5 |
6 |
7 |
8 |

Sorry but the CFP is currently unavailable

9 | Go back to homepage 10 | 11 | {# TODO: add information of CFP is finished or not yet opened #} 12 |
13 |
14 | 15 |
16 | {% endblock %} 17 | -------------------------------------------------------------------------------- /templates/conference/cfp/step2_add_speaker.html: -------------------------------------------------------------------------------- 1 | {% extends "conference/base.html" %} 2 | 3 | {% load crispy_forms_tags %} 4 | 5 | 6 | {% block content %} 7 | 8 |
9 | {% include "conference/cfp/_steps.html" with step_no=2 %} 10 | 11 |
12 |
13 |

Your Speaker Profile

14 |
15 |
16 | 17 |
18 |
19 |
20 | {% csrf_token %} 21 | {{ speaker_form|crispy }} 22 | 23 | 24 |
25 |
26 | 27 |
28 |

{{ talk.title }}

29 |

{{ talk.abstract_short }} 30 |

31 |
32 |
33 | {% endblock %} 34 | -------------------------------------------------------------------------------- /templates/conference/cfp/step3_thanks.html: -------------------------------------------------------------------------------- 1 | {% extends "conference/base.html" %} 2 | 3 | {% block content %} 4 | 5 |
6 |
7 |
8 |

Thank you for your proposal!

9 |

You can preview it here

10 |

Full information about all of your proposals is available in your dashboard

11 |
12 |
13 | 14 |
15 | {% endblock %} 16 | -------------------------------------------------------------------------------- /templates/conference/cfp/update_proposal.html: -------------------------------------------------------------------------------- 1 | {% extends "conference/base.html" %} 2 | 3 | {% load crispy_forms_tags static %} 4 | 5 | {% block morecss %} 6 | 7 | {% endblock %} 8 | 9 | {% block morejs %} 10 | 11 | {% endblock %} 12 | 13 | 14 | {% block content %} 15 | 16 |
17 |
18 |
19 |

Update your proposal

20 |
21 |
22 | 23 |
24 |
25 |
26 | {% csrf_token %} 27 | {{ proposal_edit_form|crispy }} 28 | 29 | 30 |
31 |
32 |
33 |
34 | {% endblock %} 35 | -------------------------------------------------------------------------------- /templates/conference/cfp/update_speakers.html: -------------------------------------------------------------------------------- 1 | {% extends "conference/base.html" %} 2 | 3 | {% load crispy_forms_tags static %} 4 | 5 | 6 | {% block content %} 7 |
8 |
9 |
10 |

Update the presenter's profile

11 |
12 |
13 | 14 |
15 |
16 |
17 | {% csrf_token %} 18 | {{ speaker_edit_form|crispy }} 19 | 20 | 21 |
22 |
23 |
24 |
25 | {% endblock %} 26 | -------------------------------------------------------------------------------- /templates/conference/content/_breadcrumbs.html: -------------------------------------------------------------------------------- 1 | {% for ance in ancestors %} 2 |
3 | {% endfor %} 4 | -------------------------------------------------------------------------------- /templates/conference/content/_breadcrumbs_bar.html: -------------------------------------------------------------------------------- 1 | {% load menu_tags %} 2 | 3 | 18 | -------------------------------------------------------------------------------- /templates/conference/content/_breadcrumbs_no_active.html: -------------------------------------------------------------------------------- 1 | {% for ance in ancestors %} 2 | {% include "conference/content/_breadcrumb.html" with active=False nochevron=False url=ance.get_absolute_url title=ance.get_menu_title %} 3 | {% endfor %} 4 | -------------------------------------------------------------------------------- /templates/conference/content/_menu.html: -------------------------------------------------------------------------------- 1 | {% load menu_tags %} 2 | 3 | {% for child in children %} 4 |
  • 5 | {{ child.get_menu_title }} 6 | {% if child.children %} 7 |
      8 | {% show_menu from_level to_level extra_inactive extra_active template "" "" child %} 9 |
    10 | {% endif %} 11 |
  • 12 | {% endfor %} 13 | -------------------------------------------------------------------------------- /templates/conference/content/_messages.html: -------------------------------------------------------------------------------- 1 | {% if messages %} 2 |
      3 | {% for message in messages %} 4 |
    • {{ message }}
    • 5 | {% endfor %} 6 |
    7 | {% endif %} 8 | -------------------------------------------------------------------------------- /templates/conference/content/content_only_page.html: -------------------------------------------------------------------------------- 1 | {% extends "conference/base.html" %} 2 | 3 | {% load menu_tags cms_tags static %} 4 | 5 | {% block body %} 6 | {% include "conference/content/_messages.html" %} 7 |
    8 |
    9 |
    10 |
    11 |
    12 |
    13 | {% placeholder "text" %} 14 |
    15 |
    16 |
    17 |
    18 |
    19 |
    20 | {% endblock %} 21 | 22 | {% block morejs %} 23 | 24 | {% endblock morejs %} 25 | 26 | {% block cookieconsent %} 27 | 28 | {% endblock %} 29 | 30 | {% block morecss %} 31 | 37 | {% endblock morecss %} 38 | -------------------------------------------------------------------------------- /templates/conference/content/wide_content_page.html: -------------------------------------------------------------------------------- 1 | {% extends "conference/base.html" %} 2 | 3 | {% load menu_tags cms_tags static %} 4 | 5 | {% block content %} 6 |
    7 |
    8 |
    9 |
    10 |

    {% page_attribute "title" %}

    11 |
    12 |
    13 |
    14 |
    15 |
    16 | {% placeholder "text" %} 17 |
    18 |
    19 |
    20 |
    21 |
    22 | {% endblock %} 23 | 24 | {% block morejs %} 25 | 26 | {% endblock morejs %} 27 | 28 | {% block morecss %} 29 | 35 | {% endblock morecss %} 36 | -------------------------------------------------------------------------------- /templates/conference/debugpanel/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 12 | 13 | 14 | {% for key, val in debug_vars %} 15 | 16 | {% endfor %} 17 |
    KeyValue
    {{ key }}{{ val }}
    18 | 19 |

    Additional links

    20 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /templates/conference/debugpanel/invoice_placeholders.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 13 |

    We currently still have {{ placeholders|length }} placeholder(s)

    14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | {% for invoice in placeholders %} 22 | 23 | 24 | 25 | 26 | 31 | 32 | {% endfor %} 33 |
    IDpayment_datepriceLinks
    {{ invoice.code }}{{ invoice.payment_date }}{{ invoice.price }} 27 | Preview PDF 28 | | See in admin 29 | | URL for user 30 |
    34 | 35 | 36 | -------------------------------------------------------------------------------- /templates/conference/debugpanel/reissue_invoice.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 27 | 28 | 29 | 30 |

    Creating new invoice from {{ old_invoice.code }}

    31 |
    32 | {% csrf_token %} 33 | {{ form.as_p }} 34 |

    35 | 36 |

    37 |
    38 | 39 | 40 | -------------------------------------------------------------------------------- /templates/conference/emails/order_confirmation_email.txt: -------------------------------------------------------------------------------- 1 | Hello! 2 | 3 | Thanks for buying tickets for EuroPython 2021. 4 | 5 | This is the summary of order {{ order.code }}: 6 | 7 | {% for item in order.orderitem_set.all %} 8 | {% if item.ticket %}Ticket number: {{ item.ticket.id }}{% endif %} – {{ item.code }} – {{ item.description }} € {{ item.price }} 9 | {% endfor %} 10 | 11 | 12 | Your tickets were created and are available on your profile page here: 13 | 14 | {{ user_panel_url }} 15 | 16 | Your invoice is also available on the same url. 17 | 18 | If you have purchased tickets for other attendees, please follow these 19 | steps to have them assigned to your attendees: 20 | 21 | https://ep2021.europython.eu/faq/#I-bought-the-ticket-for-someone-else-How-can-I-re-assign-it 22 | 23 | We will be running the conference using our chat server. Please follow 24 | the instructions on our website: 25 | 26 | https://ep2021.europython.eu/setup/chat-system/ 27 | 28 | If you run into any issues, please contact us at helpdesk@europython.eu 29 | 30 | Kind regards, 31 | -- 32 | EuroPython 2021 Team 33 | https://ep2021.europython.eu 34 | https://www.europython-society.org/ 35 | -------------------------------------------------------------------------------- /templates/conference/emails/password_reset_email.txt: -------------------------------------------------------------------------------- 1 | Hello! 2 | 3 | We sent you this email because you (or someone using your email address) 4 | requested a password reset for your user account at {{ domain }} 5 | 6 | Here's the link: 7 | 8 | {{ protocol }}://{{ domain }}{% url 'accounts:password_reset_confirm' uidb64=uid token=token %} 9 | 10 | Use the link to change your password. If you suddently remembered your 11 | password – you can just ignore the link. 12 | 13 | However – if you didn't ask for the password reset – please let us know. 14 | 15 | You can find up to date contact information at the website {{ protocol }}://{{ domain }} 16 | 17 | Thanks, 18 | -- 19 | EuroPython 2021 Team 20 | https://ep2021.europython.eu 21 | -------------------------------------------------------------------------------- /templates/conference/emails/password_reset_subject.txt: -------------------------------------------------------------------------------- 1 | EuroPython 2021: Reset password link 2 | -------------------------------------------------------------------------------- /templates/conference/emails/signup_verification_email.txt: -------------------------------------------------------------------------------- 1 | Hello! 2 | 3 | Thanks for creating account for EuroPython 2021. 4 | 5 | Here's the link to activate your account: 6 | 7 | {{ verification_email_url }} 8 | 9 | Thanks, 10 | -- 11 | EuroPython 2021 Team 12 | https://ep2021.europython.eu 13 | -------------------------------------------------------------------------------- /templates/conference/footer/_show_menu_in_footer.html: -------------------------------------------------------------------------------- 1 | {% load menu_tags %} 2 | 3 | {% for child in children %} 4 | {% if not child.parent %} 5 | 19 | {% endif %} 20 | {% endfor %} 21 | 22 | -------------------------------------------------------------------------------- /templates/conference/header/_homepage_jumbotron.html: -------------------------------------------------------------------------------- 1 | {% load cms_tags static %} 2 | 3 |
    4 |
    5 | EuroPython 2021; Jul 26 - Aug 1, 2021; Online 8 | 9 | {% comment %} 10 | 11 |

    euro python

    12 |

    Jul 26 - Aug 1, 2021, Online

    13 | {% endcomment %} 14 | 15 | 16 | {% comment %} 17 |
    18 | NOTE(artcz): Disabled because we will open ticket sales a bit later after launch 19 |

    Get the tickets

    20 |

    Buy tickets

    21 |
    22 | {% endcomment %} 23 |
    24 |
    25 |
    26 | {% placeholder "text" %} 27 |
    28 | -------------------------------------------------------------------------------- /templates/conference/header/_nav_menu.html: -------------------------------------------------------------------------------- 1 | {% load menu_tags %} 2 | 3 | {% for child in children %} 4 | 29 | {% endfor %} -------------------------------------------------------------------------------- /templates/conference/header/_regular.html: -------------------------------------------------------------------------------- 1 |
    2 | {% include "conference/header/_nav.html" %} 3 |
    4 | -------------------------------------------------------------------------------- /templates/conference/header/_with_jumbotron.html: -------------------------------------------------------------------------------- 1 |
    2 | {% include "conference/header/_nav.html" %} 3 | {% include "conference/header/_homepage_jumbotron.html" %} 4 |
    5 | -------------------------------------------------------------------------------- /templates/conference/homepage.html: -------------------------------------------------------------------------------- 1 | {% extends "conference/base.html" %} 2 | -------------------------------------------------------------------------------- /templates/conference/homepage/home.html: -------------------------------------------------------------------------------- 1 | {% extends "conference/base.html" %} 2 | 3 | {% block body %} 4 | 5 | {% include "conference/header/_with_jumbotron.html" %} 6 | 7 | {% include "conference/homepage/_schedule_overview.html" %} 8 | 9 | {% include "conference/homepage/_venue.html" %} 10 | 11 | {% include "conference/homepage/_sponsors.html" %} 12 | 13 | {% include "conference/footer/footer.html" %} 14 | 15 | {% endblock body %} 16 | -------------------------------------------------------------------------------- /templates/conference/homepage/home_template.html: -------------------------------------------------------------------------------- 1 | {% extends "conference/base.html" %} 2 | 3 | {% load conference %} 4 | 5 | {% block body %} 6 | 7 | {% include "conference/header/_with_jumbotron.html" %} 8 | 9 | {% include "conference/homepage/_schedule_overview.html" %} 10 | 11 | {% include "conference/homepage/_venue.html" with CCD_GOOGLEMAPS_URL="https://goo.gl/maps/X57SxAPbiJV3Fcig9" CCD_OSM_URL="https://www.openstreetmap.org/way/60270053" %} 12 | 13 | {% sponsor_data as sponsors %} 14 | {% include "conference/homepage/_sponsors.html" with sponsors=sponsors%} 15 | 16 | {% include "conference/footer/footer.html" %} 17 | 18 | {% endblock body %} 19 | -------------------------------------------------------------------------------- /templates/conference/news/list.html: -------------------------------------------------------------------------------- 1 | {% extends "conference/base.html" %} 2 | 3 | {% block content %} 4 |
    5 |
    6 | 13 | 14 |
    15 |
    16 |

    Latest News

    17 |
    18 | 19 | {% for n in news %} 20 |
    21 |

    {{ n.title }}

    22 | {{ n.published_date|timesince }} ago 23 |

    {{ n.content|safe }}

    24 |
    25 | {% endfor %} 26 | 27 | {# TODO(artcz): Add pagination #} 28 | {# Probably we won't have enough news here to paginate but who knows... #} 29 |
    30 | 31 |
    32 |
    33 | {% endblock content %} 34 | -------------------------------------------------------------------------------- /templates/conference/profiles/profile_unavailable.html: -------------------------------------------------------------------------------- 1 | {% extends "conference/base.html" %} 2 | 3 | {% block content %} 4 |
    5 | 11 | 12 |
    13 |
    14 |

    This user's profile is not publicly available.

    15 |
    16 |
    17 |
    18 | {% endblock %} 19 | -------------------------------------------------------------------------------- /templates/conference/talk_voting/_voting_form.html: -------------------------------------------------------------------------------- 1 |
    2 | {% csrf_token %} 3 | 4 | 5 | 6 | 7 | 8 |
    9 | -------------------------------------------------------------------------------- /templates/conference/talk_voting/voting_is_closed.html: -------------------------------------------------------------------------------- 1 | {% extends "conference/base.html" %} 2 | 3 | {% block content %} 4 |
    5 |
    6 |
    7 |

    Sorry, the voting is closed. :(

    8 |

    Go back to homepage

    9 |
    10 |
    11 |
    12 | {% endblock content %} 13 | -------------------------------------------------------------------------------- /templates/conference/talk_voting/voting_is_unavailable.html: -------------------------------------------------------------------------------- 1 | {% extends "conference/base.html" %} 2 | 3 | {% load cms_tags %} 4 | 5 | {% block content %} 6 |
    7 |
    8 |
    9 |

    Sorry, you can't vote yet. :(

    10 |

    Only users who have conference tickets assigned to them 11 | either for this conference or one of the previous EuroPythons 12 | (since 2015+) can vote on the talks. If you'd like to take part 13 | in our current voting that ends on {{ conference.voting_end|date }} 14 | you can buy a conference ticket 15 | here.

    16 |
    17 |
    18 |
    19 | {% endblock content %} 20 | -------------------------------------------------------------------------------- /templates/conference/user_panel/_invoices.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | {% for invoice in invoices %} 9 | 10 | 11 | 12 | 13 | 14 | {% endfor %}{# invoice in invoices #} 15 |
    TitleDate
    {{ invoice.code }}{{ invoice.payment_date }} Download as PDF
    16 | -------------------------------------------------------------------------------- /templates/conference/user_panel/_orders.html: -------------------------------------------------------------------------------- 1 |

    Your orders from this year

    2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | {% for order in orders %} 10 | 11 | 12 | 19 | 20 | {% endfor %}{# order in orders #} 21 |
    IDInvoices
    {{ order.code }} 13 | {% for invoice in order.invoices.all %} 14 | 15 | Invoice #{{ invoice.code }} 16 | 17 | {% endfor %} 18 |
    22 | -------------------------------------------------------------------------------- /templates/conference/user_panel/_proposals.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | {% for prop in proposals %} 9 | 10 | {% if prop.status == ACCEPTED_PROPOSAL %} 11 | {# If proposal is accepted link to the proper talk page on the website rather than preview #} 12 | 13 | {% else %} 14 | 15 | {% endif %} 16 | 17 | 18 | 19 | {% endfor %}{# prop in proposals #} 20 |
    TitleDate of SubmissionStatus
    {{ prop.title }}{{ prop.title }}{{ prop.created }}{{ prop.get_status_display }}
    21 | -------------------------------------------------------------------------------- /templates/conference/user_panel/_tickets.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | {% for ticket in tickets %} 12 | 13 | 14 | 15 | 16 | 17 | 26 | 27 | {% endfor %}{# ticket in tickets #} 28 |
    IDCodeTypeNameManage
    #{{ ticket.id }}{{ ticket.fare.code }}{{ ticket.fare.name }}{{ ticket.name|default:ticket.user.assopy_user.name }} 18 | {% if ticket.is_conference and ticket.user == user %} 19 | Configure ticket 20 | {% endif %} 21 | 22 | {% if ticket.is_buyer %} 23 | Assign ticket 24 | {% endif %} 25 |
    29 | -------------------------------------------------------------------------------- /templates/conference/user_panel/assign_ticket.html: -------------------------------------------------------------------------------- 1 | {% extends "conference/user_panel/base.html" %} 2 | 3 | {% load cms_tags crispy_forms_tags %} 4 | 5 | {% block breadcrumbs %} 6 | {{ block.super }} 7 | 8 | 11 | {% endblock breadcrumbs %} 12 | 13 | {% block user_content %} 14 |
    15 | 16 |
    17 |

    (re)Assign ticket #{{ ticket.id }}

    18 | 19 |
    20 | {% csrf_token %} 21 | {{ assignment_form | crispy }} 22 | 23 |
    24 |
    25 |
    26 |
    27 |
    28 | {% endblock %} 29 | -------------------------------------------------------------------------------- /templates/conference/user_panel/base.html: -------------------------------------------------------------------------------- 1 | {% extends "conference/base.html" %} 2 | {% load meta %} 3 | 4 | {% block meta %} 5 | {% render_meta title="User's Panel" %} 6 | {% endblock meta %} 7 | 8 | {% block content %} 9 |
    10 |
    11 | 20 | 21 | {% block user_content %} 22 | {% endblock %} 23 | 24 |
    25 |
    26 | {% endblock content %} 27 | -------------------------------------------------------------------------------- /templates/conference/user_panel/configure_ticket.html: -------------------------------------------------------------------------------- 1 | {% extends "conference/user_panel/base.html" %} 2 | 3 | {% load static cms_tags crispy_forms_tags %} 4 | 5 | {% block breadcrumbs %} 6 | {{ block.super }} 7 | 8 | 11 | {% endblock breadcrumbs %} 12 | 13 | {% block user_content %} 14 |
    15 | 16 |
    17 |

    Configure ticket #{{ ticket.id }}

    18 | 19 |
    20 | {% csrf_token %} 21 | {{ ticket_configuration_form | crispy }} 22 | 23 |
    24 |
    25 | {% comment "XXX Disabled for EP2020, see #1269" %} 26 |
    27 |

    Shirt size guide

    28 |
    All sizes shown are in centimeters
    29 |

    Fitted cut

    30 | Fitted cut size guide 31 |

    Straight cut

    32 | Straight cut size guide 33 |
    34 | {% endcomment %} 35 |
    36 | {% endblock %} 37 | -------------------------------------------------------------------------------- /templates/conference/user_panel/forms/privacy_settings_recruiting.html: -------------------------------------------------------------------------------- 1 |

    Sponsor messages and recruiting

    2 |

    3 | Many of our sponsors support our conference to offer jobs and recruit good Python programmers. 4 | In addition to the official recruiting sessions, you might like to receive selected job offers 5 | via email, and evaluate them in a more private environment. 6 |

    7 |

    8 | Our top-tier sponsors may also want to send you special invites, perks, 9 | etc. in form of a few sponsor messages. 10 |

    11 |
      12 |
    • 13 | Your email address will never be shared with any of our 14 | sponsors - the emails are sent by the EuroPython Organizers on 15 | behalf of the sponsors. 16 |
    • 17 |
    • 18 | You will only receive emails during the conference and in the week 19 | before and after the conference. 20 |
    • 21 |
    22 | {{ fields|safe }} 23 | -------------------------------------------------------------------------------- /templates/conference/user_panel/forms/privacy_settings_sms_messages.html: -------------------------------------------------------------------------------- 1 |

    SMS Messages

    2 |

    3 | Sometimes it is useful for organizers to send last-minute information to all participants 4 | (eg: transportation strikes, last-minute schedule changes, impromptu happenings, etc.). 5 | Do you want to receive this information via SMS? 6 |

    7 |
      8 |
    • You must add your phone number in the “Personal data” section to activate this service.
    • 9 |
    • Your phone number will never be shared with other people.
    • 10 |
    • This SMS message service will only be active for the time span of the conference.
    • 11 |
    • Please note that some companies charge for incoming SMS while roaming.
    • 12 |
    13 | {{ fields|safe }} 14 | -------------------------------------------------------------------------------- /templates/conference/user_panel/forms/privacy_settings_user_messages.html: -------------------------------------------------------------------------------- 1 |

    User Messages

    2 |

    3 | After you buy a ticket and activate your public profile, other participants will be 4 | able to find out that you are coming to the conference. Do you want them to be able 5 | to contact you through our website? 6 |

    7 |
      8 |
    • Your email address will never be shared with other participants.
    • 9 |
    • We will send you one mail notifying you of the received message.
    • 10 |
    • User messages will be active until the conference ends.
    • 11 |
    12 | {{ fields|safe }} 13 | -------------------------------------------------------------------------------- /templates/conference/user_panel/password_change.html: -------------------------------------------------------------------------------- 1 | {% extends "conference/user_panel/base.html" %} 2 | 3 | {% load crispy_forms_tags %} 4 | 5 | {% block breadcrumbs %} 6 | 7 | {% endblock breadcrumbs %} 8 | 9 | {% block user_content %} 10 |
    11 |
    12 | {% if user.is_staff %} 13 | Admin panel 14 | {% endif %} 15 | Change password 16 | Log out 17 |
    18 |
    19 | 20 |
    21 | 22 |
    23 |

    Change your password

    24 |
    25 | {% csrf_token %} 26 | {{ form|crispy }} 27 | 28 |
    29 |
    30 |
    31 |
    32 |
    33 | {% endblock %} 34 | -------------------------------------------------------------------------------- /templates/conference/user_panel/password_change_done.html: -------------------------------------------------------------------------------- 1 | {% extends "conference/user_panel/base.html" %} 2 | 3 | {% load crispy_forms_tags %} 4 | 5 | {% block breadcrumbs %} 6 | 7 | {% endblock breadcrumbs %} 8 | 9 | {% block user_content %} 10 |
    11 |
    12 | {% if user.is_staff %} 13 | Admin panel 14 | {% endif %} 15 | Change password 16 | Log out 17 |
    18 |
    19 | 20 |
    21 | 22 |
    23 |

    Password updated

    24 |
    25 |
    26 | {% endblock %} 27 | -------------------------------------------------------------------------------- /templates/conference/user_panel/privacy_settings.html: -------------------------------------------------------------------------------- 1 | {% extends "conference/user_panel/base.html" %} 2 | 3 | {% load cms_tags crispy_forms_tags %} 4 | 5 | {% block breadcrumbs %} 6 | {{ block.super }} 7 | 8 | 11 | {% endblock breadcrumbs %} 12 | 13 | {% block user_content %} 14 |
    15 | 16 |
    17 |

    Privacy settings

    18 |
    19 | We respect your privacy. We never share your personal data with anyone. Have a look at our 20 | privacy policy for further information. 21 |
    22 |

    23 | This page contains additional privacy settings for advanced opt-in features. 24 |

    25 |
    26 | {% csrf_token %} 27 | {% crispy privacy_form %} 28 |
    29 |
    30 |
    31 | {% endblock %} 32 | -------------------------------------------------------------------------------- /templates/conference/user_panel/profile_settings.html: -------------------------------------------------------------------------------- 1 | {% extends "conference/user_panel/base.html" %} 2 | 3 | {% load cms_tags crispy_forms_tags %} 4 | 5 | {% block breadcrumbs %} 6 | {{ block.super }} 7 | 10 | {% endblock breadcrumbs %} 11 | 12 | {% block user_content %} 13 |
    14 | 15 |
    16 | {% if profile_form.errors %} 17 | {% for field in profile_form %} 18 | {% for error in field.errors %} 19 |
    20 | {{ error|escape }} 21 |
    22 | {% endfor %} 23 | {% endfor %} 24 | {% endif %} 25 |
    26 | {% csrf_token %} 27 | {% crispy profile_form %} 28 |
    29 |
    30 |
    31 | {% endblock %} 32 | 33 | {% block morecss %} 34 | 39 | {% endblock %} 40 | -------------------------------------------------------------------------------- /templates/p3/admin/index.html: -------------------------------------------------------------------------------- 1 | {% extends "admin/index.html" %} 2 | {% block sidebar %} 3 |
    4 |
    5 |

    Goodies

    6 | 9 |
    10 |
    11 |
    12 | {{ block.super }} 13 | {% endblock %} 14 | -------------------------------------------------------------------------------- /tests/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EuroPython/epcon/341c22649ff4ec858fc710821303cf3b78aa59e6/tests/__init__.py -------------------------------------------------------------------------------- /tests/conftest.py: -------------------------------------------------------------------------------- 1 | import pytest 2 | 3 | from . import factories 4 | 5 | 6 | @pytest.fixture 7 | def user(): 8 | user = factories.UserFactory() 9 | user.attendeeprofile.setBio('bio') 10 | return user 11 | 12 | 13 | @pytest.fixture 14 | def user_client(client): 15 | user = factories.UserFactory() 16 | user.attendeeprofile.setBio('bio') 17 | client.login(email=user.email, password='password123') 18 | client.user = user 19 | yield client 20 | 21 | 22 | @pytest.fixture 23 | def ep_admin_client(client): 24 | """ 25 | Custom admin client for EP so that it creates all required user-related 26 | objects like AssopyUser or AttendeeProfile 27 | """ 28 | user = factories.UserFactory(is_staff=True) 29 | user.attendeeprofile.setBio('bio') 30 | client.login(email=user.email, password='password123') 31 | client.user = user 32 | yield client 33 | -------------------------------------------------------------------------------- /tests/test_accounts.py: -------------------------------------------------------------------------------- 1 | from django.contrib.sites.shortcuts import get_current_site 2 | from django.core import mail 3 | from django.test.client import RequestFactory 4 | from pytest import mark 5 | 6 | from conference.accounts import send_verification_email 7 | 8 | from . import factories 9 | 10 | 11 | @mark.django_db 12 | def test_send_verification_email(): 13 | user = factories.UserFactory() 14 | 15 | user.is_active = False 16 | user.save() 17 | 18 | request = RequestFactory() 19 | current_site = get_current_site(request) 20 | 21 | assert not mail.outbox # sanity check 22 | 23 | send_verification_email(user, current_site) 24 | 25 | assert len(mail.outbox) == 1 26 | 27 | message = mail.outbox[0] 28 | assert len(message.recipients()) == 1 29 | assert message.recipients()[0] == user.email 30 | assert current_site.domain in message.body 31 | -------------------------------------------------------------------------------- /tests/test_assopy_user.py: -------------------------------------------------------------------------------- 1 | from django.contrib.auth import get_user_model 2 | 3 | import pytest 4 | 5 | from assopy.models import AssopyUser 6 | 7 | 8 | @pytest.mark.parametrize( 9 | "first_name,last_name,expected", [ 10 | ("John", "Doe", ("John", "Doe")), 11 | ("John Doe", "Doe", ("John", "Doe")), 12 | # let's get some utf8 going 13 | ("Skřŷźňǎ", "Labrŷẓňă", ("Skřŷźňǎ", "Labrŷẓňă")), 14 | ("Skřŷźňǎ Labrŷẓňă", "Labrŷẓňă", ("Skřŷźňǎ", "Labrŷẓňă")), 15 | # Having identical first and last names is unusual but not as rare as you'd think: 16 | # https://en.wikipedia.org/wiki/List_of_people_with_reduplicated_names 17 | ("Thomas", "Thomas", ("Thomas", "Thomas")), 18 | ("Thomas Thomas", "Thomas", ("Thomas", "Thomas")), 19 | ]) 20 | def test_name_tuple(first_name, last_name, expected): 21 | user = get_user_model()(first_name=first_name, last_name=last_name) 22 | assopy_user = AssopyUser(user=user) 23 | assert assopy_user.name_tuple() == expected 24 | -------------------------------------------------------------------------------- /tests/test_avatar.py: -------------------------------------------------------------------------------- 1 | from django.urls import reverse 2 | 3 | 4 | def test_p3_profile_avatar(db, user_client): 5 | url = reverse('p3-profile-avatar', args=[user_client.user.attendeeprofile.slug]) 6 | response = user_client.get(url) 7 | assert response.status_code == 200 8 | -------------------------------------------------------------------------------- /tests/test_cmsplugins.py: -------------------------------------------------------------------------------- 1 | from cms.api import add_plugin, create_page 2 | from cms.test_utils.testcases import CMSTestCase 3 | from cms_utils.cms_plugins import TemplatePlugin 4 | 5 | 6 | class CmsPluginsTestCase(CMSTestCase): 7 | def test_template_plugin(self): 8 | page = create_page( 9 | title='test', 10 | template='conference/homepage/home_template.html', 11 | language='en', 12 | ) 13 | placeholder = page.placeholders.get(slot="text") 14 | plugin = add_plugin( 15 | placeholder=placeholder, 16 | plugin_type=TemplatePlugin.__name__, 17 | language='en', 18 | body='{% comment %}THIS IS JUST A COMMENT{% endcomment %}', 19 | ) 20 | assert plugin.plugin_type == 'TemplatePlugin' 21 | assert plugin.full_clean() is None 22 | 23 | page.publish('en') 24 | url = page.get_absolute_url('en') 25 | assert url == '/test/' 26 | 27 | response = self.client.get(url) 28 | print(response.content) 29 | 30 | # Django Template evaluated? 31 | self.assertNotContains(response, 'THIS IS JUST A COMMENT') 32 | 33 | # Nothing escaped? 34 | self.assertContains(response, '') 35 | -------------------------------------------------------------------------------- /tests/test_debugpanel.py: -------------------------------------------------------------------------------- 1 | from django.conf import settings 2 | from conference.models import Conference 3 | 4 | 5 | def test_index(admin_client): 6 | """ 7 | Basic test to see if it even works. 8 | """ 9 | url = "/nothing-to-see-here/" 10 | HTTP_OK_200 = 200 11 | Conference.objects.create( 12 | code=settings.CONFERENCE_CONFERENCE, 13 | name=settings.CONFERENCE_CONFERENCE, 14 | ) 15 | 16 | respnse = admin_client.get(url) 17 | assert respnse.status_code == HTTP_OK_200 18 | -------------------------------------------------------------------------------- /tests/test_provisioning_script.py: -------------------------------------------------------------------------------- 1 | 2 | from django.core.management import call_command 3 | 4 | from pytest import mark 5 | 6 | 7 | @mark.django_db 8 | def test_basic_create_initial_data_for_dev_run(): 9 | 10 | # just to make sure it doesn't have any syntax errors, obvious mistakes, 11 | # etc. 12 | call_command('create_initial_data_for_dev') 13 | --------------------------------------------------------------------------------