From bf2f0c7898a8f0b3c20781db07902c71a684bdc5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=AD=C3=B0ir=20Valberg=20Gu=C3=B0mundsson?= Date: Sun, 16 Jun 2019 14:32:24 +0200 Subject: [PATCH] Blackness. --- src/.coverage | 1 + src/.ropeproject/config.py | 122 ++ src/.ropeproject/globalnames | Bin 0 -> 28985 bytes src/.ropeproject/history | Bin 0 -> 14 bytes src/.ropeproject/objectdb | Bin 0 -> 6 bytes src/backoffice/apps.py | 2 +- src/backoffice/mixins.py | 13 +- src/backoffice/urls.py | 213 ++-- src/backoffice/views.py | 288 +++-- src/bar/admin.py | 4 +- src/bar/apps.py | 2 +- src/bar/migrations/0001_initial.py | 59 +- src/bar/migrations/0002_auto_20170916_2128.py | 22 +- src/bar/migrations/0003_auto_20180318_0906.py | 22 +- src/bar/models.py | 6 +- src/bornhack/asgi.py | 1 - src/bornhack/routing.py | 14 +- src/bornhack/schema.py | 22 +- src/bornhack/settings.py | 1 + src/bornhack/urls.py | 257 ++-- src/camps/admin.py | 1 - src/camps/context_processors.py | 16 +- src/camps/management/commands/createcamp.py | 46 +- src/camps/migrations/0001_initial.py | 223 +++- .../migrations/0002_auto_20160117_1718.py | 18 +- .../migrations/0003_auto_20160422_2019.py | 18 +- .../migrations/0004_camp_ticket_sale_open.py | 16 +- .../migrations/0005_auto_20160510_2011.py | 19 +- .../migrations/0006_auto_20160804_1705.py | 14 +- .../migrations/0007_auto_20161212_1803.py | 124 +- src/camps/migrations/0008_delete_day.py | 10 +- .../migrations/0009_auto_20161220_1645.py | 34 +- .../migrations/0010_auto_20161220_1714.py | 31 +- .../migrations/0011_auto_20161228_1750.py | 26 +- .../migrations/0012_auto_20161228_2312.py | 14 +- .../migrations/0013_auto_20161229_2201.py | 54 +- .../migrations/0014_auto_20161229_2202.py | 34 +- .../migrations/0015_auto_20170116_1634.py | 13 +- src/camps/migrations/0016_camp_description.py | 16 +- .../0017_remove_camp_description.py | 11 +- .../migrations/0018_auto_20170128_1841.py | 28 +- .../migrations/0019_auto_20170131_1849.py | 56 +- src/camps/migrations/0020_camp_read_only.py | 15 +- .../migrations/0021_auto_20170711_2247.py | 14 +- src/camps/migrations/0022_camp_colour.py | 17 +- src/camps/migrations/0023_camp_shortslug.py | 16 +- .../0024_populate_camp_shortslugs.py | 13 +- .../migrations/0025_auto_20180318_1250.py | 15 +- .../migrations/0026_auto_20180506_1633.py | 22 +- .../migrations/0027_auto_20180525_1019.py | 20 +- .../migrations/0028_auto_20180525_1025.py | 24 +- .../migrations/0029_auto_20180815_2018.py | 15 +- src/camps/migrations/0030_camp_light_text.py | 15 +- .../migrations/0031_auto_20180830_0014.py | 37 +- .../migrations/0032_auto_20180917_1754.py | 22 +- src/camps/mixins.py | 9 +- src/camps/models.py | 129 +- src/camps/utils.py | 5 +- src/camps/views.py | 34 +- src/economy/admin.py | 67 +- src/economy/apps.py | 2 +- src/economy/email.py | 4 +- src/economy/forms.py | 31 +- src/economy/migrations/0001_initial.py | 184 ++- src/economy/migrations/0002_revenue.py | 111 +- .../migrations/0003_auto_20180917_1933.py | 19 +- .../migrations/0004_auto_20181120_1835.py | 17 +- .../migrations/0005_auto_20190120_1532.py | 24 +- .../migrations/0006_auto_20190120_1642.py | 24 +- .../migrations/0007_auto_20190327_0936.py | 24 +- .../migrations/0008_auto_20190327_1721.py | 151 ++- .../migrations/0009_auto_20190328_0715.py | 23 +- .../migrations/0010_auto_20190330_1045.py | 26 +- src/economy/models.py | 167 +-- src/economy/urls.py | 234 ++-- src/events/admin.py | 4 +- src/events/apps.py | 2 +- src/events/handler.py | 34 +- src/events/migrations/0001_initial.py | 68 +- .../migrations/0002_create_eventtype.py | 15 +- .../0003_create_another_eventtype.py | 13 +- .../migrations/0004_auto_20180403_1228.py | 22 +- src/events/models.py | 28 +- src/feedback/admin.py | 2 +- src/feedback/apps.py | 2 +- src/feedback/migrations/0001_initial.py | 36 +- src/feedback/migrations/0002_feedback_camp.py | 17 +- src/feedback/models.py | 4 +- src/feedback/views.py | 13 +- src/info/admin.py | 19 +- src/info/apps.py | 2 +- src/info/migrations/0001_initial.py | 119 +- .../migrations/0002_auto_20161228_2312.py | 29 +- .../migrations/0003_auto_20170218_1148.py | 14 +- src/info/migrations/0004_infocategory_team.py | 18 +- .../0005_add_teams_to_categories.py | 8 +- .../migrations/0006_auto_20180520_1113.py | 27 +- .../migrations/0007_auto_20180520_1511.py | 17 +- src/info/models.py | 61 +- src/info/views.py | 6 +- src/ircbot/admin.py | 1 - src/ircbot/apps.py | 2 +- src/ircbot/irc3module.py | 208 ++-- src/ircbot/ircworker.py | 32 +- src/ircbot/migrations/0001_initial.py | 31 +- .../0002_outgoingircmessage_timeout.py | 14 +- .../0003_outgoingircmessage_expired.py | 10 +- src/ircbot/models.py | 9 +- src/ircbot/utils.py | 7 +- src/manage.py | 5 +- src/news/admin.py | 10 +- src/news/apps.py | 2 +- src/news/migrations/0001_initial.py | 33 +- .../migrations/0002_auto_20160530_2223.py | 9 +- src/news/migrations/0003_newsitem_slug.py | 12 +- .../migrations/0004_auto_20160610_1743.py | 10 +- .../migrations/0005_auto_20160618_1902.py | 10 +- .../migrations/0006_remove_newsitem_public.py | 11 +- .../migrations/0007_auto_20161220_1136.py | 10 +- src/news/migrations/0008_newsitem_archived.py | 10 +- src/news/models.py | 21 +- src/news/urls.py | 13 +- src/news/views.py | 14 +- src/people/apps.py | 2 +- src/people/views.py | 3 +- src/profiles/__init__.py | 3 +- src/profiles/admin.py | 19 +- src/profiles/apps.py | 13 +- src/profiles/migrations/0001_initial.py | 37 +- .../migrations/0002_profile_description.py | 15 +- .../migrations/0003_auto_20170413_1703.py | 22 +- .../migrations/0004_auto_20170430_1408.py | 16 +- .../migrations/0005_auto_20170711_1721.py | 23 +- .../migrations/0006_auto_20170711_1757.py | 39 +- .../migrations/0007_auto_20170711_2025.py | 11 +- .../migrations/0008_auto_20180325_2022.py | 16 +- .../0009_profile_nickserv_username.py | 16 +- .../migrations/0010_auto_20180411_2305.py | 16 +- src/profiles/models.py | 25 +- src/profiles/signal_handlers.py | 51 +- src/profiles/urls.py | 11 +- src/profiles/views.py | 17 +- src/program/__init__.py | 3 +- src/program/admin.py | 71 +- src/program/apps.py | 13 +- src/program/consumers.py | 81 +- src/program/email.py | 73 +- src/program/forms.py | 385 +++--- .../commands/notification_worker.py | 28 +- src/program/migrations/0001_initial.py | 101 +- .../migrations/0002_eventtype_color.py | 12 +- .../0003_eventtype_light_writing.py | 10 +- .../migrations/0004_auto_20160804_1712.py | 10 +- .../migrations/0005_auto_20160807_1312.py | 21 +- .../migrations/0006_auto_20160807_1320.py | 10 +- .../migrations/0007_auto_20160807_1333.py | 11 +- .../migrations/0008_auto_20160808_1747.py | 32 +- .../migrations/0009_auto_20160827_0752.py | 12 +- .../migrations/0010_auto_20161212_1809.py | 63 +- .../migrations/0011_auto_20161229_2149.py | 21 +- .../migrations/0012_auto_20161229_2150.py | 10 +- .../migrations/0013_auto_20170121_1312.py | 17 +- src/program/migrations/0014_speaker_camp.py | 17 +- .../migrations/0015_auto_20170128_1841.py | 20 +- .../migrations/0016_auto_20170131_1849.py | 12 +- .../0017_eventinstance_notifications_sent.py | 10 +- .../0018_eventtype_notifications.py | 10 +- .../migrations/0019_auto_20170205_1940.py | 52 +- .../migrations/0020_auto_20170205_1940.py | 16 +- .../migrations/0021_auto_20170205_2130.py | 16 +- .../migrations/0022_auto_20170218_1148.py | 14 +- .../migrations/0023_auto_20170218_1243.py | 24 +- .../migrations/0024_auto_20170222_1629.py | 23 +- .../migrations/0025_auto_20170306_1938.py | 15 +- src/program/migrations/0026_speaker_user.py | 15 +- .../migrations/0027_auto_20170307_1701.py | 10 +- .../migrations/0028_auto_20170307_2014.py | 32 +- .../migrations/0029_auto_20170307_2042.py | 34 +- .../migrations/0030_auto_20170312_1230.py | 317 +++-- .../migrations/0031_auto_20170312_1529.py | 19 +- .../migrations/0032_auto_20170312_1556.py | 57 +- .../migrations/0033_auto_20170312_1857.py | 220 ++-- .../migrations/0034_auto_20170314_2012.py | 28 +- .../migrations/0035_auto_20170314_2325.py | 15 +- .../migrations/0036_auto_20170316_0004.py | 30 +- .../0037_eventtype_include_in_event_list.py | 14 +- src/program/migrations/0038_favorite.py | 33 +- .../migrations/0039_auto_20170430_1408.py | 16 +- ...040_eventproposal_allow_video_recording.py | 14 +- .../migrations/0041_auto_20170711_2248.py | 36 +- .../migrations/0042_auto_20170715_1547.py | 22 +- .../migrations/0043_auto_20170801_1526.py | 22 +- .../migrations/0044_auto_20170801_1527.py | 16 +- src/program/migrations/0045_event_proposal.py | 18 +- .../migrations/0046_auto_20180318_0906.py | 16 +- .../migrations/0047_auto_20180415_1159.py | 145 ++- .../migrations/0048_auto_20180512_1625.py | 276 +++-- .../migrations/0049_add_event_tracks.py | 24 +- .../migrations/0050_auto_20180512_1650.py | 17 +- .../migrations/0051_auto_20180512_1801.py | 26 +- .../migrations/0052_auto_20180519_2324.py | 15 +- .../migrations/0053_auto_20180519_2325.py | 15 +- .../migrations/0054_auto_20180520_1509.py | 19 +- .../migrations/0055_auto_20180521_2354.py | 117 +- src/program/migrations/0056_add_urltypes.py | 52 +- .../migrations/0057_auto_20180522_0659.py | 16 +- .../migrations/0058_auto_20180523_0844.py | 17 +- .../migrations/0059_auto_20180523_2241.py | 17 +- .../migrations/0060_auto_20180603_1455.py | 49 +- .../migrations/0061_auto_20180603_1525.py | 30 +- .../migrations/0062_auto_20180717_1720.py | 16 +- .../migrations/0063_auto_20180809_1525.py | 14 +- .../migrations/0064_auto_20180810_1748.py | 14 +- .../migrations/0065_speakerproposal_email.py | 17 +- src/program/migrations/0066_speaker_email.py | 17 +- .../migrations/0067_auto_20180818_1634.py | 12 +- ...d_email_to_speaker_and_speaker_proposal.py | 12 +- .../0069_add_bogus_email_to_old_speakers.py | 10 +- .../migrations/0070_auto_20180819_1729.py | 21 +- .../migrations/0071_auto_20180827_1958.py | 11 +- src/program/mixins.py | 46 +- src/program/models.py | 508 ++++---- src/program/signal_handlers.py | 29 +- src/program/urls.py | 326 +++-- src/program/views.py | 595 ++++++--- src/rideshare/admin.py | 4 +- src/rideshare/apps.py | 2 +- src/rideshare/migrations/0001_initial.py | 47 +- .../migrations/0002_auto_20180814_1942.py | 12 +- src/rideshare/models.py | 15 +- src/rideshare/urls.py | 47 +- src/rideshare/views.py | 20 +- src/shop/__init__.py | 3 +- src/shop/admin.py | 138 +-- src/shop/apps.py | 4 +- src/shop/coinify.py | 77 +- src/shop/context_processors.py | 2 +- src/shop/email.py | 31 +- src/shop/epay.py | 16 +- src/shop/invoiceworker.py | 77 +- src/shop/managers.py | 7 +- src/shop/migrations/0001_initial.py | 231 +++- .../0002_orderproductrelation_handed_out.py | 10 +- .../migrations/0003_auto_20160513_0646.py | 42 +- .../migrations/0004_auto_20160515_1604.py | 20 +- src/shop/migrations/0005_product_slug.py | 12 +- src/shop/migrations/0006_ensure_slugs.py | 12 +- .../migrations/0007_auto_20160515_2157.py | 22 +- .../migrations/0008_auto_20160516_0954.py | 22 +- .../migrations/0009_epaycallback_md5valid.py | 10 +- .../migrations/0010_auto_20160517_1313.py | 50 +- .../migrations/0011_auto_20160517_1902.py | 13 +- src/shop/migrations/0012_ticket.py | 40 +- .../migrations/0013_ticket_qrcode_base64.py | 10 +- src/shop/migrations/0014_ticket_name.py | 16 +- .../0015_coinifyapiinvoice_coinifycallback.py | 62 +- .../migrations/0016_auto_20160529_1122.py | 12 +- .../migrations/0017_auto_20160529_1626.py | 9 +- .../migrations/0018_auto_20160529_1736.py | 9 +- .../migrations/0019_invoice_pdf_generated.py | 10 +- .../migrations/0020_auto_20160530_1824.py | 15 +- src/shop/migrations/0021_ticket_email.py | 10 +- .../migrations/0022_auto_20160530_2301.py | 35 +- src/shop/migrations/0023_order_cancelled.py | 10 +- .../migrations/0024_auto_20160605_2126.py | 26 +- src/shop/migrations/0025_creditnote.py | 55 +- src/shop/migrations/0026_order_refunded.py | 16 +- .../migrations/0027_auto_20160712_2036.py | 138 ++- .../migrations/0028_auto_20160712_2119.py | 19 +- .../migrations/0029_auto_20160712_2133.py | 12 +- .../migrations/0030_auto_20160827_0752.py | 16 +- .../migrations/0031_auto_20161109_1000.py | 21 +- .../migrations/0032_order_customer_comment.py | 16 +- .../migrations/0033_auto_20161212_1756.py | 14 +- .../migrations/0034_auto_20170131_1849.py | 52 +- .../migrations/0035_auto_20170222_1629.py | 17 +- .../migrations/0036_auto_20170319_2155.py | 10 +- .../migrations/0037_auto_20170319_2204.py | 10 +- .../migrations/0038_auto_20170323_2021.py | 22 +- .../migrations/0039_auto_20170403_1752.py | 14 +- .../migrations/0040_auto_20170408_1055.py | 10 +- .../migrations/0041_auto_20170408_1104.py | 16 +- .../migrations/0042_auto_20170507_1000.py | 16 +- .../migrations/0043_auto_20170507_1309.py | 47 +- .../0044_coinifyapiinvoice_coinify_id.py | 10 +- .../migrations/0045_auto_20170507_1648.py | 10 +- .../0046_coinifyapirequest_method.py | 12 +- .../migrations/0047_auto_20170522_1942.py | 10 +- .../migrations/0048_product_ticket_type.py | 18 +- .../migrations/0049_auto_20170914_2034.py | 20 +- .../migrations/0050_auto_20170916_1336.py | 34 +- .../migrations/0051_creditnote_danish_vat.py | 12 +- .../migrations/0052_auto_20171004_0005.py | 18 +- .../migrations/0053_auto_20180318_0906.py | 75 +- .../migrations/0054_auto_20180415_1159.py | 44 +- .../migrations/0055_order_customer_address.py | 14 +- .../migrations/0056_auto_20180827_1020.py | 18 +- src/shop/migrations/0057_order_notes.py | 16 +- src/shop/urls.py | 81 +- src/sponsors/admin.py | 12 +- src/sponsors/apps.py | 2 +- .../commands/generate_sponsor_tickets.py | 27 +- src/sponsors/migrations/0001_initial.py | 58 +- .../migrations/0002_auto_20170711_2341.py | 46 +- .../migrations/0003_sponsortier_camp.py | 18 +- .../migrations/0004_sponsortier_weight.py | 15 +- src/sponsors/migrations/0005_sponsor_url.py | 14 +- .../migrations/0006_auto_20170715_1110.py | 18 +- .../migrations/0007_auto_20180318_0906.py | 24 +- .../migrations/0008_auto_20180815_1119.py | 18 +- .../migrations/0009_sponsor_logo_filename.py | 14 +- .../migrations/0010_populate_logo_filename.py | 12 +- .../migrations/0011_auto_20181118_1513.py | 15 +- src/sponsors/models.py | 52 +- src/sponsors/views.py | 12 +- src/static_src/img/feed-icon-28x28.png | Bin 0 -> 1737 bytes .../js/bootstrap-datetimepicker.min.js | 2 + src/static_src/js/moment-with-locales.min.js | 10 + src/teams/admin.py | 78 +- src/teams/apps.py | 15 +- src/teams/email.py | 48 +- src/teams/migrations/0001_initial.py | 70 +- .../migrations/0002_auto_20170327_2208.py | 17 +- .../migrations/0003_auto_20170401_2227.py | 10 +- src/teams/migrations/0004_team_sub_team_of.py | 17 +- .../migrations/0005_auto_20170402_1331.py | 90 +- .../migrations/0006_auto_20170402_1331.py | 18 +- .../migrations/0007_teamarea_description.py | 12 +- .../migrations/0008_team_needs_members.py | 10 +- .../migrations/0009_auto_20170402_1607.py | 50 +- .../migrations/0010_remove_team_members.py | 11 +- .../migrations/0011_auto_20170402_1608.py | 10 +- .../migrations/0012_teammember_responsible.py | 10 +- .../migrations/0013_auto_20170523_2046.py | 20 +- .../0014_remove_teammember_deleted.py | 11 +- .../migrations/0015_team_mailing_list.py | 10 +- .../migrations/0016_auto_20170711_2247.py | 16 +- .../migrations/0017_auto_20171122_1928.py | 59 +- .../migrations/0018_auto_20171122_2204.py | 17 +- .../migrations/0019_auto_20180304_1019.py | 14 +- .../migrations/0020_auto_20180304_1233.py | 16 +- .../migrations/0021_auto_20180318_0906.py | 31 +- .../migrations/0022_auto_20180318_1135.py | 41 +- .../migrations/0023_auto_20180318_1256.py | 29 +- .../migrations/0024_populate_shortslugs.py | 13 +- .../migrations/0025_auto_20180318_1318.py | 14 +- src/teams/migrations/0026_team_camp.py | 18 +- src/teams/migrations/0027_fixup_teams.py | 27 +- .../migrations/0028_auto_20180331_1416.py | 18 +- src/teams/migrations/0029_remove_team_area.py | 11 +- .../migrations/0030_auto_20180402_1514.py | 32 +- .../migrations/0031_auto_20180402_2146.py | 21 +- .../migrations/0032_auto_20180402_2148.py | 16 +- .../migrations/0033_auto_20180402_2204.py | 23 +- .../migrations/0034_auto_20180402_2334.py | 9 +- .../migrations/0035_auto_20180402_2344.py | 9 +- .../migrations/0036_auto_20180403_0201.py | 9 +- .../migrations/0037_auto_20180408_1416.py | 51 +- .../migrations/0038_auto_20180412_1844.py | 64 +- src/teams/migrations/0039_fix_irc_channels.py | 24 +- .../migrations/0040_auto_20180412_2109.py | 24 +- .../migrations/0041_auto_20180412_2231.py | 18 +- .../migrations/0042_auto_20180413_1933.py | 31 +- .../migrations/0043_auto_20180702_1338.py | 57 +- .../migrations/0043_auto_20180804_1641.py | 22 +- .../migrations/0044_auto_20180702_1507.py | 12 +- .../migrations/0045_merge_20180805_1131.py | 7 +- .../migrations/0046_auto_20180808_2154.py | 9 +- src/teams/migrations/0047_taskcomment.py | 45 +- .../migrations/0048_auto_20180814_1950.py | 10 +- .../migrations/0049_auto_20180815_1119.py | 9 +- src/teams/migrations/0050_team_guide.py | 17 +- .../migrations/0051_auto_20190312_1129.py | 17 +- src/teams/models.py | 218 ++-- src/teams/signal_handlers.py | 14 +- src/teams/templatetags/teams_tags.py | 5 +- src/teams/urls.py | 307 +++-- src/teams/utils.py | 2 +- src/teams/views/base.py | 116 +- src/teams/views/guide.py | 13 +- src/teams/views/info.py | 84 +- src/teams/views/members.py | 93 +- src/teams/views/mixins.py | 33 +- src/teams/views/shifts.py | 206 ++-- src/teams/views/tasks.py | 51 +- src/tickets/__init__.py | 3 +- src/tickets/admin.py | 64 +- src/tickets/apps.py | 10 +- src/tickets/migrations/0001_initial.py | 182 ++- .../migrations/0002_auto_20170819_2222.py | 36 +- .../migrations/0003_auto_20170819_2309.py | 19 +- .../migrations/0004_auto_20170823_1228.py | 16 +- .../migrations/0005_auto_20180318_0906.py | 62 +- src/tickets/models.py | 76 +- src/tickets/signals.py | 40 +- src/tickets/urls.py | 24 +- src/tickets/views.py | 34 +- src/tokens/admin.py | 14 +- src/tokens/apps.py | 2 +- src/tokens/migrations/0001_initial.py | 43 +- src/tokens/migrations/0002_tokenfind.py | 39 +- src/tokens/migrations/0003_token_category.py | 15 +- .../migrations/0004_auto_20180819_1743.py | 7 +- .../migrations/0005_auto_20190327_2025.py | 9 +- src/tokens/models.py | 35 +- src/tokens/templatetags/token_tags.py | 1 - src/tokens/urls.py | 11 +- src/tokens/views.py | 14 +- src/utils/apps.py | 4 +- src/utils/email.py | 30 +- src/utils/factories.py | 9 +- .../management/commands/bootstrap-devsite.py | 1078 +++++++---------- .../commands/run_managepy_worker.py | 30 +- src/utils/migrations/0001_initial.py | 39 +- .../0002_remove_outgoingemail_recipient.py | 11 +- .../migrations/0003_auto_20170521_1932.py | 37 +- src/utils/mixins.py | 3 +- src/utils/models.py | 49 +- src/utils/outgoingemailworker.py | 15 +- src/utils/pdf.py | 18 +- src/utils/templatetags/bornhack.py | 1 - src/utils/templatetags/dateutils.py | 7 +- src/utils/templatetags/imageutils.py | 11 +- src/utils/templatetags/menubutton.py | 7 +- src/villages/admin.py | 13 +- src/villages/apps.py | 2 +- src/villages/migrations/0001_initial.py | 53 +- .../migrations/0002_auto_20160705_2154.py | 17 +- .../migrations/0003_auto_20160705_2159.py | 14 +- .../migrations/0004_village_deleted.py | 10 +- .../migrations/0005_auto_20160712_2036.py | 14 +- .../migrations/0006_remove_village_camp.py | 11 +- src/villages/migrations/0007_village_camp.py | 14 +- .../migrations/0008_auto_20161228_2209.py | 14 +- .../migrations/0009_auto_20161229_2143.py | 15 +- .../migrations/0010_auto_20170318_1506.py | 9 +- .../migrations/0011_auto_20180318_0906.py | 20 +- src/villages/mixins.py | 2 +- src/villages/models.py | 33 +- src/villages/urls.py | 12 +- src/villages/views.py | 55 +- 441 files changed, 9458 insertions(+), 7456 deletions(-) create mode 100644 src/.coverage create mode 100644 src/.ropeproject/config.py create mode 100644 src/.ropeproject/globalnames create mode 100644 src/.ropeproject/history create mode 100644 src/.ropeproject/objectdb create mode 100755 src/static_src/img/feed-icon-28x28.png create mode 100644 src/static_src/js/bootstrap-datetimepicker.min.js create mode 100644 src/static_src/js/moment-with-locales.min.js diff --git a/src/.coverage b/src/.coverage new file mode 100644 index 00000000..5a690a30 --- /dev/null +++ b/src/.coverage @@ -0,0 +1 @@ +!coverage.py: This is a private format, don't read it directly!{"lines":{"/home/valberg/code/bornhack/bornhack-website/src/manage.py":[2,3,5,7,8,9,10,13,15],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/__init__.py":[1,3,5,8,14,15,16,17,19,20,21,22,24],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/utils/__init__.py":[1],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/utils/version.py":[1,2,3,4,5,6,12,13,14,15,18,42,49,63,71,93,20,54,57,58,60,27,44,45,46,29,30,35,39,98,99,100,101,103,104,55],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/distutils/__init__.py":[1,2,3,4,5,9,11,12,16,17,19,20,21,22,23,25,27,28,29,30,35,52,53,70,74,75,79,80,82,83,87,88,90,91,100,101],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/core/__init__.py":[1],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/core/management/__init__.py":[1,2,3,4,5,6,7,9,10,11,12,13,16,17,20,30,40,75,151,154,155,162,195,227,301,378,380,156,157,158,160,381,306,307,314,315,316,317,318,319,320,324,325,331,335,357,359,249,250,361,370,372,375,202,63,25,26,27,65,68,69,70,72,203,204,220,224,36,37,225,95,101,102,106,110,113,115,117,119,120,123,124,125,127,128,130,131,132,133,134,144,145,146,148],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/apps/__init__.py":[1,2,4],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/apps/config.py":[1,2,4,5,7,10,11,13,51,54,81,154,170,191,200,86,90,105,107,112,116,117,118,129,135,136,142,143,152,15,19,23,30,31,34,39,40,60,61,69,74,79,45,49,108,110,35,194,196,197,198,160,163,164,165,161,183,184,185,187,189,186,166,167,168],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/core/exceptions.py":[3,6,7,8,11,12,13,16,17,18,21,22,23,26,27,30,31,32,35,36,37,40,41,42,45,46,47,50,54,55,58,62,63,66,67,68,71,72,73,76,77,78,81,82,83,86,87,88,91,94,95,96,139,147,153,161,172,177,181,182,183],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/utils/module_loading.py":[1,2,3,4,7,27,63,83,12,13,17,19,20,65,66,67,72,73,74,37,39,40,41,43,44,45,47,48,53,54,59],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/apps/registry.py":[1,2,3,4,5,6,8,10,13,18,20,59,124,134,139,144,162,163,182,209,231,240,259,273,295,322,327,352,358,374,413,423,24,34,37,41,44,47,48,53,56,67,72,73,78,82,85,86,89,90,95,96,99,100,102,103,108,111,112,249,126,250,251,252,253,254,255,256,257,213,214,215,227,228,418,419,229,366,367,384,392,397,400,406,407,267,268,269,270,408,409,420,398,399,271,411,385,141,142,114,116,119,120,150,151,152,194,197,199,200,202,204,207,122,195,136,57,370,285,175,177,178,179,180,286,288,291,293,87,292,371,372,237,238],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/conf/__init__.py":[7,9,10,11,12,13,15,16,17,18,20,23,28,29,46,54,62,73,78,91,97,98,143,146,153,154,157,159,167,172,178,183,189,195,201,67,68,71,94,56,57,35,36,44,100,101,102,105,107,112,114,115,116,117,119,122,123,120,125,128,144,131,134,135,136,140,141,58,59,60,70],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/conf/global_settings.py":[4,9,17,22,26,31,35,41,44,48,52,10,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,144,148,149,152,153,154,155,160,164,169,170,173,176,179,182,188,191,194,197,200,201,202,203,204,205,206,209,211,214,218,222,225,228,231,243,245,257,262,265,269,273,277,281,285,286,291,295,299,304,308,313,319,323,327,331,336,341,345,350,357,358,359,360,361,369,370,371,380,381,382,383,384,385,386,387,388,389,390,391,396,399,402,406,409,412,413,416,418,419,426,435,444,451,453,455,457,459,461,463,466,468,470,472,475,477,485,486,489,490,491,497,499,501,503,505,508,514,515,516,517,520,526,534,537,538,539,540,541,542,543,544,545,546,553,563,566,570,577,581,588,595,598,603,604,613,623,628,629,630,631,632,633,634,635],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/utils/deprecation.py":[1,2,5,6,9,10,13,14,20,30,40,42,44,73,74,82,83,87,84,85],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/utils/functional.py":[1,2,3,4,10,16,23,24,29,41,45,46,49,167,171,178,200,207,210,218,225,228,230,235,211,215,237,246,253,273,278,287,296,297,298,301,305,306,307,308,311,312,313,314,315,316,319,327,333,334,346,351,358,367,377,233,238,240,25,26,27,57,58,63,64,66,73,79,82,102,112,115,118,121,129,134,139,144,147,152,159,164,204,185,188,197,189,191,196,162,67,68,69,70,84,85,86,89,90,91,105,110,92,93,94,95,97,98,71,343,344,99,35,37,38,148,149,113,212,213,214,242,244,193,194,385,386,387,388,195,108,109,347],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/core/management/base.py":[4,5,6,7,8,10,11,12,13,14,17,28,29,32,35,36,39,44,45,50,57,64,76,91,95,97,98,101,107,110,114,117,118,122,129,134,137,140,148,215,217,220,221,222,223,226,228,230,239,247,285,291,299,335,365,368,369,435,462,470,477,478,480,483,496,506,517,518,519,521,524,532,46,47,48,70,72,231,130,131,124,127,132,232,233,236,237,138,125,307,308,252,253,254,255,256,257,259,245,260,261,262,263,265,266,268,273,274,275,277,278,279,280,282,283,310,52,55,311,313,314,315,316,341,344,346,349,351,353,78,88,79,80,81,82,83,85,86,87,354,363,135,376,377,378,379,366,382,383,385,410,413,414,416,417,420,423,427,429,430,433,141,142,143,144,120,145,328,329],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/core/checks/__init__.py":[1,5,8,9,10,11,12,13,14,15,19,20,21,22],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/core/checks/messages.py":[2,3,4,5,6,9,11,19,26,41,45,48,53,54,58,59,63,64,68,69,73,74,70,12,13,14,15,16,17,65],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/core/checks/registry.py":[1,3,6,9,10,11,12,13,14,15,16,17,18,21,23,27,56,78,81,86,93,24,25,94,95,96,43,49,52,53,54,44,45,46,47,50,60,61,87,88,90,63,68,70,71,72,75,76],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/utils/itercompat.py":[1,3,4,8,5,6],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/core/checks/caches.py":[1,2,4,6,7,8,12,14,16],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/core/cache/__init__.py":[14,15,17,18,19,22,25,26,29,32,57,62,63,66,83,87,64,90,96,97,100,103,106,109,113,116,124,67,68,69,70,74,79,33,35,36,47,48,49,50,54,80,81],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/core/signals.py":[1,3,4,5,6],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/dispatch/__init__.py":[7,9],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/dispatch/dispatcher.py":[1,2,4,7,13,8,10,16,19,27,28,49,113,149,152,178,214,223,262,272,35,36,38,39,40,46,47,37,82,85,92,95,97,98,99,101,104,105,107,108,216,109,110,111,285,292,286,290,86,89,291,9,102,103,170,171,93,174,175,230,231,237,238,239,240,241,242,243,245,251,252,260,244,253,255,256,257,232,235,246,247,269,217,219,220,250],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/utils/inspect.py":[1,4,12,36,43,53,61,37,38,39,5,7,8,62],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/core/cache/backends/__init__.py":[1],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/core/cache/backends/base.py":[1,2,3,5,6,9,10,13,14,19,22,25,36,50,51,77,89,103,113,120,127,134,140,155,176,182,194,201,210,226,235,239,258,274,281,52,53,54,55,58,60,61,62,63,67,68,69,73,74,75,42,47],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/core/checks/database.py":[1,3,6],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/db/__init__.py":[1,2,10,11,12,13,16,18,26,31,32,35,38,41,45,49,54,59,64,65,33],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/db/utils.py":[1,2,3,4,6,7,8,9,11,12,15,16,19,20,23,24,27,28,31,32,35,36,39,40,43,44,47,48,51,55,57,65,68,91,100,131,132,135,136,144,161,182,195,207,210,213,216,219,228,229,235,248,267,249,265,268,270,283,297,305,141,142,233,196,199,166,167,146,147,148,154,157,159,171,172,173,174,176,177,178,179,180,200,186,187,191,192,193,201,202,106,107,109,110,203,204,205,197,214,63,66,69,70,94,97,95,96,298,299,300,301,302,284,237,238,239,240,246,295,307,308,250,251,261,262,263,271,281,217,264,220,221,222,225],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/core/checks/model_checks.py":[1,2,3,5,6,9,10,31,152,153,42,45,46,154,11,12,13,16,17,27,28],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/core/checks/security/__init__.py":[1],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/core/checks/security/base.py":[1,3,5,6,8,9,14,17,18,24,27,28,33,36,37,42,45,46,51,54,55,60,63,64,69,72,73,77,78,80,83,84,85,88,89,95,98,99,100,103,104,106,110,114,118,124,130,136,146,156,165,174,183,193,199,208],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/core/checks/security/csrf.py":[1,3,5,6,11,14,15,19,23,27,33],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/core/checks/security/sessions.py":[1,3,6,13,14,15,7,8,18,21,22,23,27,30,31,32,36,43,44,45,37,38,48,51,52,53,57,60,61,62,66,79,92,96],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/core/checks/templates.py":[1,3,5,7,8,10,12,13,14,18,26,20,21,22,23,28,29,30,31,35],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/core/checks/urls.py":[1,3,5,8,17,30,53,71,96,106,98,99,100,101,103,35,38,39,40,57,59,60,62,63,64,65,67,68,66,41,42,43,44,50,10,11,12,13,21,22,23],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/core/management/color.py":[3,5,6,7,9,12,25,26,29,59,67,71,17,18,21,22,73,36,38,43,44,45,46,50,54,56],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/utils/termcolors.py":[3,5,6,7,9,10,13,58,71,72,73,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,134,137,168,169,68],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/utils/autoreload.py":[31,32,33,34,35,36,38,40,41,42,46,47,51,52,56,57,59,65,66,68,70,71,73,74,76,77,78,79,82,129,143,152,201,221,245,251,267,282,298,316],"/home/valberg/code/bornhack/bornhack-website/src/bornhack/__init__.py":[1],"/home/valberg/code/bornhack/bornhack-website/src/bornhack/settings.py":[1,2,3,5,8,18,25,27,28,29,31,33,36,40,41,42,43,44,45,46,48,49,50,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,73,74,75,76,77,78,79,80,81,82,86,87,9,10,11,88,89,92,93,94,95,96,100,101,102,104,105,106,107,108,109,110,111,119,122,123,124,125,126,127,128,130,133,134,137,138,139,140,141,142,143,144,145,148,149,151,152,153,154,156,157,159,160,161,162,163,164,165,166,167,168,169,170,177,178,181,184,185,189,190,191,192,198,199,200,201,207],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/wrapt/__init__.py":[1,2,4,10,13,16],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/wrapt/wrappers.py":[1,2,3,4,5,6,8,9,11,12,16,20,31,35,39,43,50,59,63,64,74,18,70,72,76,78,90,94,98,102,106,110,114,117,120,121,124,130,133,134,137,140,143,146,149,152,155,158,161,164,189,198,215,218,221,224,227,230,233,236,239,242,245,248,251,254,257,260,263,266,269,272,275,278,281,284,287,290,293,296,299,303,307,311,315,319,323,327,331,335,339,343,347,351,354,357,360,363,366,369,372,375,378,381,384,387,390,393,396,399,402,405,408,411,414,417,420,423,427,431,433,436,438,452,460,463,466,476,532,566,568,624,626,628,719,720,721,729,769,772,784,786,792,796,799,802,814,826,829,834,865,878,880,882,927,830,832,831,773,730,734,736,737,739,740,767,774,775,770,776],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/wrapt/decorators.py":[4,6,8,9,11,12,14,15,16,33,34,35,36,38,39,43,52,54,58,62,66,70,74,78,80,84,89,93,97,109,113,115,120,123,125,127,134,138,142,146,150,154,155,158,159,162,165,174,418,511,425,432,434,196,200,225,398,201,215,216,442,444,448,451,246,282,288,289,297,298,338,392],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/wrapt/importer.py":[4,6,7,9,10,12,13,14,18,26,27,28,37,48,103,112,127,143,145,151,153,156,162,164,167,168,226],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/views/__init__.py":[1,3],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/views/generic/__init__.py":[1,2,6,7,10,13,14,15,16,20,21,22],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/views/generic/base.py":[1,2,4,5,9,10,11,13,16,20,21,23,30,34,36,38,48,80,90,97,104,108,109,110,111,112,113,115,131,144,147,148,153,154,155,156,157,158,160,178,192,195,198,201,204,207,51,61,69,70,73,77,78,52,56],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/http/__init__.py":[1,2,5,14,15,16,17,18,19,20],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/http/cookie.py":[1,4,7,10],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/http/request.py":[1,2,3,4,5,6,8,9,10,13,14,15,16,17,18,19,21,22,25,26,29,34,35,38,39,42,43,45,64,69,88,108,116,119,122,131,154,165,198,202,209,222,225,228,232,245,249,256,262,271,289,294,326,339,346,353,360,367,371,384,388,389,391,411,412,424,430,434,438,444,448,454,461,467,471,477,481,485,489,495,499,532,546,568],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/core/signing.py":[34,36,37,38,39,40,41,43,44,45,46,47,49,52,53,54,57,58,59,62,66,71,75,81,85,86,89,93,126,145,147,158,161,164,173,175,178,182],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/utils/baseconv.py":[38,40,41,42,43,44,45,48,49,51,57,60,66,72,96,52,53,54,97,98,99,100,101],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/utils/crypto.py":[3,4,5,6,7,9,10,13,14,15,23,49,72,77],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/utils/encoding.py":[1,2,3,4,5,7,8,11,12,16,21,24,38,42,51,73,85,108,109,115,119,122,156,157,159,160,161,165,166,168,172,208,225,240,255,269,261,262,263,266,93,98,100,102,105,59,61,63,64,67,70,48],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/utils/six.py":[1,23,24,25,26,27,29,30,34,35,36,38,39,40,41,42,43,45,73,78,84,86,89,101,103,112,115,122,124,128,134,137,139,157,162,169,171,175,179,182,187,193,207,216,222,224,172,173,227,229,230,234,140,87,141,142,144,145,146,149,150,235,236,237,238,147,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,104,105,106,107,108,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,301,306,307,308,309,176,177,310,312,314,125,126,315,318,320,324,325,326,327,328,329,330,331,332,333,334,335,336,337,338,339,340,341,342,343,344,345,346,348,349,350,352,354,355,358,360,364,365,366,368,369,370,372,374,375,378,380,384,385,386,387,388,389,390,391,392,393,394,395,396,397,398,399,400,401,402,403,404,405,406,407,408,409,410,411,412,413,414,415,416,418,419,420,422,424,425,428,430,434,435,436,437,439,440,441,443,445,446,449,451,455,457,458,459,461,463,464,467,469,470,471,180,472,473,474,475,477,480,481,484,489,500,501,502,504,505,506,507,518,519,523,526,527,533,534,537,539,542,559,560,75,563,564,565,566,567,568,571,572,575,578,581,584,586,588,608,609,610,611,612,613,616,617,620,622,623,624,625,626,627,628,629,630,631,632,633,637,638,660,661,664,668,672,676,677,90,113,80,81,91,92,95,98,679,704,710,711,713,719,720,774,784,786,795,798,810,826,847,848,849,850,854,855,860,864,866,871,872,873,183,185,834,841,184,214,188,189,194,196,197,198,199,200,203,204,205,158,159],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/core/files/__init__.py":[1,3],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/core/files/base.py":[1,2,4,5,8,9,11,19,22,25,28,31,48,65,75,102,105,108,117,121,124,125,130,133,136,140,143,148,153,158],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/core/files/utils.py":[1,9,11,12,13,14,15,16,17,18,19,20,21,22,23,24,26,30,37,44,51],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/core/files/uploadhandler.py":[3,5,7,8,11,14,15,16,20,23,24,27,30,31,39,46,49,50,53,57,58,61,64,65,67,75,93,107,114,123,131,134,135,142,145,151,154,156,165,171,178,195],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/core/files/uploadedfile.py":[3,5,6,8,9,10,13,16,23,25,32,35,38,52,55,58,59,64,68,78,81,82,86,90,94,99,102,103,107],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/core/files/temp.py":[17,19,20,22,24,27,72,74],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/http/multipartparser.py":[6,7,8,9,10,12,13,16,19,20,21,23,26,27,30,33,34,37,38,39,42,48,49,100,285,296,300,309,316,317,332,335,362,378,387,390,403,425,429,430,434,444,448,451,452,456,459,466,476,478,493,496,537,562,573,632,633,637,644,676],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/utils/datastructures.py":[1,2,5,9,11,14,17,20,26,29,32,35,39,40,43,64,65,68,71,85,88,94,102,105,111,124,142,149,152,159,168,172,180,184,189,193,211,216,227,229,234,241,242,243,244,245,246,247,248,249,250,251,252,253,256,264,265,270,230,231,232,12,15,27,36,266,267,268,276,277,279,280,282,33],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/utils/text.py":[1,2,3,4,5,7,10,11,14,21,22,23,24,25,28,59,62,63,66,81,105,125,137,149,222,236,237,260,266,280,287,288,291,294,301,304,309,324,332,335,354,373,376,381,402,403,418,425,433,422,17,409,410,413,414,415],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/utils/safestring.py":[6,8,11,12,21,28,29,42,46,47,57,61,64,71,80,82,83,58],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/utils/translation/__init__.py":[3,4,5,7,10,11,12,13,14,15,16,17,18,19,20,23,26,27,38,49,51,61,64,67,71,74,79,82,87,90,94,98,99,102,139,143,148,151,155,159,163,164,168,175,184,188,192,196,205,221,225,229,233,238,242,264,267,144,103,107,109,110,113,134,135,136,75,52,53,54,57,58,198,199,202,207,208,209,210,217,218,160,185,239,165,166,169,170,173,176,177,156,178,181],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/utils/http.py":[1,2,3,4,5,6,7,8,9,15,16,17,18,19,22,29,31,32,33,34,35,36,37,38,39,40,42,43,45,48,49,57,58,66,75,84,113,132,146,182,194,207,221,229,241,255,266,285,308,327,356,386,438],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/http/response.py":[1,2,3,4,5,6,7,8,9,10,12,13,14,15,16,17,18,19,21,24,25,28,34,36,38,64,72,76,87,91,102,104,108,135,140,143,146,150,152,155,159,204,209,213,224,245,254,257,260,266,269,272,275,279,284,286,288,293,300,304,306,310,325,328,331,334,337,340,345,352,354,356,362,369,373,377,383,386,390,393,394,396,401,413,451,452,454,461,463,472,473,476,477,480,481,483,487,494,495,498,499,502,503,506,507,509,513,522,523,526,527,530,531,534,546,548,549],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/core/serializers/__init__.py":[17,19,21,22,23,27,28,29,30,33,36,43,44,46,49,53,85,94,102,108,114,122,132,143,159,127,95,96,150,151,152,66,69,70,79,82,71,72,47,74,75,76,153,156,97,99,128,167,168,169,170,171,173,174,176,181,185,186,187,188,189,193,198,177,178,179,194,195,196,197,200,209,210,211,212,213,214,219,223,220,221,224,232,234,129],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/core/serializers/base.py":[3,4,6,9,10,11,14,15,16,19,20,22,31,32,33,38,39,41,46,61,64,68,69,70,72,73,118,124,130,136,142,148,154,160,169,172,174,184,187,192,202,204,208,215,229,247,268,77,79,80,81,82,83,42,43,44,85,86,87,88,91,95,99,100,101,102,103,104,108,112,113,47,48,114,106,107,115,116,165,166],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/db/models/__init__.py":[1,2,3,4,5,8,12,13,14,15,16,17,18,19,20,23,26,27,33,34,35,36,37,38,39,40,41,42,43,44,45],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/db/models/signals.py":[1,3,4,6,9,13,14,25,31,37,38,40,41,42,44,45,47,48,49,52,53,26,27,28,15,18,19,23,20,21],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/db/models/utils.py":[1,7,8,10,14,15,16,11,12],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/db/models/aggregates.py":[3,4,5,6,9,13,14,15,16,17,19,23,27,33,37,52,59,62,78,85,86,87,89,95,101,111,112,113,114,115,117,127,130,134,135,136,139,140,141,144,145,146,148,152,156,157,158,160,166,176,177,178,180,184,20,21,54,28,29,31,55,56,39,40,41,50,63,76,25],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/db/models/expressions.py":[1,2,3,5,6,7,8,9,10,13,17,18,28,32,35,36,37,38,39,42,47,48,49,50,52,68,71,74,77,80,83,86,89,94,97,100,103,108,111,114,117,120,123,126,129,134,140,142,145,146,148,150,152,156,161,168,171,174,181,209,213,217,221,245,249,253,262,274,294,298,315,318,321,329,332,340,344,347,350,353,363,377,387,388,389,392,394,400,403,406,409,412,442,450,451,463,479,480,482,485,492,493,494,496,498,505,508,511,514,517,520,524,530,531,537,540,544,545,550,554,555,556,557,558,559,561,575,583,587,590,593,600,621,628,629,630,642,645,663,668,672,673,680,681,687,690,693,696,700,701,704,708,709,711,714,718,720,722,728,732,736,739,742,749,753,754,758,761,764,767,772,775,778,782,787,788,790,795,799,803,805,809,812,815,818,822,823,825,836,839,842,845,848,852,860,873,881,892,893,894,896,904,907,910,913,917,925,930,958,962,963,965,970,975,980,1013,1021,1030,1039,1051,1052,1053,1055,1059,1062,1068,1074,1083,1084,1086,1096,1100,1103,1106,1123,1131,1139,1145,1152,1155,1159,1160,1164,1165,1166,1168,1195,1198,1201,1204,1236,1244,1247,1251,1258,1259,1261,1265,1268,1271,1280,1283,1286,1306,1310,1311,1313,1317,1318,1320,639,153,640,723,724,725,154,726,733,734,743,744,316,211,169,236,330,157,158,159,237,238,239,241,172,243,1087,1089,1090,1091,1092,1094,1104,1101,1107,1108,1110,1112,1113,1115,1116,1117,1119,1120,1121,745,746,682,683,684,685,691,562,571,572,176,178,503,573,588,594,622,623,624,625,595,596,597,509,598,601,602,603,604,605,606,607,608,612,615,616,617,618,619,256,288,268,269,289,290,292,257,260,164,305,306,307,309,310,165,166,737],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/db/models/fields/__init__.py":[1,2,3,4,5,6,7,8,9,11,12,13,14,18,19,20,21,22,23,24,27,28,29,30,31,32,33,36,37,38,39,40,41,42,43,47,48,51,52,57,60,79,85,89,90,91,95,96,101,102,103,105,106,107,108,112,115,116,119,121,122,123,124,125,128,132,134,135,136,137,138,139,140,181,192,200,211,243,293,305,323,330,349,377,386,391,399,488,496,502,508,511,522,530,550,561,569,577,593,624,635,638,650,676,684,691,704,707,712,716,720,727,750,757,760,765,768,772,778,788,792,796,800,811,835,842,851,853,856,892,897,898,900,902,905,909,915,927,933,936,948,951,954,960,967,972,976,977,979,982,986,987,989,990,992,994,997,1014,1020,1033,1034,1036,1040,1046,1067,1072,1075,1080,1084,1096,1097,1098,1101,1105,1108,1112,1114,1121,1140,1144,1145,1147,1149,1152,1155,1162,1202,1213,1216,1246,1254,1266,1270,1276,1280,1287,1288,1290,1292,1294,1298,1302,1345,1348,1396,1407,1426,1432,1436,1443,1444,1446,1448,1451,1455,1468,1492,1516,1527,1533,1537,1545,1548,1562,1565,1569,1578,1584,1585,1587,1590,1592,1595,1614,1621,1627,1631,1638,1639,1640,1642,1647,1653,1662,1663,1666,1672,1678,1689,1705,1711,1722,1726,1727,1729,1731,1733,1739,1742,1754,1761,1762,1764,1766,1768,1774,1786,1803,1809,1812,1824,1831,1832,1833,1834,1836,1839,1847,1848,1849,1852,1855,1856,1859,1863,1868,1874,1878,1879,1880,1881,1884,1893,1899,1911,1921,1924,1934,1939,1950,1958,1960,1961,1963,1965,1970,1976,1980,1982,1997,1998,2000,2003,2010,2011,2013,2016,2023,2024,2025,2027,2033,2045,2048,2056,2057,2059,2063,2064,2066,2069,2074,2078,2089,2090,2092,2094,2097,2100,2107,2150,2161,2164,2192,2200,2204,2210,2214,2221,2222,2223,2225,2229,2235,2244,2245,2246,2248,2254,2262,2265,2268,2276,2282,2286,2293,2295,2297,2298,2300,2304,2309,2312,2322,2334,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,157,158,159,160,161,162,165,169,170,172,174,175,176,177,178,179,1156,1157,1160,2101,2102,2105,1037,1038,575,734,721,722,761,758,762,763,723,724,725,735,736,739,740,744,745,746,504,505,906,907,166,167,968,969,970,1255,1256,1257,1258,1259,1261,1262,1263,747,748,718,1644,1645,514,525,526,527,528,515,519,520,498,499,516,517,518,2301,2302,1158,1159,2226,2227,2028,2029,2031,1966,1967,1968,1452,1453,1088,1090,1092,1093,858,859,860,861,794,867,887,888,890,973,889,1437,1438,1439,1281,1282,1283,1021,1025,1029,1030,862,866,798,802,803,805,1656,1657,1658,863,864,378,379,380,384,388,389,397,708,710,493,432,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,450,451,452,453,456,457,458,459,460,462,463,464,466,469,473,474,467,470,476,477,479,481,483,484,486,494,2034,2035,2036,2037,2040,2041,2043,1538,1539,1540,1541,1542,1543,1203,1204,1206,1208,1211,480,1207,1209,1210,1205,478,928,929,930,931,471,1648,1651,2305,2306,2307,2230,2231,2233,2232,1971,1972,1973,1974,697,670,636,671,672,2310,698,644,645,646,647,648,700,701,705,1346,714,1073,2046,2067,682,766,1214,790,1272,1273,1267,774,776,1268,1217,1218,1274,807,808,86,804,557,558,770,784,785,1081,1082,1076,1077,786,1397,1402,1247,1252,1428,1429,1408,1349,1351,1352,1409,1410,1424,1430,961,962,963,965,381,382,949,1810,955,958,956,957,894,840,2082,2083,2084,2085,1825,1826,1827,1570,1571,1572,1573,1574,809,911,202,216,224,232,241,203,244,245,204,294,303,205,306,321,206,324,325,326,327,207,331,332,347,208,350,363,375,912,916,925,1116,1117,1125,1126,1127,1138,1118,1307,1310,1311,1312,1313,1314,1320,1329,1042,333,1043,1047,1055,1056,1065,1770,247,250,248,260,261,262,266,267,268,269,272,274,275,279,282,1790,1791,2014,1792,1793,1794,1795,1796,1797,1798,1799,1800,1801,1771,1775,1784,1308,2001,1456,1529,1530,1459,1469,1470,1471,1490,1460,1493,1494,1495,1514,1462,1463,1517,1525,1466,1167,1168,1837,2060,630,2323,2332,631,598,600,632,578,581,582,590,633,602,618,621,583,584,998,1000,1003,2313,2315,2318,2319,1398,1399,1400,1015,1016,1018,1813,1815,1816,2070,2071,1804,1805,1807,2075,2076,995,1806,1350,937,939,940,934,1977,952],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/forms/__init__.py":[3,5,6,7,8,9,10,11],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/forms/boundfield.py":[1,3,4,5,6,7,8,10,13,15,16,29,35,52,56,59,62,69,76,96,102,106,112,119,129,166,179,184,197,208,218,228,241,242,247,250,254,260,264],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/forms/utils.py":[1,2,4,5,6,7,8,11,18,44,45,50,51,54,57,60,68,75,79,80,83,84,92,95,105,108,118,121,124,127,130,133,139,151,171],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/utils/timezone.py":[3,5,6,7,8,10,12,15,16,17,18,19,20,26,29,36,38,44,47,50,55,58,70,81,86,89,94,99,109,124,134,145,146,149,156,165,185,205,218,232,245,258,274,222,224,255,276,279,281],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/pytz/__init__.py":[9,11,12,13,15,16,17,18,19,20,21,25,26,27,29,32,33,34,35,36,37,41,45,47,78,111,120,123,183,188,189,192,197,198,200,201,202,204,209,212,215,218,221,227,235,238,242,245,275,278,285,288,319,320,324,343,346,351,352,366,371,373,375,381,384,387,390,393,396,402,411,477,480,486,489,490,491,492,493,494,495,496,497,498,499,500,501,502,503,504,505,506,507,508,509,510,511,512,513,514,515,516,517,518,519,520,521,522,523,524,525,526,527,528,529,530,531,532,533,534,535,536,537,538,539,540,541,542,543,544,545,546,547,548,549,550,551,552,553,554,555,556,557,558,559,560,561,562,563,564,565,566,567,568,569,570,571,572,573,574,575,576,577,578,579,580,581,582,583,584,585,586,587,588,589,590,591,592,593,594,595,596,597,598,599,600,601,602,603,604,605,606,607,608,609,610,611,612,613,614,615,616,617,618,619,620,621,622,623,624,625,626,627,628,629,630,631,632,633,634,635,636,637,638,639,640,641,642,643,644,645,646,647,648,649,650,651,652,653,654,655,656,657,658,659,660,661,662,663,664,665,666,667,668,669,670,671,672,673,674,675,676,677,678,679,680,681,682,683,684,685,686,687,688,689,690,691,692,693,694,695,696,697,698,699,700,701,702,703,704,705,706,707,708,709,710,711,712,713,714,715,716,717,718,719,720,721,722,723,724,725,726,727,728,729,730,731,732,733,734,735,736,737,738,739,740,741,742,743,744,745,746,747,748,749,750,751,752,753,754,755,756,757,758,759,760,761,762,763,764,765,766,767,768,769,770,771,772,773,774,775,776,777,778,779,780,781,782,783,784,785,786,787,788,789,790,791,792,793,794,795,796,797,798,799,800,801,802,803,804,805,806,807,808,809,810,811,812,813,814,815,816,817,818,819,820,821,822,823,824,825,826,827,828,829,830,831,832,833,834,835,836,837,838,839,840,841,842,843,844,845,846,847,848,849,850,851,852,853,854,855,856,857,858,859,860,861,862,863,864,865,866,867,868,869,870,871,872,873,874,875,876,877,878,879,880,881,882,883,884,885,886,887,888,889,890,891,892,893,894,895,896,897,898,899,900,901,902,903,904,905,906,907,908,909,910,911,912,913,914,915,916,917,918,919,920,921,922,923,924,925,926,927,928,929,930,931,932,933,934,935,936,937,938,939,940,941,942,943,944,945,946,947,948,949,950,951,952,953,954,955,956,957,958,959,960,961,962,963,964,965,966,967,968,969,970,971,972,973,974,975,976,977,978,979,980,981,982,983,984,985,986,987,988,989,990,991,992,993,994,995,996,997,998,999,1000,1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1011,1012,1013,1014,1015,1016,1017,1018,1019,1020,1021,1022,1023,1024,1025,1026,1027,1028,1029,1030,1031,1032,1033,1034,1035,1036,1037,1038,1039,1040,1041,1042,1043,1044,1045,1046,1047,1048,1049,1050,1051,1052,1053,1054,1055,1056,1057,1058,1059,1060,1061,1062,1063,1064,1065,1066,1067,1068,1069,1070,1071,1072,1073,1074,1075,1076,1077,1078,1079,1080,1081,1082,1084,1086,1087,1088,1089,1090,1091,1092,1093,1094,1095,1096,1097,1098,1099,1100,1101,1102,1103,1104,1105,1106,1107,1108,1109,1110,1111,1112,1113,1114,1115,1116,1117,1118,1119,1120,1121,1122,1123,1124,1125,1126,1127,1128,1129,1130,1131,1132,1133,1134,1135,1136,1137,1138,1139,1140,1141,1142,1143,1144,1145,1146,1147,1148,1149,1150,1151,1152,1153,1154,1155,1156,1157,1158,1159,1160,1161,1162,1163,1164,1165,1166,1167,1168,1169,1170,1171,1172,1173,1174,1175,1176,1177,1178,1179,1180,1181,1182,1183,1184,1185,1186,1187,1188,1189,1190,1191,1192,1193,1194,1195,1196,1197,1198,1199,1200,1201,1202,1203,1204,1205,1206,1207,1208,1209,1210,1211,1212,1213,1214,1215,1216,1217,1218,1219,1220,1221,1222,1223,1224,1225,1226,1227,1228,1229,1230,1231,1232,1233,1234,1235,1236,1237,1238,1239,1240,1241,1242,1243,1244,1245,1246,1247,1248,1249,1250,1251,1252,1253,1254,1255,1256,1257,1258,1259,1260,1261,1262,1263,1264,1265,1266,1267,1268,1269,1270,1271,1272,1273,1274,1275,1276,1277,1278,1279,1280,1281,1282,1283,1284,1285,1286,1287,1288,1289,1290,1291,1292,1293,1294,1295,1296,1297,1298,1299,1300,1301,1302,1303,1304,1305,1306,1307,1308,1309,1310,1311,1312,1313,1314,1315,1316,1317,1318,1319,1320,1321,1322,1323,1324,1325,1326,1327,1328,1329,1330,1331,1332,1333,1334,1335,1336,1337,1338,1339,1340,1341,1342,1343,1344,1345,1346,1347,1348,1349,1350,1351,1352,1353,1354,1355,1356,1357,1358,1359,1360,1361,1362,1363,1364,1365,1366,1367,1368,1369,1370,1371,1372,1373,1374,1375,1376,1377,1378,1379,1380,1381,1382,1383,1384,1385,1386,1387,1388,1389,1390,1391,1392,1393,1394,1395,1396,1397,1398,1399,1400,1401,1402,1403,1404,1405,1406,1407,1408,1409,1410,1411,1412,1413,1414,1415,1416,1417,1418,1419,1420,1421,1422,1423,1424,1425,1426,1427,1428,1429,1430,1431,1432,1433,1434,1435,1436,1437,1438,1439,1440,1441,1442,1443,1444,1445,1446,1447,1448,1449,1450,1451,1452,1453,1454,1455,1456,1457,1458,1459,1460,1461,1462,1463,1464,1465,1466,1467,1468,1469,1470,1471,1472,1473,1474,1475,1476,1477,1478,1479,1480,1481,1482,1483,1484,1485,1486,1487,1488,1489,1490,1491,1492,1493,1494,1495,1496,1497,1498,1499,1500,1501,1502,1503,1504,1505,1506,1507,1508,1509,1510,1511,1512,1513,1514,1515,1516,1517,1518,1519,1520,1521,1522,1523,1524,1525,1526,1527,1529,210],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/pytz/exceptions.py":[3,6,7,11,23,24,27,28,31,39,42,48],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/pytz/lazy.py":[1,2,3,13,16,17,18,20,30,40,50,60,71,72,75,76,77,78,79,80,81,82,84,118,121,122,137,139,172,86,91,92,94,96,109,110,97,107,112,113,141,144,145,147,149,163,164,150,161,166,167],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/pytz/tzinfo.py":[1,3,4,5,6,10,11,13,15,18,27,28,31,42,45,58,20,21,22,23,24,25,61,66,68,69,70,72,76,81,82,88,96,104,112,118,147,150,156,162,166,170,172,176,177,179,193,203,258,396,427,466,504,518,529],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/pytz/tzfile.py":[4,6,7,9,10,13,17,15,20,25,126],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/utils/html.py":[1,3,4,5,6,10,11,12,13,16,17,20,22,23,24,25,28,29,30,31,32,36,50,51,52,53,54,55,56,57,58,59,60,61,65,68,75,76,77,81,95,110,121,140,141,152,153,158,161,164,167,171,181,196,202,237,238,373,381,386,391,396,397,398,399],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/forms/widgets.py":[3,5,6,7,8,9,11,12,13,14,15,16,17,18,19,21,30,33,36,37,40,42,54,57,60,63,71,82,92,98,133,143,169,172,173,182,183,184,185,186,188,191,197,201,205,215,227,232,237,241,248,251,263,174,176,177,144,166,179,267,270,271,272,274,280,286,287,288,291,292,293,296,297,298,301,302,303,306,307,308,310,314,320,321,322,325,329,330,332,351,358,362,363,364,365,367,371,375,379,382,383,384,385,386,388,395,401,407,414,428,442,445,452,453,455,463,464,465,467,471,475,476,477,480,481,482,485,486,487,491,495,496,497,499,505,511,518,530,536,537,538,539,540,541,542,543,545,552,559,567,572,606,627,632,641,650,659,660,661,662,663,664,665,667,673,679,693,696,697,705,711,723,724,726,733,739,740,741,742,745,746,747,748,749,751,756,761,771,780,781,783,787,791,822,827,830,836,844,853,855,860,865,868,869,870,872,885,892,895,896,898,904,910,911,912,913,914,915,916,917,918,920,952,988,1013,1029,1034,1055,546,189,550,275,276,277,278,192,193,194,195,500,503,311,312,199,468,469,457,458,460,784,785,856,857,858,459],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/templatetags/__init__.py":[1],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/templatetags/static.py":[1,3,4,5,6,8,11,13,16,23,39,49,57,75,93,94,101,105,114,122,143,162],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/template/__init__.py":[40,44,45,47,49,55,56,57,60,65,68],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/template/engine.py":[1,3,4,5,7,8,9,10,13,15,16,17,22,55,56,81,87,90,96,100,108,122,132,139,150,166,23,24,25,26,27,28,29,31,37,39,40,42,43,44,45,46,47,48,49,50,51,91,92,93,94,52,53,88,74,75,76,30,32,77,78],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/template/base.py":[51,53,54,55,56,58,61,62,63,64,67,68,70,73,74,75,76,77,78,79,80,81,82,83,84,88,92,93,94,95,97,100,101,102,103,104,107,109,113,117,118,123,126,133,141,142,158,162,165,175,200,279,288,289,312,317,333,334,338,352,382,383,409,410,426,486,493,507,520,537,546,549,552,555,559,565,580,581,582,583,584,586,599,600,601,602,603,604,607,610,623,624,668,705,721,723,727,744,746,792,810,813,816,883,886,887,888,890,896,910,913,928,931,933,943,951,952,955,958,962,978,979,982,985,997,1000],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/template/context.py":[1,2,5,8,9,10,13,14,20,23,27,28,31,37,42,45,48,57,62,66,78,85,89,92,98,105,114,123,135,136,137,148,158,163,172,186,187,189,192,195,198,201,202,215,221,222,235,256,265],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/utils/formats.py":[1,2,3,4,6,7,8,9,16,17,20,21,23,24,25,26,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,49,60,87,99,141,144,155,165,187,210,235],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/utils/dateformat.py":[12,13,14,15,16,18,21,22,24,25,28,29,44,46,59,65,71,75,91,102,110,114,118,122,126,142,155,159,180,184,210,211,213,217,224,228,232,236,240,253,257,261,265,269,273,277,281,285,289,302,306,313,317,342,346,350,358,364],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/utils/dates.py":[1,3,6,7,10,11,14,15,16,19,20,23,24,25,26,27,28,29,30,31,32,33,34,37,38,39,40,41,42,43,44,45,46,47,48],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/utils/datetime_safe.py":[10,11,12,17,18,22,23,26,32,36,37,40,45,57,60,73],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/utils/numberformat.py":[1,3,4,8],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/template/exceptions.py":[6,9,26,27,38,41,42],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/template/library.py":[1,2,3,5,6,8,9,12,13,16,22,23,27,50,54,96,100,136,164,169,170,176,184,186,190,201,203,207,237,312,24,25,28,31,32,34,51,52,37,39,38,40,42,43,62,64,66,65,97,98,67,76,78,79,80,81,83,86,87,88,89,68,73,75,74,70,316,317,323,324,108,127,129,109,110,112,124,125,130,132,145,161,146,147,149,159,160],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/template/utils.py":[1,2,3,5,6,7,8,9,12,13,16,17,25,64,86,89,93,22,23,90,87,27,28,30,31,32,33,36,44,45,46,47,48,51,52,54,55,56,62,65,66,67,68,69,78,79,80,81,83,84],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/forms/renderers.py":[1,2,4,5,6,7,8,10,11,12,13,16,19,25,26,29,34,35,38,48,52,53,56,60,61,64,68,69],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/template/backends/__init__.py":[1],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/template/backends/django.py":[1,2,4,5,6,7,8,9,11,14,16,18,29,32,38,48,50,54,58,66,79,87,114,19,20,21,22,23,24,25,43,94,95,96,97,98,100,101,102,107,108,119,120,121,128,129,109,103,105,111,44,45,26,27],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/template/backends/base.py":[1,4,5,6,9,14,28,34,44,57,68,20,21,22,23,24],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/utils/_os.py":[1,2,3,5,6,9,12,17,25,53],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/template/loader.py":[1,2,5,22,52,65],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/template/backends/jinja2.py":[1],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/forms/fields.py":[3,5,6,7,8,9,10,11,12,13,15,16,18,19,20,21,28,29,30,31,32,41,45,46,47,48,52,54,56,57,58,118,121,124,128,142,152,165,173,192,199,207,208,220,230,241,242,244,246,248,260,277,287,289,292,308,315,322,324,327,332,350,357,370,372,377,387,391,392,393,395,398,411,415,416,417,419,422,433,437,438,439,441,444,449,464,468,470,471,474,479,496,497,505,508,517,520,521,522,524,528,529,531,532,533,534,535,536,537,538,541,546,567,586,591,595,596,598,599,604,647,654,655,657,659,661,664,696,697,699,711,715,723,727,728,730,746,750,751,754,758,759,761,764,768,773,776,787,789,795,805,820,821,826,842,847,848,849,851,852,855,862,875,889,890,895,914,918,925,928,929,938,949,965,967,968,971,986,991,994,1048,1059,1077,1078,1079,1122,1123,1124,1126,1127,1130,1145,1158,1159,1164,1173,1174,1176,1183,1185,1188,1193,765,82,83,84,85,86,87,88,89,94,95,99,102,171,103,106,108,109,110,111,112,114,116,766,780,783,785,91,209,210,211,212,213,231,232,235,238,214,216,218,234,104,217,373,374,525,237,215,662,249,250,253,278,279,280,282,284,255,257,972,973,974,975,976,977,979,984,542,543,544,328,329,358,359,360,363,366,367,330,648,649,650,651,316,317,318,319],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/core/validators.py":[1,2,3,4,6,7,8,9,10,13,16,28,30,31,32,33,34,36,52,62,73,74,75,78,79,82,84,88,93,95,98,101,18,25,102,103,105,110,152,153,154,155,37,38,39,40,41,42,43,45,47,50,159,163,165,166,167,168,170,171,173,174,175,177,178,179,181,189,210,224,233,182,184,186,235,236,237,239,240,243,244,245,246,247,251,258,263,274,275,276,280,295,303,304,296,297,298,300,308,310,311,313,318,324,332,335,339,340,341,342,344,348,349,350,351,353,357,358,359,360,361,362,363,365,368,372,373,374,375,376,377,378,380,383,387,392,394,395,396,397,398,400,401,402,403,405,406,407,408,412,416,457,465,467,468,471,473,482,494,503,513,517,519,520,521,523,529,533,106,107,314,315,524,526,413,414,319,384,320,321,381,57,20,21,23,24,58,59,336,354,345],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/utils/deconstruct.py":[1,3,6,13,53,55,14,20,48,49,51,16,17,18],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/utils/ipv6.py":[1,3,4,7,8,38],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/utils/dateparse.py":[1,8,9,11,13,14,17,18,22,23,29,30,41,42,56,57,68,80,97,124],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/utils/duration.py":[1,4,18,31,43],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/forms/forms.py":[3,5,6,8,10,11,13,14,15,16,17,18,20,22,25,26,27,55,61,68,69,70,71,72,74,75,76,119,141,144,156,160,176,183,187,196,200,277,287,297,307,315,362,368,385,407,416,423,432,436,460,468,475,482,489,500,58,501,29,30,31,34,36,39,40,42,46,47,43,50,51,53,32,33],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/forms/formsets.py":[1,2,3,4,5,6,7,8,9,11,14,15,16,17,18,19,22,25,28,33,34,45,49,50,51,63,66,70,74,77,84,103,122,131,139,148,176,181,186,198,207,225,263,267,277,284,289,293,311,353,362,366,377,380,390,399,407,412,418,419,420,438],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/forms/models.py":[4,6,7,9,12,13,14,15,16,19,20,26,29,32,70,95,106,193,194,206,207,278,279,280,281,282,308,349,353,381,411,422,443,466,469,470,208,209,210,214,216,218,219,473,474,475,476,556,559,560,563,566,571,577,582,591,625,644,648,652,657,671,673,676,745,755,765,768,794,808,852,853,854,855,856,857,881,882,884,906,911,934,938,955,982,987,1042,1043,1044,1045,1046,1047,1048,1086,1090,1091,1093,1096,1108,1123,1127,1128,1132,1142,1148,1151,1155,1156,1160,1163,1165,1166,1167,1184,1194,1201,1204,1208,1212,1220,1235,1237,1245,1255,1258,1266,1267,1268,1269,1271,1272,1274,1277,1280,1285,1299,1336,1344,1358,221,195,196,197,198,199,200,201,202,203,226,227,228,237,239,246,251,252,253,254,256,137,138,139,141,142,143,144,152,153,154,157,158,160,162,164,166,168,169,171,172,178,179,181,184,185,186,187,188,190,260,261,262,269,273,275,249,183,1278,1169,1172,1176,1177,1178,1180,1205,1206,1223,1233,1129,1130,1202,1181,1182,145,271,996,997,998,1015,1016,1017,1018,1021,1022,1039],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/db/models/constants.py":[3,6],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/db/models/query_utils.py":[7,8,9,10,11,13,14,19,22,23,24,27,33,37,38,40,43,47,51,53,54,55,56,58,63,80,83,86,92,99,116,120,121,124,142,156,158,162,163,168,177,186,197,202,203,212,213,223,259,272,300,301,303,59,60,61,313,321,327,334,204,205,206,207,208,209,199,28,200,29,30,210,122,129,130,169,170,160,165,166,192,193,194,195,171,173,175,279,295,281,87,88,89,90],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/utils/tree.py":[4,6,8,11,16,19,21,29,30,43,47,50,56,60,64,68,75,78,122,23,24,25,39,40,41,93,95,98,100,113,114,62,101,108,109,70,124],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/utils/hashable.py":[1,4],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/db/models/deletion.py":[1,2,4,5,8,9,14,21,31,42,46,50,54,63,64,80,107,119,154,167,228,236,241,260],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/db/transaction.py":[1,3,8,9,10,13,23,28,33,38,43,52,60,68,75,80,95,107,134,136,140,176,265,275,283,268,272,137,138,141,18,20,143,145,146,147,162,173,174,177,179,183,185,186,191,192,211,212,252,253,256,167,171,180,194,258,168,169,92,224,225,228,231,232,235,243,244],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/db/models/sql/__init__.py":[1,2,3,4,5,7],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/db/models/sql/query.py":[8,9,10,11,12,13,15,18,19,20,21,22,23,24,25,28,31,34,37,38,39,41,44,51,59,60,61,65,66,68,80,83,86,93,105,108,112,115,133,134,136,137,139,141,230,236,242,246,251,262,269,275,278,285,293,339,354,359,403,492,503,506,518,526,627,713,738,742,746,780,799,808,844,890,902,910,952,985,992,1005,1008,1019,1037,1048,1068,1114,1130,1248,1251,1269,1295,1317,1330,1427,1528,1556,1583,1650,1653,1656,1679,1683,1686,1694,1702,1711,1715,1722,1760,1785,1795,1811,1827,1860,1864,1884,1908,1927,1931,1939,1943,1954,1989,2008,2023,2093,2112,2126,2137,2145,2149,2151,2166,2173,142,143,149,153,154,155,156,157,158,159,160,168,169,170,177,178,179,180,181,182,183,184,185,187,189,193,199,200,201,204,205,206,212,213,214,216,217,222,224,226,227,228,344,298,299,301,303,304,305,306,307,308,309,310,318,319,320,321,324,325,328,330,331,333,334,335,336,337,345,347,348,349,350,352,1955,1956,1862,1957,1708,1709,1959,1964,1965,1966,1967,1968,1971,1981,1948,1951,1952,1982,1933,1936,1937,1986,1987,1727,895,899,291,926,933,936,941,721,722,728,733,734,735,736,942,948,949,950,900,1728,1730,1731,1732,1735,1458,1464,1469,1470,1471,1472,1473,1345,1346,1347,1348,1351,1352,1353,1354,1361,1365,1372,1373,1394,1400,1417,1418,1419,1423,1424,1485,1486,1487,1502,1526,1736,1737,1738,1739,1541,1542,1554,1741,1742,1465,1743,1744,1712,1713,279,281,282,283,2010,2012,2013,1995,1997,1998,804,805,806,744,1692,1262,1263,1271,1272,1273,1274,1275,1276,2152,2153,2154,2160,2161,2164,1277,1278,1284,1285,1286,1287,1159,1161,1162,1164,1023,1024,1028,1029,1030,1035,1166,1172,1175,1176,1009,1011,1017,1177,1179,1180,1185,1186,1187,1189,1190,1191,1192,1196,1198,1050,1202,1208,1209,1210,1211,1213,1223,1225,1078,1079,1083,1084,1085,1096,1099,1108,1112,1226,1227,1229,1230,1246,1289,2171,1290,1291,896,248,249,897,740,1292,2180,2181,2184,2195,2207,2209,2225,757,758,2226,790,791,792,793,2227,1293,1264,1265,1266,1790,1791,1792,1769,1770,1778,1780,1783,641,642,643,961,962,1401,1402,1408,1409,1410,1411,1412,1413,1414,1355,1356,1358,1381,1382,1390,1503,1507,1508,1509,1510,1511,2107,2109,1514,1515,1516,1518,1519,1520,1521,934,943,946,947,1523,1524,1056,1062,1064,1065,1066,1042,1043,1543,1545,1547,1548,1549,1551,1552,1553,1215,1216,1218,1219,937,938,2120,2121,2123,238,239,240,1550,507,508,509,512,1696,1697,1698,1699,1700,513,1793,514,1665,1666,1669,1670,1676,515,516,1832,1837,1838,1841,1842,1843,1844,1845,1846,1850,1852,232,233,234,1853,1855,1857,2014,2015,2016,2017,2019,2011,1771,1773,1781,1063,987,988,1557,1559,1569,1570,1571,1572,1577,1578,1580,1581,989,1940,990,407,1999,2006,409,410,411,412,413,426,427,473,474,475,476,478,479,1681,480,481,482,483,484,487,488,490,1349,1010,993,312,323,995,851,869,873,874,860,861,862,875,876,877,882,883,884,885,886,887,888,814,818,819,821,822,827,828,830,831,832,833,834,836,837,838,839,840,841,842,996,999,1000,1001,1002,1003,276,244,1006,2155,2156,1231,1232,1233,1234,346,351,908],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/db/models/fields/related_lookups.py":[1,7,8,10,14,18,22,26,46,47,62,102,103,119,133,134,137,138,141,142,145,146,149,150,153,154,48,50,27,28,29,30,31,32,34,35,40,55,58,59,60,63,87,99,104,106,111,114,115,117,120,130,41,42],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/db/models/lookups.py":[1,2,3,5,6,7,8,9,10,13,14,15,16,18,33,38,55,60,66,73,76,82,97,100,107,113,116,120,124,129,133,134,135,137,141,151,152,161,168,172,176,177,179,191,195,196,198,214,222,230,244,245,246,248,263,264,265,266,268,275,276,277,280,281,282,285,286,287,290,291,292,295,299,300,306,307,308,311,312,313,316,317,318,320,348,351,357,380,381,382,384,400,407,408,409,412,413,414,417,418,419,420,423,424,425,428,429,430,431,434,435,436,439,440,441,443,447,448,449,450,452,460,461,462,463,465,475,476,477,480,481,490,491,501,504,510,511,513,531,532,534,538,539,541,545,546,548,552,553,555,19,20,67,69,70,21,24,25,31,118,162,153,77,78,79,80,154,155,156,157,158,159,163,249,250,260,83,84,91,95,181,182,184,186,187,164,165,169,166,98,199,200,204,205,209,210,211,212,352,353,355,321,322,328,329,330,334,339,231,39,41,51,185,52,53,236,237,238,223,224,226,228,240,241,340,341,349,335,101,102,103,105,203,343,346,215,220,92,93],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/db/models/sql/constants.py":[3,5,9,14,15,16,17,19,21,22,26,27],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/db/models/sql/datastructures.py":[4,6,7,10,15,16,22,23,26,42,44,61,106,119,128,131,136,142,148,149,150,151,153,157,162,165,154,155,158,159,160,46,47,49,51,54,56,58,59,129,121,122,123,124,125,67,68,69,70,73,74,75,76,77,78,83,84,85,89,94,101,102,103,104,163,107,108,109,113,114,115,116],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/db/models/sql/where.py":[3,5,6,7,10,11,14,27,28,29,30,32,65,117,123,126,130,142,157,162,168,172,178,182,186,192,193,194,196,200,202,204,208,213,216,218,224,148,149,150,155,38,170,164,165,39,72,73,74,75,79,105,106,107,115,151,154,166,80,81,85,86,87,95,100,108,113,114,82,83,96,99,135,136,139,140,152,112],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/db/models/sql/subqueries.py":[3,5,6,7,8,11,13,16,17,19,21,27,44,79,80,82,84,88,97,102,109,131,143,151,169,170,172,177,183,187,189,191,173,174,175,178,179,180,93,94,95,137,138,141,157,158],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/db/models/fields/files.py":[1,2,4,5,6,7,8,9,10,11,14,15,22,29,36,40,46,49,52,54,59,64,71,79,85,94,96,113,115,120,125,133,146,147,150,208,212,216,219,221,223,232,239,251,265,274,277,284,291,295,309,319,327,331,332,349,350,357,358,359,360,362,366,372,388,396,405,462,224,226,227,229,230,292,293,148,363,364,397,402,403,389,266,267,268,269,270,272,390,392,394,463,464,465,320,321,322,323,234,235,240,249,236,252,263,368,369,373,374,386],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/core/files/images.py":[5,6,7,9,12,16,17,21,25,33],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/core/files/storage.py":[1,2,3,5,6,7,8,9,10,11,12,13,14,15,16,17,19,22,26,31,35,53,60,91,100,111,117,124,131,137,144,151,158,166,167,170,173,180,192,195,199,203,209,213,217,220,293,307,310,320,323,326,334,345,348,351,355,359,360,364,174,175,176,177,178,201,197,193],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/core/files/locks.py":[18,19,21,24,29,89,90,91,92,93,107,111],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/core/files/move.py":[6,8,9,10,12,14,17,30],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/db/models/fields/proxy.py":[4,6,9,13,15],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/db/models/indexes.py":[1,3,4,6,9,10,13,15,35,47,55,62,70,75,86,114,117],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/db/backends/__init__.py":[1],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/db/backends/utils.py":[1,2,3,4,5,6,8,9,10,11,13,16,17,21,23,30,34,37,49,67,70,73,79,87,93,97,114,139,143,154,190,196,210,227,249,218,203,204,205,206,207,220,221,255,256,18,19,35,68,74,75,77,80,81,82,85,24,25,26,41,42,28,83],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/db/models/manager.py":[1,2,3,5,6,9,11,14,18,20,26,34,38,75,78,100,101,109,117,125,131,139,146,155,161,165,102,103,104,105,106,80,87,88,90,93,94,95,91,97,81,83,84,85,98,166,169,171,174,195,196,200,22,23,24,27,28,122,123,29,30,31,32,110,111,113,172,115,197,198,82,144,175,178,183,192,45,46,56,57,59,60,68,69,70,71,72,126,127,128,129,133,153,76],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/db/models/query.py":[3,5,6,7,8,9,10,12,13,14,18,19,20,21,22,23,24,25,26,27,28,29,32,35,38,39,45,46,48,88,91,93,110,114,116,141,145,147,148,154,167,171,173,180,181,183,197,203,204,210,220,225,243,249,253,271,275,305,316,331,334,344,372,385,406,416,421,475,490,514,532,562,597,600,603,608,613,641,669,670,672,678,680,696,698,713,714,716,721,726,733,740,748,754,785,801,822,832,839,846,853,865,882,893,900,909,915,930,952,974,1020,1029,1040,1048,1056,1072,1092,1102,1115,1126,1137,1138,1140,1158,1170,1184,1190,1204,1215,1222,1230,1232,1239,1247,1259,1260,1264,1268,1270,1274,1278,1280,1292,1302,1311,1315,1324,1330,1334,1338,1342,1375,1378,1381,1386,1395,1413,1424,1425,1438,1448,1452,1455,1461,1466,1469,1473,1485,1611,1658,1758,1772,1773,1819,1835,199,200,201,202,184,185,186,187,188,189,190,191,192,193,194,195,1094,1163,1175,1176,1177,1178,1179,1180,1181,1182,1164,1167,1168,1095,1096,837,755,757,760,761,762,763,764,765,775,777,741,742,744,745,746,779,780,781,783,268,1185,1186,40,41,42,117,118,119,1118,1120,121,122,123,124,127,129,130,138,1187,269,411,412,413,1119,1131,1132,1134,1135,1136,414,390,844,854,855,858,859,862,863,391,392,1022,1024,1025,1026,1027,393,250,49,50,51,54,55,56,57,58,59,60,61,62,1836,1837,1838,1841,63,64,65,67,72,85,251,394,395,441,446,449,450,717,718,396,397,398,399,481,538,539,540,541,542,543,544,545,546,547,548,549,554,560,484,485,486,487,488,519,520,521,522,523,451,452,453,454,455,417,418,419,456,457,458,463,464,465,1144,1145,1146,1147,1148,1149,1150,1151,1156,466,467,468,469,470,471,473,339,341,342,332,875,880,352,354,1249,1250,355,359,360,363,365,366,367,368,370,1223,1227,1228,1229,272,273,851,860,705,707,708,710,711,712],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/db/models/functions/__init__.py":[1,2,8,12,19,21,22,23,24,25,27,28,29,31,32],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/db/models/functions/comparison.py":[1,2,5,6,7,8,10,13,17,22,29,30,31,33,38,54,61,62,64,69,74,81,82,84,89],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/db/models/functions/datetime.py":[1,3,4,8,11,14,15,17,31,32,33,35,43,63,79,80,83,84,87,88,91,95,96,99,104,105,108,109,112,113,116,117,120,121,124,125,126,127,128,129,131,132,133,135,136,137,139,140,141,142,143,146,147,148,150,157,158,159,161,165,180,209,227,229,234,235,238,239,242,243,246,247,248,251,252,255,256,257,258,260,268,269,270,271,273,281,282,285,286,289,290,293,294],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/db/models/functions/text.py":[1,2,5,13,14,21,22,23,25,30,33,37,41,42,44,50,56,66,71,72,73,75,81,90,91,92,94,104,107,110,111,114,115,116,117,118,120,124,125,126,129,130,132,138,139,140,143,144,145,146,148,151,155,156,158,163,169,170,172,176,177,179,183,184,187,188,189,192,197,198,199,200,202,206,207,209,223,226,230,231,232,235,236,237],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/db/models/functions/window.py":[1,4,5,9,10,11,12,13,16,17,18,19,20,23,24,25,26,27,30,31,33,49,54,55,56,59,60,61,62,63,66,67,68,71,72,73,74,76,83,88,89,90,91,92,94,100,101,102,103,104,107,108,109,110,111,114,115,116,117,118],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/db/models/base.py":[1,2,3,4,5,7,8,9,10,14,18,19,20,23,24,25,26,29,30,31,32,33,36,37,40,44,47,61,62,63,302,309,355,359,364,365,372,373,374,379,380,383,385,489,502,505,508,518,523,529,533,551,555,558,560,569,623,641,719,722,761,763,785,836,863,871,882,884,888,904,919,924,933,949,997,1042,1071,1088,1118,1154,1179,1209,1236,1249,1257,1267,1298,1315,1372,1397,1421,1441,1455,1482,1509,1515,1563,1630,64,68,69,70,1710,1722,1729,1746,1756,73,74,75,76,78,79,80,81,82,84,87,89,90,99,101,304,305,102,103,104,105,106,107,108,109,110,111,55,56,57,307,112,113,114,115,116,117,118,119,120,121,130,134,138,139,142,143,144,145,147,150,170,173,174,176,177,179,182,183,188,190,191,194,195,288,290,298,311,312,314,329,330,332,333,336,349,353,299,300,77,294,295,296,337,342,343,344,197,198,248,251,252,253,254,255,256,259,265,269,184,185,361,387,388,389,390,392,395,401,405,417,418,427,428,430,432,433,450,451,452,457,461,469,470,459,472,486,487,653,656,677,678,681,564,565,566,682,708,717,718,732,733,734,735,737,739,740,741,742,743,745,746,747,765,766,748,790,791,793,797,552,553,798,799,800,801,802,804,806,817,818,826,827,828,830,831,357,868,869,832,833,834,750,752,755,756,757,758,491,497,406,411,412,414,498,499,500,519,521,434,436,437,447,466,467,366,368,369,556,1181,1212,1213,1234,1238,1239,1247,1252,1253,1254,1255,1182,1183,1184,1260,1261,1262,1263,1265,1185,1272,1273,1275,1278,1281,1283,1296,1186,1636,1637,1638,1641,1643,1645,1646,1647,1650,1651,1652,1657,1660,1661,1665,1677,1701,1189,1301,1303,1313,1190,1318,1319,1322,1344,1349,1350,1355,1356,1367,1368,1370,1191,1399,1400,1401,1410,1419,1192,1423,1424,1426,1429,1427,1430,1439,1193,1443,1444,1453,1195,1198,1199,1375,1376,1378,1379,1382,1393,1395,1200,1201,1458,1467,1477,1478,1480,1202,1485,1494,1504,1505,1507,1203,1512,1513,1517,1521,1522,1525,1526,1561,1204,1569,1578,1581,1590,1591,1594,1597,1601,1605,1608,1612,1613,1614,1615,1618,1620,1628,1207,1506,1527,1528,1540,1551,1264,1284,1285,1295,1679,1684,1685,1686,1579,1159,1160,1162,1163,1164,1168,1169,1171,1172,1170,1176,931,938,957,958,959,961,962,966,967,973,978,979,982,983,984,985,987,988,989,991,993,995,940,998,1000,1004,1005,1006,1007,1009,1010,1013,1016,1019,1022,1030,1031,1033,1040,941,1043,1044,1069,943,946,438,439,441,442,443,657,664,674,968,970,1020,1032,1015,807,808,809,810,811,812,841,842,849,861,813,815],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/db/models/fields/related.py":[1,2,3,5,6,7,8,9,10,11,12,13,14,15,16,18,19,20,25,29,33,36,61,82,83,86,87,88,89,91,97,107,126,155,170,189,283,288,319,329,342,361,376,385,389,400,420,427,439,443,446,449,450,451,452,454,455,456,457,461,479,486,508,564,600,616,622,626,630,634,637,640,658,662,666,669,684,698,712,726,727,734,738,750,751,752,753,754,755,756,759,766,769,770,771,772,774,776,778,780,784,815,822,845,855,873,876,880,894,916,919,924,931,939,942,947,959,962,965,968,973,979,983,989,992,993,994,995,997,998,999,1001,1003,1007,1013,1018,1024,1029,1076,1084,1087,1088,1089,1090,1092,1094,1099,1134,1143,1154,1187,1386,1418,1461,1487,1490,1493,1506,1524,1554,1591,1609,1612,1615,1618,1633,1636,1641,785,786,787,788,801,802,803,804,805,806,807,809,811,463,473,475,476,477,813,799,735,290,920,917,921,922,292,294,295,298,299,307,314,317,76,50,54,55,58,77,78,79,736,315,316,386,378,381,383,387,943,741,742,746,944,1100,1101,1109,1110,1112,1117,1118,1119,1120,1121,1122,1123,1124,1125,1127,1129,1131,1132,1561,1564,1571,1577,1578,1582,1583,1030,1032,1035,1036,1037,56,1039,1040,1041,1045,1046,1498,1500,1503,1504,1047,1048,1049,1050,1051,1052,1053,1056,1057,1058,1059,1060,1061,1062,1063,1064,1066,1067,1068,1069,1070,1071,296,300,301,302,303,305,1586,1589,1610,1594,1595,1598,1599,1601,1602,1604,1605,1606,1607,1033,308,309,310,312,1004,1005,1102,1103,1113,1579,1581,1580,1620,1621,1622,1626,1631,408,409,413,414,415,417,418,94,95,856,565,320,321,323,325,327,566,567,568,570,573,574,582,367,369,370,373,583,598,857,858,860,861,864,867,868,871,869,870,1419,1421,1423,1426,1427,1433,1443,1444,1459,324,326,585,593,594,595,596,1008,1009,1010,1011,1434,1435,1446,1454,1455,1456,1457,966,963,878,632,618,619,601,603,605,606,607,608,609,611,613,614,620,960,932,935,700,701,702,703,704,705,612,706,707,708,709,425,663,664,980,729,730,731,732,696,940,974,975,977,440,937,948,952,953,954,955,956,817,481,99,100,108,109,110,111,101,127,129,130,131,142,153,102,156,157,158,159,168,103,171,187,104,191,193,194,198,213,217,218,219,220,225,226,227,228,239,253,254,255,256,257,258,269,281,482,488,491,492,493,506,483,509,510,513,514,518,521,523,524,526,528,530,531,533,550,562,818,823,824,833,843,819,853,494,495,1136,1137,1144,1152,1138,1188,1189,1190,1194,1196,1208,1214,1215,1216,1219,1220,1221,1224,1235,1257,1258,1259,1261,1262,1263,1266,1283,1300,1313,1384,1139,1155,1157,1166,1174,1185,1140,1387,1389,1391,1392,1394,1499,1395,1398,1416,112,113,124,1026,926,927,929,874,895,897,898,901,902,903,905,396,398,906],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/db/models/fields/mixins.py":[1,4,5,7,10,19,22,25,23,11,12,13,20],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/db/models/fields/related_descriptors.py":[64,66,67,68,69,72,83,85,88,104,107,110,141,146,193,259,268,278,280,299,316,327,329,334,349,352,355,373,420,479,484,498,500,504,513,528,534,541,731,746,748,753,760,770,777,86,501,502,749,751,523,524,332,758,204,213,214,215,216,218,221,226,246,247,251,256,156,157,162,163,186,191,300,257,303],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/db/models/fields/reverse_related.py":[10,12,13,15,16,19,25,28,29,30,31,35,38,54,58,62,66,77,84,88,92,96,100,103,106,110,117,129,133,136,139,149,166,169,177,190,193,205,210,219,223,229,232,245,251,255,274,194,195,196,197,198,199,200,39,40,41,42,43,44,45,47,48,203,220,131,79,82,156,157,158,160,162,164,256,257,258,259,260,263,265,267,269,271,272,163,233,234,235,236,237,238,239,242,206,207,208,60,56,174],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/db/models/options.py":[1,2,3,4,6,7,8,9,10,11,12,13,14,15,16,17,19,21,24,37,41,63,67,69,70,71,73,75,77,133,137,141,146,150,205,245,249,279,284,293,296,299,315,321,346,366,370,398,422,456,469,482,496,513,528,543,568,585,596,616,646,668,704,708,721,736,819,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,115,119,120,121,122,126,129,131,151,152,154,155,157,158,159,163,166,167,168,172,173,174,175,176,177,178,182,47,48,50,52,53,56,183,49,187,191,194,198,201,254,256,259,260,280,270,277,711,712,713,715,719,246,247,716,717,206,222,224,225,242,243,281,282,439,442,445,450,451,452,748,756,757,758,759,762,764,767,768,769,771,774,775,789,800,801,802,808,809,813,64,816,817,453,440,443,447,139,348,349,350,351,352,353,356,357,358,359,361,362,363,271,272,273,274,275,330,344,188,202,203,257,54,714,179,180,331,332,333,334,342,354,547,550,515,516,517,518,522,523,526,197,255,465,466,491,492,493,400,401,408,419,420,51,57,60,368,135,304,306,307,308,310,313,731,733,793,706,675,677,678,679,682,685,688,686,689,690,692,698,699,702,794,718,797,798,478,479,372,373,375,376,381,392,393,394,395,396,318,319,551,554,561,564,530,531,532,533,537,538,539,540,541,565,566,590,591,594,822,823,824,825,826,827,297,305,524,525,403,404,405,406,507,508,509,510,144,377,379],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/core/serializers/json.py":[3,5,6,7,8,10,11,14,15,16,19,20,21,23,33,37,44,56,61,76,80,81,34,24,25,26,27,28,31,35,46,47,51,53,54,48,49,50,83,84,85,86,87,88,89,38,40,41,58],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/core/serializers/python.py":[5,6,8,9,10,11,14,17,19,21,25,28,31,35,42,49,52,63,75,79,143,29,50,43,47,36,37,38,39,40,53,60,61],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/template/response.py":[1,3,6,7,10,11,14,45,60,69,72,86,97,113,117,124,132,139,140,143],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/urls/__init__.py":[1,6,7,8,9,13,16,17,18,19,20,21,22],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/urls/base.py":[1,2,4,5,6,8,9,10,15,18,21,27,93,96,102,111,120,130,142,150,163,106,108],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/urls/exceptions.py":[1,4,5,8,9],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/urls/resolvers.py":[7,8,9,10,11,12,14,15,16,17,18,19,20,21,22,24,25,26,29,30,53,56,63,64,70,81,82,85,104,105,114,137,138,83,140,147,158,165,177,186,190,191,195,235,236,238,245,259,271,274,278,279,283,288,296,302,305,308,312,313,319,322,327,341,349,363,364,383,394,400,459,466,473,480,485,523,530,545,554,557,65,66,67,141,142,143,144,145,365,369,370,371,372,373,374,375,376,379,380,381,533,525,526,314,315,316,317,239,240,241,242,243,202,203,204,205,206,207,208,209,230,232,231,210,211,212,213,218,219,222,223,228,229,221,534,535,543,528,395,396,397,323,331,339,324,159,160,118,89,94,95,96,179,180,97,119,123,134,161,163,325,398,162,166,167,175,260,272,261,262,269],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/utils/regex_helper.py":[7,12,13,14,15,16,17,18,19,20,21,25,26,29,30,33,34,37,189,210,231,268,282],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/urls/converters.py":[1,3,6,7,9,12,16,17,19,22,26,27,29,32,36,37,40,41,45,46,47,48,49,53,56,61,66,67,63],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/utils/lru_cache.py":[1],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/urls/utils.py":[1,2,4,5,8,55],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/urls/conf.py":[1,2,3,5,7,12,57,76,77,13,14,31,33,34,58,69,70,71,35,36,37,44,47,48,49,50,54,60,61,62,63,64,65,66,67],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/utils/decorators.py":[1,4,5,8,9,15,24,55,91,107,117,126,167,168,171,174,113,127,164,128,130,163,63,83,84,86,87,88,64,65,29,35,37,48,49,18,131,162,21,51,52,169,10,12],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/views/generic/dates.py":[1,3,4,5,6,7,8,9,10,11,14,19,20,21,22,24,31,44,48,52,63,68,69,70,71,73,80,93,97,101,115,120,121,122,123,125,132,145,149,153,161,166,167,168,169,171,178,191,195,199,210,214,229,230,231,232,234,240,250,260,273,293,294,295,296,298,307,311,318,344,351,375,378,379,381,392,393,394,397,398,399,400,402,430,438,439,440,443,444,445,447,473,474,475,478,479,481,512,513,514,517,518,519,531,548,549,550,553,554,556,561,562,563,566,570,571,601,605,606,609,625,715],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/views/generic/detail.py":[1,2,3,4,5,8,11,12,13,14,15,16,17,18,20,58,78,82,91,103,104,105,111,112,113,115,164,170],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/views/generic/list.py":[1,2,3,4,5,6,9,10,11,12,13,14,15,16,17,18,19,21,50,54,77,84,90,97,104,113,139,140,141,161,162,163,165,194,198],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/core/paginator.py":[1,2,3,5,6,9,10,13,14,17,18,21,22,25,28,35,52,65,74,83,94,102,110,129,132,134,139,142,145,154,157,160,163,166,169,179],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/views/generic/edit.py":[1,2,3,4,5,10,11,12,13,14,15,17,21,25,29,35,49,55,59,63,70,71,72,74,103,110,123,129,130,131,135,148,152,153,156,157,160,165,166,170,175,178,179,182,187,188,192,197,198,199,202,203,204,206,217,220,228,233,236,240,241],"/home/valberg/code/bornhack/bornhack-website/src/bornhack/environment_settings.py":[1,4,5,7,8,9,10,11,12,15,16,17,19,20,21,25,26,27,29,30,32,33,34,36,37,38,39,40,41,43,44,45,47,48,50,51,52,53,54,56,58,60,63,64,68],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/utils/log.py":[1,2,3,5,6,7,8,9,10,12,19,20,23,26,30,31,32,33,38,39,40,43,44,45,48,49,50,55,56,59,60,61,67,79,84,86,91,124,127,130,137,142,143,146,152,153,157,158,162,163,167,195,199,68,70,72,164,165,87,88,89,75,76],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/core/mail/__init__.py":[3,4,9,14,15,18,19,20,21,22,26,40,64,90,105],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/core/mail/message.py":[1,2,5,6,7,8,9,10,11,12,13,14,15,17,18,19,23,24,25,26,30,32,35,36,41,42,43,44,45,46,47,48,49,50,51,55,74,98,126,127,140,154,156,162,164,168,172,184,186,190,195,196,197,198,199,203,245,251,278,285,293,325,341,344,358,388,402,415,420,421,425,436,442,445],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/core/mail/utils.py":[3,5,10,11,14,20],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/views/debug.py":[1,2,3,4,5,7,8,9,10,11,12,13,14,15,16,22,23,24,27,29,31,34,40,41,44,48,72,84,98,104,109,113,115,121,125,129,131,140,154,179,193,244,245,246,258,329,336,343,388,456,512],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/template/defaultfilters.py":[1,2,3,4,5,6,7,8,9,11,12,13,14,18,19,22,23,25,26,28,35,60,61,40,51,53,71,72,78,79,85,94,95,166,167,173,174,175,190,191,197,198,209,210,220,239,240,247,248,258,259,272,273,286,287,300,301,307,308,309,324,325,326,331,332,333,343,344,350,351,357,358,364,365,371,372,378,379,393,394,400,401,411,412,413,423,424,425,437,438,444,454,455,465,491,503,515,524,525,536,545,554,563,569,587,588,658,670,695,696,709,710,723,724,736,737,751,757,765,771,772,808,851,852,895,901],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/utils/timesince.py":[1,2,4,5,6,9,10,11,12,13,14,23,27,87],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/templatetags/i18n.py":[1,2,3,4,5,6,8,11,12,15,20,21,25,31,32,36,44,50,51,54,59,60,63,68,70,79,98,101,111,125,181,182,186,192,213,234,259,264,270,275,280,299,319,412,534],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/template/defaulttags.py":[1,2,3,4,5,6,7,9,10,11,12,13,15,22,23,24,26,29,30,31,34,45,46,50,51,70,71,76,88,95,96,104,105,108,115,116,120,133,134,136,145,155,219,220,222,226,249,262,263,265,270,273,281,283,286,289,293,297,314,315,318,332,335,336,340,346,362,363,367,368,372,383,384,387,392,393,396,401,402,403,404,405,406,407,408,409,412,415,419,420,426,456,457,460,464,465,471,497,498,506,509,515,532,541,629,634,649,679,728,820,837,857,866,867,871,874,878,879,881,885,889,976,1018,1029,1051,1082,1129,1152,1221,1247,1278,1313,1380,1403,1441],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/utils/lorem_ipsum.py":[3,5,8,46,52,56,71,80,97],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/template/smartif.py":[3,11,15,16,17,18,20,26,32,38,43,68,94,48,49,51,56,65,95,96,73,74,76,81,87,97,98,99,100,101,102,103,104,105,106,110,111,114,117,121,122,124,127,130,133,136,140,141,143,147,150,151,153,173,181,189,197,207],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/template/loader_tags.py":[1,2,4,6,9,11,13,16,17,21,25,31,34,41,42,45,48,67,80,81,82,84,90,93,109,126,153,154,156,162,191,220,250,272],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/contrib/__init__.py":[1],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/contrib/admin/__init__.py":[3,4,9,10,13,14,17,18,19,20,21,25,29,26],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/contrib/admin/decorators.py":[1,12,13,15,30,16,19,21,24,27,29],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/contrib/admin/filters.py":[7,8,10,11,14,15,16,17,20,21,22,24,34,40,48,54,62,64,66,81,84,92,101,104,118,119,120,122,132,135,143,144,155,162,163,178,186,193,196,199,219,145,153,222,223,233,236,254,257,258,265,268,292,295,296,346,352,361,362,368,369,384,387,412,415,416],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/contrib/admin/options.py":[1,2,3,4,5,6,7,9,10,11,12,13,16,17,18,23,24,27,28,31,32,33,34,35,36,40,41,42,43,44,45,46,47,48,49,50,51,52,53,55,56,59,62,69,73,74,81,82,83,85,86,87,88,89,90,91,92,93,94,97,100,101,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,121,124,132,189,207,220,243,277,284,297,306,312,322,330,336,342,348,360,364,418,463,472,487,502,521,524,538,539,541,542,543,544,545,546,547,548,549,550,551,552,553,554,555,558,559,560,561,562,563,564,567,568,569,570,571,572,574,580,583,599,624,628,643,656,659,710,717,745,760,773,787,794,797,813,829,845,850,852,870,886,902,913,943,950,962,969,976,983,1031,1049,1055,1056,1080,1087,1093,1099,1103,1109,1121,1168,1245,1320,1333,1340,1347,1414,1455,1476,1494,1509,1522,1523,1527,1633,1636,1639,1642,1647,1663,1664,1818,1825,1826,1830,1888,1927,1973,1980,1981,1982,1983,1984,1985,1986,1987,1988,1989,1990,1991,1992,1993,1995,2006,2017,2022,2026,2030,2034,2121,2124,2130,2140,2149,2158,2174,2175,2178,2179,575,576,577,578,127,128,130,626,600,602,608,611,603,605,606,612,613,614,615,616,618,619,622,122,854,857,858,859,863,864,865,868,920,927,928,937,940,941,1996,1997,1998,1999,2000,2001,2002,2003,2004,921,922,938],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/contrib/messages/__init__.py":[1,2,4],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/contrib/messages/api.py":[1,2,8,12,13,16,37,45,56,69,75,81,87,93],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/contrib/messages/constants.py":[1,2,3,4,5,8,9,10,11,12,16,17,18,19,20],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/contrib/messages/storage/__init__.py":[1,2,5],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/contrib/admin/helpers.py":[1,3,4,5,9,10,11,12,13,14,15,17,20,21,22,23,24,25,26,30,33,34,45,54,58,62,70,71,72,80,92,97,98,113,120,128,129,135,153,157,158,190,197,228,231,235,252,277,304,317,321,325,333,336,338,346,353,364,367,374,378,383,384,388,395,396,397],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/contrib/admin/utils.py":[1,2,3,5,6,7,8,9,10,11,12,13,14,17,18,19,22,47,60,77,96,109,119,175,176,182,185,201,205,220,230,238,257,275,301,322,382,394,419,440,441,444,451,482,502,100,101,102,105,106,491,492,493,494,497,498,499,495,445,446],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/contrib/admin/widgets.py":[3,4,5,7,8,9,10,11,12,13,14,15,16,19,25,26,38,43,53,54,65,70,71,82,87,90,91,93,99,106,107,110,111,114,134,138,139,141,147,171,177,183,205,209,210,212,219,222,225,230,234,238,239,243,264,271,275,279,283,310,313,316,320,321,325,326,330,331,335,336,338,341,349,350,352,356,357,363,368,370,373,379,380,382,389,393,414,440,462,463,466,467],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/contrib/admin/checks.py":[1,2,4,5,6,9,10,11,12,13,14,17,18,19,22,30,69,71,88,100,143,155,172,204,219,254,267,295,313,321,331,341,356,367,391,407,419,431,454,466,477,491,528,541,565,567,585,594,603,614,641,653,686,703,717,726,778,786,794,802,814,864,872,895,922,924,937,966,974,982,992,1002,1010,1025,1035,1045,34,36,45,46,57,58,66,23,24,25,26,569,73,92,95,96,97,74,147,150,151,152,75,177,178,76,208,209,77,298,299,78,315,319,79,323,326,327,328,80,333,336,337,338,345,346,351,354,81,358,361,362,364,82,422,425,426,428,83,408,417,84,481,483,486,487,488,493,500,510,512,517,519,521,522,526,85,531,532,570,588,592,571,597,601,572,606,609,610,611,573,645,648,649,650,654,656,657,574,689,691,693,696,697,698,699,575,718,721,722,723,576,781,784,577,789,792,578,797,800,579,806,809,810,811,580,867,870,581,875,876,582,900,901,902,903,905,906,907,919,210,213,214,215,216,223,225,227,229,237,240,241,249,250,251,259,265,268,274,275,281,293,282,658,659,660,664,672,735,737,753,762,765,766,776,482,904,300,302,311,661,662,655,533,536,537,538,542,544,546,547,616,618,620,628,636,639,925,1011,1012,1013,1017,1018,926,928,929,967,968,972,930,940,941,945,948,949,931,977,980,932,985,986,933,995,996,934,1005,1008,160,161,166,170,815,816,820,829,839,851,862,739,743,752,272,371,372,377,389,394,396,405,545,27],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/contrib/admin/exceptions.py":[1,4,5,6,9,10,11],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/contrib/admin/templatetags/__init__.py":[1],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/contrib/admin/templatetags/admin_urls.py":[1,3,4,5,6,8,11,16,21,22],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/contrib/admin/views/__init__.py":[1],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/contrib/admin/views/autocomplete.py":[1,2,5,6,7,8,10,38,42,50],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/contrib/auth/__init__.py":[1,2,4,5,6,7,8,9,10,12,14,15,16,17,20,24,37,41,56,62,87,135,160,174,204,211,225,164,165,208],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/middleware/__init__.py":[1],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/middleware/csrf.py":[6,7,8,9,10,12,13,14,15,16,17,18,19,21,23,24,25,26,27,28,30,31,32,33,36,41,45,57,71,75,94,106,123,132,139,142,149,159,182,199,205,314],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/utils/cache.py":[18,19,20,21,23,24,25,26,27,30,31,32,34,37,86,100,106,116,134,174,195,203,222,229,248,256,276,287,299,312,320,342,383],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/contrib/auth/signals.py":[1,3,4,5],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/views/decorators/__init__.py":[1],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/views/decorators/csrf.py":[1,3,4,6,7,12,15,17,21,22,27,30,31,34,41,42,46,49,53,55,56],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/contrib/admin/sites.py":[1,2,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,20,23,24,27,28,31,38,41,44,47,50,52,54,55,56,57,58,59,60,62,69,85,126,139,145,153,159,166,173,177,181,188,232,283,287,305,322,335,344,345,366,367,400,466,482,483,501,524,525,534,526,527,63,64,65,66,67,99,100,102,103,108,113,116,124,101,285,233,237,239,247,240,242,243,248,249,250,251,252,253,254,256,257,258,259,260,266,267,268,269,271,272,211,224,225,228,229,230,276,277,278,279,281,74,75,76,78,79,80,81,82,171,143,83],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/contrib/admin/actions.py":[3,5,6,7,8,9,10,13,78,79],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/views/decorators/cache.py":[1,3,4,5,8,27,38,42,47],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/middleware/cache.py":[44,46,47,48,52,55,63,64,71,74,113,120,121,127,156,162,163],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/views/i18n.py":[1,2,3,4,5,7,8,9,10,11,12,13,14,17,18,20,23,60,175,178,195,203,214,215,216,218,230,241,252,264,273,295,302,315,331,332],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/utils/translation/trans_real.py":[1,2,3,4,5,6,7,8,9,11,12,13,14,15,16,17,19,23,24,27,30,34,38,40,41,42,45,48,60,68,69,71,108,111,127,134,149,155,170,184,188,193,203,213,222,232,244,259,275,301,312,322,333,341,352,366,386,394,395,429,446,494,283,285,286,198,199,73,74,77,78,79,80,83,85,86,90,129,130,131,119,120,121,122,123,124,132,172,174,176,177,178,181,92,97,136,137,143,144,145,146,147,180,173,99,151,100,103,159,160,104,200,287,289,295,298,218,234,235,241,228,229,236,237,208,210,190],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/conf/locale/__init__.py":[8,12,13,14,15,18,19,20,21,24,25,26,27,30,31,32,33,36,37,38,39,42,43,44,45,48,49,50,51,54,55,56,57,60,61,62,63,66,67,68,69,72,73,74,75,78,79,80,81,84,85,86,87,90,91,92,93,96,97,98,99,102,103,104,105,108,109,110,111,114,115,116,117,120,121,122,123,126,127,128,129,132,133,134,135,138,139,140,141,144,145,146,147,150,151,152,153,156,157,158,159,162,163,164,165,168,169,170,171,174,175,176,177,180,181,182,183,186,187,188,189,192,193,194,195,198,199,200,201,204,205,206,207,210,211,212,213,216,217,218,219,222,223,224,225,228,229,230,231,234,235,236,237,240,241,242,243,246,247,248,249,252,253,254,255,258,259,260,261,264,265,266,267,270,271,272,273,276,277,278,279,282,283,284,285,288,289,290,291,294,295,296,297,300,301,302,303,306,307,308,309,312,313,314,315,318,319,320,321,324,325,326,327,330,331,332,333,336,337,338,339,342,343,344,345,348,349,350,351,354,355,356,357,360,361,362,363,366,367,368,369,372,373,374,375,378,379,380,381,384,385,386,387,390,391,392,393,396,397,398,399,402,403,404,405,408,409,410,411,414,415,416,417,420,421,422,423,426,427,428,429,432,433,434,435,438,439,440,441,444,445,446,447,450,451,452,453,456,457,458,459,462,463,464,465,468,469,470,471,474,475,476,477,480,481,482,483,486,487,488,489,492,493,494,495,498,499,500,501,504,505,506,507,510,511,512,513,516,517,518,519,522,523,524,525,528,529,530,531,534,535,536,537,540,543,544,545,546,549,550,551,552,555,558,561,564,567],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/contrib/admin/apps.py":[1,2,3,4,7,8,10,11,12,14,19,20,22,23,15,16,24],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/contrib/auth/apps.py":[1,2,3,4,5,7,8,9,10,13,14,15,17,18,19,20,22,24,25,26,27,28],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/contrib/auth/checks.py":[1,2,4,5,6,8,11,97,12,13,26,29,39,50,74,84,94,98,99,103,104,105,107,108,109,113,112,115,129,130,132,143,154,164,166],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/contrib/auth/management/__init__.py":[3,4,5,7,8,9,10,13,22,36,85,100,37,40,41,42,43,44,48,53,55,56,59,61,62,17,27,28,29,30,31,33,18,19,63,68,69,71,75,76,77,79,80],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/contrib/contenttypes/__init__.py":[1],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/contrib/contenttypes/apps.py":[1,2,5,6,7,9,14,15,16,18,19,20,21,22],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/contrib/contenttypes/checks.py":[1,3,4,7,24,8,10,11,14,16,19,17,20,21,25,26,29,30,31,41],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/contrib/contenttypes/management/__init__.py":[1,2,3,6,7,13,38,41,45,87,104,50,54,55,59,61,63,64,74,76,77,78,83,108,111,112,113,114,118,88,91,93,95,97,99,101,120,124,128,129,131,132,121],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/db/migrations/__init__.py":[1,2],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/db/migrations/migration.py":[1,3,6,21,24,28,33,38,45,49,51,60,67,70,73,76,90,127,179,183,185,191,193,186,187,188,52,53,55,56,57,58,71,74,82,83,86,87,88,99,102,113,114,116,117,124,125],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/db/migrations/exceptions.py":[1,4,5,6,9,10,11,14,15,16,19,20,21,24,25,26,29,30,31,34,35,37,42,45,49,50,53,54],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/db/migrations/operations/__init__.py":[1,2,7,10,11,12,13,14],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/db/migrations/operations/fields.py":[1,2,3,5,6,9,10,14,18,22,25,28,31,34,41,42,44,49,63,75,89,94,97,120,121,123,134,147,152,158,162,166,168,173,187,208,220,223,226,241,242,244,249,253,257,269,324,334,344,347,353,169,170,171,11,12,45,46,47,245,246,247,188,192,194,196,16,195,203,204,206,135,136,137,138,139,141,142,144,145,65,69,70,72,73,66,67,270,272,273,274,275,276,280,281,288,289,290,277,278,292,297,298,299,305,306,307,308,309,310,311,313,314,316,317,318,319,320,322,282,283,284,301,302,189,190,209,210,211,212,213,214,216,217,76,77,78,79,80,82,83,84,86],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/db/migrations/operations/base.py":[1,2,5,19,23,26,30,33,35,37,43,55,62,69,77,83,95,104,116,128,136,39,40,41,129,131,132,111,114],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/db/migrations/operations/utils.py":[1,2,3,4,5,6,7,9,8],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/db/migrations/operations/models.py":[1,2,3,4,5,7,12,22,23,26,30,33,40,41,43,45,61,78,88,93,98,101,123,133,224,225,227,237,240,245,250,254,255,257,262,266,270,281,322,373,382,388,391,408,409,411,415,426,430,448,451,457,463,464,470,471,479,483,484,486,491,502,507,517,520,529,533,537,538,540,545,556,561,571,574,583,587,588,590,594,605,610,628,631,640,644,649,653,654,655,656,657,658,659,660,661,662,663,666,670,681,689,692,695,699,700,702,704,708,715,720,723,726,730,731,733,738,739,741,750,757,762,767,778,786,787,789,793,799,806,813,824,46,47,48,49,50,24,53,13,14,15,19,54,55,57,59,487,488,489,667,668,258,259,260,79,80,81,82,83,84,85,503,28,504,505,682,683,684,685,686,687,238,283,264,284,285,268,287,288,289,290,291,292,293,294,295,311,314,296,297,299,302,303,304,305,307,317,319,320,89,90,91,508,509,510,511,512,513,514,690],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/db/migrations/state.py":[1,2,3,5,6,7,8,9,10,11,12,13,14,15,17,20,28,47,58,80,85,87,93,99,107,155,160,167,193,204,208,212,217,226,230,231,233,235,242,246,250,251,280,292,318,330,340,348,357,359,395,399,400,526,539,553,576,582,588,591,88,90,91,360,361,362,363,364,365,366,368,370,372,377,382,388,94,397,95,96,156,100,101,541,542,543,544,548,549,550,161,210,257,258,259,260,263,264,236,240,265,243,269,271,297,300,284,285,286,287,301,302,303,304,305,306,556,557,559,560,561,562,567,568,569,572,529,530,531,532,536,537,574,331,332,336,337,338,309,316,289,290,274,275,276,277,195,196,197,199,200,320,298,321,322,324,325,327,328,201,202,97,157,108,111,113,114,115,116,126,129,130,131,138,139,151,153,158,169,170,171,341,342,344,345,173,177,182,183,184,188,191,132,134,21,22,23,135,140,141,145,148,69,70,31,34,35,36,41,42,44,71,77,343,109,120,121,52,54,37,38,146,185,186,123,72,73,75,76,74,205,206],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/db/migrations/operations/special.py":[1,3,6,12,14,16,20,32,36,44,59,63,69,70,72,79,95,99,103,107,113,116,133,136,138,140,156,172,176,181,192,198,201,141,143,145,147,150,152,153,154,148,179],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/contrib/sessions/__init__.py":[1],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/contrib/sessions/apps.py":[1,2,5,6,7],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/contrib/messages/apps.py":[1,2,5,6,7],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/contrib/staticfiles/__init__.py":[1],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/contrib/staticfiles/apps.py":[1,2,3,4,7,8,9,10,12,13],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/contrib/staticfiles/checks.py":[1,4,6,7,8,9,13,10,11,14],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/contrib/staticfiles/finders.py":[1,2,3,5,6,7,8,9,10,13,14,15,18,21,24,25,31,40,48,52,53,71,90,105,119,129,133,134,135,137,155,164,180,193,197,198,200,212,230,238,241,242,244,253,275,280,276,277,286,287,290,55,57,58,59,62,63,64,65,66,67,68,69,72,73,79,80,82,88,139,141,142,143,146,147,148,149,150,151,152,153,26,27],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/contrib/staticfiles/utils.py":[1,2,4,5,8,16,38],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/contrib/sites/__init__.py":[1],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/contrib/sites/apps.py":[1,2,3,5,8,9,10,12,13],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/contrib/sites/management.py":[3,5,6,7,8,11,12,13,17,20],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/graphene_django/__init__.py":[1,2,4,6],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/graphene_django/types.py":[1,3,4,5,6,7,9,10,11,14,35,36,37,38,40,43,44,47,48,49,50,51,52,53,54,55,56,57,114,117,130],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/graphene/__init__.py":[1,3,32,41,42,45,47,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,87],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/graphene/pyutils/__init__.py":[1],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/graphene/pyutils/version.py":[1,3,4,5,8,33,40,53,61,10,44,47,48,50,17,35,36,37,19,20,26,30],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/graphene/types/__init__.py":[2,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,23,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,54],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/graphql/__init__.py":[23,24,27,30,90,106,115,118,121,161,171,172,266],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/graphql/pyutils/__init__.py":[1],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/graphql/pyutils/version.py":[1,3,4,5,8,33,40,53,61,10,44,47,48,50,17,35,36,37,19,20,26,30],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/graphql/graphql.py":[1,2,4,38,55,76],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/graphql/execution/__init__.py":[20,21,22,23,27,28,29,30,31,32],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/graphql/execution/executor.py":[1,2,3,4,5,6,8,9,11,12,13,14,15,25,35,36,45,48,66,156,182,227,262,312,367,438,458,495,571,605,627,676,689,714],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/__init__.py":[1,2,9,10,14,15,25,26,27,28,31,32,33,35,36],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/core/__init__.py":[2,4,5,6,7,8,15,16,17,18,20,21,22],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/core/py3/__init__.py":[1],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/core/py3/observer.py":[1,4,5,9,13],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/core/py3/observable.py":[1,4,5],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/core/py3/disposable.py":[1,4,5,7,11,15],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/core/py3/scheduler.py":[1,4,5,6,10,11,14,15,18,19],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/core/observerbase.py":[1,3,4,7,11,13,16,21,25,35,39,46,50,57],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/internal/__init__.py":[1,2,3,4,5,6,7],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/internal/priorityqueue.py":[1,3,4,7,8,10,16,21,28,36,43,50,11,12,14],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/internal/exceptions.py":[4,5,9,10,14,15,19,20,24,25,29,30,34,35],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/internal/basic.py":[1,5,10,15,19,23,27,31],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/internal/extensionmethod.py":[1,39,14,36,20,21,25,27,28,34,35,51,22,23,29,32,30],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/internal/enumerable.py":[1,3,6,8,11,14,17,21,34,47,48,53,54],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/internal/enumerator.py":[1,2,4,7,11,13],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/internal/concurrency.py":[2,3,5,8,12,17,18,21,24,27,31,32,35,38,41,44],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/core/observablebase.py":[1,2,4,5,7,8,9,12,13,15,22,90],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/concurrency/__init__.py":[1,3,4,6,7,8,9,10,13,14,15,17,18,19,20,21,22,23,24,25,26],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/concurrency/scheduleditem.py":[1,4,8,9,16,20,26,29,32,35],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/disposables/__init__.py":[1,2,3,4,5,6,7,8],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/disposables/anonymousdisposable.py":[1,2,3,6,7,9,25,37,41],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/disposables/booleandisposable.py":[1,2,5,6,8,16],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/disposables/compositedisposable.py":[1,2,5,6,8,18,35,53,68,79,90,93,96],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/disposables/singleassignmentdisposable.py":[1,2,5,9,11,21,24,42,44],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/disposables/multipleassignmentdisposable.py":[1,2,5,7,9,16,19,33,35],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/disposables/serialdisposable.py":[1,2,5,8,10,17,20,39,41],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/disposables/refcountdisposable.py":[1,2,5,8,10,12,17,23,35,53,67],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/disposables/scheduleddisposable.py":[1,2,5,7,9,20],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/concurrency/immediatescheduler.py":[1,3,4,5,8,9,14,23,30],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/concurrency/schedulerbase.py":[1,3,4,5,8,11,13,20,48,57,69,80,91],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/concurrency/currentthreadscheduler.py":[2,3,4,5,7,8,9,11,12,14,17,18,34,37,39,46,52,75,81,87,93,95,105,112,43,44],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/concurrency/virtualtimescheduler.py":[1,3,5,6,7,9,12,14,16,32,38,43,55,62,66,83,88,123,137,150,160],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/concurrency/scheduleperiodic.py":[1,4,7,9,22,33],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/concurrency/timeoutscheduler.py":[1,2,3,5,6,8,10,13,14,16,31,55,61,69],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/concurrency/newthreadscheduler.py":[1,2,3,5,6,7,9,12,14,16,26,32,38,43,69,17,19,24],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/concurrency/eventloopscheduler.py":[1,2,3,5,6,7,8,9,11,13,16,18,20,40,55,60,79,102,110,159,171,180,21,22,24,29,30,31,32,33,34,35,36,38],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/concurrency/threadpoolscheduler.py":[1,3,5,8,9,11,12,14,19,22,25,29,32,26,27],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/concurrency/historicalscheduler.py":[1,2,5,7,9,26,33,45,51],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/concurrency/catchscheduler.py":[1,2,4,7,8,21,24,29,34,39,42,54,64],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/concurrency/mainloopscheduler/__init__.py":[1,2,3,4,5,6,7,8,9,10],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/concurrency/mainloopscheduler/asyncioscheduler.py":[1,2,4,5,6,8,11,12,14,21,35,63,80],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/concurrency/mainloopscheduler/ioloopscheduler.py":[1,3,4,5,7,10,13,15,19,37,65,78],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/concurrency/mainloopscheduler/geventscheduler.py":[1,3,5,6,7,9,12,16,18,24,39,68,81],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/concurrency/mainloopscheduler/gtkscheduler.py":[1,2,3,6,11,13,44,48,57,68],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/concurrency/mainloopscheduler/twistedscheduler.py":[1,3,4,5,7,10,11,13,16,21,50,63],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/concurrency/mainloopscheduler/tkinterscheduler.py":[1,2,3,6,10,12,15,20,44],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/concurrency/mainloopscheduler/pygamescheduler.py":[1,2,4,6,7,8,10,13,17,19,28,34,45,62,74],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/concurrency/mainloopscheduler/qtscheduler.py":[1,3,4,5,7,10,11,13,17,46,50,61,74],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/concurrency/mainloopscheduler/wxscheduler.py":[1,3,4,5,7,10,12,14,29,38,70,74,85,98],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/concurrency/mainloopscheduler/eventletscheduler.py":[1,3,5,6,7,9,12,16,18,24,39,68,81],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/core/anonymousobserver.py":[1,2,5,6,13,16,19],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/core/autodetachobserver.py":[1,3,6,8,14,21,27,33,36,38],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/core/anonymousobservable.py":[1,4,6,8,19],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/core/checkedobserver.py":[1,2,3,6,8,12,19,26,33,47],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/core/observerextensions.py":[1,3,4,7,21],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/core/disposableextensions.py":[1,2,3,6,11],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/backpressure/__init__.py":[1,2,3,4,5,6,7],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/backpressure/controlledobservable.py":[1,2,4,7,9,15,18,24,25],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/backpressure/controlledsubject.py":[1,2,3,4,5,8,9,22,25,34,44,53,66,86],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/subjects/__init__.py":[1,2,3,4],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/subjects/subject.py":[1,2,3,5,6,9,12,14,24,28,42,57,77,94,101],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/subjects/anonymoussubject.py":[1,4,5,11,14,17,20],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/subjects/innersubscription.py":[1,4,5,11],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/subjects/behaviorsubject.py":[1,2,3,5,8,12,14,34,38,56,71,86,98],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/subjects/replaysubject.py":[1,2,4,5,6,7,8,11,12,16,22,26,28,52,56,76,83,101,122,140],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/core/scheduledobserver.py":[1,2,4,7,8,23,28,33,38,49,69],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/subjects/asyncsubject.py":[1,2,3,5,8,11,13,28,32,53,77,92,99],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/core/notification.py":[1,2,3,5,8,9,11,15,34,57,63,67,68,70,78,81,84,88,89,91,98,101,104,108,109,111,117,120,123,126,149],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/backpressure/pausable.py":[2,3,4,5,8,9,20,35,38,42],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/backpressure/pausablebuffered.py":[1,2,3,4,7,56,58,69,113,116,120],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/backpressure/stopandwait.py":[1,3,4,7],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/backpressure/stopandwaitobservable.py":[1,3,4,7,9,18,24,30,39,48,50,56],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/internal/utils.py":[1,3,4,6,9,16,75,80,84,86,91,93],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/backpressure/windowed.py":[1,3,4,7],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/backpressure/windowedobservable.py":[1,3,4,5,6,9,10,20,24,28,37,50,51,59],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/linq/__init__.py":[1,2],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/linq/observable/__init__.py":[1,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,140],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/linq/observable/all.py":[1,2,5],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/linq/observable/amb.py":[1,2,3,6,83],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/linq/observable/and_.py":[1,2,4,7],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/joins/__init__.py":[1,2],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/joins/pattern.py":[1,3,4,9,23,37],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/joins/plan.py":[1,2,5,6,10,36],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/joins/activeplan.py":[1,2,10,14],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/joins/joinobserver.py":[1,2,5,7,17,28,31,34,37,40,45],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/linq/observable/some.py":[1,2,5,6],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/linq/observable/asobservable.py":[1,2,5],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/linq/observable/average.py":[1,2,5,7,12,13],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/linq/observable/buffer.py":[1,2,5,6,23,24],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/linq/observable/bufferwithtime.py":[1,2,3,6,7],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/linq/observable/bufferwithtimeorcount.py":[1,2,3,6,7],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/linq/observable/case.py":[1,2,5,6],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/linq/observable/catch.py":[1,2,4,5,6,9,37,38,62],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/linq/observable/concat.py":[1,2,3,4,5,8,28,37,48,60,112],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/linq/observable/contains.py":[1,2,3,5,6],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/linq/observable/combinelatest.py":[1,2,3,6,32],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/linq/observable/count.py":[1,2,5,6],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/linq/observable/create.py":[1,2,5],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/linq/observable/debounce.py":[1,2,4,5,8,9,70],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/linq/observable/defaultifempty.py":[1,2,5,6],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/linq/observable/defer.py":[1,2,5],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/linq/observable/delay.py":[1,2,4,5,6,7,9,12,13,18,93,101,102],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/linq/observable/delaysubscription.py":[1,2,3,6,7],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/linq/observable/delaywithselector.py":[1,2,4,7,9],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/linq/observable/dematerialize.py":[1,2,5],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/linq/observable/distinct.py":[1,2,3,6,12,13,17,23,24],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/linq/observable/distinctuntilchanged.py":[1,2,3,6,7],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/linq/observable/doaction.py":[1,2,3,6,8,81,103,117,140,172,201],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/linq/observable/dowhile.py":[1,2,5],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/linq/observable/elementat.py":[1,2,4,7],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/linq/observable/elementatordefault.py":[1,2,3,7,36,37],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/linq/observable/empty.py":[1,2,3,6,7],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/linq/observable/exclusive.py":[1,3,4,7],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/linq/observable/expand.py":[1,3,5,6,9,10],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/linq/observable/finallyaction.py":[1,2,5],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/linq/observable/find.py":[1,2,5,30],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/linq/observable/findindex.py":[1,2,4,7],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/linq/observable/first.py":[1,2,4,7,8],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/linq/observable/firstordefault.py":[1,2,3,5,22,23],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/linq/observable/forin.py":[1,2,3,6],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/linq/observable/fromiterable.py":[1,2,3,4,5,8,9],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/linq/observable/fromcallback.py":[1,2,5,6],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/linq/observable/fromfuture.py":[1,2,3,6],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/linq/observable/generate.py":[1,2,3,4,7,8],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/linq/observable/generatewithrelativetime.py":[1,2,3,4,7,10],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/linq/observable/groupby.py":[1,2,5,7],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/linq/observable/groupbyuntil.py":[1,3,4,5,7,8,9,12,14],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/linq/groupedobservable.py":[1,2,3,6,7,16],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/linq/observable/groupjoin.py":[1,2,4,5,6,8,9,11,14],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/linq/observable/ifthen.py":[1,2,5,6],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/linq/observable/ignoreelements.py":[1,2,3,6],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/linq/observable/interval.py":[1,2,3,6,7],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/linq/observable/isempty.py":[1,2,4],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/linq/observable/join.py":[1,2,4,5,6,7,9,12],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/linq/observable/last.py":[1,2,4,7,8],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/linq/observable/lastordefault.py":[1,2,3,6,26,27],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/linq/observable/let.py":[1,2,5],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/linq/observable/manyselect.py":[1,2,3,4,5,6,7,10,12,22,27,30,33,38,39],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/linq/observable/materialize.py":[1,2,3,6],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/linq/observable/merge.py":[1,2,3,4,7,73,104],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/linq/observable/max.py":[1,2,3,5,8,9],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/linq/observable/min.py":[1,2,3,4,7,14,15],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/linq/observable/maxby.py":[1,2,3,5,7,8],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/linq/observable/minby.py":[1,2,3,5,46,47],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/linq/observable/multicast.py":[1,2,3,4,7,8],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/linq/connectableobservable.py":[1,2,3,6,7,9,17,20,34,61],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/linq/observable/never.py":[1,2,5],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/linq/observable/observeon.py":[1,2,3,6],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/core/observeonobserver.py":[1,4,5,8,12,16],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/linq/observable/onerrorresumenext.py":[1,2,4,5,8,26],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/linq/observable/of.py":[1,2,5],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/linq/observable/pairwise.py":[1,2,5],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/linq/observable/partition.py":[1,2,3,6],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/linq/observable/pluck.py":[1,2,5,22],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/linq/observable/publish.py":[1,2,3,6,7,33],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/linq/observable/publishvalue.py":[1,2,3,6,7],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/linq/observable/range.py":[1,2,3,4,7,8],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/linq/observable/reduce.py":[1,2,5,6],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/linq/observable/repeat.py":[1,2,3,4,7,8,25,38,39],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/linq/observable/replay.py":[1,2,3,6,7],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/linq/observable/retry.py":[1,2,3,6,7],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/linq/observable/returnvalue.py":[1,3,4,7,8,37,38],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/linq/observable/scan.py":[1,2,5,6],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/linq/observable/sample.py":[1,2,3,4,7,36,37],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/linq/observable/select.py":[1,2,3,6],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/linq/observable/selectswitch.py":[1,2,5],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/linq/observable/selectmany.py":[1,2,3,4,7,19,20],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/linq/observable/sequenceequal.py":[1,3,4,5,6,9,10],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/linq/observable/single.py":[1,2,4,7,8],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/linq/observable/singleordefault.py":[1,2,3,5,28],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/linq/observable/skip.py":[1,2,3,6],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/linq/observable/skiplast.py":[1,2,5],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/linq/observable/skiplastwithtime.py":[1,2,3,6,7],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/linq/observable/skipuntil.py":[1,2,3,6],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/linq/observable/skipuntilwithtime.py":[1,3,4,5,6,9,10],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/linq/observable/skipwhile.py":[1,2,3,6],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/linq/observable/skipwithtime.py":[1,2,3,4,6,7],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/linq/observable/slice.py":[1,2,5,6,61],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/linq/observable/start.py":[1,2,5,6],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/linq/observable/startasync.py":[1,2,5],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/linq/observable/startswith.py":[1,3,4,7],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/linq/observable/statistics.py":[1,2,3,6,18,26,39,54],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/linq/observable/subscribeon.py":[1,2,3,6],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/linq/observable/sum.py":[1,2,5,6],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/linq/observable/switchlatest.py":[1,2,4,7],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/linq/observable/take.py":[1,2,3,6,7],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/linq/observable/takelast.py":[1,2,5],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/linq/observable/takelastbuffer.py":[1,2,5],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/linq/observable/takelastwithtime.py":[1,2,3,6,7],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/linq/observable/takeuntil.py":[1,2,3,4,7],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/linq/observable/takeuntilwithtime.py":[1,3,4,5,6,8,9],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/linq/observable/takewhile.py":[1,2,3,6],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/linq/observable/takewithtime.py":[1,2,3,4,7,8],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/linq/observable/thendo.py":[1,2,4,6],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/linq/observable/throttlefirst.py":[1,2,3,6,7],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/linq/observable/throw.py":[1,3,4,7,8],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/linq/observable/timeinterval.py":[1,2,3,4,7,8],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/linq/observable/timer.py":[1,2,4,5,6,7,9,12,22,45,57,73,74],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/linq/observable/timeout.py":[1,3,4,6,7,10,11],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/linq/observable/timeoutwithselector.py":[1,2,4,7,9],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/linq/observable/timestamp.py":[1,3,4,5,6,8,11,12],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/linq/observable/toasync.py":[1,2,3,4,7,8],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/linq/observable/toblocking.py":[1,2,3,6],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/core/blockingobservable.py":[1,4,5,18],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/linq/observable/todict.py":[1,2,4,33,34],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/linq/observable/tofuture.py":[1,2,3,6,7,52],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/linq/observable/toiterable.py":[1,2,5],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/linq/observable/tolist.py":[1,2,5,20,21],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/linq/observable/toset.py":[1,2,4,16],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/linq/observable/transduce.py":[15,17,18,21,23,25,28,31,34,37,41],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/linq/observable/using.py":[1,2,3,6],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/linq/observable/when.py":[1,2,3,6],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/linq/observable/where.py":[1,2,3,6],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/linq/observable/whiledo.py":[1,3,4,7],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/linq/observable/window.py":[1,3,4,5,6,8,9,11,14,15,44,47,79],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/linq/observable/windowwithcount.py":[1,3,4,5,6,7,8,10,13,14],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/linq/observable/windowwithtime.py":[1,3,4,5,6,8,9,12,13],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/linq/observable/windowwithtimeorcount.py":[1,2,3,4,6,7,10,11],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/linq/observable/withlatestfrom.py":[1,2,3,6,10,36],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/linq/observable/zip.py":[1,2,3,6,72,93],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/linq/observable/ziparray.py":[1,2,5],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/linq/observable/blocking/__init__.py":[1,2,3,4],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/linq/observable/blocking/foreach.py":[1,2,3,4,7],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/linq/observable/blocking/toiterable.py":[1,2,3,4,7,51],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/linq/observable/blocking/first.py":[1,3,6,21],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/linq/observable/blocking/last.py":[1,3,6,31],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/linq/enumerable/__init__.py":[1],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/rx/linq/enumerable/whiledo.py":[1,2,4],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/six.py":[21,23,25,26,27,28,29,31,32,36,37,38,40,41,42,43,44,45,47,75,80,86,88,91,103,105,114,117,124,126,130,136,139,141,159,164,171,173,177,181,184,189,195,209,218,224,226,174,175,229,231,232,236,142,89,143,144,146,147,148,151,152,237,238,239,240,149,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,106,107,108,109,110,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,305,310,311,312,313,178,179,314,316,318,127,128,319,322,324,328,329,330,331,332,333,334,335,336,337,338,339,340,341,342,343,344,345,346,347,348,349,350,351,352,354,355,356,358,360,361,364,366,370,371,372,374,375,376,378,380,381,384,386,390,391,392,393,394,395,396,397,398,399,400,401,402,403,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,422,423,424,426,427,428,430,432,433,436,438,442,443,444,445,447,448,449,451,453,454,457,459,463,465,466,467,469,471,472,475,477,478,479,182,480,481,482,483,485,488,489,492,497,508,509,510,512,513,514,515,526,527,531,534,535,541,542,545,547,550,567,568,77,571,572,573,574,575,576,579,580,583,586,589,592,594,596,616,617,618,619,620,621,624,625,628,630,631,632,633,634,635,636,637,638,639,640,641,645,646,668,669,672,676,680,684,685,92,115,82,83,93,94,97,100,687,719,728,729,734,740,741,795,805,807,816,819,835,853,872,892,912,933,934,935,936,940,941,946,947,950,952,185,187,837,850,838,839,840,841,843,845,846,847,848,849,824,826,829,832,831,827,844,186,216,190,191,196,198,199,200,201,202,205,206,207,160,161,626],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/promise/__init__.py":[1,4,8,9,10,13,15,17,18,27,30,31,32,33,34,35,36,37],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/promise/pyutils/__init__.py":[1],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/promise/pyutils/version.py":[1,3,4,5,8,33,40,55,63,10,44,49,50,52,17,35,36,37,19,20,26,30],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/promise/promise.py":[1,2,3,4,5,7,8,9,15,16,17,18,40,42,45,50,55,56,58,59,61,62,63,65,68,72,73,74,77,82,91,92,95,99,106,107,108,109,110,111,112,113,114,115,116,117,119,120,122,150,155,165,169,171,172,174,179,180,182,187,215,227,242,263,269,279,288,296,304,332,343,353,361,369,377,385,392,436,443,449,455,471,497,498,502,506,512,516,517,519,538,544,550,556,567,596,597,598,600,630,635,655,685,714,723,725,737,738,740,760,762,777,782,802,820,823,832,833,834,837,743,749,758],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/promise/async_.py":[2,9,10,17,20,23,26,30,35,40,46,53,60,68,70,81,99,118,126,132,11,12,13,14,15],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/promise/compat.py":[1,2,9,10,27,28],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/promise/iterate_promise.py":[7],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/promise/utils.py":[1,2,3,4,5,8,15,16,22,42,43,45,46,47,48,49,50,17,19,20,23,24,32,34,39],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/promise/promise_list.py":[1,2,17,19,21,38,42,54,71,108,122,132,137,144],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/promise/schedulers/__init__.py":[1],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/promise/schedulers/immediate.py":[1,8,9,16],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/graphql/error/__init__.py":[1,2,3,4,6],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/graphql/error/base.py":[1,2,12,21,32,45,55,66,73],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/graphql/language/__init__.py":[1],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/graphql/language/location.py":[6,9,10,12,17,21,30],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/graphql/error/located_error.py":[1,3,10,13,18],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/graphql/error/syntax_error.py":[1,2,9,12,13,29],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/graphql/error/format_error.py":[1,3,10],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/graphql/pyutils/default_ordered_dict.py":[1,2,9,10,13,21,28,35,38,41,44],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/graphql/pyutils/ordereddict.py":[1,4,5,6,8],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/graphql/utils/__init__.py":[1],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/graphql/utils/undefined.py":[1,2,4,8,10,15],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/graphql/type/__init__.py":[2,24,37,44,46],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/graphql/type/definition.py":[1,2,4,5,6,7,8,9,16,33,41,56,61,69,73,79,88,89,92,93,95,99,103,108,112,127,129,137,162,167,192,200,218,223,229,262,297,298,306,315,325,329,334,335,342,350,359,363,376,383,399,405,422,429,445,452,484,502,504,512,515,518,530,539,546,551,556,584,585,588,595,599,609,629,636,648,652,657,677,678,685,693,702,719,721,723,730,734,740,756,758,760,770,774,140,141,142,143,145,151,152,153,158,159,160,765,18,19,21,22,23,24,25,26,27,28,766,768,345,346,347,348,35,81,82,83,85,36,37,203,204,205,206,208,213,214,215,216,590,591,592,593,505,506,507,508,510,558,563,564,567,568,569,570,574,575,576,579,581,309,310,311,312,313],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/graphql/language/ast.py":[10,11,12,13,16,17,20,21,22,24,29,38,42,46,51,58,65,76,86,99,111,122,127,128,129,131,138,149,159,163,168,169,170,172,177,186,190,194,199,200,203,204,205,214,224,237,249,260,265,266,267,269,275,285,291,295,300,301,302,308,315,325,334,338,343,344,345,352,360,371,381,387,392,393,394,402,411,423,434,444,449,450,453,454,455,457,462,470,474,478,483,484,485,487,492,501,505,509,514,515,516,518,523,532,536,540,545,546,547,549,554,563,567,571,576,577,578,580,585,594,598,602,607,608,609,611,616,625,629,633,638,639,640,642,647,656,660,664,669,670,671,673,678,687,691,695,700,701,702,704,710,720,726,730,735,736,737,743,750,760,766,770,775,776,779,780,781,783,788,797,801,805,810,811,812,814,819,828,832,836,841,842,843,845,850,859,863,867,872,873,874,876,881,890,894,898,906,907,910,911,914,915,916,922,929,937,946,950,955,956,957,959,965,973,982,986,991,992,993,1001,1010,1022,1033,1039,1044,1045,1046,1054,1063,1075,1085,1091,1096,1097,1098,1106,1115,1127,1138,1144,1149,1150,1151,1158,1166,1177,1187,1191,1196,1197,1198,1205,1213,1224,1234,1238,1243,1244,1245,1251,1258,1268,1277,1281,1286,1287,1288,1295,1303,1314,1324,1328,1333,1334,1335,1341,1348,1358,1367,1371,1376,1377,1378,1385,1393,1404,1414,1418,1423,1424,1425,1427,1432,1441,1447,1451,1456,1457,1458,1465,1473,1484,1493,1497],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/graphql/pyutils/cached_property.py":[6,12,14,18,15,16],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/graphql/pyutils/compat.py":[21,23,24,25,27,28,36,37,39,40,41,42,43,44,53,54,61,64,65,72,73,81,83,86,89,92,111,113,116,119,121,122,138,139,141,177,188,189,195,203,204,205,206,207,208,209,219,226],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/graphql/utils/assert_valid_name.py":[1,3,4,7,10,11,13],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/graphql/type/directives.py":[1,3,4,5,6,9,11,12,13,14,15,16,17,20,21,22,23,24,25,26,27,28,29,30,32,34,36,39,40,42,68,69,70,72,73,77,78,79,43,44,45,46,49,50,51,53,54,55,57,58,59,60,64,84,85,86,88,89,93,94,95,100,103,104,105,107,108,110,114,117,121,122,123],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/graphql/type/scalars.py":[1,3,4,15,16,19,36,45,46,47,51,52,53,57,64,71,72,73,76,77,78,82,93,101,109,110,111,114,115,116,120,127,128,129,130,131,132,136,143,144,145,150,151,152],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/graphql/type/schema.py":[1,3,4,5,6,19,42,51,60,103,107,111,115,119,124,128,136,140],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/graphql/type/introspection.py":[1,3,4,5,18,19,27,28,29,33,48,49,50,53,105,106,107,109,110,111,117,171,172,175,177,180,181,182,183,187,188,189,190,194,195,196,197,201,202,203,207,208,209,210,214,215,216,217,221,222,223,224,228,229,230,231,235,236,237,238,242,243,244,245,249,250,251,252,256,257,258,259,263,264,265,266,270,271,272,273,277,278,279,280,284,285,286,287,291,292,293,294,298,299,300,301,309,310,311,312,313,314,315,316,317,320,322,323,324,325,326,327,328,329,332,345,349,370,377,387,391,402,409,410,411,419,486,487,488,490,522,523,524,527,545,546,547,550,572,573,574,575,578,579,580,584,585,586,587,592,593,594,595,600,601,602,603,608,609,610,611,616,617,618,619,624,625,626,627,632,633,634,635,643,645,647,648,649,650,653,654,656,657,658,661,662,664,665,666],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/graphql/language/printer.py":[1,3,47,50,55,56,58,62,66,70,83,87,91,104,110,114,126,136,140,143,147,151,155,159,163,169,175,179,183,189,195,199,203,216,226,236,246,256,266,270,280,284,293,300,308,315],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/graphql/language/visitor.py":[1,3,5,6,17,18,21,26,27,30,31,34,35,37,46,176,177,178,180,194,209,210,212,220,240,261,262,264,269,286],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/graphql/language/visitor_meta.py":[1,4,5,6,10,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,47,50,51,52,53,55,56,59,62,63,68,73,74,75,76,77,57,60,69,70,71,64,65,66],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/graphql/utils/ast_from_value.py":[1,2,3,5,7,8,14,17],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/graphql/type/typemap.py":[1,2,4,5,24,25,46,55,75,143],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/graphql/utils/type_comparators.py":[1,23,36,69],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/graphql/execution/base.py":[2,13,14,24,27,29,31,42,51,66,78,93,110,111,112,113,114,115,116,117,118,119,120],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/graphql/execution/utils.py":[2,3,5,6,7,8,9,10,15,16,35,38,42,56,59,130,136,146,154,174,175,177,182,186,191,220,281,319,339,347,358],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/graphql/utils/type_from_ast.py":[1,2,12],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/graphql/execution/values.py":[1,2,4,6,7,8,9,17,18,19,28,31,89,148],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/graphql/utils/is_valid_value.py":[3,5,6,8,10,22,25],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/graphql/utils/value_from_ast.py":[1,2,17],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/graphql/execution/executors/__init__.py":[1],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/graphql/execution/executors/sync.py":[6,7,11,14],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/graphql/execution/middleware.py":[1,2,3,5,12,15,20,23,32,44,47,58,73],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/graphql/backend/__init__.py":[5,7,8,9,10,16,19,27,37,38,39,40,41,42,43],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/graphql/backend/base.py":[1,2,4,5,15,16,23,24,31,49],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/graphql/backend/core.py":[1,2,4,5,6,7,9,21,37,39,41,45],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/graphql/language/base.py":[1,2,3,4,5,6,9,10,11,12,13,14,15,16,17,18],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/graphql/language/lexer.py":[1,3,5,12,15,16,18,25,31,42,43,45,50,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,81,89,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,117,126,127,128,129,130,131,132,133,134,135,136,137,141,152,201,204,206,207,209,210,212,217,246,304,328,329,330,331,332,333,334,335,339,420,434,451],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/graphql/language/parser.py":[1,3,4,5,6,51,54,69,81,82,84,93,94,96,102,107,116,129,137,143,155,174,191,201,215,229,239,252,281,310,324,334,348,356,365,373,398,406,420,446,462,470,518,523,528,539,551,564,572,585,604,610,662,676,687,699,714,729,742,750,765,780,793,806,821,832,845,855,871],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/graphql/language/source.py":[1,4,5,7,12],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/graphql/validation/__init__.py":[1,2,4],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/graphql/validation/validation.py":[1,2,3,4,5,27,36,44,45,47,52,53,55,60,63,68,78,81,93,96,100,104,115,128,150,167,170,179,183,187,191,195,199],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/graphql/utils/type_info.py":[1,3,4,11,12,39,46,47,56,59,70,76,82,88,94,98,102,109,116,124,133,136,148,158,160,163,175,181,190,194,199,202,206,207,209,212,217,221],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/graphql/utils/get_field_def.py":[1,2,16],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/graphql/validation/rules/__init__.py":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/graphql/validation/rules/arguments_of_correct_type.py":[1,2,3,4,12,13,36],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/graphql/utils/is_valid_literal_value.py":[1,2,3,17,20],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/graphql/validation/rules/base.py":[1,8,9,11],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/graphql/validation/rules/default_values_of_correct_type.py":[1,2,3,4,5,13,14,40,51,54,61],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/graphql/validation/rules/fields_on_correct_type.py":[1,3,4,5,6,7,8,15,17,18,20,23,36,37,40,45,47,91,131],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/graphql/utils/quoted_or_list.py":[1,8,11],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/graphql/utils/suggestion_list.py":[1,4,23],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/graphql/validation/rules/fragments_on_composite_types.py":[1,2,3,4,12,13,34,47,51],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/graphql/validation/rules/known_argument_names.py":[1,2,3,4,5,13,23,33,34],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/graphql/validation/rules/known_directives.py":[1,2,3,4,7,8,40,44,52,53,54,58],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/graphql/validation/rules/known_fragment_names.py":[1,2,5,6,15],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/graphql/validation/rules/known_type_names.py":[1,2,3,4,12,20,21,24,27,30,33],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/graphql/validation/rules/lone_anonymous_operation.py":[1,2,3,12,13,15,20,28,42],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/graphql/validation/rules/no_fragment_cycles.py":[1,2,12,13,15,23,34,39,73],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/graphql/validation/rules/no_undefined_variables.py":[1,2,11,12,14,19,20,27,38,62],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/graphql/validation/rules/no_unused_fragments.py":[1,2,11,16,19,25,37,41,59],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/graphql/validation/rules/no_unused_variables.py":[1,2,11,12,14,19,30,57,60],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/graphql/validation/rules/overlapping_fields_can_be_merged.py":[1,2,4,5,6,7,8,16,17,18,36,37,39,52,87,92,100,166,224,271,347,428,462,503,585,608,632,676,693,721,730],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/graphql/pyutils/pair_set.py":[6,7,9,13,16,19,22,36,42],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/graphql/validation/rules/possible_fragment_spreads.py":[1,2,3,4,12,13,37,56,61,67],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/graphql/validation/rules/provided_non_null_arguments.py":[1,2,3,11,12,41,61,67],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/graphql/validation/rules/scalar_leafs.py":[1,2,3,11,12,42,48],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/graphql/validation/rules/unique_argument_names.py":[1,2,11,12,14,19,30,33,55],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/graphql/validation/rules/unique_fragment_names.py":[1,2,11,12,14,19,30,43],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/graphql/validation/rules/unique_input_field_names.py":[1,2,11,12,14,20,32,43,64],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/graphql/validation/rules/unique_operation_names.py":[1,2,11,12,14,19,43,46],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/graphql/validation/rules/unique_variable_names.py":[1,2,11,12,14,19,30,42],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/graphql/validation/rules/variables_are_input_types.py":[1,2,3,4,5,8,9,22],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/graphql/validation/rules/variables_in_allowed_position.py":[1,2,3,4,5,14,15,17,22,33,67,78,85],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/graphql/backend/decider.py":[1,2,3,4,5,8,9,10,18,20,27,28,30,39,44,49,81,104,121,132,136,153,156,158,159,165,166,167,168,189,193,199],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/graphql/backend/cache.py":[1,3,4,6,13,15,18,30,42,44,50,62,71],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/graphql/utils/base.py":[4,7,10,13,16,19,22,25,28,31,35,38,41,44,47,50,53,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/graphql/utils/introspection_query.py":[90],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/graphql/utils/get_operation_ast.py":[1,9],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/graphql/utils/build_client_schema.py":[1,2,3,25,26,37,40,44,48,52],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/graphql/utils/build_ast_schema.py":[1,2,3,4,28,38,41,51,58,66,70,74,338],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/graphql/utils/extend_schema.py":[1,3,4,5,6,20,30,37,38,41,388],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/graphql/utils/schema_printer.py":[1,2,10,11,28,35,40,45,50,55,58,63,83,102,123,128,142,147,152,159,170,178,190,203,213,220],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/graphql/utils/concat_ast.py":[1,3,10],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/graphene/types/objecttype.py":[1,3,4,5,6,9,10,14,15,16,19,25,27,30,31,32,33,66,68,36,37,39,41,47,48,50,55,58,60,61,62,64],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/graphene/types/base.py":[1,2,5,6,7,9,11,14,17,23,27,28,32,33,34,35,36,12,18,19,37,38,39,15,40,41],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/graphene/utils/__init__.py":[1],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/graphene/utils/subclass_with_meta.py":[1,3,5,6,9,10,12,17,21,22,25,54,27,28,29,41,43,44,50,51,52,30,32,33,40,45],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/graphene/pyutils/init_subclass.py":[1,3,23],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/graphene/utils/props.py":[1,2,5,6,9,12,13,14],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/graphene/utils/trim_docstring.py":[1,4,9],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/graphene/types/field.py":[1,2,3,5,6,7,8,9,11,14,21,33,70,74,36,37,41,43,47,48,51,56,60,61,62,63,65,66,67,68],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/graphene/types/argument.py":[1,2,4,5,6,7,10,18,30,34,43,44,45,46,48,51,52,53,54,83],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/graphene/types/dynamic.py":[1,2,4,7,11,13,19],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/graphene/types/mountedtype.py":[1,2,5,6,11,15,16,17,18,19],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/graphene/utils/orderedtype.py":[1,4,5,6,8,11,17,20,26,32,38,9,13,14,15,28,29],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/graphene/types/unmountedtype.py":[1,4,16,18,23,30,33,41,49,57,19,20,21],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/graphene/types/structures.py":[1,2,5,9,11,23,27,35,42,44,47,55,66,68,74,77,69,12,13,21,70],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/graphene/types/utils.py":[1,2,3,5,7,8,9,12,24,41,29,30,31,16,18,32,33,36,37,38,19,21,34],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/graphene/utils/module_loading.py":[1,2,5,45],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/graphene/types/interface.py":[1,3,4,5,8,9,13,14,17,25,27,28,43,50,29,32,33,34,36,37,41],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/graphene/types/mutation.py":[1,3,4,5,6,7,8,11,12,17,18,19,20,23,26,28,30,79,81],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/graphene/utils/deprecated.py":[1,2,3,5,8,12,19,29,43,31,34,36,41],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/graphene/utils/get_unbound_function.py":[1],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/graphene/types/scalars.py":[1,2,4,5,8,9,12,19,21,26,27,28,30,44,45,48,54,56,68,69,71,23,24,79,84,86,94,95,97,103,108,110,116,117,119,125,128,130,131,133,139,146,148,149,151,36],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/graphene/types/datetime.py":[1,3,5,6,8,11,16,18,27,32,40,45,47,54,59,67,72,74,81,86],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/aniso8601/__init__.py":[10,11,12,13],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/aniso8601/time.py":[9,11,12,15,16,18,76,116,131,142,157,185,232,238,254,255,256],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/aniso8601/date.py":[9,11,13,15,86,104,127,143,153,186,204,226,244,245,246,247,248,249],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/aniso8601/exceptions.py":[9,10,12,13,15,16,18,19,21,22,24,25,27,28,30,31,33,34,36,37],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/aniso8601/resolution.py":[9,11,12,14,15],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/aniso8601/compat.py":[9,11,13,16],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/aniso8601/timezone.py":[9,11,13,43,44,55,83,86,89],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/aniso8601/duration.py":[9,11,12,13,14,16,33,84,122,178,199,234,255],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/aniso8601/interval.py":[9,10,11,12,13,15,41,68,143,154],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/graphene/types/json.py":[1,3,5,7,10,11,13,17,22],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/graphene/types/uuid.py":[1,3,5,7,10,11,13,22,27],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/graphene/types/schema.py":[1,3,4,9,10,11,13,14,15,18,28,34,43,64,67,70,73,87,101,104,110,113,116],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/graphene/types/definitions.py":[1,11,15,17,22,23,26,27,30,31,34,35,38,39,42,43],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/graphene/types/typemap.py":[1,2,3,5,17,18,19,21,22,23,32,33,34,35,36,37,38,39,40,41,42,45,54,72,76,77,82,91,119,141,172,206,228,239,262,267,308,331],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/graphene/utils/str_converters.py":[1,6,15,20],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/graphene/types/enum.py":[1,3,5,7,8,9,12,18,21,22,23,26,27,37,40,43,46,53,64,44,65,66,76,28,31,32,33,34],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/graphene/pyutils/compat.py":[1,3,5,7,8,12,20],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/graphene/types/inputobjecttype.py":[1,3,4,5,6,9,10,14,15,16,19,20,21,23,28,32,40,42,43,60],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/graphene/types/inputfield.py":[1,2,3,6,15,27],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/graphene/types/resolver.py":[1,5,9,12,18],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/graphene/types/union.py":[1,2,5,6,11,12,15,22,24,25,34,42],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/graphene/types/context.py":[1,2],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/graphene/types/abstracttype.py":[1,2,5,6],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/graphene/relay/__init__.py":[1,2,3,6,7,8,9,10,11,12],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/graphene/relay/node.py":[1,2,3,5,7,8,9,12,29,30,35,36,41,50,51,64,68,69,70,72,81,82,84,88,92,93,113,117,74,75,76,31,32,33,78],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/graphql_relay/__init__.py":[1,5,10,16,22,24,26,28,30],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/graphql_relay/connection/__init__.py":[1],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/graphql_relay/connection/connection.py":[1,3,13,16,17,18,19,20,24,63,64,65,66],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/graphql_relay/utils.py":[1,3,6,10,14,18],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/graphql_relay/connection/arrayconnection.py":[1,3,4,7,24,34,110,113,117,124,134,145],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/graphql_relay/connection/connectiontypes.py":[1,3,7,14,17,23,32,34,38],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/graphql_relay/node/__init__.py":[1],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/graphql_relay/node/node.py":[1,2,4,6,15,52,60,70],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/graphql_relay/mutation/__init__.py":[1],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/graphql_relay/mutation/mutation.py":[1,2,3,12,13,16],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/graphene/relay/mutation.py":[1,2,4,6,7,10,11,12,14,16,58],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/graphene/relay/connection.py":[1,2,3,5,6,8,9,10,11,14,15,16,17,18,21,22,23,24,27,28,29,32,33,34,38,39,42,43,44,46,47,89,90,97,115,134,147,152],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/graphene/utils/resolve_only_args.py":[1,3,6],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/graphene_django/converter.py":[1,2,4,20,21,22,24,25,26,28,31,40,55,82,83,89,90,91,92,93,94,95,96,97,101,102,106,107,111,112,113,114,115,116,120,121,125,126,130,131,132,133,137,138,142,143,147,148,152,153,169,170,171,172,197,198,199,212,213,220,221,222,226,227],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/graphene_django/compat.py":[1,2,5,8],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/contrib/postgres/__init__.py":[1],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/contrib/postgres/fields/__init__.py":[1,2,3,4,5],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/contrib/postgres/fields/array.py":[1,3,4,5,6,7,8,9,10,12,13,14,16,19,20,22,23,25,27,39,46,51,75,79,83,87,92,102,109,119,132,153,172,185,194,195,196,202,203,204,210,211,212,218,219,220,226,227,228,229,231,240,241,242,258,260,265,269,274,276,280,284,286,291,296,298,302,28,29,30,35,37,76,77,48,49,93,94,95,96,97,98,100,41,42,43,44,52,53,63,64,73],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/contrib/postgres/lookups.py":[1,2,4,7,8,15,16,17,20,21,22,25,26,27,30,31,32,33,36,37,38,40,44,45,46,49,50,51,52,55,56,58,65,66,67,70,71,73],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/contrib/postgres/search.py":[1,2,3,4,7,8,10,17,24,26,30,32,36,37,39,47,48,49,50,51,53,64,73,89,90,95,96,97,99,114,117,120,123,127,128,130,135,144,156,161,165,166,171,172,173,175,186,201,204,205,207,213,214,217,218,219],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/contrib/postgres/forms/__init__.py":[1,2,3,4],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/contrib/postgres/forms/array.py":[1,2,4,5,8,9,11,14,16,19,30,34,39,62,78,94,105,106,108,113,117,121,127,133,154,158,163,168,170,173,181],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/contrib/postgres/validators.py":[1,2,6,7,10,11,12,13,14,17,18,19,20,21,24,26,29,30,32,34,40,58,67,68,70,73,74,76],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/contrib/postgres/utils.py":[1,2,3,6],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/contrib/postgres/forms/hstore.py":[1,3,4,5,7,10,13,14,16,17,20,25,50],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/contrib/postgres/forms/jsonb.py":[1,3,4,6,9,10,13,14,17,19,21,23,43,51,56],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/contrib/postgres/forms/ranges.py":[1,3,4,5,6,9,10,14,16,17,20,29,43,63,64,65,66,69,70,71,72,75,76,77,78,81,82,83,84,87,88,92,21,22,89,90,23,24,25,26,27],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/psycopg2/__init__.py":[18,50,63,68,69,70,75,76,80,81,82,85,120,121,123,126,129,130,131,134],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/psycopg2/tz.py":[6,29,30,32,35,48,49,50,52,54,60,71,76,80,83,95,99,100,101,104,107,111,112,118,124,127,136],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/psycopg2/extensions.py":[12,35,37,44,45,49,50,52,53,60,70,71,72,73,74,75,79,80,81,82,83,84,87,91,92,93,94,98,99,100,101,102,105,111,112,113,117,120,131,135,140,141,144,148,183,184,199,201,202,203,207,211,107,212,219,220,221,223,150,154,159,160,163,166,168,173,174,188,191,192,195,177,179],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/psycopg2/_json.py":[6,30,32,33,37,38,47,48,51,52,55,66,67,78,82,97,100,107,111,117,155,168,181,203,164,165,141,144,145,183,184,187,189,194,195,196,200,147,149,150,152,177,178],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/psycopg2/_range.py":[3,27,29,30,31,34,43,44,46,57,64,69,74,79,86,93,100,107,129,132,139,142,149,165,171,177,183,190,195,226,231,232,234,237,241,244,274,280,281,295,330,386,398,400,402,433,441,446,447,450,451,452,455,456,457,460,461,462,470,471,472,496,502,503,282,283,301,302,306,307,308,309,313,317,318,319,321,322,326,285,287,289,290,291,504,434,435,436,438,506,507,508,510,511,512,514,515,303,304,516,518,519,520,522,523,524,47,48,51,52,53,133,134,235,242,245,250,251,77,254,67,255,256,258,262,72,263,264,266,271,108,111,112,113,119,120,124,127,268,114,125],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/psycopg2/extras.py":[5,28,29,30,31,33,35,36,37,38,39,41,49,54,60,63,64,66,78,87,96,105,123,124,125,130,131,133,138,143,148,155,156,158,160,164,169,174,177,180,183,186,192,196,199,202,205,208,211,216,217,218,219,220,223,224,225,230,237,238,243,248,253,260,261,263,265,273,278,281,286,287,288,293,308,309,311,315,319,323,331,338,345,361,362,367,385,389,391,403,412,419,424,429,435,436,438,444,451,461,462,466,473,478,479,481,485,490,492,497,499,504,512,513,516,517,519,549,556,613,619,624,626,629,633,636,640,674,681,682,685,688,691,697,701,705,738,750,778,793,794,795,798,805,829,840,842,853,855,856,888,897,931,995,1003,1004,1020,1035,1047,1051,1053,1055,1070,1080,1131,1159,1178,1203,1281,650,652,653,654,661,662,663,665,666,667,669,627,634],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/psycopg2/_ipaddress.py":[2,26,30,33,36,65,75,82,88],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/contrib/postgres/fields/mixins.py":[1,4,5,7,26,27,28,8,24,29],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/contrib/postgres/fields/utils.py":[1,2],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/contrib/postgres/fields/citext.py":[1,3,6,8,11,15,16,19,20,23,24],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/contrib/postgres/fields/hstore.py":[1,3,4,5,6,7,9,11,14,15,16,18,20,22,25,31,41,46,49,55,73,74,75,76,77,80,81,83,87,92,94,97,101,102,103,104,105,108,109,110,111,112],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/contrib/postgres/fields/jsonb.py":[1,3,5,6,7,10,12,14,17,20,21,25,30,31,32,34,36,38,44,47,53,59,64,76,79,86,87,88,89,90,91,94,95,96,98,102,120,121,122,123,126,131,132,140,141,144,145,148,149,152,153,156,157,160,161,164,165,168,169,172,173,174,175,176,177,178,179,182,184,187,39,41,42,48,49,51],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/contrib/postgres/fields/ranges.py":[1,2,4,6,7,9,12,13,17,18,20,26,33,38,47,59,63,80,85,86,87,88,90,94,95,96,97,99,103,104,105,106,108,112,113,114,115,117,121,122,123,124,126,130,131,132,135,139,140,142,150,162,163,166,167,169,170,171,172,173,176,187,191,192,193,194,195,198,199,200,201,204,205,206,207,210,211,212,213,216,217,218,219,222,223,224,225,228,229,230,231,233,238,239,240,241,243,248,249,250,251,252,22,23,24,60,61,35,36,28,29,30,31,81,82,48,55,57,39,41,42],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/graphene_django/fields.py":[1,3,5,7,8,9,11,12,15,16,19,23,27,31,32,43,56,60,64,70,78,104,145],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/graphene_django/settings.py":[13,14,16,17,18,20,21,29,30,31,32,35,37,40,41,44,47,61,81,89,91,97,103,123,92,94,95,126,133],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/test/__init__.py":[1,3,4,8,14,15,16,17],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/test/client.py":[1,2,3,4,5,6,7,8,9,10,11,13,14,15,16,17,20,21,22,23,24,25,26,27,28,29,31,34,35,36,38,41,42,43,49,55,56,63,66,77,85,94,113,118,119,123,161,174,223,252,264,265,271,299,303,315,323,334,342,343,351,359,364,370,377,384,391,417,434,435,440,444,457,525,532,533,540,548,556,564,572,579,586,601,613,641,655,665,436,266,267,268,269,437,120,121,438],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/core/handlers/__init__.py":[1],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/core/handlers/base.py":[1,2,4,5,6,7,8,9,11,13,16,17,18,19,20,22,63,70,73,96,160],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/core/handlers/exception.py":[1,2,3,5,6,7,11,12,13,14,15,18,41,105,116],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/core/handlers/wsgi.py":[1,2,3,4,6,7,8,9,10,11,12,14,17,18,19,25,34,46,66,67,100,103,109,114,117,122,128,131,132,134,138,156,163,194,207],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/test/signals.py":[1,2,3,4,6,7,8,9,10,11,12,13,14,16,22,25,32,49,77,83,104,111,123,129,136,145,153,164,174,181],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/test/utils.py":[1,2,3,4,5,6,7,8,9,10,11,12,13,15,16,17,18,19,20,21,22,23,24,25,26,28,29,30,31,38,41,44,45,49,52,56,60,61,70,76,83,90,99,100,103,139,155,199,241,286,300,313,324,325,329,332,335,338,341,361,370,378,384,385,389,407,417,427,437,441,442,452,460,485,490,491,498,509,514,576,580,583,584,587,590,593,596,600,611,619,620,628,633,637,638,665,666,667,672,683,693,708,718,728,741,758,775,776,777,781,785,789,793,794,800,804,819,820,824,830,834,301,302,304,305,308,309,310,108,115,118,119,121,123,125,126,128,129,131,132,134,136,157,253,254,255,256,258,259,260,262,269,270,271,273,275,278,281,204,205,208,211,212,213,214,215,220,222,223,224,227,228,229,230,231,235,237,238,282,283,159,161,162,163,164,165,168,169,170,171,172,173,174,176,188,192,196,288,289,290,297,144,146,147,148,149,151,152],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/test/testcases.py":[1,2,3,4,5,6,7,8,9,10,11,12,13,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,36,37,40,43,55,64,65,70,86,87,94,99,102,105,109,125,126,129,133,134,138,146,150,151,152,156,158,173,188,214,223,227,234,243,321,352,371,382,438,517,541,570,587,593,606,622,633,678,696,706,718,735,752,772,789,793,796,799,802,808,812,814,851,852,863,874,897,900,927,945,957,968,973,985,986,995,1002,1022,1030,1035,1040,1050,1060,1067,1068,1069,1072,1075,1088,1112,1120,1128,1136,1140,1141,1145,1149,1150,1155,1163,1168,1178,1187,1193,1197,1198,1201,1205,1209,1210,1213,1217,1218,1220,1229,1255,1258,1266,1276,1277,1278,1279,1280,1282,1286,1314,1323,1336,1343,1351,1352,1354,1364,1004,160,161,164,167,1005,970,1007,989,990,855,861,991,992,993,1009,1016,1017,1033,194,196,197,200,201,202,822,220,221,823,833,834,1041,1047,1048,848,849,206,207,208,209,907,908,1051,1053,1054,1055,1062,1063,1056,1058,998,999,1000,909,225,910,1036,1037,920,1024,1025,1026,1027,1028,175,180,183,186],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/core/management/sql.py":[1,2,5,21,38,23,24,26,28,29,30,31,32,33,34,25,40,41,43,45,46,47,48,49,50,51,42],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/core/servers/__init__.py":[1],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/core/servers/basehttp.py":[8,10,11,12,13,14,16,17,18,19,21,23,26,53,58,59,61,63,69,76,77,78,81,82,84,97,109,113,119,120,122,126,156,167,177,197],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/core/wsgi.py":[1,2,5],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/test/html.py":[1,3,4,6,9,13,14,19,37,54,74,77,100,103,106,109,124,128,129,132,136,137,140,143,146,152,155,164,171,176,191,202,205,208,212],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/views/static.py":[4,5,6,7,8,10,13,14,15,16,19,79,80,83,108],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/graphene_django/utils.py":[1,3,4,10,11,14,15,17,22,36,42,59,63,64,65,69,75,83],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django_filters/__init__.py":[2,4,5,9,11,13,16,30,21,22,23,24,25,28],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django_filters/filterset.py":[1,2,4,5,6,7,13,14,15,31,39,54,55,65,66,83,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,135,136,137,143,144,145,151,152,153,159,160,161,166,167,168,172,173,174,181,182,184,202,208,215,230,241,255,265,297,313,360,361,381,426,452,453,67,86,87,88,92,96,99,100,107,69,70,56,57,58,60,62,71,321,322,74,81,456],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django_filters/conf.py":[1,2,3,5,8,11,12,13,17,18,19,20,21,22,23,24,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,47,48,49,50,51,52,57,61,66,68,82,90,106,107],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django_filters/utils.py":[1,2,4,5,6,7,8,9,10,11,12,13,14,15,17,20,24,25,27,31,40,41,43,78,94,97,101,121,131,145,177,221,229,261,288,311],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django_filters/exceptions.py":[2,5,6],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django_filters/constants.py":[2,5],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django_filters/filters.py":[1,2,4,5,6,7,8,9,10,12,13,14,29,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,65,66,67,69,70,90,96,116,101,104,115,118,130,119,126,129,132,143,153,154,157,158,161,162,164,168,176,177,180,181,184,206,207,209,211,217,231,255,262,263,266,267,270,271,274,283,284,287,288,291,292,295,317,318,322,328,335,346,347,349,354,355,358,359,362,363,365,379,380,382,397,401,403,404,405,406,407,411,416,421,425,429,434,454,464,465,468,469,472,473,476,477,480,481,489,490,498,501,502,504,516,543,545,550,551,553,558,580,581,582,584,593,615,629,644,652,677,678,680,699,706,713,736,750,754,755,758,764],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django_filters/fields.py":[1,2,4,5,6,7,9,10,11,12,21,22,24,31,37,38,40,46,63,64,66,73,74,76,83,84,86,93,94,104,106,109,117,130,138,139,140,142,153,162,163,165,171,186,192,195,198,201,214,218,222,232,238,243,255,260,261,267,270,275,279,280,282,287,288,290,295,296,298,305,306,308],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django_filters/widgets.py":[1,2,3,5,6,7,8,9,10,11,12,15,16,21,26,39,53,71,75,81,82,84,90,93,100,106,112,120,126,127,128,130,134,140,141,144,145,147,153,157,158,164,176,191,192,195,204,222,223,226,235,237],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/graphene_django/registry.py":[1,2,6,21,24,27,31,34,41],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/channels/__init__.py":[1,3,4],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/channels/apps.py":[1,6,8,11,13,14,16,18,20],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/daphne/__init__.py":[1],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/daphne/server.py":[2,3,4,6,7,18,20,21,22,23,24,26,27,28,29,31,32,34,37,59,87,142,156,160,171,179,189,213,226,246,297,314,323],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/twisted/__init__.py":[8,11,12],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/twisted/_version.py":[3,8,10,11],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/incremental/__init__.py":[8,10,12,13,19,22,24,25,26,27,42,104,105,108,109,52,55,61,67,73,79,85,91,92,93,94,95,96,97,122,125,128,131,132,139,141,179,187,216,217,218,220,242,247,314,325,350,158,160,167,172,173,174,175,176,177,353,198,201,202,206,207,211,212,213,214,321,322],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/incremental/_version.py":[3,8,10,11],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/twisted/internet/__init__.py":[12],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/twisted/internet/asyncioreactor.py":[7,9,11,13,15,16,17,19,20,22,23,29,32,38,39,43,51,52,55,56,57,59,72,128,144,166,191,215,240,245,250,255,259,265,272,277,282,286,307,313,320,61,62,64,65,66,67,68,69,145,146,149,150,151,152,153,154,321,322],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/zope/interface/__init__.py":[50,51,53,54,57,58,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,83,86,88,90],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/zope/interface/interface.py":[15,16,18,19,20,21,22,24,25,28,29,30,32,34,42,50,53,60,69,73,77,81,85,89,93,95,101,109,114,116,117,118,122,123,125,127,145,157,158,159,164,165,166,171,182,185,186,188,193,196,205,217,219,220,223,256,267,278,281,301,302,309,310,377,382,385,389,401,404,417,425,427,430,433,436,455,467,486,489,520,527,531,535,539,543,547,552,312,313,315,328,330,331,337,338,340,61,65,66,67,342,343,347,351,189,190,191,207,211,212,215,226,227,228,229,231,232,234,521,522,525,236,237,239,240,242,243,244,247,249,252,355,373,375,554,556,563,566,571,578,579,580,584,586,588,590,593,601,614,659,668,684,528,511,514,515,518,529,238,685,686,687,669,671,316,317,318,332,348,213,194,356,360,361,362,363,364,366,367,615,616,617,618,620,621,622,624,625,630,632,633,634,585,636,639,643,646,649,651,653,656,333,334,335,62,63,365,320,324,640,641,208,197,198,199,672,674,675,677,678,680,681,253,402,391,394,396,397,399,647,259,260,261,380,262,263,264],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/zope/interface/exceptions.py":[15,17,19,21,22,23,26,31,33,35,39,45,47,49,53,58,60,62,67],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/zope/interface/ro.py":[15,16,18,47,61,64,48,49,50,51,57,58,37,38,39,40,41,42,43,45],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/zope/interface/declarations.py":[26,27,29,30,31,32,33,35,36,37,38,39,40,43,45,48,51,53,56,60,61,63,66,73,79,84,89,99,114,123,126,129,131,133,145,148,151,176,186,190,194,198,202,214,299,301,315,345,352,379,381,384,397,419,421,424,436,454,486,518,522,524,529,532,534,545,549,551,564,567,603,614,621,623,636,637,640,641,645,648,654,655,661,665,667,685,735,743,744,746,749,753,797,804,819,821,870,872,877,879,891,895,915,64,903,904,906,907,910,913,67,68,69,70,71,917,918,922,923,924,926,929,382,385,386,324,219,220,251,254,255,256,260,212,261,268,269,275,140,141,142,177,143,276,278,279,292,293,295,297,911,908,280,281,283,285,287,288,289,656,657,658,659,325,328,329,330,331,332,333,335,337,338,339,340,341,343,387,776,777,780,784,788,789,557,558,559,525,526,527,560,562,82,422,425,433,310,311,312,313,434,747,750,576,577,586,587,590,591,592,595,600,751,581,582,593,594,598],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/zope/interface/advice.py":[26,28,29,30,31,32,36,38,74,154,159,188],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/zope/interface/_compat.py":[15,16,17,19,36,43,44,46,48,49,51,56,37,39,40],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/zope/interface/interfaces.py":[15,16,18,19,20,23,25,27,29,30,32,38,44,47,51,52,54,55,59,60,62,78,86,87,89,97,105,109,118,128,133,135,141,143,150,152,160,246,248,259,271,277,283,291,294,301,303,308,310,317,321,333,347,358,362,384,386,395,401,423,430,451,458,464,503,513,528,564,596,625,628,653,663,673,675,682,696,704,708,716,720,726,732,736,746,753,759,760,762,763,765,770,772,775,776,778,781,786,788,789,791,792,794,800,807,813,820,827,835,841,847,853,862,864,866,868,870,875,877,879,881,882,883,885,887,889,891,896,898,901,903,905,907,909,911,913,915,920,922,923,926,927,929,930,933,935,937,938,939,941,943,945,946,948,949,951,953,955,956,983,984,1016,1023,1024,1058,1059,1100,1107,1108,1145,1146,1191,1198,1233,1269,1277,1279],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/twisted/logger/__init__.py":[43,47,50,51,52,55,58,61,64,67,70,71,74,77,80,83,86,87,90,92,94,99,101,103,105,107,112,114,116,118,122],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/twisted/logger/_levels.py":[7,9,13,16,17,27,60,62,63,64,65,66,69,89,107,108,109],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/constantly/__init__.py":[4,8,9,10,12,13,14,18,19,20,21,22,23],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/constantly/_constants.py":[8,10,13,14,16,17,18,20,21,24,34,35,40,48,66,84,102,120,137,141,142,200,160,161,165,166,167,212,214,216,226,242,261,277,285,289,293,294,169,170,171,178,179,187,189,298,305,306,312,316,317,319,339,360,367,368,373,403,411,419,428,441,448,460,465,469,474,475,477,479,36,37,172,176,180,239,181,132,133,182,270,272,273,256,257],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/constantly/_version.py":[7,8,17,20,21],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/twisted/logger/_flatten.py":[9,11,12,14,16,20,24,26,33,67,128,158],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/twisted/python/__init__.py":[6,8,11,12,13,15,16,17,18,21,22,23,24,27,28,29],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/twisted/python/compat.py":[22,24,26,27,28,29,30,31,32,33,34,36,39,42,44,45,49,52,54,57,61,78,81,100,163,198,199,203,204,210,214,217,220,221,224,225,231,250,251,252,253,269,334,335,336,343,404,430,462,463,478,482,483,491,492,497,501,522,551,561,579,582,583,584,586,588,589,590,592,594,595,596,598,600,601,602,603,604,605,615,616,620,624,627,628,629,653,660,667,669,683,703,726,727,729,731,732,733,734,735,737,738,739,746,762,763,769,795,796,797,804,826,827,831,832,838,867,868,869,870,871,872,873,874,875,876,877,878,879,880,881,882,883,884,885,886,887,888,889,890,891,892,893,894,895,896,897,898,899,900,901,902,903,904,905,906,907,70,72,73,93,94,95,96,373,375,279,283,290,297,304,311,318,324,325,326,327,328,329,330],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/twisted/python/deprecate.py":[72,74,77,78,79,80,81,82,86,87,88,89,91,92,94,99,127,128,129,132,148,169,207,242,269,312,395,403,415,422,423,427,432,438,464,465,472,481,490,521,540,541,552,568,594,621,656,699,759,613,614,615,466,424,467,433,434,468,469,616,618,584,585,545,546,547,548,549,588,589,590,499,500,428,429,503,505,512,513,516,517,514,501,485,486,487,288,308,292,293,237,238,107,108,112,113,114,194,195,196,197,198,199,200,201,142,144,202,295,303,304,162,163,164,165,251,254,256,257,265,305,306,252,258,261,262,263,264],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/twisted/python/versions.py":[8,10,12,14],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/twisted/logger/_format.py":[7,9,11,12,13,14,16,18,22,46,87,124,183,189,190,198,212,244,283,308,344,345,346,347],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/twisted/python/failure.py":[12,14,17,18,19,20,21,22,24,25,27,28,30,31,35,82,86,90,94,113,117,119,132,139,141,154,157,158,164,166,183,200,202,203,211,212,218,380,412,445,464,466,476,479,178,179,494,551,553,559,563,596,609,627,636,642,650,719,726,734,750,752,753,754,773,243,244,245,246,248,251,253,256,261,262,263,267,272,276,290,291,293,297,298,303,305,307,311,313,327,350,373,374,375,603,566,568,571,575,579,581,585,589,592,593,604],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/twisted/python/reflect.py":[8,10,12,13,14,15,16,17,18,19,21,24,25,26,27,28,31,52,93,113,155,168,176,180,200,203,207,210,214,218,222,226,230,261,325,363,371,379,391,415,431,454,458,459,462,467,475,487,524,536,540,544,548,554,558,620,622,624,625,626,627,628,629,632,634,367],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/twisted/python/_oldstyle.py":[7,9,11,12,14,18,49,61,83,29,45,84,31,32,39,43,41,57],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/twisted/python/_tzhelper.py":[7,9,12,13,18,27,29,43,73,92,99,107,119,64,65,68,70,39,40],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/twisted/logger/_logger.py":[7,9,11,12,13,17,31,33,47,76,107,111,147,193,209,225,241,257,274,63,64,41,42,66,67,69,70,73,71,275],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/twisted/logger/_global.py":[8,10,11,13,14,16,17,18,19,20,21,22,23,28,35,78,80,84,120,194,239,240,94,95,96,97,98,99,100,101,102,103,104,105,106,112,115,116],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/twisted/logger/_buffer.py":[7,9,11,13,16,20,21,36,38,47,51,44],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/twisted/logger/_observer.py":[7,9,11,12,17,22,29,31,70,71,77,79,84,96,108,144,80,81,90,92,93],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/twisted/logger/_filter.py":[7,9,11,13,15,16,20,38,39,40,41,45,48,50,59,96,97,101,105,125,138,139,145,147,157,191,210,218,152,153,154,214,215,120,121,122],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/twisted/logger/_io.py":[7,9,11,15,26,28,31,56,67,78,89,100,118,125,132,142,152,173,185,195,196,197,198,199,200,201,202,44,45,47,50,52,53],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/twisted/logger/_file.py":[7,9,11,12,13,14,15,19,20,23,24,43,64,34,37,39,40],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/twisted/logger/_stdlib.py":[7,9,11,13,14,15,16,22,23,24,25,26,29,41,35,36,37,38,39,45,46,63,65,67,81,103,120,124,125,133,137,140,141],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/twisted/logger/_legacy.py":[7,9,11,12,13,14,18,19,26,28,37,44,97],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/twisted/logger/_json.py":[7,9,11,12,13,15,16,17,18,20,21,23,27,48,73,105,109,110,111,115,116,117,123,124,129,148,171,211,226,257],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/twisted/internet/base.py":[7,9,11,12,14,15,16,18,20,26,27,32,33,34,35,36,40,43,44,49,50,53,79,88,107,130,150,154,164,174,184,229,230,240,242,247,252,258,273,297,298,301,312,340,341,348,367,380,396,417,437,453,454,455,484,486,488,489,490,491,492,494,496,525,527,532,547,561,570,579,586,590,594,598,602,607,612,617,630,642,655,666,677,688,698,705,713,723,730,739,762,771,773,786,806,810,823,833,863,928,999,1000,1002,1004,1006,1011,1023,1035,1038,1057,1066,1073,1085,1086,1089,1090,1095,1096,1097,1099,1105,1112,1126,1135,1143,1148,1158,1166,1173,1177,1179,1180,1182,1189,1196,1210,1212,1214,1235,1249,1265,1270,1288,497,498,499,500,501,502,503,504,505,507,508,509,514,515,716,717,718,342,343,344,345,719,720,361,363,364,516,517,519,520,1007,555,556,557,558,1008,521],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/twisted/internet/interfaces.py":[8,10,12,15,20,24,29,31,36,44,49,58,59,87,93,95,98,101,108,114,116,124,137,145,151,154,191,192,215,237,259,281,303,325,347,369,391,413,435,457,479,501,523,545,567,589,611,633,655,677,699,729,731,753,778,780,801,820,823,825,844,867,870,872,893,913,918,920,935,946,949,951,974,980,983,1001,1034,1036,1067,1100,1136,1138,1139,1233,1236,1238,1246,1266,1276,1282,1284,1291,1301,1313,1327,1335,1341,1343,1359,1365,1367,1375,1380,1382,1391,1399,1402,1404,1405,1409,1414,1421,1427,1437,1452,1460,1495,1511,1531,1538,1540,1553,1557,1559,1563,1566,1579,1589,1591,1600,1610,1616,1618,1629,1640,1647,1654,1664,1673,1683,1686,1688,1697,1705,1713,1717,1719,1727,1730,1732,1745,1765,1770,1772,1782,1787,1789,1799,1802,1805,1808,1810,1815,1821,1824,1826,1839,1842,1844,1872,1878,1890,1896,1898,1907,1914,1916,1923,1931,1935,1937,1947,1949,1966,1979,1984,1997,2000,2002,2012,2025,2035,2049,2063,2071,2073,2088,2098,2106,2108,2125,2131,2132,2144,2147,2149,2163,2168,2174,2185,2187,2200,2212,2220,2232,2241,2244,2246,2258,2270,2275,2283,2288,2297,2302,2309,2312,2313,2336,2349,2351,2365,2376,2378,2392,2400,2402,2414,2422,2424,2436,2441,2443,2462,2465,2467,2474,2478,2479,2489,2494,2497,2498,2499,2504,2507,2508,2523,2526,2528,2529,2534,2539,2544,2549,2555,2573,2578,2597,2600,2602,2609,2614,2620,2623,2625,2637,2650,2658,2666,2674,2683,2686,2688,2693,2699,2702,2704,2709,2714,2720,2723,2725,2730,2737,2742,2747,2752,2757,2765,2771,2777,2779,2792,2798,2800,2812,2818,2820,2826,2830,2842,2857,2859,2865,2869,2894,2900,2902,2906],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/twisted/internet/fdesc.py":[8,10,11,12,13,18,21,30,39,44,53,62,97,118,25,26,27,48,49,50],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/twisted/internet/main.py":[11,13,15,17,18,22,37,29,30,31,33,34],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/twisted/internet/error.py":[6,8,10,12,13,17,18,20,29,38,39,45,52,55,59,60,62,71,72,74,83,84,89,90,92,96,107,108,112,113,117,118,122,123,127,128,132,133,137,138,142,143,147,148,152,153,157,159,163,165,169,172,176,177,179,180,181,183,191,212,215,219,220,222,231,237,241,242,244,253,262,266,267,271,272,274,283,284,286,295,301,303,310,311,312,313,314,318,319,321,329,336,337,363,367,371,372,374,383,384,386,395,398,401,404,408,411,414,417,421,428,430,440,444,448,452,456,460,463,467,471,478,480,494,495,496,497,498,499,500,501,502,503,504,505,506],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/twisted/internet/abstract.py":[7,9,11,13,16,17,18,20,23,35,72,73,74,75,77,87,116,126,127,132,134,147,157,158,159,160,161,168,169,170,171,172,173,174,175,177,179,192,211,225,235,292,300,304,308,313,327,340,359,387,412,416,424,432,437,450,451,453,465,469,472,476,486,531,546],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/twisted/internet/defer.py":[17,19,21,22,23,24,25,26,27,30,31,32,33,34,36,39,40,44,47,50,53,57,71,94,113,130,164,165,171,176,187,195,196,200,244,246,247,248,249,254,258,260,262,295,315,325,336,348,410,438,463,504,511,522,551,571,579,714,728,731,735,736,755,756,759,800,845,868,922,926,928,930,943,968,969,979,980,986,994,1003,1020,1041,1043,1044,1047,1103,1124,1147,1155,1189,1190,1195,1199,1201,1212,1219,1275,1276,1343,1344,1349,1366,1367,1376,1378,1379,1383,1496,1534,1538,1542,1619,1620,1624,1629,1662,1669,1671,1674,1689,1707,1725,1739,1741,1753,1768,1784,1801,1802,1806,1807,1811,1827,1829,1836,1851,1865,1886,1890,1894,1910,1911,1912,1913,1916,1930,1996,1997,1998,1999,2000,2001,2002,2003,1601,1614],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/attr/__init__.py":[1,3,5,6,7,8,21,23,24,25,26,27,29,30,32,33,36,37,38,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/attr/converters.py":[3,5,7,10,29,21,26],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/attr/_make.py":[1,3,4,5,6,7,8,10,12,13,21,31,32,33,35,37,41,43,46,51,53,55,60,64,56,57,58,71,72,73,74,75,76,77,78,79,80,81,82,222,252,253,256,258,260,232,234,235,237,238,239,240,244,245,247,265,276,292,299,424,431,438,441,456,459,495,498,509,557,653,659,672,676,685,700,711,745,962,969,985,993,1000,1065,1073,1086,1091,1194,1208,1211,1260,1271,1311,1339,1367,1384,1388,1395,1675,1684,1697,1713,1753,1756,1766,1767,1796,1807,1816,1822,1837,1846,1847,1716,1720,1734,1735,1736,1737,1738,1739,1740,1741,1742,1743,1746,1747,1750,1751,1850,1851,1264,1267,1215,1217,1257,1268,1198,1201,1202,1092,1095,1096,1221,1222,1223,1224,1225,1227,1229,1230,1231,1232,1233,1243,1244,1245,1246,1247,1248,1249,1252,1251,61,1253,1255,1097,1099,1100,1101,1105,1106,1107,1108,1109,1110,1112,1116,1117,1118,1119,1120,1125,1126,1127,1128,1130,1131,1133,1139,1152,1165,1178,1191,1205,1852,1069,1001,1002,1003,1004,1007,1010,1011,1012,1013,1015,1017,1032,1045,1023,1024,1027,1028,1030,1047,1048,1049,1050,1051,1056,1057,1058,1059,1062,1070,1856,1863,1876,1878,1879,1889,1891,1892,1893,1894,1895,1896,1897,1898,1899,1902,1904,1934,1948,1966,1265,1199,1969,890,956,957,1970,1983,1985,176,181,195,205,206,208,209,210,211,212,213,214,215,216,217,218,1917,1918,1919,1921,1924,1925,1926,1927,1928,1929,1930,1931,1932,1986,1988,892,895,897,898,899,900,901,902,903,904,905,906,471,472,307,308,280,281,282,310,315,345,347,348,351,349,355,358,1769,1770,1775,1777,1778,1784,1787,1788,1789,1790,1791,1792,361,362,363,366,378,380,382,386,388,389,390,392,393,403,404,412,418,421,475,476,477,478,479,480,481,482,990,483,484,485,486,487,489,491,909,910,654,655,715,716,720,721,722,727,657,911,913,914,701,706,709,916,921,929,933,677,678,679,683,943,946,952,504,505,561,562,564,565,568,571,576,578,579,580,581,583,587,588,590,592,593,594,597,598,601,607,609,625,626,629,637,638,643,645,646,647,648,651,1997,2054,2055,2058,2060,2062,944,686,687,688,689,690,691,692,693,694,1274,1277,1278,1279,1281,1282,1406,1407,1408,1392,1410,1473,1479,1487,1488,1489,1493,1494,1496,1497,1499,1500,1501,1502,1505,1506,1547,1562,1599,1602,1603,1609,1474,1475,1476,1611,1614,1625,1633,1647,1652,1653,1667,1668,1670,1671,1284,1285,1286,1287,1289,1294,1299,1300,1301,1302,1305,1306,1308,698,2067,243,1114,507,513,514,517,518,532,533,540,555,405,409,411,1498,1548,1549,1551,1554,1555,1561,1615,1616,1617,1618,1619,1620,1621,1623,1624,959,930,935,941,673,674,520,521,523,524,394,922,1604,1480,1481,1482,1483,1484,1607,1507,1527,1539,1540,1541,1542,1543,1993,1994,1563,1564,1567,1568,1569,1571,1572,1588,1589,1590,1591,1592,1593,1594,1597],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/attr/_config.py":[1,4,6,9,19],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/attr/_compat.py":[1,3,4,5,6,9,10,13,14,21,101,103,115,118,120,123,127,136,159,140,146,147,131,133,149,150,151,156,124,121],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/attr/exceptions.py":[1,4,12,14,15,18,23,26,31,34,40,43,49,52,57],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/attr/filters.py":[3,5,7,8,11,21,38],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/attr/validators.py":[3,5,7,10,13,14,15,17,35,41,57,58,59,61,76,82,98,99,100,102,108,114,132,133,134,136,149,155,173,174,175,182,186,199,200,201,196,202,203,127,129,206,216,183,109,110,231,246,247,248,249,250,252,263,269,170,150,151],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/attr/_funcs.py":[1,3,5,6,7,12,13,14,15,85,118,119,120,121,215,227,265],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/twisted/python/lockfile.py":[8,10,12,13,15,17,18,20,23,25,26,27,28,29,30,121,138,140,141,143,147,209,227,248],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/twisted/python/runtime.py":[5,7,8,9,10,12,16,25,26,27,28,29,36,41,45,47,48,49,51,59,69,79,89,107,118,131,141,170,197,211,232,52,55,233,76,234,115,204,205,206],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/twisted/internet/threads.py":[8,10,12,13,16,18,19,22,58,75,83,93,126,127],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/twisted/internet/_resolver.py":[9,11,13,15,18,20,22,23,24,25,26,27,28,31,32,35,37,45,48,49,50,54,55,59,60,64,65,70,71,75,77,101,142,143,146,148,150,158,206,207,210,212,221,230,242,252,253,256,257,266,94,95,96,97,263],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/twisted/internet/address.py":[6,8,10,11,13,14,15,16,17,18,21,22,23,36,37,38,39,43,44,45,66,67,68,69,70,71,75,76,79,83,84,85,94,96,97,101,102,103,109,111,113,114,141,147,154,168,169,171],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/twisted/python/filepath.py":[7,9,11,12,13,14,16,17,18,20,21,22,23,25,31,32,33,34,36,37,38,40,44,45,49,62,63,64,68,95,96,98,110,118,123,131,139,147,155,164,172,180,188,197,202,213,216,220,224,228,238,239,250,258,262,277,285,287,298,314,381,412,426,444,476,484,491,498,506,522,523,524,530,535,554,569,571,573,582,587,600,605,606,610,631,653,668,669,670,726,727,728,731,740,751,762,774,786,800,814,828,863,883,903,934,960,974,990,1016,1036,1045,1057,1072,1086,1100,1114,1135,1159,1185,1205,1225,1241,1259,1276,1293,1310,1327,1342,1354,1369,1381,1385,1401,1416,1437,1457,1469,1481,1492,1545,1551,1562,1575,1590,1615,1617,1690,1737,1759,1760,1761,1762,1763,1766],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/twisted/python/win32.py":[12,14,16,17,21,22,23,24,26,28,32,34,35,36,37,40,41,42,57,70,84,85,90,108,111,136,95,96,97,98,99,100,101,102,103,104,105,106,107,86,87,88],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/twisted/python/util.py":[5,7,8,9,12,13,17,18,19,20,23,25,26,27,28,29,33,41,48,58,63,70,78,87,94,97,105,112,119,126,137,147,155,163,168,173,178,184,189,193,197,205,220,244,258,266,278,296,344,353,358,387,408,437,444,445,456,464,467,472,476,480,488,500,517,519,532,537,538,545,556,559,568,581,598,600,603,616,620,627,628,630,640,648,650,656,664,684,730,733,734,736,741,745,749,753,757,761,765,769,773,777,781,785,789,793,798,823,851,898,921,944,985,1011,1012,1013,1014,1015,1016,1017,1021,1022,1023,1024,1025,1026,1027],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/twisted/internet/_idna.py":[8,10,34],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/twisted/python/log.py":[7,9,11,12,13,15,17,19,20,21,22,23,24,25,26,34,35,39,46,50,56,57,79,80,83,90,111,140,143,147,148,158,162,164,167,168,190,201,217,227,240,251,289,293,294,313,314,315,316,169,173,175,176,177,178,184,185,186,187,320,309,311,310,332,344,359,369,418,460,464,466,473,481,487,489,491,497,512,544,567,575,577,585,599,609,611,612,613,614,616,624,628,632,636,639,640,641,642,645,655,663,677,688,692,693,695,701,710,716,723,733,734,735,736,737,738,739,743,749,750,752,766,767],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/twisted/python/context.py":[13,15,17,19,22,24,26,60,61,65,90,110,111,114,121,124,128,137,112,133,134,135],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/twisted/python/threadable.py":[8,10,12,14,17,19,24,29,33,43,48,60,76,103,104,111,118,125,126,128,129,132,133,137,83,84,85,86,88,89,92,99,141,68,69,70,71,49,56,72],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/twisted/internet/posixbase.py":[7,9,11,12,13,14,16,18,19,20,21,26,27,30,31,34,35,36,37,38,39,40,41,43,45,46,47,48,49,52,60,66,67,69,87,96,104,110,123,124,126,127,129,141,148,162,167,169,185,186,192,198,199,203,210,217,232,235,238,239,262,263,264,270,274,276,289,290,309,328,329,330,363,374,388,394,404,418,432,434,441,462,479,493,498,505,519,534,557,570,572,631,632,652,655,656,657,660,667,685,695,703,711,722,734,746,753,760,774,789,791,792,793,794,795,796,798,661,662,663,664,283,284,132,133,134,135,136,137,138,285,286],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/twisted/internet/udp.py":[16,18,21,22,23,24,26,28,29,47,48,49,50,53,54,55,56,60,61,62,63,80,82,83,84,86,87,89,120,159,165,171,182,216,221,254,314,330,343,349,358,363,380,388,401,408,422,433,445,449,451,456,461,467,471,476,480,485,490,494,507,513,514,517,520,528],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/twisted/internet/tcp.py":[9,11,13,14,15,16,17,19,21,23,24,25,26,28,31,35,37,38,41,42,45,46,49,68,69,70,71,72,73,74,75,76,77,78,79,81,84,87,88,89,90,91,92,93,96,100,103,123,131,139,144,145,147,173,179,180,182,200,201,202,211,214,222,227,246,262,283,298,311,330,332,337,340,343,347,353,403,405,406,408,432,456,477,498,506,524,540,542,543,545,557,566,576,630,660,662,687,713,715,717,753,762,771,777,782,786,799,800,802,804,831,838,878,888,898,921,923,933,944,951,963,964,965,973,974,976,977,980,991,1008,1019,1031,1032,1035,1037,1047,1053,1061,1099,1102,1120,1124,1125,1136,1137,1138,1139,1141,1151,1165,1237,1238,1272,1274,1276,1277,1278,1279,1281,1285,1289,1291,1292,1293,1295,1308,1332,1339,1346,1389,1392,1457,1472,1474,1481,1500,1506,1516,1525,1526,1528,1541,1551],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/twisted/internet/_newtls.py":[11,13,15,16,18,19,21],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/twisted/protocols/__init__.py":[6,9,10,12,13,14,15,18,19,20,21],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/twisted/protocols/tls.py":[37,39,41],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/twisted/internet/task.py":[7,9,11,13,14,15,17,19,20,21,22,23,25,26,27,30,59,61,62,63,64,65,66,68,75,90,147,150,166,199,211,225,244,279,295,301,305,309,313,317,321,324,328,331,335,339,343,347,351,352,353,357,362,363,368,402,404,418,438,453,466,490,501,510,532,563,566,567,568,595,615,627,640,651,665,675,676,684,695,710,722,586,587,588,589,590,591,592,724,738,757,763,765,767,771,783,790,804,811,829,840,871,941,943,945,947],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/twisted/internet/protocol.py":[10,12,14,15,17,18,19,20,23,24,31,34,36,37,39,60,67,81,99,112,125,146,152,154,164,174,185,194,196,197,199,205,209,220,230,240,260,262,269,296,312,328,346,366,367,368,373,380,382,383,384,385,386,387,389,392,398,404,443,459,470,486,489,493,501,502,503,505,517,529,530,533,534,550,552,560,575,587,588,590,594,598,602,603,607,608,610,614,618,622,626,627,631,632,636,638,645,651,657,666,672,678,684,692,702,706,708,709,710,712,718,731,746,754,762,774,784,785,793,795,803,813,818,820,827,836,837,844,846,847,848,849,851,855,862,869,879,883,888,892,900,906,912,916,921,926,930,931,932,933],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/twisted/python/components.py":[29,31,34,35,38,39,40,45,48,50,74,89,109,119,98,99,105,106,122,129,131,147,151,152,154,159,168,175,186,188,190,193,196,203,213,219,241,245,259,292,296,297,300,308,344,359,360,365,380,393,394,399,410,418,428,429,430,58,59,63,66,67,68,70,71,64,332,334,335,336,395,396,337,338,339,340],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/zope/interface/adapter.py":[15,16,18,19,20,21,22,24,25,27,29,34,38,40,87,92,93,96,101,105,140,159,207,234,294,300,301,303,308,313,326,348,361,364,380,395,409,411,412,417,423,428,433,437,441,445,447,448,453,455,461,492,497,509,516,524,547,558,576,579,602,616,617,619,620,622,624,631,634,638,649,656,657,659,660,662,664,670,688,700,627,629,55,59,63,79,97,456,457,458,493,494,459,98,99,85,639,640,643,647,88,89,90,650,102,103,462,463,467,652,141,665,668,142,143,144,145,146,106,108,112,113,114,115,116,117,118,119,121,122,123,124,125,126,128,131,133,134,135,136,498,499,500,505,502,506,138,148,149,151,152,153,154],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/twisted/internet/ssl.py":[54,56,59],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/twisted/internet/unix.py":[11,13,15,16,17,18,19,21,23,26,27,28,29,30,31,34,35,41,51,52,69,71,72,74,78,102,111,155,194,225,229,233,234,240,242,244,248,282,285,290,303,304,314,315,316,318,319,322,329,348,356,359,411,419,428,429,430,431,432,434,445,448,452,453,458,461,465,466,469,471,473,480,488,503,521,538,543,544,545,548,550,557,566,578,600,623],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/twisted/python/sendmsg.py":[7,9,11,12,14,16,21,23,27,54,94],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/twisted/internet/process.py":[11,13,15,17,21,22,23,24,25,26,27,28,29,31,32,36,37,41,43,44,45,46,47,48,49,53,55,57,68,92,104,128,114,115,116,117,121,122,123,124,132,144,145,146,147,149,181,188,201,206,237,251,257,258,260,272,279,287,294,298,306,316,319,320,321,323,354,365,387,399,501,508,526,535,549,551,552,553,555,561,573,603,613,622,644,557,558,646,655,656,668,669,670,672,673,675,676,680,781,874,878,887,893,899,906,910,914,920,930,943,950,960,964,976,991,992,995,997,998,1001,1049,1098,1104,1108,1112,1121,1128,1139,1149],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/twisted/internet/_baseprocess.py":[8,10,11,12,13,15,20,21,22,23,24,26,30,44,55],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/twisted/internet/_signals.py":[33,35,37,40,64],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/twisted/internet/endpoints.py":[13,15,17,18,19,20,21,23,24,26,28,29,30,33,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,55,57,58,64,65,67,68,69,70,71,72,73,74,75,79,83,85,103,112,121,128,135,142,150,158,167,179,180,182,192,200,225,232,239,257,267,268,275,277,279,286,296,297,298,304,308,309,310,318,322,330,332,344,355,371,388,396,397,398,402,403,410,411,412,413,433,454,455,458,460,479,492,495,496,513,516,517,534,535,538,540,565,580,581,594,596,597,598,599,601,615,630,639,653,654,664,665,667,678,723,724,750,751,752,753,756,799,820,845,891,1028,1046,1047,1050,1053,1076,1089,1090,1093,1096,1125,1141,1142,1145,1146,1163,1175,1176,1179,1180,1201,1218,1219,1226,1227,1228,1230,1246,1266,1293,1327,1412,1413,1418,1419,1421,1431,1438,1439,1447,1448,1450,1452,1480,1488,1489,1494,1495,1497,1518,1525,1526,1527,1530,1532,1575,1608,1609,1610,1614,1615,1616,1620,1649,1662,1736,1772,1812,1841,1857,1883,1922,1953,1979,1980,1981,1986,2071,2094,2095,2098,2100,2108,2118,2119,2122,2124,2132,2142,2175,2231,2232,2239,2240,2242],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/twisted/internet/stdio.py":[23,25,27,29,35,37],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/twisted/internet/_posixstdio.py":[12,14,16,17,20,21,22,25,26,27,29,30,31,32,34,47,51,55,59,68,71,76,79,92,113,127,140,146,151,154,158,162,166],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/twisted/plugin.py":[11,13,15,16,18,20,31,24,25,27,28,29,33,34,35,36,37,41,48,52,53,60,65,68,77,81,97,98,105,115,116,126,199,226,229,259],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/twisted/python/modules.py":[57,59,61,64,66,67,68,69,71,73,74,75,76,77,80,82,83,84,87,89,104,113,118,120,176,188,195,203,213,235,246,257,258,273,276,286,295,299,310,312,328,331,338,347,367,374,398,406,414,419,425,447,455,456,463,466,469,472,476,477,490,492,493,495,498,500,501,504,527,531,541,559,562,563,564,565,566,567,618,624,626,658,678,689,729,743,749,757,766,606,608,609,610,611,612,613,614,615,768,776,785],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/twisted/python/zippath.py":[9,11,13,14,15,17,19,20,21,22,24,26,30,31,32,35,37,57,64,72,83,90,107,111,115,119,123,127,139,149,153,159,164,168,178,188,201,212,223,224,226,253,263,270,277,284,291,295],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/twisted/python/systemd.py":[10,12,14,16,19,34,35,37,45,46,85,61,62,63,64,66,68,69,70,71,82,42],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/twisted/web/__init__.py":[12,14,15,17,18,20,21,22,23],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/twisted/web/http.py":[26,28,31,32,34,35,37,38,39,40,41,42,44,45,46,48,50,51,53,54,59,60,61,62,63,64,65,66,67,69,70,74,75,78,89,92,94,95,96,97,98,99,100,101,102,103,104,106,108,110,111,113,114,115,118,140,144,146,150,153,157,158,159,160,161,162,164,193,219,236,252,273,329,341,362,381,384,386,387,390,391,395,405,416,426,432,449,462,475,485,489,490,492,494,499,518,519,520,521,522,524,527,533,537,553,595,598,609,612,615,625,630,636,650,654,657,658,695,696,697,698,699,700,701,702,703,704,705,706,707,708,709,710,711,712,713,715,742,771,785,801,823,832,920,936,947,960,970,986,993,1037,1067,1143,1236,1254,1268,1278,1315,1348,1362,1380,1390,1425,1440,1457,1479,1498,1515,1532,1546,1553,1574,1595,1605,1606,1607,1608,1610,1611,1614,1621,1625,1634,1638,1644,1648,1663,1664,1670,1702,1723,1760,1761,1763,1769,1788,1797,1807,1819,1825,1836,1848,1849,1854,1855,1865,1875,1885,1893,1894,1895,1896,1999,2001,2002,2003,2005,2006,2007,2008,2009,2012,2014,2015,2016,2017,2018,2019,2020,2021,2022,2024,2032,2040,2114,2119,2169,2193,2214,2223,2236,2280,2306,2319,2336,2347,2362,2388,2400,2412,2421,2430,2442,2484,2500,2513,2549,2569,2577,2593,2618,2650,2651,2660,2661,2666,2670,2671,2685,2693,2701,2711,2724,2755,2756,2757,2758,2759,2760,2761,2764,2772,2778,2788,2803,2813,2828,2836,2851,2860,2873,2916,2924,2945,2947,2949,2951,2953,2954,2989,2997,3013,3026,3037,3045],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/twisted/internet/_producer_helpers.py":[7,8,10,12,13,14,15,19,22,23,46,48,51,56,84,93,106,113,120],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/twisted/protocols/policies.py":[9,11,14,16,19,20,21,22,25,39,49,51,53,58,66,80,84,88,93,97,101,105,109,113,119,123,131,134,136,138,143,150,155,160,164,168,172,176,183,191,194,198,203,208,213,218,223,227,231,236,242,248,250,252,253,267,277,284,291,304,315,324,334,343,353,368,383,384,388,394,395,399,401,403,406,414,421,433,434,435,436,438,455,458,463,466,468,483,498,513,521,526,531,536,541,552,555,556,559,564,569,580,583,602,607,614,619,624,630,635,640,646,647,649,651,657,661,668,676,685,686,688,690,700,715,741,745],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/twisted/protocols/basic.py":[8,10,13,14,15,16,18,21,22,23,28,29,38,42,44,47,51,54,57,119,120,121,123,126,128,131,133,137,139,152,166,188,202,212,228,245,262,286,305,324,334,355,378,391,401,412,421,433,434,435,436,438,459,469,479,488,489,491,496,502,508,524,525,526,527,528,529,531,542,586,603,612,619,629,639,653,657,661,676,677,682,703,705,706,707,711,713,724,736,786,803,811,812,813,817,825,826,827,831,839,840,841,845,858,860,862,884,892,894,896,897,899,927,945,949],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/twisted/web/iweb.py":[11,13,15,16,19,24,26,27,28,30,31,32,33,39,40,43,44,48,49,52,65,71,81,93,101,115,127,138,149,164,175,182,190,197,204,210,218,228,234,247,255,277,299,317,320,321,336,340,341,358,366,367,368,372,386,405,425,434,439,441,453,464,468,470,484,497,501,503,513,518,520,521,526,529,530,533,536,537,544,545,548,549,554,577,587,593,595,607,618,623,625,633,638,639,640,644,645,649,650,655,693,694,729,737,739,760,767,769,787,790,791,792,794],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/twisted/cred/__init__.py":[7],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/twisted/cred/credentials.py":[9,11,13,15,16,17,18,19,21,22,24,25,26,27,28,32,38,42,46,47,58,70,72,88,103,105,121,124,128,129,132,134,141,164,189,207,209,210,219,221,223,229,249,259,267,287,349,395,396,408,409,410,411,413,417,433,437,441,447,450,454,459,462,466,471,473,477,497,501,503],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/twisted/python/randbytes.py":[7,9,11,13,15,17,18,24,27,31,34,38,45,48,50,53,63,92,103,104,105,120,123,141,143,145,147,150],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/twisted/cred/_digest.py":[9,11,13,14,21,30,32,37,83,107],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/twisted/cred/error.py":[6,8,11,12,16,19,23,25,29,34,38,45],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/twisted/web/http_headers.py":[7,9,11,14,28,29,49,51,52,53,54,55,56,57,59,66,73,85,101,116,134,151,160,173,185,206,226,250,260,275],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/twisted/web/_http2.py":[15,17,19,20,21,23,25,27],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/twisted/web/_responses.py":[7,9,11,12,14,15,16,17,18,19,20,21,23,24,25,26,27,28,29,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,50,51,52,53,54,55,56,57,61,62,65,66,67,68,69,70,71,72,75,76,77,78,79,80,82,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,105,106,107,108,109,110,111,112],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/daphne/http_protocol.py":[1,2,3,4,6,7,8,9,10,12,14,17,24,44,45,47,48,49,52,66,196,206,218,286,292,310,319,327,351,354,358,359,365,367,371,385],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/daphne/utils.py":[1,3,6,18,31],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/daphne/ws_protocol.py":[1,2,3,4,6,11,13,15,18,22,24,27,29,98,118,127,141,157,180,203,216,224,245,257,266,272,292,295,298,302,307,309,311,315],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/autobahn/__init__.py":[27,29,31],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/autobahn/_version.py":[27],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/autobahn/twisted/__init__.py":[28,30,31,33,35,40,41,44,51,58,83,86,89],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/autobahn/twisted/util.py":[27,29,31,32,33,34,39,40,41,48,52,72,94],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/autobahn/twisted/choosereactor.py":[27,29,30,32,33,35,36,41,45,56,177],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/txaio/__init__.py":[27,29,30,32,39,55,57,99,103,106,118,130,146,147,135,136,137,139,140,138,108,110,111,112,113,114,115],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/txaio/_version.py":[1],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/txaio/interfaces.py":[27,29,30,34,35,36,37,38,39,40,44,45,70,72,84,85,118,140,143,146,149,152,155,159,160,176,178],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/txaio/_unframework.py":[31,33,34,36,37,38,41,49,50,51,52,53,54,55,56,57,58,59,60,61,63,65,66,67,69,71,72,73,74,76,78,79,81],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/txaio/tx.py":[27,29,30,31,32,34,36,37,38,39,41,43,44,45,46,48,50,51,52,53,54,55,59,60,62,63,71,72,73,74,76,78,80,81,83,84,85,86,134,138,142,159,161,175,183,192,203,211,242,245,251,271,272,277,279,280,281,282,283,284,287,293,303,332,368,371,373,376,389,396,408,419,422,425,431,434,437,464,467,470,480,483,495,509,530,541,554,565,569,374,572,573,574,575,576,577,578,579,580,581,582,583,584,585,586,587,588,589,255,256,261,262,265,266,267,163,165,166,168,171,215,217,218,219,221,229,231,234,235,237,238,222,223,224,225,240,173,268],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/txaio/_iotype.py":[27,29,31,32,37],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/txaio/_common.py":[2,3,6,12,14,20,24,28,38,41,53,77,113],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/autobahn/twisted/websocket.py":[27,29,31,33,34,36,37,38,41,42,43,44,45,46,48,74,78,81,83,85,87,105,134,137,144,147,150,153,156,159,162,165,168,171,174,177,188,195,196,201,203,205,212,213,218,220,222,225,229,236,239,242,243,248,250,268,269,274,276,294,295,313,315,333,336,348,351,360,365,369,373,378,381,384,387,390,393,401,437,444,448,453,456,464,503,511,512,555,556,591,592,599,602,603,606,608,610,633,634,641,644,645,648,650,652],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/autobahn/util.py":[27,29,30,31,32,33,34,35,36,37,38,39,40,42,44,46,47,48,49,50,70,73,87,88,79,80,84,138,170,171,190,201,215,217,220,233,271,274,294,314,336,341,358,359,422,434,446,461,473,476,488,495,497,511,524,540,556,571,574,576,585,594,628,643,649,652,656,664,666,686,699,718,721,733,734,735,737,744,757,775,803,827,836,837,839,842,846,856,81,83],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/autobahn/wamp/__init__.py":[27,29,41,50,52,82],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/autobahn/wamp/types.py":[27,29,31,33,53,57,58,62,70,73,119,123,124,127,130,131,134,142,145,180,184,185,188,192,195,210,214,215,218,222,225,241,245,246,249,261,264,319,323,324,329,341,344,384,399,403,404,417,422,425,445,448,456,481,507,508,513,514,515,519,522,537,544,548,549,553,563,568,606,620,624,625,629,640,644,705,709,710,714,730,747,819,857,861,862,866,877,882,920,940,944,945,949,959,963,1019,1023,1024,1027,1036,1046,1079,1096,1100,1101,1105,1111,1114,1141,1145,1146,1149,1155,1158,1184,1187,1189,1195,1198,1200,1205,1210,1233,1236,1238,1243,1248],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/autobahn/wamp/request.py":[28,42,46,50,52,54,66,70,73,75,77,98,107,111,114,116,118,135,138,140,142,163,172,175,177,179,196,200,202,204,217,220,222,224,240,243,245,247,267,270,272,274,281,284,286,288,305,308,311,314,316,318,326,329,331,333],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/autobahn/wamp/exception.py":[27,29,31,32,42,46,47,50,53,54,58,61,62,66,69,70,75,78,79,83,86,87,91,93,99,104,110,116,122,127,132,137,146,152,158,163,169,176,182,187,193,200,205,210,216,223,229,234,239,250,263,272,279,280,283,286,287,290,293,294,297],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/autobahn/wamp/uri.py":[28,30,32,34,35,42,46,93,94,105,107,108,109,111,112,113,115,120,128,136,232,233,243,244,254,264,290,300,310,321,322,348,349,368,373,379,374,375,376,377,149,150,151,152,153,154,156,159,161,162,163,164,165,166,168,169,193,194,204,205,206,207,217,225,226,227,228,229,230,378],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/autobahn/wamp/interfaces.py":[27,28,30,39,43,44,45,50,52,53,60,61,73,74,87,88,89,92,94,95,101,102,108,109,121,122,139,140,141,143,145,146,154,155,156,167,168,182,183,190,191,192,196,198,199,214,215,224,225,233,234,243,244,289,290,291,293,294,302,303,314,315,326,327,337,338,339,342,344,345,352,353,373,374,380,381,390,395,396,407,408,423,424,435,436,437,452,453,462,463,469,470,476,477,483,484,490,491,505,506,518,519,520,532,533,569,570,571,613,614,650,651,652,688,689,691,699,711,712,713,728,730,731,732,755,756],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/autobahn/wamp/websocket.py":[27,29,31,32,33,34,39,42,45,47,49,53,67,83,107,129,135,144,154,157,169,172,174,176,195,198,200,202,218,221,223,286,289,292,295],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/autobahn/websocket/__init__.py":[28,30,32,42],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/autobahn/websocket/types.py":[27,29,31,32,41,45,46,51,62,65,115,126,130,131,136,143,146,171,178,182,183,188,190,192,221,222,226,228,230,235,240,245,250,255,260,265,270,286,289,291,294,297,299,301,319,322,324,326,352,355,357,359],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/autobahn/websocket/interfaces.py":[27,28,30,36,39,40,41,46,48,54,75,76,82,104,105,130,210,211,218,219,220,225,227,234,262,263,270,295,296,316,380,381,388,389,390,397,399,400,420,421,428,429,442,443,456,457,458,470,471,487,488,499,509,510,521,531,534,536,545,555,562,563,576,577,593,601,604,606,616,626,634,643,644],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/autobahn/websocket/protocol.py":[27,29,30,31,32,33,34,35,36,37,38,40,41,43,45,49,51,52,53,54,55,56,57,59,60,62,65,72,75,104,152,154,157,178,220,224,229,231,253,298,302,304,308,317,350,353,356,360,369,371,373,380,385,390,396,402,408,413,418,426,427,428,429,430,433,434,435,436,441,444,447,450,453,456,459,462,465,468,471,474,477,480,483,486,489,490,491,492,493,494,495,496,497,498,499,502,503,504,505,506,507,508,509,510,511,512,513,514,515,516,517,522,523,524,525,526,527,528,529,530,531,532,533,538,539,540,541,542,543,548,552,558,566,587,604,613,620,632,642,653,662,673,772,788,811,827,837,861,888,908,930,944,1060,1107,1118,1130,1148,1169,1184,1226,1232,1238,1247,1278,1315,1324,1569,1610,1649,1687,1760,1851,1865,1885,1899,1942,1971,1996,2084,2127,2149,2168,2246,2279,2280,2281,2284,2289,2291,2358,2363,2365,2425,2428,2431,2433,2435,2437,2457,2468,2478,2481,2840,3013,3023,3034,3048,3059,3071,3076,3078,3080,3085,3091,3092,3093,3094,3095,3129,3157,3225,3313,3322,3325,3327,3329,3331,3341,3358,3367,3381,3460,3468,3539,3759,3772,3777,3779,3781,3786,3792,3793,3794,3795,3796,3797,3828,3849,3898],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/autobahn/websocket/utf8validator.py":[31,49,52,53,57,58,60,67,69,74,76,82,87,90,96,115,123],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/autobahn/websocket/xormasker.py":[27,29,32,37,42,44,45,48,50,52,54,57,60,63,66,70,72,74,79,82,85,96,98,100,117,120,123,135],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/autobahn/websocket/compress.py":[27,29,36,47,48,49,50,51,52,53,54,55,56,57,63,64,65,66,67,68,74,75,79,88,89,90,91,92,94,96,97,98,99,100,104,106,107,108],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/autobahn/websocket/compress_base.py":[32,36,39,42,45,48,51,54,57,60,63],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/autobahn/websocket/compress_deflate.py":[27,29,31,32,44,48,51,53,58,64,68,71,72,76,78,167,200,218,231,241,242,246,255,320,338,356,366,367,370,372,440,461,474,484,485,489,496,538,551,562,565,566,567,569,583,602,617,626,629,640,643,647,655,660],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/autobahn/websocket/compress_bzip2.py":[27,29,31,43,47,50,52,57,60,63,67,69,117,136,150,161,171,175,180,213,227,239,249,252,254,302,308,319,329,333,337,359,370,380,383,384,386,393,400,411,417,420,428,431,440,444,447],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/autobahn/websocket/util.py":[27,29,31,32,41,46,48,49,50,51,52,53,57,61,62,124],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/autobahn/twisted/wamp.py":[27,29,30,31,32,34,35,37,39,41,42,44,45,47,50,51,52,56,57,58,59,60,63,67,68,75,76,84,86,89,92,94,99,102,103,110,112,126,195,207,208,426,429,431,443,451,464,472,480,484,486,488,509,523,535,599,635,668,686,689,700,701,703,734,768,772,775,778,781,784,789,791,825,829,832,834,852,869],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/autobahn/rawsocket/__init__.py":[1],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/autobahn/rawsocket/util.py":[27,29,31,41,46,48,49,50,51,52,53,57,61,62,106],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/autobahn/twisted/rawsocket.py":[27,29,31,32,33,35,36,37,38,44,48,51,52,54,92,103,115,130,147,153,162,176,177,184,186,261,268,269,276,278,294,350,357,360,363,364,367,369,371,431,432,435,437,439],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/autobahn/wamp/protocol.py":[27,29,30,31,32,34,35,36,37,38,39,40,41,42,43,44,59,63,68,70,72,113,117,121,125,129,133,137,150,215,307,308,311,313,347,355,362,379,386,395,430,438,445,452,469,490,1155,1192,1199,1205,1211,1249,1267,1268,1288,1299,1390,1391,1451,1485,1583,1584,1643,1665,1675,1678,1680,1683,1701,1712,1726,1729,1734,1779,1794,1797,1800,1803,1811,1814,1816,1821,1829],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/autobahn/wamp/message.py":[27,29,30,32,34,35,36,38,39,42,43,78,82,85,88,91,94,97,100,105,108,111,114,117,119,120,121,122,125,126,127,128,131,133,134,135,136,137,138,139,142,143,144,145,146,147,148,151,154,177,202,217,276,303,329,365,370,372,383,386,399,403,408,412,417,421,426,430,435,458,470,482,485,489,492,498,531,536,538,552,555,613,721,760,767,772,774,791,794,867,951,999,1006,1011,1013,1020,1023,1039,1072,1085,1092,1097,1099,1106,1109,1125,1151,1160,1167,1172,1174,1181,1184,1200,1226,1235,1242,1247,1249,1254,1262,1265,1286,1327,1343,1350,1360,1362,1377,1381,1450,1549,1577,1584,1594,1596,1654,1676,1821,1864,1867,1873,1878,1886,1891,1898,1903,1910,1915,1922,1927,1935,1940,1948,1953,1963,1971,1981,1989,1999,2007,2017,2025,2035,2043,2053,2061,2069,2074,2082,2087,2094,2099,2107,2112,2117,2122,2126,2263,2461,2497,2516,2523,2528,2530,2537,2540,2556,2579,2588,2595,2600,2602,2607,2608,2609,2615,2618,2645,2689,2700,2709,2716,2721,2723,2730,2733,2749,2772,2781,2788,2793,2795,2802,2805,2821,2844,2853,2860,2868,2870,2878,2881,2905,2943,2960,2967,2977,2979,3028,3035,3127,3164,3167,3173,3178,3184,3189,3196,3201,3208,3213,3220,3225,3233,3238,3246,3251,3259,3264,3272,3277,3283,3288,3296,3301,3309,3314,3321,3326,3334,3339,3344,3349,3353,3429,3568,3614,3621,3626,3629,3635,3638,3649,3671,3680,3687,3697,3699,3715,3729,3809,3918,3940,3959,3966,3973,3975,3980,3981,3982,3987,3990,4021,4078,4094,4101,4111,4113,4127,4131,4200,4294,4324,4331,4336,4338,4343,4344,4345,4347,4348,4349,4350,4351,4352,4360,4363,4398,4487,4504,4513,4520,4525,4527,4534,4537,4553,4576,4585,4592,4597,4599,4606,4609,4625,4648,4657,4664,4672,4674,4682,4685,4708,4746,4763,4770,4780,4782,4802,4820,4915,5064,5107,5114,5121,5123,5128,5129,5135,5138,5181,5242,5262,5269,5279,5281,5295,5299,5364,5458,5488],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/autobahn/wamp/role.py":[27,29,31,32,43,47,51,53,55,58,66,74,78,80,95,113,117,119,128,140,144,146,154,165,169,171,186,204,208,210,218,229,233,235,247,264,265,266,267,268,269,275,276,277,278,279,280,130,131,132,133,134,135,136,137,68,69,70,282,283,284,285,286,287,288,156,157,158,159,160,161,162,290,291,292,293,294,295,220,221,222,223,224,225,226,297,298,299,300,301,302,303,304,305,249,250,251,252,253,254,255,256,257,258,259],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/autobahn/wamp/auth.py":[27,29,30,31,32,33,34,35,36,37,38,39,40,42,43,44,48,49,53,54,66,70,97,98,100,103,107,112,116,119,120,122,131,135,139,143,146,147,149,183,187,190,194,197,219,226,232,233,235,244,253,309,329,332,333,335,353,357,373,377,380,381,398,399,426,452,480,482,484,489,520,521,549,550,580,586,587,607],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/twisted/application/__init__.py":[6],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/twisted/application/service.py":[15,17,19,21,22,23,24,25,26,29,37,38,39,42,43,46,47,51,63,64,67,68,75,79,76,78,82,86,83,85,90,95,97,98,100,101,103,104,106,114,125,138,143,153,163,164,171,173,174,175,177,183,188,195,200,203,206,211,218,220,230,235,247,264,265,273,275,280,285,290,299,302,305,317,330,335,336,340,342,346,348,352,356,357,364,365,367,382,402,422,423,424],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/twisted/persisted/__init__.py":[6],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/twisted/persisted/sob.py":[10,12,14,15,17,18,19,20,21,22,23,27,29,31,37,46,49,51,55,62,74,78,88,108,110,112,114,120,131,164,181,193,194],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/twisted/persisted/styles.py":[7,9,12,13,14,15,16,17,18,19,21,24,25,27,30,31,32,33,35,36,49,62,83,119,121,141,160,162,166,175,176,177,181,196,218,235,258,259,260,261,268,272,274,281,290,295,296,298,305,314,331,350,351,352,354,358,374],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/corsheaders/__init__.py":[1,3],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/corsheaders/checks.py":[1,3,4,6,7,9,11,12,16,19,114,21,23,116,117,31,39,47,55,63,71,79,87,95,103,111],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/corsheaders/conf.py":[1,3,5,8,11,13,17,21,25,29,33,37,41,45,49,53,58,15,19,23,27,31,35,39,43,47,51,55],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/corsheaders/defaults.py":[10,19],"/home/valberg/code/bornhack/bornhack-website/src/profiles/__init__.py":[1],"/home/valberg/code/bornhack/bornhack-website/src/profiles/apps.py":[1,2,3,4,5,8,9,11,13,14,15],"/home/valberg/code/bornhack/bornhack-website/src/profiles/signal_handlers.py":[1,5,6,7,10,20,33,58,15,16,17,24,25,26,27,29,37,41,46,47,48,52,53,54,30,63],"/home/valberg/code/bornhack/bornhack-website/src/events/__init__.py":[1],"/home/valberg/code/bornhack/bornhack-website/src/events/handler.py":[1,2,3,4,5,8,38,64,17,18,19,25,28],"/home/valberg/code/bornhack/bornhack-website/src/ircbot/__init__.py":[1],"/home/valberg/code/bornhack/bornhack-website/src/ircbot/utils.py":[1,2,3,4,5,8],"/home/valberg/code/bornhack/bornhack-website/src/camps/__init__.py":[1],"/home/valberg/code/bornhack/bornhack-website/src/shop/__init__.py":[1],"/home/valberg/code/bornhack/bornhack-website/src/shop/apps.py":[1,2,3,6,7],"/home/valberg/code/bornhack/bornhack-website/src/news/__init__.py":[1],"/home/valberg/code/bornhack/bornhack-website/src/utils/__init__.py":[1],"/home/valberg/code/bornhack/bornhack-website/src/villages/__init__.py":[1],"/home/valberg/code/bornhack/bornhack-website/src/program/__init__.py":[1],"/home/valberg/code/bornhack/bornhack-website/src/program/apps.py":[1,2,5,6,8,9,14,18,19,20,22],"/home/valberg/code/bornhack/bornhack-website/src/info/__init__.py":[1],"/home/valberg/code/bornhack/bornhack-website/src/sponsors/__init__.py":[1],"/home/valberg/code/bornhack/bornhack-website/src/teams/__init__.py":[1],"/home/valberg/code/bornhack/bornhack-website/src/people/__init__.py":[1],"/home/valberg/code/bornhack/bornhack-website/src/tickets/__init__.py":[1],"/home/valberg/code/bornhack/bornhack-website/src/tickets/apps.py":[1,2,3,4,5,8,9,11,13],"/home/valberg/code/bornhack/bornhack-website/src/tickets/signals.py":[1,2,6,7,8,10],"/home/valberg/code/bornhack/bornhack-website/src/bar/__init__.py":[1],"/home/valberg/code/bornhack/bornhack-website/src/backoffice/__init__.py":[1],"/home/valberg/code/bornhack/bornhack-website/src/rideshare/__init__.py":[1],"/home/valberg/code/bornhack/bornhack-website/src/tokens/__init__.py":[1],"/home/valberg/code/bornhack/bornhack-website/src/feedback/__init__.py":[1],"/home/valberg/code/bornhack/bornhack-website/src/economy/__init__.py":[1],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/allauth/__init__.py":[9,11,13,14,15,16,17,18,19],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/allauth/account/__init__.py":[1],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/allauth/account/apps.py":[1,2,5,6,7],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/allauth_2fa/__init__.py":[1],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django_otp/__init__.py":[1,2,5,8,31,40,43,62,85,108,126,139,146],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django_otp/plugins/__init__.py":[1],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django_otp/plugins/otp_totp/__init__.py":[1],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django_otp/plugins/otp_static/__init__.py":[1],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/bootstrap3/__init__.py":[3],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django_extensions/__init__.py":[2,5,6,7,13],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/reversion/__init__.py":[7,9,10,16,21,39],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/reversion/errors.py":[1,3,6,8,11,13],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/reversion/revisions.py":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,18,23,27,33,37,39,43,40,46,50,56,64,85,89,108,112,116,120,124,128,132,136,140,159,170,211,217,273,278,300,306,308,313,316,319,327,332,338,342,345,349,353,367,368,407,414,419,427,369,401,402,371,346,339,376,377,378,379,385,382,383,380,386,388,389,390,391,394,396,354,397,355,356,399],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/reversion/signals.py":[1,5,6,9,10],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/betterforms/__init__.py":[1],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/pkg_resources/__init__.py":[16,18,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,46,47,52,53,57,58,61,62,63,64,69,70,72,73,75,79,80,81,82,83,84,85,88,91,94,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,120,124,127,134,137,142,150,157,161,166,170,174,177,203,204,205,206,207,210,211,212,215,216,219,220,223,226,227,228,231,234,237,238,239,240,241,244,247,251,252,254,258,264,266,268,272,276,279,290,294,296,298,303,304,306,309,313,317,323,326,330,331,334,336,337,338,339,340,341,344,354,367,383,387,411,412,414,417,463,473,476,487,492,497,502,503,506,509,515,518,521,525,526,528,533,538,543,546,549,553,554,556,569,589,611,626,630,646,660,668,685,716,808,891,907,921,925,931,939,942,944,959,960,963,190,393,395,396,408,191,192,198,964,986,1000,1004,1019,1030,1040,1067,1079,1085,1097,1106,1109,1122,1125,1126,1127,1129,1132,1136,1142,1148,1154,1160,1166,1194,1219,1245,1265,1291,1305,1317,1325,1337,1346,1354,1368,1383,1384,1386,1387,1388,1390,1394,1397,1400,1403,1406,1409,1415,1418,1421,1424,1427,1432,1455,1460,1465,1470,1476,1538,1546,351,1549,1550,1552,1556,1571,1572,1574,1577,1580,1583,1586,1590,1598,1592,1593,1594,1595,1601,1602,1604,1606,1608,1611,1614,1618,1615,1621,1624,1626,1645,1648,1651,1652,1654,1668,1669,1671,1672,1674,1678,1690,1700,1704,1717,1726,1781,1797,1806,1823,1827,1830,1833,1836,1840,1843,1853,1855,1858,1861,1870,1878,1882,1900,1902,1907,1908,1910,1922,138,139,1925,1935,1942,1969,1932,1972,1976,1979,2005,2037,2054,2061,2062,2064,2067,2071,2092,2107,2118,2132,2134,2135,2137,2138,2141,2159,2190,2224,2258,2270,2283,2156,2284,2286,2287,2290,2294,2297,2302,2313,2321,2328,2338,2346,2360,2361,2370,2371,2375,2376,2378,2387,2395,2398,2413,2423,2436,2437,2445,2446,2465,2474,2475,2487,2488,2507,2516,2529,2530,2531,2534,2535,2536,2546,2547,2563,2566,2577,2580,2583,2586,2589,2592,2598,2605,2613,2620,2646,2657,2669,2691,2698,2712,2717,2728,2739,2745,2753,2759,2768,2772,2773,2779,2788,2795,2807,2811,2879,2901,2909,2917,2922,2923,2941,2945,2946,2947,2949,2959,2967,2992,2993,2994,2998,3011,3012,3016,3038,3039,3059,3065,3068,3080,3083,3086,3092,3102,3110,3116,3129,3155,3170,3174,3179,3180,3175,3182,1130,3183,3184,3185,3186,3187,3176,3191,3204,574,558,559,560,561,563,564,566,567,621,622,623,1937,1938,3104,3097,3099,3105,3106,3107,1939,2007,2314,2315,2316,2317,2299,2310,2318,2009,2333,2325,2017,2075,2076,2023,2024,2029,1994,2002,2025,2041,2042,2045,2047,2049,2050,2063,2030,1973,1998,1999,2000,2031,2032,2033,2093,2094,2095,2098,1903,1904,2101,2102,2103,2548,2549,2550,2551,2553,2554,2555,2556,2558,2559,2560,2537,1322,2538,2539,1329,1331,2540,2541,2542,2543,2544,2564,2034,624,697,700,702,703,704,2607,2608,2755,2756,2609,2610,2611,708,709,710,711,713,922,575,576,577,579,3205,3207,3208,3209,3210,3212,3217,3218,3219,674,675,676,680,681,682,683,2719,2720,2721,2831,2832,2835,2836,2837,2839,2840,2847,2841,2846,2722,2723,2260,2261,2262,2267,2724,2713,2757,1407,1471,1517,1518,1519,1521,1522,1472,1473,1575,2714,1416,1410,1412,1587,1588,1413,2348,2349,2350,2352,2353,2715,2725,2726,2227,2228,2229,2232,2233,2235,2246,2247,2249,2252,2162,2163,2167,2168,2169,2171,2172,2164,2255,2263,2264,3221,3222,3223,913,915,916,917,3225,3227,706,3228,3230,3236,478,479,3088,3022,3024,3026,3029,3035,3041,3042,3045,3046,3047,3049,3050,3052,3053,3054,3055,3057,3089,480,481,356,357,640,641,3069,3070,3073,2648,2649,3078,644,482,484,128,129],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/pkg_resources/extern/__init__.py":[1,4,8,10,15,23,35,64,72,73,11,12,13,68,69,28,29,31,33,39,40,20,41,42,43,44,45,51,52,53,30],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/pkg_resources/_vendor/__init__.py":[1],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/pkg_resources/_vendor/six.py":[1,23,25,26,27,28,29,31,32,36,37,38,40,41,42,43,44,45,47,75,80,86,88,91,103,105,114,117,124,126,130,136,139,141,159,164,171,173,177,181,184,189,195,209,218,224,226,174,175,229,231,232,236,142,89,143,144,146,147,148,151,152,237,238,239,240,149,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,106,107,108,109,110,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,303,308,309,310,311,178,179,312,314,316,127,128,317,320,322,326,327,328,329,330,331,332,333,334,335,336,337,338,339,340,341,342,343,344,345,346,347,348,350,351,352,354,356,357,360,362,366,367,368,370,371,372,374,376,377,380,382,386,387,388,389,390,391,392,393,394,395,396,397,398,399,400,401,402,403,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,420,421,422,424,426,427,430,432,436,437,438,439,441,442,443,445,447,448,451,453,457,459,460,461,463,465,466,469,471,472,473,182,474,475,476,477,479,482,483,486,491,502,503,504,506,507,508,509,520,521,525,528,529,535,536,539,541,544,561,562,77,565,566,567,568,569,570,573,574,577,580,583,586,588,590,610,611,612,613,614,615,618,619,622,624,625,626,627,628,629,630,631,632,633,634,635,639,640,662,663,666,670,674,678,679,92,115,82,83,93,94,97,100,681,706,712,713,715,721,722,776,786,788,797,800,812,828,849,850,851,852,856,857,862,863,866,868,864,865,185,186,216,190,191,196,198,199,200,201,202,205,206,207,160,161,187],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/pkg_resources/py31compat.py":[1,2,3,5,8,20,21,23],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/pkg_resources/_vendor/appdirs.py":[9,16,17,20,21,23,25,26,28,41,45,100,166,206,257,314,356,407,408,410,417,422,427,432,437,442,447,455,479,506,532,558,576],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/pkg_resources/_vendor/packaging/__init__.py":[4,6,12,13],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/pkg_resources/_vendor/packaging/__about__.py":[4,7,8,11,12,13,15,17,18,20,21],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/pkg_resources/_vendor/packaging/version.py":[4,6,7,8,10,14,18,19,20,24,36,39,42,44,47,50,53,56,59,62,65,72,74,78,81,84,88,92,96,100,105,106,110,114,131,188,191,193,194,195,198,233,236,266,270,283,289,293,298,329,332,343,30,31,200,201,202,32,33,75,76,136,140,141,115,116,118,121,125,142,144,149,152,145,128,153,155,205,206,207,208,209,210,299,321,212,213,214,216,217,218,220,336,224,225,226,227,228,229,230,349,350,351,352,353,362,366,367,370,371,374,375,377,379,393,119,302,306,311,313,315,317,320,123,54,66,69,48,237,240,244,247,251,255,259,264,248],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/pkg_resources/_vendor/packaging/_structures.py":[4,7,9,12,15,18,21,24,27,30,33,36,39,41,44,47,50,53,56,59,62,65,68,34],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/pkg_resources/_vendor/packaging/specifiers.py":[4,6,7,8,9,11,12,15,18,21,23,30,36,43,50,57,64,65,70,71,78,80,82,95,108,111,114,125,136,139,144,148,152,156,160,163,182,214,227,230,231,234,235,236,237,238,239,242,247,250,253,256,259,262,266,275,369,372,373,376,377,378,379,380,381,382,383,386,267,272,413,448,452,456,460,485,516,519,543,548,551,562,589,591,612,621,624,627,650,660,670,673,676,693,697,700,729,594,598,599,606,610,674,625,702,703,708,717,724,725,726],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/pkg_resources/_vendor/packaging/_compat.py":[4,6,9,10,14,15,20,27,28,30,29],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/pkg_resources/_vendor/packaging/requirements.py":[4,6,7,9,10,11,12,14,15,18,21,24,26,27,28,29,30,31,32,34,35,36,38,39,41,42,44,45,47,48,50,51,52,53,54,56,57,59,60,61,63,64,66,67,70,72,75,81,88,109,126,89,90,96,97,104,105,106,107],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/pkg_resources/_vendor/pyparsing.py":[75,77,78,79,81,82,83,84,85,86,87,88,89,90,91,92,94,95,99,101,102,108,109,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,139,140,141,142,143,144,145,148,183,185,195,196,198,199,200,201,202,203,205,206,209,220,228,243,246,248,258,261,279,280,282,284,285,287,290,291,306,307,308,311,314,315,317,319,321,324,362,363,372,411,420,433,454,457,458,459,460,461,462,468,471,474,475,478,481,482,506,511,563,585,605,619,637,644,658,663,679,687,690,693,704,720,755,766,827,834,871,916,940,947,960,963,966,968,981,993,1003,1006,1009,1012,1039,1103,1104,1105,1106,1108,1123,1144,1167,1190,1204,1232,1250,1288,1298,1325,1338,1351,1363,1366,1370,1441,1447,1455,1456,1477,1478,1479,1536,1537,1538,1542,1565,1567,1572,1573,1574,1608,1658,1729,1772,1799,1821,1841,1853,1865,1877,1945,1948,1960,1972,1984,1996,2008,2020,2026,2045,2052,2061,2070,2079,2102,2112,2153,2156,2159,2164,2167,2173,2193,2201,2204,2207,2210,2213,2232,2364,2367,2368,2372,2375,2376,2383,2386,2387,2394,2398,2411,2412,2431,2436,2437,2439,2455,2456,2458,2479,2493,2498,2504,2514,2515,2522,2527,2535,2536,2539,2545,2569,2570,2579,2606,2652,2653,2707,2742,2765,2777,2778,2779,2813,2826,2838,2862,2863,2928,2963,2975,2990,2991,3015,3032,3046,3053,3055,3056,3057,3058,3059,3061,3081,3097,3098,3104,3107,3108,3112,3121,3130,3150,3151,3155,3160,3163,3164,3169,3180,3183,3184,3188,3195,3198,3199,3203,3213,3220,3221,3226,3233,3240,3241,3247,3256,3259,3260,3280,3283,3288,3297,3309,3319,3353,3357,3363,3368,3382,3384,3385,3390,3397,3422,3427,3434,3444,3457,3458,3465,3503,3508,3517,3523,3539,3540,3547,3571,3576,3585,3591,3644,3645,3651,3700,3709,3715,3718,3719,3737,3743,3750,3762,3768,3775,3781,3792,3808,3809,3813,3818,3828,3829,3836,3841,3850,3851,3859,3888,3912,3914,3923,3934,3935,3939,3945,3954,3955,3957,3958,3961,3962,3996,3997,4003,4017,4026,4080,4081,4094,4141,4159,4160,4163,4176,4179,4183,4190,4197,4214,4222,4223,4226,4229,4230,4234,4250,4251,4261,4268,4278,4291,4292,4296,4299,4334,4335,4339,4364,4382,4383,4386,4390,4393,4394,4397,4403,4406,4450,4469,4500,4509,4537,4565,4573,4646,4681,4718,4725,4750,2377,2369,1145,1146,1148,1149,1150,1151,1152,1153,1154,1155,1156,1157,1158,1159,1160,1161,1162,1163,1164,1165,2378,2379,2380,1198,1199,1200,1202,4751,3152,3099,3100,3101,3102,3153,4752,3165,3166,2065,2066,2067,2068,3167,4753,3185,3186,4754,3200,3201,4756,2654,2655,2659,2660,2661,2662,2663,2668,2670,2673,2675,2678,2680,2681,2682,2684,2743,2744,2154,2745,2746,2749,2751,2757,2758,2752,2755,2753,2762,2685,2686,2687,2689,1284,1040,1042,1043,1046,1047,1052,1063,1066,1049,1050,1051,1067,1069,1093,1094,1095,1096,1099,1101,1285,1286,4757,2781,2783,2784,2788,2789,2791,2792,2793,2808,2827,2828,2829,2830,2832,2833,2835,2809,2810,2811,4758,4759,1952,1954,1958,3541,3261,3262,3265,3267,3268,3270,3272,3278,3542,3543,2992,2993,2994,2996,2999,3001,3004,3006,3007,3008,3010,3033,3034,3035,3036,3038,3039,3042,3044,3011,3012,3013,4760,4231,3720,3721,3722,3723,2413,2414,2415,2416,2417,2422,2423,2424,2425,3726,3727,3728,3729,3730,3731,3732,3733,3734,3735,4232,1833,1835,1839,3391,3392,3393,3394,3395,4293,4294,4761,3998,3999,4000,4001,1224,1183,1184,1185,1186,1188,1225,1228,1229,1230,3852,3853,3854,3855,3857,1834,4763,4787,4797,4811,4825,4869,4857,4860,4861,4862,4865,4867,4872,4875,4904,4923,4932,4995,4997,5032,5033,5034,5036,5148,5151,4252,4254,4255,3744,3745,3364,3365,1187,3366,3746,3747,3291,3292,3293,3294,2058,2059,3295,3748,4256,4257,4258,4259,5152,5153,5154,5155,5157,5247,5361,4781,4782,4783,1635,1569,1570,1636,1637,3320,2160,2161,2162,3322,3323,3763,3764,3765,3766,3328,3329,3330,3339,3340,3349,3435,3438,3439,4018,4021,4022,4024,3441,3351,3577,3580,3581,3583,3331,3332,3333,3334,3335,3336,3337,3782,3783,3784,3785,3787,3788,3789,3341,3342,3343,3344,3345,3346,3347,3915,3918,3919,3921,1639,1641,1642,1643,1644,1371,1373,1395,1396,1352,1355,1356,1357,1358,1361,1399,1400,1401,1402,3400,1398,1406,2432,2433,2434,1408,1367,1410,364,366,367,368,373,374,375,376,377,378,379,380,382,384,387,388,390,1411,1434,1439,3401,3402,3403,3406,3417,4004,4005,2435,210,211,215,216,217,218,4006,4007,4014,4015,383,391,393,395,396,3418,509,3738,3739,3860,3861,3862,3863,3868,3870,3548,3549,3550,3551,3552,2708,2716,2719,2720,2721,2722,2723,2724,2725,2728,2729,2730,2731,2733,2737,2738,3554,3555,3556,3557,2814,2815,2818,2819,2820,2821,2824,365,1412,1427,1428,1070,1071,1072,412,413,1073,1074,1429,1430,1431,1432,1433,3553,4384,3419,664,675,676,677,3420,4297,3871,3872,3873,3874,3876,3879,3880,3881,3882,2717,2816,3016,3017,3565,3566,3567,1403,3883,3884,3886,397,399,400,403,316,421,422,423,318,430,431,404,415,416,665,666,667,668,669,670,671,672,673,1645,1656,645,646,5362,5364,2690,2692,2697,2698,4567,4568,4569,4570,4571,2699,2700,2702,2703,4921,4877,4881,4883,4884,4890,4891,2665,2666,2760,2691,4895,2040,2041,3936,3937,4336,4337,4896,4898,3354,3355,4899,4900,4901,4902,5365,5366,5367,5372,5375,5378,5379,5382,5385,5388,5391,2656,2657,5392,5393,2024,3830,3832,3833,3834,3842,3845,3846,3848,5394,4463,4464,4467,5399,5533,5535,5540,5545,5548,5551,5554,2043,5556,1294,1295,1296,5558,2050,5560,1041,5562,5565,5569,5572,5575,5578,5581,5582,1845,1846,1847,1851,1897,1898,1918,1920,1922,1925,1939,1942,1943,5583,1899,1900,1901,1903,1910,1911,1912,1926,1931,1937,1927,1928,1930,5584,1315,1316,1317,1318,1321,1322,1323,5585,5586,5589,5592,5593,5614,5615,5636,5639,5642,5645,5646,5661,5662,3062,3063,3064,3066,3067,3068,3070,3072,3075,3077,5663,5666,5669,5670,5673,2864,2867,2868,2872,2873,2880,2881,2882,2883,2884,2885,2886,2887,2888,2890,2897,2898,2899,2900,2901,2902,2908,2910,2913,2915,2916,2917,2923,2964,2965,2966,2967,2969,2970,2972,2924,2925,2926,4161,4164,4166,4167,4168,4169,4170,4171,4172,4173,4174,1976,1978,1982,3459,3460,3461,4705,4706,4707,4708,4709,4710,4714,4715,4716,4215,4216,3946,3949,3950,3952,4184,4185,4186,4187,4188,4198,4200,3509,3512,3513,3515,3189,3193,2709,2710,2713,2714,3940,3941,2711,3942,3943,4269,759,760,761,762,763,764,4270,434,435,436,439,444,445,447,4271,694,695,696,698,701,702,4273,4276,406,407,424,428,429,1404,1364,408,409,3466,3467,3468,3469,3470,3471,1442,1443,1444,3472,3473,3474,3475,3476,3485,3496,3497,3498,647,648,401,3204,3206,3207],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/pkg_resources/_vendor/packaging/markers.py":[4,6,7,8,9,11,12,13,15,16,20,21,25,28,31,34,37,41,44,46,49,52,55,59,61,65,67,71,73,94,95,98,99,100,101,102,103,105,114,115,118,119,121,122,124,126,128,129,131,132,134,135,136,138,141,148,172,173,174,175,176,177,178,179,183,200,203,214,241,249,272,274,282,285,288],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/debug_toolbar/__init__.py":[1,3,6,7,9,16,18],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/debug_toolbar/apps.py":[1,3,5,6,7,8,9,10,13,14,15,18,76,20,22,23,24,26,27,28,33,34,77,78,81,82,36,37,39,50,61,73],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/middleware/gzip.py":[1,3,4,5,7,10,15,16],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/contrib/admin/models.py":[1,3,4,5,6,7,8,9,10,12,13,14,17,18,19,23,24,26,39,40,41,42,43,45,46,47,48,50,51,52,53,54,56,58,59,61,63,65,66,67,68,69,71,74,87,90,93,96,136,140],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/contrib/contenttypes/models.py":[1,3,4,5,8,9,11,17,25,30,34,62,105,119,125,134,135,136,137,12,15,139,140,141,142,143,145,148,155,162,171,177,40,26,27,28,41,42,31,32,43,44,48,51,59,129,130,131,60,123,52,55,56,57],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/contrib/auth/models.py":[1,2,3,4,5,6,7,8,9,11,14,23,24,26,33,55,56,57,58,59,60,62,63,65,66,67,68,70,72,79,81,84,87,88,90,94,110,111,112,113,114,115,118,120,121,122,124,127,131,132,134,147,152,165,173,188,203,207,208,209,210,211,212,216,217,218,219,220,221,224,225,227,228,229,230,231,232,233,236,237,239,251,254,269,276,288,294,295,297,298,299,300,301,302,304,307,308,309,310,311,312,313,315,316,317,318,319,323,325,327,328,329,331,332,333,334,336,340,347,351,356,362,363,364,367,368,369,370,371,372,373,374,375,377,380,383,386,389,392,395,398,402,406,409,412,415,418,421,425,429],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/contrib/auth/base_user.py":[4,5,7,8,11,12,13,16,18,33,43,47,48,49,51,53,57,59,60,62,66,69,72,78,81,89,97,101,113,117,123,130,137,87,95,73,74],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/contrib/auth/password_validation.py":[1,2,3,4,5,7,8,11,12,13,14,17,22,35,54,66,78,88,91,94,95,98,110,118,128,129,131,135,156,160,169,170,172,182,189,193,196,197,204],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/contrib/auth/hashers.py":[1,2,3,4,5,6,7,9,10,11,12,13,16,17,19,20,23,31,65,81,94,99,106,129,150,160,168,169,170,172,187,191,195,204,213,216,230,237,238,239,240,242,250,256,266,270,277,283,284,285,288,295,296,297,299,300,301,303,316,329,344,356,361,389,397,398,399,400,401,403,407,419,425,436,440,451,463,464,465,468,471,472,474,480,486,495,499,502,503,505,511,517,526,530,538,539,541,544,549,553,561,565,575,576,578,581,585,591,597,601,606,607,608,610,613,621,627,636],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/db/backends/postgresql/__init__.py":[1],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/db/backends/postgresql/base.py":[5,7,8,10,11,12,13,14,15,16,17,19,20,21,22,27,32,28,29,34,39,40,41,42,43,44,45,47,48,52,53,54,55,56,58,61,62,63,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,96,97,100,101,102,103,104,105,106,107,108,109,110,111,112,113,124,126,127,128,129,130,131,134,135,137,138,139,140,141,143,145,177,197,207,216,226,236,240,248,257,280,259,260,261,146,148,152,163,164,166,167,168,169,170,171,172,173,175,178,185,186,187,188,189,195,237,238,208,210,198,199,200,201,202,203,204,211,213,278,217,222,223,224,227,228,229,231,232,220,249,251,255,245,246],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/db/backends/base/__init__.py":[1],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/db/backends/base/base.py":[1,2,3,4,5,7,8,10,11,12,13,14,15,16,17,18,19,21,24,25,27,29,31,32,33,34,35,37,38,39,40,41,42,44,46,47,108,115,135,147,151,161,165,169,173,179,201,212,220,231,236,241,246,253,257,266,276,297,301,305,309,315,335,350,360,368,376,381,412,419,428,434,442,454,462,469,479,491,518,536,543,551,558,562,566,583,598,607,616,627,635,647,50,54,55,57,58,63,65,67,69,72,75,78,79,80,83,84,89,93,99,101,102,103,104,105,106,592,593,594,595,214,215,549,216,182,202,184,185,186,188,189,190,191,193,194,195,393,430,394,397,401,404,406,408,196,140,142,143,378,379,197,199,255,232,233,234,224,525,225,149,228,564,229,435,278,279,284,285,541,611,614,398,259,260,261,237,238,239,263,264,409,628,629,630,631,410,321,311,324,325,327,328,330,331,298,299,333,423,426,339,342,343,302,303,347,354,357,358,306,307,268,269,270,242,243,244,272,273,274,286,287,247,248,249,289,293],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/db/backends/base/validation.py":[1,2,3,6,9,4,10,12,25],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/db/backends/signals.py":[1,3],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/db/backends/postgresql/client.py":[1,2,3,5,6,9,16,17,19,70],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/db/backends/base/client.py":[1,2,5,7,11,9],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/db/backends/postgresql/creation.py":[1,3,5,6,9,11,14,22,32,36,53,23,24,27,28,29,15,16,18,20,37,38,33,34,41],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/psycopg2/errorcodes.py":[4,33,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,103,106,107,108,109,110,111,112,113,116,117,120,123,124,125,126,127,128,129,132,135,138,141,142,145,146,149,152,153,156,159,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,216,217,218,219,220,221,222,225,228,229,230,231,232,233,234,235,236,237,238,239,242,245,248,249,252,253,256,259,260,261,262,263,266,269,270,271,272,273,276,277,278,279,280,281,284,285,288,291,294,295,296,297,298,301,302,303,304,305,306,307,308,309,310,311,312,313,314,315,316,317,318,319,320,321,322,323,324,325,326,327,328,329,330,331,332,333,334,335,336,337,338,339,340,341,342,343,344,347,350,351,352,353,354,357,358,359,360,363,364,365,366,367,370,371,372,373,374,375,378,379,380,381,384,387,388,391,392,393,394,395,396,397,398,399,400,401,402,403,404,405,406,407,408,409,410,411,412,413,414,415,416,417,420,421,422,423,424,427,428,429],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/db/backends/base/creation.py":[1,2,4,5,6,7,11,14,18,19,22,29,85,92,122,131,140,151,154,197,216,226,234,264,276,282,20,288,290,291,292,293,147,149,35,37,39,40,41,42,44,45,46,135,136,137,54,158,160,161,164,27,165,166,195,56,57,58,63,64,65,66,67,68,75,76,99,100,101,102,104,105,106,108,111,118,119,112,113,114,115,116,120,78,81,83,239,240,241,245,246,247,248,249,250,251,256,260,261,262],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/db/backends/postgresql/features.py":[1,2,3,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,42,50,51,52,53,54,56,60,61,62,63],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/db/backends/base/features.py":[1,2,3,6,7,8,9,10,11,14,19,23,25,26,27,28,29,30,34,35,36,37,38,39,42,46,49,54,57,60,61,64,67,71,74,77,80,83,87,90,93,96,100,103,107,110,113,118,121,124,127,130,133,136,139,142,146,149,152,156,159,162,165,168,171,174,179,182,185,188,191,195,198,201,203,206,210,214,218,221,224,225,226,227,231,234,237,240,244,245,248,251,254,258,260,263,268,282,261],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/db/backends/postgresql/introspection.py":[1,4,7,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,30,32,41,54,72,92,111,128,43,49,50,51,52],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/db/backends/base/introspection.py":[1,4,7,10,11,12,14,17,27,35,43,58,65,94,110,135,143,151,160,15,50,53,56,51,52],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/db/backends/postgresql/operations.py":[1,3,4,5,8,9,10,12,25,33,37,42,46,50,54,59,62,65,73,92,95,98,103,106,129,145,151,195,198,211,218,225,228,233,236,239,242,247,254,263,209,99,101,104,63,234,237,229,230,231,226,74,77,78,87,90,71],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/db/backends/base/operations.py":[1,2,3,5,6,7,8,9,10,13,17,18,23,24,25,26,27,30,31,32,37,39,42,43,44,45,46,49,51,55,64,72,82,90,97,103,111,120,126,134,142,150,157,164,175,183,192,199,209,217,225,247,256,264,271,278,285,292,312,319,328,338,345,349,360,368,374,380,388,404,411,421,431,435,441,452,458,460,468,487,496,505,516,523,530,544,562,571,575,586,596,599,606,613,621,628,638,648,656,659,52,53,334,335,336,569,611,181,190,584,269,219,210,211,212,220,221,222,70,466,619,366,378,372],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/db/backends/postgresql/schema.py":[1,3,6,8,10,11,12,14,15,16,17,21,23,25,28,35,57,109,29,30,40,41,49,51,53,55,31,33,52,32,112,120,121,122,125,126,132,113,114,115],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/db/backends/base/schema.py":[1,2,3,5,8,9,10,11,12,14,17,33,42,47,50,51,52,53,55,56,57,58,59,60,61,62,63,64,66,67,69,70,73,76,77,79,80,82,83,85,87,96,103,112,135,138,151,199,206,215,241,253,322,338,342,346,362,378,389,404,412,454,484,526,775,797,828,849,870,899,909,910,936,955,964,967,970,975,983,1002,1013,1021,1048,1058,88,89,90,92,97,98,99,100,101,104,105,107,108,259,260,261,263,157,158,159,161,164,166,167,180,183,185,186,188,189,193,194,197,264,267,268,271,272,274,276,287,288,136,289,292,190,181,191,299,303,304,305,307,312,116,122,124,125,132,133,315,941,943,944,945,959,960,965,962,916,900,901,903,905,907,917,918,919,921,927,928,929,930,931,932,933,947,951,953,318,277,278,279,284,285,984,985,986,987,989,992,993,994,995,996,997,998,999,961,493,494,495,496,497,498,504,509,515,522,523,529,530,542,557,558,561,580,593,604,611,612,613,615,626,217,219,224,234,236,239,627,629,630,631,635,638,639,782,787,788,790,791,792,794,640,641,644,647,648,651,653,654,655,657,658,659,660,661,663,665,685,689,692,971,972,703,707,708,711,968,725,741,746,751,764,772,418,421,204,168,169,184,423,426,427,430,431,432,433,435,438,446,448,449,451,352,353,355,358,359,360,1003,1005,1006,1007,1008,1009,1010,1004,877,878,144,145,146,147,879,881,882,883,106,923,924,925,990,559,220,223],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/db/backends/ddl_references.py":[4,7,8,10,16,22,28,34,37,41,42,44,48,51,55,59,60,62,66,69,76,77,79,84,94,95,97,102,106,107,109,115,118,124,128,132,140,147,148,152,158,164,169,174,45,46,98,99,100,63,64,80,81,82,149,150,110,111,112,113,175,56,103,85,91,86,87,88,89,133,134,135,137],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/db/backends/postgresql/utils.py":[1,4,5,7],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/contrib/auth/validators.py":[1,3,4,5,8,9,10,11,12,15,18,19,20,21,22,25],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/contrib/sessions/models.py":[1,6,7,10,26,27,29,34,35],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/contrib/sessions/base_session.py":[4,5,6,9,10,17,26,27,28,29,31,33,34,35,36,38,41,45],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/contrib/sites/models.py":[1,3,4,5,6,7,9,12,27,28,30,36,50,71,76,80,82,83,84,85,86,88,89,91,92,93,94,95,97,100,104,120,121],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/corsheaders/models.py":[1,3,6,7,8,9,11],"/home/valberg/code/bornhack/bornhack-website/src/profiles/models.py":[1,2,3,5,8,9,10,11,13,14,15,16,17,20,21,22,23,24,27,28,29,30,33,34,35,36,39,40,41,44,45,46,47,50,54,57,65],"/home/valberg/code/bornhack/bornhack-website/src/utils/models.py":[1,2,3,4,5,6,7,10,11,12,14,34,35,36,38,39,40,41,45,46,47,49,50,53,55,57,58,60,68,76,81,82,83,84,85,86,87,88,89,91,92,93,94,96,97,98,99,101,102,104,107,15,21,22,23,31],"/home/valberg/code/bornhack/bornhack-website/src/camps/models.py":[1,2,3,4,5,6,7,8,9,10,11,14,17,18,19,20,28,32,33,34,35,36,38,39,40,41,44,45,46,47,50,51,52,55,56,57,60,61,62,65,66,67,70,71,72,75,76,77,80,81,82,83,86,87,88,91,92,93,96,97,98,99,102,103,104,107,108,109,110,113,116,134,137,142,147,151,155,159,163,206,213,220],"/home/valberg/code/bornhack/bornhack-website/src/program/models.py":[1,2,3,4,5,7,8,9,10,11,12,13,14,15,16,17,18,19,21,24,27,30,31,32,33,34,37,38,39,40,43,44,46,50,59,60,61,62,63,66,67,70,71,72,73,76,77,78,79,80,81,82,85,86,87,88,89,90,91,94,95,96,97,98,99,100,103,104,105,106,107,108,109,112,115,129,145,150,151,152,153,160,164,166,167,169,170,171,172,175,176,177,180,181,182,185,186,187,191,192,193,196,197,198,199,202,205,213,222,223,225,226,227,228,229,232,233,234,237,238,239,242,243,246,247,248,251,252,253,256,260,263,302,309,310,311,312,313,314,315,318,319,320,323,324,325,328,329,330,331,334,335,336,337,338,341,342,343,346,347,348,349,350,353,354,355,358,362,364,368,374,384,423,433,434,436,437,438,441,442,445,446,447,448,449,452,453,454,455,456,459,462,463,465,472,473,475,476,479,481,482,483,486,487,488,489,492,495,496,498,506,507,508,509,510,511,514,516,517,518,519,522,523,524,527,528,529,532,533,534,535,538,539,540,543,544,545,548,549,550,553,554,555,556,559,562,571,572,574,575,576,579,580,583,584,585,586,589,590,591,592,595,596,597,598,599,602,603,604,605,606,609,610,611,614,615,616,617,618,619,620,623,624,625,627,630,635,639,641,647,650,675,676,678,679,680,681,684,686,687,690,691,692,693,696,697,699,702,706,710,712,723,730,739,774,775,777,778,779,782,783,784,787,788,791,792,793,794,797,798,799,800,801,802,805,806,807,808,809,812,813,814,815,816,817,818,821,822,823,826,827,828,830,833,838,841,850,851,852,853,854,856,857,858,861,862,866,870,871,873,880,887],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/icalendar/__init__.py":[2,4,17,39,45],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/icalendar/cal.py":[6,7,8,9,10,11,12,13,14,15,16,17,19,20,21,23,29,32,34,51,52,53,54,57,60,64,66,67,68,69,70,71,73,79,98,104,106,111,118,156,209,227,248,256,267,272,282,293,319,320,404,410,420,429,443,445,450,453,458,460,463,465,468,470,472,477,479,482,486,488,490,493,497,501,503,505,508,510,513,514,515,516,517,519,568,580,654,655,656,657,658,661,662,663,664,665,668,670,672,675,677,678,681,683,684,685,686,687,690,691,37,38,39,40,41,42,43,44,45,46],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/icalendar/caselessdict.py":[2,3,5,8,18,25,28,30,40,44,48,52,56,60,64,68,71,75,84,87,90,95,97,103,33,45,46,34,35,36],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/icalendar/compat.py":[2,5,10,11,12],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/icalendar/parser_tools.py":[2,5,6,9,22,12,13],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/icalendar/parser.py":[8,9,11,12,13,14,15,17,20,33,52,65,103,115,117,118,119,120,121,124,131,139,142,154,179,185,188,190,215,230,231,267,273,278,288,291,292,300,301,321,357,358,365,372,376,377,382,399],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/icalendar/prop.py":[37,38,39,40,41,42,44,45,49,50,51,52,53,54,55,56,57,58,59,61,62,63,64,65,68,69,70,71,72,73,74,82,83,84,85,86,89,92,94,95,99,102,105,109,111,112,118,124,127,136,138,140,144,147,150,158,160,161,163,168,173,181,183,184,190,193,196,201,203,204,209,212,220,222,223,228,231,239,241,242,258,262,263,270,272,277,280,281,286,290,291,315,330,331,352,354,355,361,365,378,388,389,393,411,412,444,447,449,455,480,499,501,502,534,539,546,553,563,571,573,574,575,578,594,597,605,607,609,610,611,612,613,614,615,616,619,627,630,638,640,642,643,650,652,653,654,655,656,657,658,659,660,661,662,663,664,665,666,669,673,687,693,712,714,716,723,726,729,735,737,739,748,751,761,763,765,771,774,782,784,786,798,801,810,812,814,819,825,846,866,870,871,877,880,885,891,893,942,946,947,948,949,951,952,953,954,955,956,957,958,959,960,961,962,964,965,966,967,968,969,970,972,973,974,975,976,978,979,980,981,982,983,984,986,987,988,989,991,992,993,995,996,997,998,1000,1003,1004,1005,1006,1007,1008,1009,1010,1011,1012,1013,1014,1015,1016,1017,1018,1019,1020,1021,1022,1025,1030,1037,895,897,898,899,900,901,902,903,904,905,906,907,908,909,910,911,912,913,914,915,916,917,919,920,921,922,923,924,925,926,927,928,929,930,931,932,933,934,935,936],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/dateutil/__init__.py":[2,3,7,8],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/dateutil/_version.py":[4],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/dateutil/tz/__init__.py":[2,3,8,10,11,12,13,16,17],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/dateutil/tz/tz.py":[9,10,11,12,13,14,15,16,17,19,20,21,22,23,24,26,27,28,29,30,31,34,36,37,38,41,42,73,74,77,80,84,100,108,115,117,120,123,126,127,136,137,148,151,154,158,162,176,182,184,187,192,195,198,199,212,221,230,234,252,256,296,311,313,316,319,322,323,324,326,330,338,350,352,355,361,367,371,372,373,375,380,450,452,476,482,706,721,732,737,773,802,815,824,840,846,853,855,858,861,864,868,942,945,990,1014,1025,1030,1031,1072,1073,1105,1146,1150,1152,1161,1162,1171,1216,1224,1230,1237,1241,1244,1247,1257,1258,1275,1281,1308,1324,1449,1453,1454,1455,1456,1457,1458,1464,1666,1465,1466,1469,1538,1539,1546,1573,1579,1584,1585,1663,1541,1542,1543,1544,1667,1670,1704,1750,1796,1804,1805,1818,1820,1821,1822,1826,1827,1830,1833],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/dateutil/tz/_common.py":[1,3,5,8,10,13,35,37,132,149,152,154,179,204,207,244,137,146,267,288,289,292,302,312,19,30,319,352,374,395,407,411,413,416,419],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/dateutil/tz/_factories.py":[1,2,3,6,7,11,17,18,23,24,29,50,51,56,8,9,25,26,27,52,53,54,12,13,14],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/dateutil/tz/win.py":[8,10,11,13],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/icalendar/timezone_cache.py":[3],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/icalendar/windows_to_olson.py":[10,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/dateutil/rrule.py":[7,8,9,10,11,12,14,15,19,20,21,23,24,27,29,30,31,32,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,51,59,62,63,66,69,70,77,71,74,80,93,94,104,112,123,148,170,182,190,211,229,270,304,426,432,699,761,775,1031,1078,1111,1112,1113,1114,1115,1117,1122,1252,1255,1262,1277,1283,1293,1301,1306,1312,1314,1315,1324,1334,1336,1339,1342,1345,1348,1355,85,90,1361,1367,1375,1382,1417,1460,1462,1463,1464,1465,1466,1467,1468,1470,1471,1473,1476,1479,1480,1481,1482,1483,1484,1485,1486,1487,1488,1489,1491,1494,1505,1508,1534,1540,1562,1622,1730,1734],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/dateutil/_common.py":[3,6,7,9,13,19,27,33,36,10,11],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/contrib/contenttypes/fields.py":[1,3,4,5,6,7,8,9,10,14,15,18,25,28,29,30,31,33,34,35,36,37,38,39,41,49,55,62,69,74,81,93,108,158,161,171,217,246,258,261,263,271,274,277,279,280,281,282,284,286,289,312,318,330,350,354,394,411,424,428,451,454,457,464,472,483,494,496,504,42,43,44,45,46,47,50,51,52,53,76,82,91,77,94,95,106,78,113,114,127,141,156],"/home/valberg/code/bornhack/bornhack-website/src/shop/models.py":[1,3,4,5,6,7,8,9,10,11,12,13,14,15,16,18,19,21,24,25,26,29,30,33,34,37,38,39,40,43,44,45,48,51,59,60,61,62,64,65,66,69,70,71,72,73,74,77,78,79,80,83,84,85,86,89,90,91,92,95,96,97,98,102,103,104,105,108,109,110,111,112,115,117,118,119,120,123,124,125,126,127,130,131,132,135,136,137,138,141,143,146,151,155,168,176,179,182,185,188,192,195,224,230,255,267,273,280,286,297,312,313,314,315,317,318,319,321,324,329,330,331,332,333,335,336,337,338,341,342,344,345,348,350,351,352,357,358,359,360,361,364,366,369,370,373,375,381,387,400,406,412,416,429,438,439,440,441,442,444,448,455,456,457,458,459,461,462,464,468,469,470,471,473,474,475,478,479,480,482,483,484,487,488,491,492,493,494,497,498,499,500,501,502,503,504,507,508,509,510,513,514,515,518,519,520,521,524,526,539,553,560,565,566,567,568,569,570,572,573,574,575,576,578,579,581,600,604,608,609,610,611,613,616,621,622,623,624,625,626,628,632,633,634,635,636,638,325,326,382,418,419,420,421,422,424,426,395,402,403,404,396,397,431,432,433,398,449],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/unidecode/__init__.py":[16,17,18,20,23,31,56,66,68],"/home/valberg/code/bornhack/bornhack-website/src/shop/managers.py":[1,2,5,7,14,16,19,22,25,28],"/home/valberg/code/bornhack/bornhack-website/src/news/models.py":[1,2,3,4,6,9,10,11,12,14,15,16,17,18,20,23,46],"/home/valberg/code/bornhack/bornhack-website/src/villages/models.py":[1,2,3,4,7,9,10,11,13,14,15,16,17,18,21,22,23,26,27,30,33,36,61],"/home/valberg/code/bornhack/bornhack-website/src/info/models.py":[1,2,3,5,8,9,10,11,13,14,15,18,19,22,23,24,27,28,29,30,31,34,41,45,47,52,53,54,55,56,58,59,60,61,64,65,66,69,70,73,74,77,78,79,82,86,88,93],"/home/valberg/code/bornhack/bornhack-website/src/sponsors/models.py":[1,3,6,16,17,18,19,22,24,25,28,29,30,33,34,35,36,39,41,44,48,51,52,53,54,57,58,61,62,63,64,65,66,69,70,72,75,76,77,78,81],"/home/valberg/code/bornhack/bornhack-website/src/ircbot/models.py":[1,2,3,4,7,8,9,10,11,12,14,17],"/home/valberg/code/bornhack/bornhack-website/src/teams/models.py":[1,3,4,5,6,7,8,9,10,12,14,38,41,42,43,44,45,48,49,50,53,54,55,56,59,60,63,65,66,67,70,71,72,73,77,78,81,82,83,86,87,88,92,93,94,95,96,97,99,100,101,103,104,105,107,108,109,112,113,114,115,116,117,119,120,121,123,124,125,127,128,129,132,133,134,137,138,139,141,142,143,144,145,148,151,154,166,191,202,211,220,231,243,256,258,259,260,261,264,265,266,267,270,271,272,275,276,277,280,281,282,285,286,288,296,301,304,305,306,307,308,309,311,312,313,315,316,317,318,320,321,323,324,325,326,328,329,330,333,334,335,337,340,345,347,354,355,356,357,360,362,363,365,366,367,368,369,372,374,375,376,379,380,383,388,390,397],"/home/valberg/code/bornhack/bornhack-website/src/tickets/models.py":[1,2,3,4,5,6,7,8,12,13,14,15,19,20,21,23,27,28,29,30,32,33,35,39,47,58,63,71,72,74,77,82,83,84,87,90,95,96,97,98,99,101,103,104,106,109,110,113,114,115,119,128,134,139],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/qrcode/__init__.py":[1,2,3,6,9,23],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/qrcode/main.py":[1,2,4,5,8,14,20,26,37,39,40,41,42,43,58,67,85,99,126,144,173,191,220,273,300,311,334,345,376,421],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/qrcode/constants.py":[2,3,4,5],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/qrcode/exceptions.py":[1,2],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/qrcode/util.py":[1,2,4,5,7,10,11,12,13,17,18,19,20,23,24,25,26,29,30,31,32,35,36,39,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,86,89,90,92,93,96,98,100,99,104,112,119,127,131,154,163,175,188,229,256,332,340,370,384,394,405,410,412,433,436,461,465,467,471,474,478,482,485,494,558],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/qrcode/base.py":[1,3,5,7,8,10,12,13,15,16,19,20,21,22,33,34,35,36,39,40,41,42,45,46,47,48,51,52,53,54,57,58,59,60,63,64,65,66,69,70,71,72,75,76,77,78,81,82,83,84,87,88,89,90,93,94,95,96,99,100,101,102,105,106,107,108,111,112,113,114,117,118,119,120,123,124,125,126,129,130,131,132,135,136,137,138,141,142,143,144,147,148,149,150,153,154,155,156,159,160,161,162,165,166,167,168,171,172,173,174,177,178,179,180,183,184,185,186,189,190,191,192,195,196,197,198,201,202,203,204,207,208,209,210,213,214,215,216,219,220,221,222,225,226,227,228,231,232,233,234,237,238,239,240,243,244,245,246,249,250,251,252,255,256,257,258,261,262,263,264,267,268,269,270,275,281,285,287,299,302,305,308,317,334,336,341,342,346,347,349,351,352,353,354,337,338,356],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/qrcode/LUT.py":[28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/qrcode/image/__init__.py":[1],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/qrcode/image/base.py":[1,4,5,6,8,15,21,27,36,42,48],"/home/valberg/code/bornhack/bornhack-website/src/utils/pdf.py":[1,2,3,5,6,7,8,9,10,13],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/wkhtmltopdf/__init__.py":[1,2,3,5,6],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/wkhtmltopdf/utils.py":[1,3,4,5,6,7,8,9,11,13,14,15,20,21,22,23,24,26,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,52,73,149,168,172,173,174,176,188,194,239,254,273,278,312],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/wkhtmltopdf/subprocess.py":[1,3,7,8],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/wkhtmltopdf/views.py":[1,3,4,5,7,10,11,14,24,38,39,45,63,84,85,88,91,94,95,96,97,100,101,104,110,116,128,131,134],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/PyPDF2/__init__.py":[1,2,3,4,5],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/PyPDF2/pdf.py":[37,39,40,42,43,45,46,47,48,49,50,51,54,56,59,61,62,63,64,65,66,67,69,72,75,76,79,83,84,113,117,122,130,140,151,164,172,190,214,247,328,354,373,382,398,445,529,541,596,602,616,651,665,690,751,759,774,784,839,893,963,965,978,999,1003,1005,1019,1039,1041,1044,1060,1061,1089,1106,1109,1125,1131,1158,1164,1179,1180,1189,1231,1246,1252,1276,1286,1327,1333,1379,1395,1408,1422,1427,1452,1453,1460,1474,1478,1492,1496,1531,1584,1636,1649,1669,1676,1685,1919,1922,1930,1965,1991,2025,2043,2046,2051,2054,2070,2076,2080,2089,2101,2102,2107,2140,2142,2153,2164,2168,2181,2183,2193,2195,2203,2205,2214,2216,2228,2241,2315,2330,2346,2363,2379,2410,2436,2462,2498,2512,2544,2553,2567,2581,2623,2082,2083,2084,2085,2630,2639,2646,2652,2657,2660,2661,2676,2708,2756,2775,2778,2781,2794,2796,2799,2805,2809,2812,2816,2819,2823,2826,2832,2835,2841,2842,2845,2854,2855,2860,2904,2931,2955,2970],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/PyPDF2/filters.py":[33,34,35,37,38,39,42,43,45,46,48,51,109,110,150,152,154,157,158,176,179,182,183,184,195,199,219,253,254,258,259,332,335],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/PyPDF2/utils.py":[30,31,32,35,37,38,39,40,43,44,46,47,48,52,57,62,68,73,89,99,112,120,144,145,149,152,168,185,192,205,206,209,210,213,214,217,218,221,222,225,229,231,244,251,261,268,275,282,291,295,232,233,235,238,239,240,241,245,248,54],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/PyPDF2/generic.py":[33,34,35,37,38,39,40,41,42,43,44,45,46,49,50,51,54,101,102,107,108,111,116,119,120,123,129,138,141,142,149,168,171,172,177,180,183,192,195,198,223,226,227,233,244,247,251,252,253,255,262,265,268,274,280,303,325,400,405,407,421,422,423,430,432,445,467,468,469,471,474,494,497,498,501,508,515,526,542,544,553,641,644,645,648,651,654,665,690,758,775,776,780,791,801,803,821,822,825,829,830,833,848,852,861,862,868,873,876,879,882,885,888,891,894,897,900,903,906,909,912,915,918,921,924,927,930,935,940,945,949,952,956,957,967,972,977,982,987,992,999,1005,1011,1016,1021,1024,1044,1045,1067,1070,1087,1094,1101,1108,1115,1122,1129,1136,1141,1144,1145,1162,1173,1184,1185,1186,1187,1188,1189,1190,1191,1192,1193,1194,1195,1196,1197,1198,1199,1200,1201,1202,1203,1204,1205,1206,1207,1208,1209,1210,1211,1212,1213,1214,1215,1218,1220,1221,1222,1223,1224,1225,1226],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/PyPDF2/merger.py":[30,31,32,33,34,35,39,40,41,44,48,49,56,68,70,79,183,205,235,248,258,275,291,307,331,347,421,438,462,476,507,519,520,526,531,550],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/PyPDF2/pagerange.py":[8,10,11,13,14,18,19,33,36,48,50,84,85,87,95,99,111,115,123,63,67,71,72,74,80,81,126],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/PyPDF2/_version.py":[1],"/home/valberg/code/bornhack/bornhack-website/src/bar/models.py":[1,2,5,6,7,9,12,13,16,17,18,19,20,21,22,24,26,27,29],"/home/valberg/code/bornhack/bornhack-website/src/events/models.py":[1,2,3,5,12,13,14,15,18,19,20,23,24,25,27,30,39,44,45,46,47,48,49,52,53,54,55,56,59,35,36],"/home/valberg/code/bornhack/bornhack-website/src/rideshare/models.py":[1,2,4,7,8,9,10,11,12,13,15,24],"/home/valberg/code/bornhack/bornhack-website/src/tokens/models.py":[1,2,5,6,7,8,11,12,13,16,17,20,21,24,26,29,30,33,34,35,37,38,39,42,43,44,47,49,52],"/home/valberg/code/bornhack/bornhack-website/src/feedback/models.py":[1,3,6,7,8,9],"/home/valberg/code/bornhack/bornhack-website/src/economy/models.py":[1,3,4,5,6,7,8,10,11,14,18,19,20,22,23,24,25,28,29,30,31,34,35,36,39,42,48,54,55,56,57,59,60,61,62,63,66,67,68,69,72,73,74,77,78,81,82,83,86,89,98,107,108,109,110,111,112,115,116,117,118,119,120,123,124,125,126,127,130,131,132,133,136,137,138,141,142,143,146,147,150,151,152,153,154,155,156,159,160,161,162,163,166,167,168,171,172,173,176,180,184,193,215,231,232,233,234,235,236,239,240,241,242,243,244,247,248,249,250,251,254,255,256,257,260,261,262,265,266,267,270,271,272,275,276,279,280,281,282,283,286,287,288,291,292,293,294,295,296,297,300,301,302,305,309,313,322,344,360,363,364,365,366,367,368,371,372,373,374,375,378,379,380,381,382,385,386,387,390,391,392,395,402],"/home/valberg/code/bornhack/bornhack-website/src/economy/email.py":[1,3,5,9,24,36,49,64,76],"/home/valberg/code/bornhack/bornhack-website/src/utils/email.py":[1,2,3,4,5,6,7,8,9,15,16,17,18,19,20,21,67,68,69,70,71,72,73],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/magic.py":[18,20,21,22,23,24,25,27,30,31,36,40,43,69,84,94,103,118,120,126,138,153,155,158,159,161,179,183,185,192,202,208,225,226,227,229,230,231,233,234,235,237,238,239,241,242,243,244,246,249,250,251,252,254,258,259,260,261,263,266,267,268,270,271,272,274,275,276,280,281,282,283,284,285,286,287,288,289,290,291,293,294,295,296,297,298,299,300,301],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/allauth/models.py":[1],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/allauth/account/models.py":[1,3,5,6,7,8,9,10,12,13,14,15,16,19,20,22,23,24,25,26,27,28,29,31,33,34,35,36,39,42,55,63,77,78,80,81,82,83,84,85,86,88,90,91,92,94,97,103,108,110,119,129,131,134,140,156,165],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/allauth/account/app_settings.py":[1,3,4,5,6,8,11,14,16,18,35,42,46,56,65,75,83,90,104,110,117,124,131,139,150,157,164,171,178,185,192,197,201,205,212,220,224,228,232,236,240,248,257,264,268,277,286,290,294,298,321,324,19,21,106,107,36,37,38,39,40,108,22,88,24,25,122,26,95,96,98,99,102,27,28,29,234,325,326,115,288,190,162,176,262],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/allauth/account/signals.py":[1,2,5,8,10,11,12,14,15,16,18,20,21,22,23],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/allauth/app_settings.py":[1,4,6,8],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/allauth/account/adapter.py":[1,3,4,5,6,8,9,10,11,17,18,19,20,21,22,23,24,25,26,27,28,29,31,32,41,45,47,49,51,54,57,60,65,68,71,83,90,97,135,139,155,164,177,186,193,214,217,246,280,287,299,305,323,348,373,393,396,404,408,414,418,433,452,456,460,468,483,500,510,514],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/contrib/sites/shortcuts.py":[1,4],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/shortcuts.py":[5,6,8,11,12,13,14,17,31,40,61,74,98,119],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/allauth/utils.py":[1,2,3,4,5,6,7,8,10,11,12,13,14,15,16,23,24,25,30,32,33,36,64,74,82,92,113,125,143,150,158,161,193,229,253,288,295],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/allauth/account/managers.py":[1,3,4,5,7,10,13,23,29,35,44,61,63,66,69,74],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/allauth/account/utils.py":[1,2,4,5,6,7,8,9,10,11,12,13,14,16,18,19,20,26,27,30,41,55,58,66,73,82,107,113,119,172,186,246,283,337,359,375,392,400,416],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/allauth/compat.py":[1,4,5,9,10,15,37],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/allauth/exceptions.py":[1,5,6],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django_otp/models.py":[1,3,4,5,6,7,10,14,15,34,70,71,72,73,75,77,78,80,86,94,98,108,130,142,159,161],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django_otp/plugins/otp_totp/models.py":[1,3,4,5,7,8,9,10,11,13,14,15,18,22,26,72,73,74,75,76,77,78,79,81,82,84,91,113],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django_otp/oath.py":[1,3,4,5,6,8,10,11,17,54,89,137,138,146,150,154,167,171,175],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django_otp/util.py":[1,3,4,6,7,10,51],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django_otp/plugins/otp_static/models.py":[1,3,4,6,8,11,25,26,36,47,48,49,51],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/bootstrap3/models.py":[1],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django_extensions/models.py":[1],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/reversion/models.py":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,21,37,38,40,42,43,44,45,48,49,50,51,52,53,54,57,58,59,60,63,66,100,103,104,105,108,110,114,116,124,129,132,175,184,185,187,189,191,192,193,194,197,198,199,202,203,204,205,208,212,217,218,219,222,223,224,227,228,229,232,233,236,237,240,256,279,300,303,306,307,309,311,314,316,318,319,321,324,329],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/betterforms/models.py":[1],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/contrib/auth/admin.py":[1,2,3,4,5,6,9,10,11,12,13,14,15,16,17,18,19,21,22,25,26,27,28,29,31,40,41,42,43,45,46,47,48,49,52,53,54,57,58,59,60,61,62,63,64,66,71,81,90,94,95,96,100,127,128,190,83,84,85,86,88],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/contrib/auth/forms.py":[1,3,4,7,10,11,12,13,14,15,16,17,18,20,23,24,25,27,44,45,47,51,56,60,61,65,69,71,73,74,75,76,77,79,80,81,82,83,86,87,88,89,91,96,106,117,125,126,127,128,129,48,49,135,136,137,138,140,149,156,160,161,162,163,164,165,169,170,173,176,191,204,221,224,232,233,236,252,265,266,267,268,269,270,299,303,305,307,308,309,310,311,313,314,315,316,319,323,335,343,347,349,350,352,353,354,355,358,360,373,376,378,380,381,382,383,384,385,387,388,389,390,391,394,398,410,418],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/contrib/auth/tokens.py":[1,3,4,5,8,12,13,14,16,23,54,65,85,88,93],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/views/decorators/debug.py":[1,3,6,41,64,78,65,77],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/contrib/contenttypes/admin.py":[1,3,4,5,6,9,10,11,12,15,16,20,83,84,85,86,88,90,124,125,128,129],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/contrib/contenttypes/forms.py":[1,2,3,4,7,10,13,33,38,46,52,53,54,55,56,57,58,59],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/contrib/sites/admin.py":[1,2,5,6,7,8],"/home/valberg/code/bornhack/bornhack-website/src/profiles/admin.py":[1,2,5,6,7,10,11,12,13,14,18,21,24],"/home/valberg/code/bornhack/bornhack-website/src/camps/admin.py":[1,2,5,6,7],"/home/valberg/code/bornhack/bornhack-website/src/shop/admin.py":[1,3,4,19,20,21,22,23,26,27,29,30,31,32,33,37,38,40,41,42,43,44,45,46,47,51,55,56,58,59,60,61,62,63,64,65,69,73,74,76,80,84,87,91,94,103,104,106,107,108,109,110,111,112,116,117,120,123,124,127,128,129,133,136,140,141,142,143,144,145,146,147,148,149,150,154,155,156,157,158,159,162,164,166,168,171,173,176,178,181,184],"/home/valberg/code/bornhack/bornhack-website/src/tickets/admin.py":[1,3,11,12,13,15,18,21,22,24,25,29,30,34,35,37,38,39,40,44,45,46,47,50,53,54,55,58,59,60,63,67,68,69,70,71,72,73,77,78,79,80,81,84,87,88],"/home/valberg/code/bornhack/bornhack-website/src/news/admin.py":[1,3,6,7,8,9,11,13,15,17],"/home/valberg/code/bornhack/bornhack-website/src/villages/admin.py":[1,3,6,7,9,10,11,12,16,17,18],"/home/valberg/code/bornhack/bornhack-website/src/program/admin.py":[1,5,8,23,24,25,28,30,31,34,36,39,40,41,55,57,60,61,62,65,66,67,68,71,72,73,74,76,77,78,79,80,83,84,85,88,89,90,91,94,95,96,99,100,103,104,105,107,108,112,115,117,118,119,121,122,123],"/home/valberg/code/bornhack/bornhack-website/src/info/admin.py":[1,2,3,9,10,11,12,15,16,17,18,21,22,23,24,25,26],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/reversion/admin.py":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,25,27,29,31,33,35,37,39,43,51,59,67,79,89,96,130,143,157,161,165,194,214,230,238,264,131,133,144,145,146,147,149,150,151,153],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/conf/urls/__init__.py":[1,2,4,6,7,8,9,12,13],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/views/defaults.py":[1,3,7,8,10,11,12,13,19,20,63,64,81,82,103,104],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/reversion/views.py":[1,3,6,8,12,16,21,49,55,57,59,61,63,72],"/home/valberg/code/bornhack/bornhack-website/src/sponsors/admin.py":[1,3,6,7,8,9,12,13,14,15,16,17],"/home/valberg/code/bornhack/bornhack-website/src/ircbot/admin.py":[1,2,4],"/home/valberg/code/bornhack/bornhack-website/src/teams/admin.py":[1,2,3,4,7,8,10,11,12,13,17,18,21,22,23,25,28,29,30,31,32,33,34,35,36,37,41,42,43,44,45,46,48,51,52,54,55,56,59,61,78,80,96,100,101,103],"/home/valberg/code/bornhack/bornhack-website/src/teams/email.py":[1,2,3,6,21,43],"/home/valberg/code/bornhack/bornhack-website/src/camps/utils.py":[1,2,3,6,13,17,18,19,21,32],"/home/valberg/code/bornhack/bornhack-website/src/bar/admin.py":[1,2,5,6,7,10,11,12,13],"/home/valberg/code/bornhack/bornhack-website/src/events/admin.py":[1,2,4,5,6,8,9,10],"/home/valberg/code/bornhack/bornhack-website/src/rideshare/admin.py":[1,3,6,7,8,9],"/home/valberg/code/bornhack/bornhack-website/src/tokens/admin.py":[1,2,4,5,6,7,8,11,12,13,14,15],"/home/valberg/code/bornhack/bornhack-website/src/feedback/admin.py":[1,3,6,7,8],"/home/valberg/code/bornhack/bornhack-website/src/economy/admin.py":[1,3,8,9,10,11,12,15,16,17,18,19,24,27,30,33,36,37,38,39,40,41,46,49,52,55,58,59,60,61,62,63,68,69,70,72,73,74],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/allauth/account/admin.py":[1,3,4,5,8,9,10,11,12,14,19,20,21,22,25,27],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django_otp/admin.py":[1,3,4,5,6,8,11,28,33,34,35,39,41,50,57,64,68,70,75,12,14,16,18,20,22,25,77,80],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/contrib/admin/forms.py":[1,2,3,6,9,11,12,13,17,19,29,30],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django_otp/forms.py":[1,3,4,5,7,8,11,57,59,60,61,62,63,66,95,112,127,138,145,150,213,214,215,219,221,228,263,264,265,266,268,274,281],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django_otp/plugins/otp_totp/admin.py":[1,3,4,5,6,7,8,10,11,15,18,22,23,26,27,29,30,32,33,35,36,39,40,41,43,53,61,67,75,88,104,105,69,70,71,73],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django_otp/plugins/otp_static/admin.py":[1,3,4,6,9,10,11,14,18,20,21,24,27,32,33],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django_extensions/admin/__init__.py":[5,6,7,8,9,11,12,13,14,15,16,17,18,19,21,24,47,49,50,51,53,66,127,133,143,157,158,161,162,165,166],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django_extensions/admin/widgets.py":[2,3,4,5,6,7,8,11,12,13,16,20,22,24,26,34,36,42,46],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/channels/hacks.py":[1,7,10,12],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/contrib/staticfiles/management/commands/runserver.py":[1,2,3,8,9,11,22],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/contrib/staticfiles/handlers.py":[1,2,4,5,6,7,8,11,15,18,20,25,30,34,42,49,53,63],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/contrib/staticfiles/views.py":[5,6,7,9,10,11,12,15],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/core/management/commands/runserver.py":[1,2,3,4,5,6,8,9,10,13,15,20,23,24,27,28,30,31,32,33,34,36,54,62,66,97,106,161],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/channels/management/__init__.py":[1],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/channels/management/commands/__init__.py":[1],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/channels/management/commands/runserver.py":[1,2,3,5,6,7,8,10,11,12,13,15,17,20,21,22,24,50,61,116,130],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/channels/routing.py":[1,3,5,6,7,9,11,12,24,45,49,51,56,65,92,99,104,106,123,157,161,163,166],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/channels/http.py":[1,2,3,4,5,6,8,9,10,11,12,13,14,15,17,18,20,23,27,31,33,138,142,145,151,154,160,161,163,168,178,180,183,185,195,216,256,272,308,358],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/asgiref/__init__.py":[1],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/asgiref/sync.py":[1,2,3,4,5,8,14,16,25,66,72,85,90,93,97,99,102,110,116,127,128,100],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/channels/exceptions.py":[1,5,7,10,13,15,18,21,23,26,30,32,35,39,41,44,47,49,52,55,57,60,63,65],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/daphne/endpoints.py":[2],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/channels/staticfiles.py":[1,2,4,5,6,7,9,12,16,18,22,26,35,44,47,49,56,62],"/home/valberg/code/bornhack/bornhack-website/src/program/signal_handlers.py":[1,3,5,6,7,9,10,11,14,33],"/home/valberg/code/bornhack/bornhack-website/src/program/email.py":[1,3,4,5,6,9,33,57,81],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/core/management/commands/test.py":[1,3,4,5,8,9,12,13,15,28,52,21,22,23,26,29,30,31,33,34,35,37,38,39,41,42,43,47,49,50,53,55,56,58],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/test/runner.py":[1,2,3,4,5,6,7,8,9,10,12,13,14,15,19,21,22,23,24,27,28,33,39,47,52,57,64,74,83,85,94,98,106,122,169,176,180,183,186,189,193,196,201,206,217,220,223,233,238,243,245,247,252,260,272,275,300,313,327,330,331,332,334,340,395,396,398,399,400,401,402,407,422,462,466,548,554,557,564,569,574,583,587,590,612,628,650,676,689,424,425,426,428,429,430,432,433,434,436,437,438,440,441,442,444,445,446,448,449,450,264,266,267,268,269,451,453,454,455,457,458,459,409,410,411,412,413,414,415,416,417,418,419,420,602,463,464,603,467,468,469,471,472,473,474,477,478,479,481,484,486,499,500,501,502,509,510,512,618,619,620,621,625,514,518,520,522,525,532,640,641,642,643,661,662,664,665,666,668,669,670,671,644,645,646,647,534,546,604,549,550,551,605,567,606,570,559,560,555,561,571,572,607,576,577,578,579,580,608,584,585,609,588],"/home/valberg/code/bornhack/bornhack-website/src/backoffice/migrations/__init__.py":[1],"/home/valberg/code/bornhack/bornhack-website/src/bar/migrations/__init__.py":[1],"/home/valberg/code/bornhack/bornhack-website/src/camps/management/__init__.py":[1],"/home/valberg/code/bornhack/bornhack-website/src/camps/management/commands/__init__.py":[1],"/home/valberg/code/bornhack/bornhack-website/src/camps/migrations/__init__.py":[1],"/home/valberg/code/bornhack/bornhack-website/src/economy/migrations/__init__.py":[1],"/home/valberg/code/bornhack/bornhack-website/src/events/migrations/__init__.py":[1],"/home/valberg/code/bornhack/bornhack-website/src/events/tests.py":[1],"/home/valberg/code/bornhack/bornhack-website/src/feedback/migrations/__init__.py":[1],"/home/valberg/code/bornhack/bornhack-website/src/feedback/tests.py":[1],"/home/valberg/code/bornhack/bornhack-website/src/info/migrations/__init__.py":[1],"/home/valberg/code/bornhack/bornhack-website/src/ircbot/migrations/__init__.py":[1],"/home/valberg/code/bornhack/bornhack-website/src/news/migrations/__init__.py":[1],"/home/valberg/code/bornhack/bornhack-website/src/people/migrations/__init__.py":[1],"/home/valberg/code/bornhack/bornhack-website/src/profiles/migrations/__init__.py":[1],"/home/valberg/code/bornhack/bornhack-website/src/program/migrations/__init__.py":[1],"/home/valberg/code/bornhack/bornhack-website/src/rideshare/migrations/__init__.py":[1],"/home/valberg/code/bornhack/bornhack-website/src/rideshare/tests.py":[1],"/home/valberg/code/bornhack/bornhack-website/src/shop/management/__init__.py":[1],"/home/valberg/code/bornhack/bornhack-website/src/shop/management/commands/__init__.py":[1],"/home/valberg/code/bornhack/bornhack-website/src/shop/migrations/__init__.py":[1],"/home/valberg/code/bornhack/bornhack-website/src/shop/templatetags/__init__.py":[1],"/home/valberg/code/bornhack/bornhack-website/src/shop/tests.py":[1,2,4,6,12,13,15,21,35,42,53,65,17,18,19,37,39,40,67,68,70,72,74,75,55,56,58,60,62,63,23,25,26,27,28,29,31,32,33,44,45,46,48,50,51],"/home/valberg/code/bornhack/bornhack-website/src/shop/factories.py":[1,3,5,7,9,12,13,14,16,19,20,21,23,24,25,26,27,28,29,37,38,39,41,44,45,46,48,49,50,51,30,31,32],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/factory/__init__.py":[4,15,22,26,28,46,71,72,73,74,77,78,81,82],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/factory/base.py":[4,6,7,8,10,11,12,13,14,16,21,26,34,35,37,53,96,103,104,105,108,118,119,125,137,143,144,156,163,178,201,235,246,261,272,284,308,319,326,341,367,375,378,385,391,393,396,401,405,406,409,410,412,416,145,146,147,148,149,150,151,153,154,419,421,422,433,442,443,463,464,480,485,502,503,513,528,543,548,560,565,577,586,598,615,633,648,667,668,673,68,23,69,70,74,75,77,28,29,30,78,31,80,81,83,84,86,87,88,89,90,91,203,204,206,180,183,184,185,186,189,170,120,121,122,123,171,172,173,174,175,190,191,126,127,128,129,130,132,135,192,193,195,208,373,209,210,212,238,244,216,217,218,219,220,222,223,334,336,339,226,231,345,347,349,360,361,365,233,158,159,161,94,678,681,682,683,688,690,691,692,694,698,239,240,335,703,704,705,706,708,715,720,721,722,725,726,727,728,730,739,744,745,746,749,338,224,43,45,46,563,493,499,500,269,252,255,256,440,394,270,397,398,399,286,288,483,291,292,293,297,301,302,303,306,309,311,313,314,320,321,322,323,253],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/factory/builder.py":[1,3,5,6,7,8,11,12,13,17,18,19,23,33,35,40,57,67,70,96,108,114,117,124,127,132,139,143,147,151,152,155,159,205,206,213,223,231,236,244,245,251,308,313,328,330,332,341,345,348,388,36,37,38,76,83,84,160,161,164,165,166,185,188,104,189,191,196,198,202,167,176,115,182,105,52,55,192,199,77,78,79,246,247,248,249,254,255,256,257,68,141,134,135,136,260,262,265,267,268,269,270,207,208,209,210,211,272,214,215,216,217,333,390,391,334,336,337,339,220,125,221,354,358,360,361,118,119,120,121,362,363,364,365,366,367,368,369,372,373,374,375,378,379,381,382,232,310,233,274,276,277,278,279,282,283,109,110,111,301,302,303,304,306],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/factory/declarations.py":[4,6,7,9,10,11,12,15,18,24,26,30,32,43,56,57,62,68,70,74,79,85,87,91,96,97,100,129,140,142,151,161,169,177,179,189,201,207,217,218,223,228,236,237,244,252,253,258,278,289,291,294,296,300,306,326,343,348,349,362,370,377,384,386,387,388,390,394,398,417,418,420,422,426,427,429,431,440,441,445,448,451,452,473,494,508,512,518,520,532,537,538,542,547,554,555,556,560,576,580,591,592,594,596,608,609,610,614,629,637,639,641,648,652,678,679,682,694,695,706,391,297,298,392,350,351,352,353,71,72,33,35,37,34,320,321,324,406,396,363,368,407,408,409,410,411,413,414,75,76],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/factory/enums.py":[5,6,7,12,16,18,21,24,25],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/factory/compat.py":[5,7,8,10,12,24,27,29,33,35,25,30],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/factory/errors.py":[5,6,9,10,13,14,17,18,21,22,25,30],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/factory/utils.py":[4,6,8,9,12,45,71,83,90,95,96,98,102,105,115,123,124,125,131,140,145,149,151,153,165,176,154,155,156,157,158,159,160,161,162,99,100,120],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/factory/faker.py":[14,17,18,20,22,23,25,28,41,42,48,55,58,59,61,62,71,72,82,83,43,44,45,46,56,49,50,51,52,73,74,76,77,78,80,53],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/faker/__init__.py":[1,2,4,6],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/faker/generator.py":[3,5,6,8,9,10,13,15,17,23,41,49,53,57,61,70,71,74,81,95,102,109,18,19,20,21,25,28,30,32,35,37,33,39,100,79,82,83,55,107,110,111,112],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/faker/factory.py":[3,4,6,7,9,10,12,13,14,17,20,21,24,27,29,35,66,67,89,90,37,38,41,42,43,47,48,50,52,54,55,58,69,92,94,96,97,99,100,110,111,113,114,115,117,130,71,72,59,60,61,62,101,102,103,104,107,121,124,127,128,64],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/faker/config.py":[2,3,5,8,11,12,14],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/faker/utils/__init__.py":[4,11],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/faker/utils/loading.py":[1,2,3,4,7,20,27,39,40,41,43,44,21,8,16,17,22,23,24,46,47,28,30,32,33,34,35,36],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/faker/providers/__init__.py":[3,4,6,9,10,11,12,13,14,17,19,20,24,25,29,30,31,32,33,34,35,36,37,38,40,41,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,84,87,93,96,106,113,120,130,140,159,164,171,175,179,206,224,242,255,275,302,312,321,85,222,180,182,185,189,193,196,197,199,200,201,202,203,264,266,267,268,269,271,273,104,240,190,191,319,288,289,290,291,292,293,294,295,296,297,298,299,300,310],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/faker/utils/distribution.py":[3,4,7,13,20,45,46,49,51,52,53],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/faker/providers/address/__init__.py":[2,4,5,7,10,11,12,13,14,15,16,17,18,19,21,22,24,25,27,33,39,45,52,59,66,72,79,82],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/faker/providers/date_time/__init__.py":[3,5,7,8,9,11,12,14,15,17,19,22,28,38,39,42,43,44,45,48,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,305,306,307,308,309,310,311,312,313,314,315,316,317,318,319,320,321,322,323,324,325,326,327,328,329,330,331,332,333,334,335,336,337,338,339,340,341,342,343,344,345,346,347,348,349,350,351,352,353,354,355,356,357,358,359,360,361,362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,380,381,382,383,384,385,386,387,388,389,390,391,392,393,394,395,396,397,398,399,400,401,402,403,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,422,423,424,425,426,427,428,429,430,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,450,451,452,453,454,455,456,457,458,459,460,461,462,463,464,465,466,467,468,469,470,471,472,473,474,475,476,477,478,479,480,481,482,483,484,485,486,487,488,489,490,491,492,493,494,495,496,497,498,499,500,501,502,503,504,505,506,507,508,509,510,511,512,513,514,515,516,517,518,519,520,521,522,523,524,525,526,527,528,529,530,531,532,533,534,535,536,537,538,539,540,541,542,543,544,545,546,547,548,549,550,551,552,553,554,555,556,557,558,559,560,561,562,563,564,565,566,567,568,569,570,571,572,573,574,575,576,577,578,579,580,581,582,583,584,585,586,587,588,589,590,591,592,593,594,595,596,597,598,599,600,601,602,603,604,605,606,607,608,609,610,611,612,613,614,615,616,617,618,619,620,621,622,623,624,625,626,627,628,629,630,631,632,633,634,635,636,637,638,639,640,641,642,643,644,645,646,647,648,649,650,651,652,653,654,655,656,657,658,659,660,661,662,663,664,665,666,667,668,669,670,671,672,673,674,675,676,677,678,679,680,681,682,683,684,685,686,687,688,689,690,691,692,693,694,695,696,697,698,699,700,701,702,703,704,705,706,707,708,709,710,711,712,713,714,715,716,717,718,719,720,721,722,723,724,725,726,727,728,729,730,731,732,733,734,735,736,737,738,739,740,741,742,743,744,745,746,747,748,749,750,751,752,753,754,755,756,757,758,759,760,761,762,763,764,765,766,767,768,769,770,771,772,773,774,775,776,777,778,779,780,781,782,783,784,785,786,787,788,789,790,791,792,793,794,795,796,797,798,799,800,801,802,803,804,805,806,807,808,809,810,811,812,813,814,815,816,817,818,819,820,821,822,823,824,825,826,827,828,829,830,831,832,833,834,835,836,837,838,839,840,841,842,843,844,845,846,847,848,849,850,851,852,853,854,855,856,857,858,859,860,861,862,863,864,865,866,867,868,869,870,871,872,873,874,875,876,877,878,879,880,881,882,883,884,885,886,887,888,889,890,891,892,893,894,895,896,897,898,899,900,901,902,903,904,905,906,907,908,909,910,911,912,913,914,915,916,917,918,919,920,921,922,923,924,925,926,927,928,929,930,931,932,933,934,935,936,937,938,939,940,941,942,943,944,945,946,947,948,949,950,951,952,953,954,955,956,957,958,959,960,961,962,963,964,965,966,967,968,969,970,971,972,973,974,975,976,977,978,979,980,981,982,983,984,985,986,987,988,989,990,991,992,993,994,995,996,997,998,999,1000,1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1011,1012,1013,1014,1015,1016,1017,1018,1019,1020,1021,1022,1023,1024,1025,1026,1027,1028,1029,1030,1031,1032,1033,1034,1035,1036,1037,1038,1039,1040,1041,1042,1043,1044,1045,1046,1047,1048,1049,1050,1051,1052,1053,1054,1055,1056,1057,1058,1059,1060,1061,1062,1063,1064,1065,1066,1067,1068,1069,1070,1071,1072,1073,1074,1075,1076,1077,1078,1079,1080,1081,1082,1083,1084,1085,1086,1087,1088,1089,1090,1091,1092,1093,1094,1095,1096,1097,1098,1099,1100,1101,1102,1103,1104,1105,1106,1107,1108,1109,1110,1111,1112,1113,1114,1115,1116,1117,1118,1119,1120,1121,1122,1123,1124,1125,1126,1127,1128,1129,1130,1131,1132,1133,1134,1135,1136,1137,1138,1139,1140,1141,1142,1143,1144,1145,1146,1147,1148,1149,1150,1151,1152,1153,1154,1155,1156,1157,1158,1159,1160,1161,1162,1163,1164,1165,1166,1167,1168,1169,1170,1171,1172,1173,1174,1175,1176,1177,1178,1179,1180,1181,1182,1183,1184,1185,1186,1187,1188,1189,1190,1191,1192,1193,1194,1195,1196,1197,1198,1199,1200,1201,1202,1203,1204,1205,1206,1207,1208,1209,1210,1211,1212,1213,1214,1215,1216,1217,1218,1219,1220,1221,1222,1223,1224,1225,1226,1227,1228,1229,1230,1231,1232,1233,1234,1235,1236,1237,1238,1239,1240,1241,1242,1243,1244,1245,1246,1247,1248,1249,1250,1251,1252,1253,1254,1255,1256,1257,1258,1259,1260,1261,1262,1263,1264,1265,1266,1267,1268,1269,1270,1271,1272,1273,1274,1275,1276,1277,1278,1279,1280,1281,1282,1283,1284,1285,1286,1287,1288,1289,1290,1291,1292,1293,1294,1295,1296,1297,1298,1299,1300,1301,1302,1303,1304,1305,1306,1307,1308,1309,1310,1311,1312,1313,1314,1315,1316,1317,1318,1319,1320,1321,1322,1323,1324,1325,1326,1327,1328,1329,1330,1331,1332,1333,1334,1335,1336,1337,1338,1339,1340,1341,1342,1343,1344,1345,1346,1347,1348,1349,1350,1351,1352,1353,1354,1355,1356,1357,1358,1359,1360,1361,1362,1363,1366,1368,1378,1389,1402,1429,1436,1444,1451,1460,1467,1474,1481,1501,1512,1513,1528,1546,1570,1585,1600,1613,1628,1645,1680,1695,1725,1755,1784,1810,1833,1855,1877,1907,1939,1942,1945,1948,1951,1954,1957,1963,1967],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/dateutil/relativedelta.py":[2,3,5,6,8,9,11,13,15,18,103,110,231,264,268,272,282,317,404,407,410,439,457,475,493,495,518,520,547,567,570,578,580,596],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/faker/utils/datetime_safe.py":[14,15,16,17,18,21,22,26,27,30,35,39,44,56,59,72],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/faker/providers/automotive/__init__.py":[3,4,5,7,10,11,13],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/faker/providers/bank/__init__.py":[2,3,4,5,7,8,11,16,18,21,22,24,27,33],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/faker/providers/barcode/__init__.py":[3,4,7,9,26,29],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/faker/providers/color/__init__.py":[2,3,5,7,10,11,151,157,160,163,166,173,177,180],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/faker/providers/company/__init__.py":[3,4,7,10,14,17,324,495,497,504,510,520,501,502],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/faker/providers/credit_card/__init__.py":[2,3,5,8,16,24,30,31,32,33,34,35,36,37,38,40,41,42,17,18,19,20,21,43,44,45,46,47,48,49,50,51,52,53,55,56,58,59,61,67,74,78,96,101,109],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/faker/providers/currency/__init__.py":[3,6,172,219,222,225,228,231,234,237],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/faker/providers/file/__init__.py":[2,4,5,7,10,49,62,76,85,97,107,123,135,138,139,140,141,142,143,144,145,146,152,161,170,177,193,196,197,198,199,200,201,203,205,213,222,230,242,251],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/faker/providers/geo/__init__.py":[2,4,6,9,15,975,978,992,996,999,1002,1011],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/faker/providers/internet/__init__.py":[2,4,6,8,12,15,18,25,27,28,29,32,34,36,41,42,43,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,66,67,68,72,73,74,76,78,81,85,89,96,100,104,111,119,122,124,131,132,140,146,150,154,158,165,173,179,185,193,194,209,210,227,228,235,238,256,279,322,330,365,394,419,428,432,435,441,444,448,449,455,160,161,162,187,188,189,125,128,129,191,220,222,223,230,231,232,233,236],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/text_unidecode/__init__.py":[2,3,4,6,8,9,10,11,13,17,18,21],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/faker/utils/decorators.py":[3,5,8,15,22,29,30,33,23,26,9,12,32,25],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/faker/utils/text.py":[3,5,6,9,10,11,14,22,25,27,28,29,30,31],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/faker/providers/isbn/__init__.py":[3,4,5,6,9,21,23,44,64,69],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/faker/providers/isbn/isbn.py":[5,8,10,12,19,21,25,38,43,45,49,60],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/faker/providers/isbn/rules.py":[11,13,15,16,20,22,23,24,25,26,27,28,29,30,31,34,35,36,37,38,39,40,41,42,43],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/faker/providers/job/__init__.py":[2,4,7,647,650],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/faker/providers/lorem/__init__.py":[1,3,6,9,24,25,26,28,45,56,81,100,127,141,54,40,41,43,115,118,119,121,122,93,94,70,73,74,76,77,79,125],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/faker/providers/misc/__init__.py":[3,4,5,6,7,9,12,13,16,23,31,41,51,62,77],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/faker/providers/person/__init__.py":[1,3,6,9,10,12,14,16,23,26,29,37,45,50,55,60,65,74,79,84,93,98,27,24],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/faker/providers/phone_number/__init__.py":[1,3,6,7,10,13,16],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/faker/providers/profile/__init__.py":[3,4,7,11,13,33],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/faker/providers/python/__init__.py":[3,5,6,8,10,13,14,17,35,59,62,65,72,79,89,94,106,123,139,60],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/faker/providers/ssn/__init__.py":[2,4,6,9,10,12],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/faker/providers/user_agent/__init__.py":[3,5,7,10,12,19,22,24,26,29,32,37,62,97,137,154,161,164,168],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/factory/helpers.py":[5,7,8,10,11,14,15,30,46,51,56,61,66,71,76,81,86,91,96,100,105,109,113,117],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/factory/alchemy.py":[4,6,7,9,10,12,13,14,18,19,26,39,59,60,62,64,65,67],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/factory/django.py":[5,7,8,10,11,12,14,15,16,23,24,25,26,28,31,34,40,43,52,67,68,74,86,94,101,103,105,106,108,117,134,157,167,168,175,176,178,180,184,188,225,234,235,237,256,274,276,280,291,304,307,69,70,71,87,88,89,45,46,58,62,63,64,48,49,91,75,76,84,160,119,123,124,130,132,162,165,170],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/factory/mogo.py":[5,8,10,13,14,15,16,18,22],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/factory/mongoengine.py":[5,8,11,14,15,17,18,20,24],"/home/valberg/code/bornhack/bornhack-website/src/utils/factories.py":[1,2,5,6,7,9,10],"/home/valberg/code/bornhack/bornhack-website/src/sponsors/management/__init__.py":[1],"/home/valberg/code/bornhack/bornhack-website/src/sponsors/management/commands/__init__.py":[1],"/home/valberg/code/bornhack/bornhack-website/src/sponsors/migrations/__init__.py":[1],"/home/valberg/code/bornhack/bornhack-website/src/teams/migrations/__init__.py":[1],"/home/valberg/code/bornhack/bornhack-website/src/teams/templatetags/__init__.py":[1],"/home/valberg/code/bornhack/bornhack-website/src/teams/views/__init__.py":[1],"/home/valberg/code/bornhack/bornhack-website/src/tickets/migrations/__init__.py":[1],"/home/valberg/code/bornhack/bornhack-website/src/tickets/templatetags/__init__.py":[1],"/home/valberg/code/bornhack/bornhack-website/src/tokens/migrations/__init__.py":[1],"/home/valberg/code/bornhack/bornhack-website/src/tokens/templatetags/__init__.py":[1],"/home/valberg/code/bornhack/bornhack-website/src/utils/management/__init__.py":[1],"/home/valberg/code/bornhack/bornhack-website/src/utils/management/commands/__init__.py":[1],"/home/valberg/code/bornhack/bornhack-website/src/utils/migrations/__init__.py":[1],"/home/valberg/code/bornhack/bornhack-website/src/utils/templatetags/__init__.py":[1],"/home/valberg/code/bornhack/bornhack-website/src/villages/migrations/__init__.py":[1],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/core/management/commands/migrate.py":[1,2,3,5,6,7,10,13,14,15,16,17,18,21,22,24,58,63,229,263,25,26,27,29,30,31,34,35,36,38,39,40,41,43,44,45,47,48,49,53,54,55,66,67,71,72,73,76,77,80,82,85,89,90,102,103,125,133,135,136,139,162,163,164,165,169,170,172,265,266,270,274,275,278,286,287,288,292,294,295,296,309,175,177,199,200,201,202,203,230,207,208,213,214,215,219,220,225,226],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/db/migrations/autodetector.py":[1,2,3,5,6,7,8,9,10,11,12,16,19,30,32,38,50,90,104,197,221,236,326,344,360,423,431,451,494,649,683,776,789,827,832,863,868,884,960,978,989,1000,1019,1056,1059,1062,1079,1115,1142,1156,1205,1230,1251],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/db/migrations/optimizer.py":[1,10,12,41],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/db/migrations/questioner.py":[1,2,3,5,6,7,9,12,17,19,24,55,60,65,69,73,77,83,85,93,108,142,161,186,192,198,206,226,228,232,236],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/db/migrations/loader.py":[1,2,3,5,6,7,8,10,15,18,41,43,51,64,126,130,148,176,186,199,275,301,315,44,45,46,47,48,49,206,66,67,68,69,71,58,61,62,72,75,76,77,89,93,97,99,100,101,102,105,106,107,108,117,121,122,123,78,81,82,83,84,98,208,211,212,215,216,217,218,220,181,183,222,184,225,226,187,189,191,149,155,158,163,164,165,166,192,193,194,190,150,228,246,247,280,281,282,284,286,287,307,308,309,310,312,313],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/db/migrations/graph.py":[1,2,4,5,7,10,17,22,23,28,31,34,37,40,43,46,49,54,67,79,80,85,95,99,120,122,127,139,144,168,204,241,245,252,271,290,300,311,325,345,348,352,355,363,381,123,124,125,129,130,134,24,25,26,135,136,137,246,150,156,162,50,35,163,47,164,166,158,159,161,140,81,82,83,141,142,132,91,92,93,382,305,306,307,38,308,309,243,29,319,320,321,322,323,258,261,328,329,330,331,332,333,334,335,338,339,340,341,343,262,263,264,265,57,58,59,60,32,61,62,63],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/db/migrations/recorder.py":[1,2,3,4,6,9,20,22,23,24,25,27,28,29,30,32,35,38,42,46,59,68,73,78,36,61,44,62,40,50,51,70,71],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/db/migrations/utils.py":[1,2,4,7,8,12,16],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/db/migrations/topological_sort.py":[1,26],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/db/migrations/executor.py":[1,2,4,5,6,7,10,14,16,22,64,82,127,152,213,231,256,274,291,17,18,19,20,26,27,30,31,33,42,47,48,49,52,50,58,59,60,61,62,69,70,72,28,73,74,75,77,78,79,80,91,93,96,98,99,101,105,113,114,117,132,133,134,140,141,147,233,234,235,236,241,243,244,246,250,252,253,254,148,139,150,123,285,286,125],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/graphene_django/management/__init__.py":[1],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/allauth/account/management/__init__.py":[1],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django_otp/plugins/otp_static/management/__init__.py":[1],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django_extensions/management/__init__.py":[1],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/reversion/management/__init__.py":[1],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/debug_toolbar/management/__init__.py":[1],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/contrib/admin/migrations/__init__.py":[1],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/contrib/admin/migrations/0001_initial.py":[1,2,3,6,9,10,14,15,17,18,19,20,21,22,23,24,25,26,27,28,30,31,32,33,37,38,39,40,42,44],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/contrib/admin/migrations/0002_logentry_remove_auto_add.py":[1,2,5,8,13,14,15,16,17,18,19],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/contrib/admin/migrations/0003_logentry_add_action_flag_choices.py":[1,4,7,12,13,14,15,16,17],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/contrib/auth/migrations/__init__.py":[1],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/contrib/auth/migrations/0008_alter_user_username_max_length.py":[1,2,5,8,12,13,14,15,16,17,18,19,20,21],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/contrib/auth/migrations/0001_initial.py":[1,2,3,4,7,10,14,15,17,18,19,20,21,22,23,25,28,29,30,31,34,37,38,40,41,42,45,46,49,52,53,55,56,57,58,59,60,61,63,64,65,66,68,69,70,71,72,73,75,76,77,81,82,83,84,85,89,90,91,92,96,97,98,101],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/contrib/auth/migrations/0003_alter_user_email_max_length.py":[1,4,7,11,12,13,14],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/contrib/auth/migrations/0007_alter_validators_add_error_messages.py":[1,2,5,8,12,13,14,15,16,17,18,19,20,21],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/contrib/auth/migrations/0006_require_contenttypes_0002.py":[1,4,7,8,11],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/contrib/auth/migrations/0002_alter_permission_name_max_length.py":[1,4,7,11,12,13,14],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/contrib/auth/migrations/0004_alter_user_username_opts.py":[1,2,5,8,13,14,15,16,17,18,19,20],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/contrib/auth/migrations/0005_alter_user_last_login_null.py":[1,4,7,11,12,13,14],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/contrib/auth/migrations/0009_alter_user_last_name_max_length.py":[1,4,7,11,12,13,14],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/contrib/contenttypes/migrations/__init__.py":[1],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/contrib/contenttypes/migrations/0001_initial.py":[1,2,5,7,11,12,14,15,16,17,20,21,22,23,25,27,30,31,32],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/contrib/contenttypes/migrations/0002_remove_content_type_name.py":[1,4,14,17,21,22,23,25,26,27,28,30,31,32,33,35,36,37],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/contrib/sessions/migrations/__init__.py":[1],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/contrib/sessions/migrations/0001_initial.py":[1,2,5,7,11,12,14,15,17,18,21,22,23,24,27],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/contrib/sites/migrations/__init__.py":[1],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/contrib/sites/migrations/0001_initial.py":[1,2,3,6,8,11,12,14,15,16,18,21,22,23,24,26,28],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/contrib/sites/migrations/0002_alter_domain_unique.py":[1,2,5,8,12,13,14,15,16,17],"/home/valberg/code/bornhack/bornhack-website/src/profiles/migrations/0001_initial.py":[4,5,6,9,12,16,17,19,20,21,22,25,26],"/home/valberg/code/bornhack/bornhack-website/src/profiles/migrations/0007_auto_20170711_2025.py":[3,5,7,10,13,14,18],"/home/valberg/code/bornhack/bornhack-website/src/profiles/migrations/0002_profile_description.py":[3,5,8,11,15,16,17,18],"/home/valberg/code/bornhack/bornhack-website/src/profiles/migrations/0009_profile_nickserv_username.py":[3,5,8,11,15,16,17,18],"/home/valberg/code/bornhack/bornhack-website/src/profiles/migrations/0010_auto_20180411_2305.py":[3,5,8,11,15,16,17,18],"/home/valberg/code/bornhack/bornhack-website/src/profiles/migrations/0005_auto_20170711_1721.py":[3,5,8,11,15,16,17,18,20,21,22,23],"/home/valberg/code/bornhack/bornhack-website/src/profiles/migrations/0006_auto_20170711_1757.py":[3,5,8,11,15,16,17,19,20,21,22,24,25,26,27,29,30,31,32],"/home/valberg/code/bornhack/bornhack-website/src/profiles/migrations/0004_auto_20170430_1408.py":[3,5,8,11,15,16,17,18],"/home/valberg/code/bornhack/bornhack-website/src/profiles/migrations/0008_auto_20180325_2022.py":[3,5,8,11,15,16,17,18],"/home/valberg/code/bornhack/bornhack-website/src/profiles/migrations/0003_auto_20170413_1703.py":[3,5,8,11,15,16,17,18,20,21,22,23],"/home/valberg/code/bornhack/bornhack-website/src/camps/migrations/0010_auto_20161220_1714.py":[5,8,11,15,16,17,19,20,21,22,23,25,26,27,28,29],"/home/valberg/code/bornhack/bornhack-website/src/camps/migrations/0020_camp_read_only.py":[3,5,8,11,15,16,17,18],"/home/valberg/code/bornhack/bornhack-website/src/camps/migrations/0006_auto_20160804_1705.py":[5,8,11,15,16,17],"/home/valberg/code/bornhack/bornhack-website/src/camps/migrations/0024_populate_camp_shortslugs.py":[3,5,7,14,16,20],"/home/valberg/code/bornhack/bornhack-website/src/camps/migrations/0009_auto_20161220_1645.py":[5,6,7,10,13,17,18,19,20,22,23,24,25,27,28,29,30,31,33,34,35,36,37],"/home/valberg/code/bornhack/bornhack-website/src/camps/migrations/0008_delete_day.py":[5,8,11,12,16,17],"/home/valberg/code/bornhack/bornhack-website/src/camps/migrations/0016_camp_description.py":[5,8,11,15,16,17,18],"/home/valberg/code/bornhack/bornhack-website/src/camps/migrations/0030_camp_light_text.py":[3,6,9,13,14,15,16],"/home/valberg/code/bornhack/bornhack-website/src/camps/migrations/0028_auto_20180525_1025.py":[3,6,9,13,14,15,16,18,19,20,21],"/home/valberg/code/bornhack/bornhack-website/src/camps/migrations/0005_auto_20160510_2011.py":[5,8,11,15,16,17,19,20,21,22],"/home/valberg/code/bornhack/bornhack-website/src/camps/migrations/0026_auto_20180506_1633.py":[3,6,9,13,14,15,16,18,19,20,21],"/home/valberg/code/bornhack/bornhack-website/src/camps/migrations/0019_auto_20170131_1849.py":[3,5,6,9,12,16,17,18,19,21,22,23,24,26,27,28,29,31,32,33,34,36,37,38,39,41,42,43,44],"/home/valberg/code/bornhack/bornhack-website/src/camps/migrations/0007_auto_20161212_1803.py":[5,6,7,8,9,12,15,16,20,21,22,24,25,26,28,29,30,32,33,34,36,37,38,40,41,42,44,45,46,47,48,50,51,52,53,54,56,57,58,59,60,62,63,64,65,66,68,69,70,71,73,74,75,76,78,79,80,81,83,84,85,86,88,89,90,91],"/home/valberg/code/bornhack/bornhack-website/src/camps/migrations/0018_auto_20170128_1841.py":[5,6,9,12,16,17,18,19,21,22,23,24,26,27,28,29],"/home/valberg/code/bornhack/bornhack-website/src/camps/migrations/0021_auto_20170711_2247.py":[3,5,8,11,15,16,17],"/home/valberg/code/bornhack/bornhack-website/src/camps/migrations/0031_auto_20180830_0014.py":[3,6,9,13,14,16,19,20,21,24,25,26],"/home/valberg/code/bornhack/bornhack-website/src/camps/migrations/0022_camp_colour.py":[3,5,8,11,15,16,17,18,19],"/home/valberg/code/bornhack/bornhack-website/src/camps/migrations/0003_auto_20160422_2019.py":[5,8,11,15,16,17,19,20,21,23,24],"/home/valberg/code/bornhack/bornhack-website/src/camps/migrations/0001_initial.py":[4,5,6,9,12,16,17,19,20,21,22,23,24,27,28,31,32,34,35,36,37,38,41,42,45,46,48,49,50,51,52,53,54,55,58,59,62,63,65,66,67,68,69,70,71,74,75],"/home/valberg/code/bornhack/bornhack-website/src/camps/migrations/0002_auto_20160117_1718.py":[5,6,9,12,16,17,18,19],"/home/valberg/code/bornhack/bornhack-website/src/camps/migrations/0013_auto_20161229_2201.py":[5,6,9,12,16,17,18,20,21,22,24,25,26,28,29,30,32,33,34,35,37,38,39,40,42,43,44,45],"/home/valberg/code/bornhack/bornhack-website/src/camps/migrations/0015_auto_20170116_1634.py":[5,8,11,15,16,17,19,20],"/home/valberg/code/bornhack/bornhack-website/src/camps/migrations/0004_camp_ticket_sale_open.py":[5,8,11,15,16,17,18],"/home/valberg/code/bornhack/bornhack-website/src/camps/migrations/0029_auto_20180815_2018.py":[3,6,9,13,14,15],"/home/valberg/code/bornhack/bornhack-website/src/camps/migrations/0011_auto_20161228_1750.py":[5,8,11,15,16,17,18,19,21,22,23,24,25],"/home/valberg/code/bornhack/bornhack-website/src/camps/migrations/0012_auto_20161228_2312.py":[5,8,11,15,16,17,19,20,21],"/home/valberg/code/bornhack/bornhack-website/src/camps/migrations/0032_auto_20180917_1754.py":[3,6,9,13,14,15],"/home/valberg/code/bornhack/bornhack-website/src/camps/migrations/0014_auto_20161229_2202.py":[5,6,7,10,13,17,18,19,20,22,23,24,25,27,28,29,30],"/home/valberg/code/bornhack/bornhack-website/src/camps/migrations/0025_auto_20180318_1250.py":[3,5,8,11,15,16,17,18],"/home/valberg/code/bornhack/bornhack-website/src/camps/migrations/0017_remove_camp_description.py":[5,8,11,15,16,17],"/home/valberg/code/bornhack/bornhack-website/src/camps/migrations/0027_auto_20180525_1019.py":[3,6,9,13,14,15,16,18,19,20,21],"/home/valberg/code/bornhack/bornhack-website/src/camps/migrations/0023_camp_shortslug.py":[3,5,8,11,15,16,17,18],"/home/valberg/code/bornhack/bornhack-website/src/shop/migrations/0036_auto_20170319_2155.py":[3,5,8,11,15,16,17,18],"/home/valberg/code/bornhack/bornhack-website/src/shop/migrations/0009_epaycallback_md5valid.py":[5,8,11,15,16,17,18],"/home/valberg/code/bornhack/bornhack-website/src/shop/migrations/0041_auto_20170408_1104.py":[3,5,6,9,12,16,17,18,19,20,22,23,24,25],"/home/valberg/code/bornhack/bornhack-website/src/shop/migrations/0055_order_customer_address.py":[3,6,9,13,14,15,16],"/home/valberg/code/bornhack/bornhack-website/src/shop/migrations/0019_invoice_pdf_generated.py":[5,8,11,15,16,17,18],"/home/valberg/code/bornhack/bornhack-website/src/shop/migrations/0054_auto_20180415_1159.py":[3,4,7,10,14,15,16,17,19,20,21,22,24,25,26,27,29,30,31,32],"/home/valberg/code/bornhack/bornhack-website/src/shop/migrations/0010_auto_20160517_1313.py":[5,6,9,12,16,17,19,20,21,22,23,26,29,30,31,33,34,35,36],"/home/valberg/code/bornhack/bornhack-website/src/shop/migrations/0012_ticket.py":[5,6,7,10,13,17,18,20,21,22,23,24,27],"/home/valberg/code/bornhack/bornhack-website/src/shop/migrations/0017_auto_20160529_1626.py":[5,8,11,15,16,17],"/home/valberg/code/bornhack/bornhack-website/src/shop/migrations/0053_auto_20180318_0906.py":[3,5,6,7,10,13,17,18,19,20,22,23,24,25,27,28,29,30,32,33,34,35,37,38,39,40,42,43,44,45,47,48,49,50],"/home/valberg/code/bornhack/bornhack-website/src/shop/migrations/0027_auto_20160712_2036.py":[5,6,7,10,13,14,18,19,21,22,23,24,25,26,27,30,33,34,35,37,38,39,40,42,43,44,45,47,48,49,50,52,53,54,55,57,58,59,60,62,63,64,65,67,68,69,70,72,73,74,75],"/home/valberg/code/bornhack/bornhack-website/src/shop/migrations/0026_order_refunded.py":[5,8,11,15,16,17,18],"/home/valberg/code/bornhack/bornhack-website/src/shop/migrations/0023_order_cancelled.py":[5,8,11,15,16,17,18],"/home/valberg/code/bornhack/bornhack-website/src/shop/migrations/0008_auto_20160516_0954.py":[5,6,7,10,13,17,18,19,20,21,23,24,25,26,27],"/home/valberg/code/bornhack/bornhack-website/src/shop/migrations/0043_auto_20170507_1309.py":[3,5,6,7,10,13,17,18,20,21,22,23,24,25,28,31,32,33,34],"/home/valberg/code/bornhack/bornhack-website/src/shop/migrations/0030_auto_20160827_0752.py":[5,8,11,15,16,17,19,20,21,22],"/home/valberg/code/bornhack/bornhack-website/src/shop/migrations/0046_coinifyapirequest_method.py":[3,5,8,11,15,16,17,18,19],"/home/valberg/code/bornhack/bornhack-website/src/shop/migrations/0042_auto_20170507_1000.py":[3,5,6,9,12,16,17,18,19],"/home/valberg/code/bornhack/bornhack-website/src/shop/migrations/0034_auto_20170131_1849.py":[3,5,8,11,15,16,17,18,20,21,22,23,25,26,27,28,30,31,32,33,35,36,37,38],"/home/valberg/code/bornhack/bornhack-website/src/shop/migrations/0005_product_slug.py":[5,8,11,15,16,17,18,19],"/home/valberg/code/bornhack/bornhack-website/src/shop/migrations/0003_auto_20160513_0646.py":[5,6,9,12,16,17,18,19,21,22,23,24,26,27,28,29,31,32,33,34],"/home/valberg/code/bornhack/bornhack-website/src/shop/migrations/0013_ticket_qrcode_base64.py":[5,8,11,15,16,17,18],"/home/valberg/code/bornhack/bornhack-website/src/shop/migrations/0015_coinifyapiinvoice_coinifycallback.py":[5,6,7,10,13,17,18,20,21,22,23,24,27,30,31,33,34,35,36,37,40],"/home/valberg/code/bornhack/bornhack-website/src/shop/migrations/0002_orderproductrelation_handed_out.py":[5,8,11,15,16,17,18],"/home/valberg/code/bornhack/bornhack-website/src/shop/migrations/0033_auto_20161212_1756.py":[5,8,11,15,16,17,19,20,21],"/home/valberg/code/bornhack/bornhack-website/src/shop/migrations/0038_auto_20170323_2021.py":[3,5,8,11,15,16,17,18],"/home/valberg/code/bornhack/bornhack-website/src/shop/migrations/0018_auto_20160529_1736.py":[5,8,11,15,16,17],"/home/valberg/code/bornhack/bornhack-website/src/shop/migrations/0056_auto_20180827_1020.py":[3,6,9,13,14,15,17,18,19,20],"/home/valberg/code/bornhack/bornhack-website/src/shop/migrations/0001_initial.py":[5,6,7,8,9,10,13,15,18,19,23,24,26,27,28,29,32,33,36,37,39,40,41,42,43,46,47,50,51,53,54,55,56,57,58,61,64,65,67,68,69,72,73,75,76,77,78,79,80,81,84,85,86,89,90,92,93,94,95,98,99,102,103,104,105,107,108,109,110,112,113,114,115,117,118,119,120,122,123,124,125],"/home/valberg/code/bornhack/bornhack-website/src/shop/migrations/0006_ensure_slugs.py":[5,8,19,22,26],"/home/valberg/code/bornhack/bornhack-website/src/shop/migrations/0029_auto_20160712_2133.py":[5,8,11,15,16,17,18],"/home/valberg/code/bornhack/bornhack-website/src/shop/migrations/0028_auto_20160712_2119.py":[5,8,11,15,16,17,18,19,21,22,23,24],"/home/valberg/code/bornhack/bornhack-website/src/shop/migrations/0031_auto_20161109_1000.py":[5,8,11,15,16,17,18],"/home/valberg/code/bornhack/bornhack-website/src/shop/migrations/0039_auto_20170403_1752.py":[3,5,6,9,12,16,17,18,19,21,22,23,24],"/home/valberg/code/bornhack/bornhack-website/src/shop/migrations/0050_auto_20170916_1336.py":[3,5,6,7,10,13,17,18,19,20,22,23,24,25,27,28,29,30],"/home/valberg/code/bornhack/bornhack-website/src/shop/migrations/0004_auto_20160515_1604.py":[5,6,9,12,16,17,18,19,20,22,23,24,25],"/home/valberg/code/bornhack/bornhack-website/src/shop/migrations/0052_auto_20171004_0005.py":[3,5,8,11,15,16,17,19,20,21,23,24],"/home/valberg/code/bornhack/bornhack-website/src/shop/migrations/0016_auto_20160529_1122.py":[5,6,9,12,16,17,18,19,20,22,23,24,25],"/home/valberg/code/bornhack/bornhack-website/src/shop/migrations/0035_auto_20170222_1629.py":[3,5,8,11,15,16,17,18],"/home/valberg/code/bornhack/bornhack-website/src/shop/migrations/0037_auto_20170319_2204.py":[3,5,8,11,15,16,17,18],"/home/valberg/code/bornhack/bornhack-website/src/shop/migrations/0057_order_notes.py":[3,6,9,13,14,15,16],"/home/valberg/code/bornhack/bornhack-website/src/shop/migrations/0014_ticket_name.py":[5,8,11,15,16,17,18,19],"/home/valberg/code/bornhack/bornhack-website/src/shop/migrations/0007_auto_20160515_2157.py":[5,8,11,15,16,17,18,20,21,22,24,25,26],"/home/valberg/code/bornhack/bornhack-website/src/shop/migrations/0051_creditnote_danish_vat.py":[3,5,8,11,15,16,17,18],"/home/valberg/code/bornhack/bornhack-website/src/shop/migrations/0021_ticket_email.py":[5,8,11,15,16,17,18],"/home/valberg/code/bornhack/bornhack-website/src/shop/migrations/0044_coinifyapiinvoice_coinify_id.py":[3,5,8,11,15,16,17,18],"/home/valberg/code/bornhack/bornhack-website/src/shop/migrations/0040_auto_20170408_1055.py":[3,5,6,9,12,16,17,18,19],"/home/valberg/code/bornhack/bornhack-website/src/shop/migrations/0011_auto_20160517_1902.py":[5,8,11,15,16,17,19,20,21,22],"/home/valberg/code/bornhack/bornhack-website/src/shop/migrations/0020_auto_20160530_1824.py":[5,8,11,15,16,17,19,20,21,22],"/home/valberg/code/bornhack/bornhack-website/src/shop/migrations/0032_order_customer_comment.py":[5,8,11,15,16,17,18],"/home/valberg/code/bornhack/bornhack-website/src/shop/migrations/0045_auto_20170507_1648.py":[3,5,8,11,15,16,17,18],"/home/valberg/code/bornhack/bornhack-website/src/shop/migrations/0047_auto_20170522_1942.py":[3,5,6,9,12,16,17,18,19],"/home/valberg/code/bornhack/bornhack-website/src/shop/migrations/0022_auto_20160530_2301.py":[5,6,9,12,16,17,18,19,21,22,23,24,26,27,28,29],"/home/valberg/code/bornhack/bornhack-website/src/shop/migrations/0025_creditnote.py":[5,6,7,10,13,14,18,19,21,22,23,24,25,26,27,28,29,32],"/home/valberg/code/bornhack/bornhack-website/src/shop/migrations/0049_auto_20170914_2034.py":[3,5,8,11,15,16,17,18,20,21,22,23],"/home/valberg/code/bornhack/bornhack-website/src/shop/migrations/0048_product_ticket_type.py":[3,5,6,9,12,13,17,18,19,20],"/home/valberg/code/bornhack/bornhack-website/src/shop/migrations/0024_auto_20160605_2126.py":[5,8,11,15,16,17,19,20,21,22],"/home/valberg/code/bornhack/bornhack-website/src/news/migrations/0008_newsitem_archived.py":[5,8,11,15,16,17,18],"/home/valberg/code/bornhack/bornhack-website/src/news/migrations/0003_newsitem_slug.py":[5,8,11,15,16,17,18,19],"/home/valberg/code/bornhack/bornhack-website/src/news/migrations/0001_initial.py":[5,8,10,12,16,17,19,20,21,22,23,24,25,28],"/home/valberg/code/bornhack/bornhack-website/src/news/migrations/0005_auto_20160618_1902.py":[5,8,11,15,16,17,18],"/home/valberg/code/bornhack/bornhack-website/src/news/migrations/0007_auto_20161220_1136.py":[5,8,11,15,16,17,18],"/home/valberg/code/bornhack/bornhack-website/src/news/migrations/0004_auto_20160610_1743.py":[5,8,11,15,16,17,18],"/home/valberg/code/bornhack/bornhack-website/src/news/migrations/0006_remove_newsitem_public.py":[5,8,11,15,16,17],"/home/valberg/code/bornhack/bornhack-website/src/news/migrations/0002_auto_20160530_2223.py":[5,8,11,15,16,17],"/home/valberg/code/bornhack/bornhack-website/src/utils/migrations/0001_initial.py":[3,5,8,10,12,16,17,19,20,21,22,23,24,25,26,27,28,31],"/home/valberg/code/bornhack/bornhack-website/src/utils/migrations/0003_auto_20170521_1932.py":[3,5,6,9,12,16,17,18,19,21,22,23,24,26,27,28,29],"/home/valberg/code/bornhack/bornhack-website/src/utils/migrations/0002_remove_outgoingemail_recipient.py":[3,5,8,11,15,16,17],"/home/valberg/code/bornhack/bornhack-website/src/villages/migrations/0001_initial.py":[5,6,7,8,11,13,16,17,21,22,24,25,26,27,28,29,30,31,32,35],"/home/valberg/code/bornhack/bornhack-website/src/villages/migrations/0011_auto_20180318_0906.py":[3,5,6,7,10,13,17,18,19,20,22,23,24,25],"/home/valberg/code/bornhack/bornhack-website/src/villages/migrations/0009_auto_20161229_2143.py":[5,8,11,15,16,17,18],"/home/valberg/code/bornhack/bornhack-website/src/villages/migrations/0003_auto_20160705_2159.py":[5,8,11,15,16,17,18],"/home/valberg/code/bornhack/bornhack-website/src/villages/migrations/0006_remove_village_camp.py":[5,8,11,15,16,17],"/home/valberg/code/bornhack/bornhack-website/src/villages/migrations/0008_auto_20161228_2209.py":[5,6,9,12,16,17,18,19],"/home/valberg/code/bornhack/bornhack-website/src/villages/migrations/0004_village_deleted.py":[5,8,11,15,16,17,18],"/home/valberg/code/bornhack/bornhack-website/src/villages/migrations/0007_village_camp.py":[5,6,9,12,13,17,18,19,20],"/home/valberg/code/bornhack/bornhack-website/src/villages/migrations/0005_auto_20160712_2036.py":[5,8,11,15,16,17,18],"/home/valberg/code/bornhack/bornhack-website/src/villages/migrations/0010_auto_20170318_1506.py":[3,5,8,11,12,16,17,18],"/home/valberg/code/bornhack/bornhack-website/src/villages/migrations/0002_auto_20160705_2154.py":[5,8,11,15,16,17,19,20,21,22],"/home/valberg/code/bornhack/bornhack-website/src/program/migrations/0015_auto_20170128_1841.py":[5,8,11,12,16,17,18,19,21,22,23,24,26,27,28,30,31,32],"/home/valberg/code/bornhack/bornhack-website/src/program/migrations/0008_auto_20160808_1747.py":[5,8,11,15,16,17,19,20,21,23,24,25,26,28,29,30,31,33,34,35,36,38,39,40,41],"/home/valberg/code/bornhack/bornhack-website/src/program/migrations/0017_eventinstance_notifications_sent.py":[3,5,8,11,15,16,17,18],"/home/valberg/code/bornhack/bornhack-website/src/program/migrations/0019_auto_20170205_1940.py":[3,5,6,9,12,13,17,18,20,21,22,23,24,25,26,29,32,33,34,35],"/home/valberg/code/bornhack/bornhack-website/src/program/migrations/0033_auto_20170312_1857.py":[3,5,6,7,8,9,12,15,16,17,21,22,24,25,26,27,28,29,30,31,34,37,38,40,41,42,43,44,45,46,47,48,49,52,55,56,57,59,60,61,63,64,65,67,68,69,71,72,73,75,76,77,79,80,81,83,84,86,87,89,90,91,92,94,95,96,97,99,100,101,102],"/home/valberg/code/bornhack/bornhack-website/src/program/migrations/0038_favorite.py":[3,5,6,7,10,13,14,18,19,21,22,23],"/home/valberg/code/bornhack/bornhack-website/src/program/migrations/0056_add_urltypes.py":[3,5,49,52,56],"/home/valberg/code/bornhack/bornhack-website/src/program/migrations/0005_auto_20160807_1312.py":[5,8,11,15,16,17,18,19,21,22,23,24],"/home/valberg/code/bornhack/bornhack-website/src/program/migrations/0002_eventtype_color.py":[5,8,11,15,16,17,18,19],"/home/valberg/code/bornhack/bornhack-website/src/program/migrations/0012_auto_20161229_2150.py":[5,6,9,12,16,17,18,19],"/home/valberg/code/bornhack/bornhack-website/src/program/migrations/0064_auto_20180810_1748.py":[3,6,9,13,14,15,16],"/home/valberg/code/bornhack/bornhack-website/src/program/migrations/0006_auto_20160807_1320.py":[5,8,11,15,16,17,18],"/home/valberg/code/bornhack/bornhack-website/src/program/migrations/0071_auto_20180827_1958.py":[3,6,9,13,14,15],"/home/valberg/code/bornhack/bornhack-website/src/program/migrations/0010_auto_20161212_1809.py":[5,6,9,12,13,17,18,20,21,22,23,24,27,30,31,32,34,35,36,38,39,40,42,43,44,45,47,48,49,50],"/home/valberg/code/bornhack/bornhack-website/src/program/migrations/0061_auto_20180603_1525.py":[3,4,7,10,14,15,16,17,19,20,21,22],"/home/valberg/code/bornhack/bornhack-website/src/program/migrations/0063_auto_20180809_1525.py":[3,6,9,13,14,15,16],"/home/valberg/code/bornhack/bornhack-website/src/program/migrations/0027_auto_20170307_1701.py":[3,5,6,9,12,13,14,18,19,20],"/home/valberg/code/bornhack/bornhack-website/src/program/migrations/0035_auto_20170314_2325.py":[3,5,8,11,15,16,17,18],"/home/valberg/code/bornhack/bornhack-website/src/program/migrations/0068_add_email_to_speaker_and_speaker_proposal.py":[3,6,21,24,28],"/home/valberg/code/bornhack/bornhack-website/src/program/migrations/0049_add_event_tracks.py":[3,5,21,24,28],"/home/valberg/code/bornhack/bornhack-website/src/program/migrations/0043_auto_20170801_1526.py":[3,5,8,11,15,16,17,18,20,21,22,23],"/home/valberg/code/bornhack/bornhack-website/src/program/migrations/0059_auto_20180523_2241.py":[3,4,7,10,14,15,16,18,19,20,21],"/home/valberg/code/bornhack/bornhack-website/src/program/migrations/0007_auto_20160807_1333.py":[5,8,11,15,16,17,18],"/home/valberg/code/bornhack/bornhack-website/src/program/migrations/0055_auto_20180521_2354.py":[3,4,7,10,14,15,17,18,19,20,21,22,23,24,27,30,31,33,34,35,36,37,40,43,44,45,46],"/home/valberg/code/bornhack/bornhack-website/src/program/migrations/0024_auto_20170222_1629.py":[3,5,8,11,15,16,17,18,20,21,22,23],"/home/valberg/code/bornhack/bornhack-website/src/program/migrations/0039_auto_20170430_1408.py":[3,5,6,9,12,13,17,18,19,20,22,23,24],"/home/valberg/code/bornhack/bornhack-website/src/program/migrations/0057_auto_20180522_0659.py":[3,6,9,13,14,15,16],"/home/valberg/code/bornhack/bornhack-website/src/program/migrations/0004_auto_20160804_1712.py":[5,8,11,15,16,17,18],"/home/valberg/code/bornhack/bornhack-website/src/program/migrations/0018_eventtype_notifications.py":[3,5,8,11,15,16,17,18],"/home/valberg/code/bornhack/bornhack-website/src/program/migrations/0028_auto_20170307_2014.py":[3,5,8,11,15,16,17,18,20,21,22,23],"/home/valberg/code/bornhack/bornhack-website/src/program/migrations/0029_auto_20170307_2042.py":[3,5,8,11,15,16,17,18,20,21,22,23],"/home/valberg/code/bornhack/bornhack-website/src/program/migrations/0045_event_proposal.py":[3,5,6,9,12,16,17,18,19],"/home/valberg/code/bornhack/bornhack-website/src/program/migrations/0053_auto_20180519_2325.py":[3,6,9,13,14,15,16],"/home/valberg/code/bornhack/bornhack-website/src/program/migrations/0014_speaker_camp.py":[5,6,9,12,13,17,18,19,20],"/home/valberg/code/bornhack/bornhack-website/src/program/migrations/0058_auto_20180523_0844.py":[3,6,9,13,14,15,17,18,19,20],"/home/valberg/code/bornhack/bornhack-website/src/program/migrations/0036_auto_20170316_0004.py":[3,5,6,9,12,16,17,18,19,21,22,23,24],"/home/valberg/code/bornhack/bornhack-website/src/program/migrations/0048_auto_20180512_1625.py":[3,4,5,8,11,12,13,17,18,20,21,22,23,24,25,26,29,30,31,33,34,35,37,38,39,41,42,43,45,46,47,48,50,51,52,53,55,56,57,58,60,61,62,63,65,66,67,68,70,71,72,73,75,76,77,78,80,81,82,83,85,86,87,88,90,91,92,93,95,96,97,98,100,101,102,103,105,106,107,108,110,111,112,113,115,116,117,118,120,121,122,123,125,126,127,128,130,131,132],"/home/valberg/code/bornhack/bornhack-website/src/program/migrations/0066_speaker_email.py":[3,6,9,13,14,15,16],"/home/valberg/code/bornhack/bornhack-website/src/program/migrations/0001_initial.py":[5,6,9,11,14,18,19,21,22,23,24,25,26,27,28,31,34,35,37,38,39,40,41,44,47,48,50,51,52,53,54,55,56,59,62,63,64,65],"/home/valberg/code/bornhack/bornhack-website/src/program/migrations/0022_auto_20170218_1148.py":[3,5,8,11,15,16,17,18,20,21,22,23],"/home/valberg/code/bornhack/bornhack-website/src/program/migrations/0026_speaker_user.py":[3,5,6,7,10,13,14,18,19,20,21],"/home/valberg/code/bornhack/bornhack-website/src/program/migrations/0050_auto_20180512_1650.py":[3,6,9,13,14,15,17,18,19,21,22,23],"/home/valberg/code/bornhack/bornhack-website/src/program/migrations/0051_auto_20180512_1801.py":[3,4,7,10,14,15,16,17,19,20,21,22],"/home/valberg/code/bornhack/bornhack-website/src/program/migrations/0046_auto_20180318_0906.py":[3,5,6,7,10,13,17,18,19,20],"/home/valberg/code/bornhack/bornhack-website/src/program/migrations/0041_auto_20170711_2248.py":[3,5,8,11,15,16,17,18,20,21,22,23],"/home/valberg/code/bornhack/bornhack-website/src/program/migrations/0040_eventproposal_allow_video_recording.py":[3,5,8,11,15,16,17,18],"/home/valberg/code/bornhack/bornhack-website/src/program/migrations/0003_eventtype_light_writing.py":[5,8,11,15,16,17,18],"/home/valberg/code/bornhack/bornhack-website/src/program/migrations/0031_auto_20170312_1529.py":[3,5,8,11,15,16,17,19,20,21,22],"/home/valberg/code/bornhack/bornhack-website/src/program/migrations/0011_auto_20161229_2149.py":[5,6,9,12,16,17,18,20,21,22,24,25,26,28,29,30,31],"/home/valberg/code/bornhack/bornhack-website/src/program/migrations/0025_auto_20170306_1938.py":[3,5,8,11,15,16,17,18],"/home/valberg/code/bornhack/bornhack-website/src/program/migrations/0044_auto_20170801_1527.py":[3,5,8,11,15,16,17,18],"/home/valberg/code/bornhack/bornhack-website/src/program/migrations/0069_add_bogus_email_to_old_speakers.py":[3,6,15,18,22],"/home/valberg/code/bornhack/bornhack-website/src/program/migrations/0013_auto_20170121_1312.py":[5,6,9,12,16,17,18,19],"/home/valberg/code/bornhack/bornhack-website/src/program/migrations/0009_auto_20160827_0752.py":[5,8,11,15,16,17,18],"/home/valberg/code/bornhack/bornhack-website/src/program/migrations/0020_auto_20170205_1940.py":[3,5,6,9,12,16,17,18,19],"/home/valberg/code/bornhack/bornhack-website/src/program/migrations/0052_auto_20180519_2324.py":[3,6,9,13,14,15,16],"/home/valberg/code/bornhack/bornhack-website/src/program/migrations/0067_auto_20180818_1634.py":[3,6,9,13,14,15],"/home/valberg/code/bornhack/bornhack-website/src/program/migrations/0034_auto_20170314_2012.py":[3,5,6,9,12,16,17,18,19,21,22,23,24],"/home/valberg/code/bornhack/bornhack-website/src/program/migrations/0070_auto_20180819_1729.py":[3,6,9,13,14,15,16,18,19,20,21],"/home/valberg/code/bornhack/bornhack-website/src/program/migrations/0060_auto_20180603_1455.py":[3,4,5,8,11,15,16,17,18,20,21,22,23,25,26,27,28,30,31,32,33,35,36,37,38],"/home/valberg/code/bornhack/bornhack-website/src/program/migrations/0047_auto_20180415_1159.py":[3,4,5,8,11,15,16,17,18,20,21,22,23,25,26,27,28,30,31,32,33,35,36,37,38,40,41,42,43,45,46,47,48,50,51,52,53,55,56,57,58,60,61,62,63,65,66,67,68,70,71,72,73,75,76,77,78,80,81,82,83],"/home/valberg/code/bornhack/bornhack-website/src/program/migrations/0042_auto_20170715_1547.py":[3,5,8,11,15,16,17,18,20,21,22,23],"/home/valberg/code/bornhack/bornhack-website/src/program/migrations/0054_auto_20180520_1509.py":[3,6,9,13,14,15,17,18,19,20],"/home/valberg/code/bornhack/bornhack-website/src/program/migrations/0016_auto_20170131_1849.py":[3,5,8,11,15,16,17,18],"/home/valberg/code/bornhack/bornhack-website/src/program/migrations/0062_auto_20180717_1720.py":[3,6,9,13,14,15,16],"/home/valberg/code/bornhack/bornhack-website/src/program/migrations/0023_auto_20170218_1243.py":[3,5,6,9,12,16,17,18,19,21,22,23,24],"/home/valberg/code/bornhack/bornhack-website/src/program/migrations/0032_auto_20170312_1556.py":[3,5,8,11,15,16,17,18,20,21,22,23,25,26,27,28,30,31,32,33,35,36,37,38,40,41,42,43],"/home/valberg/code/bornhack/bornhack-website/src/program/migrations/0021_auto_20170205_2130.py":[3,5,8,11,12,16,17,18,19,21,22,23,24,26,27,28],"/home/valberg/code/bornhack/bornhack-website/src/program/migrations/0065_speakerproposal_email.py":[3,6,9,13,14,15,16],"/home/valberg/code/bornhack/bornhack-website/src/program/migrations/0030_auto_20170312_1230.py":[3,5,6,7,8,9,12,15,16,17,21,22,24,25,26,27,28,29,30,31,32,35,38,39,41,42,43,44,45,46,47,48,49,50,53,56,57,58,60,61,62,63,65,66,67,68,70,71,72,73,75,76,77,78,80,81,82,83,85,86,87,88,90,91,92,93,95,96,97,98,100,101,102,103,105,106,107,108,110,111,112,113,115,116,117,118,120,121,122,123,125,126,127,128,130,131,132,133,135,136,137,139,140,141,142,144,145,146],"/home/valberg/code/bornhack/bornhack-website/src/program/migrations/0037_eventtype_include_in_event_list.py":[3,5,8,11,15,16,17,18],"/home/valberg/code/bornhack/bornhack-website/src/info/migrations/0001_initial.py":[5,6,9,11,14,18,19,21,22,23,24,25,26,27,30,33,34,36,37,38,39,40,41,42,43,46,49,50,51,53,54,55],"/home/valberg/code/bornhack/bornhack-website/src/info/migrations/0006_auto_20180520_1113.py":[3,4,7,10,14,15,16,17,19,20,21,23,24,25],"/home/valberg/code/bornhack/bornhack-website/src/info/migrations/0003_auto_20170218_1148.py":[3,5,8,11,15,16,17,19,20,21],"/home/valberg/code/bornhack/bornhack-website/src/info/migrations/0002_auto_20161228_2312.py":[5,8,11,15,16,17,19,20,21,22,24,25,26,27],"/home/valberg/code/bornhack/bornhack-website/src/info/migrations/0005_add_teams_to_categories.py":[3,4,7,70,73,77],"/home/valberg/code/bornhack/bornhack-website/src/info/migrations/0007_auto_20180520_1511.py":[3,4,7,10,14,15,16,17],"/home/valberg/code/bornhack/bornhack-website/src/info/migrations/0004_infocategory_team.py":[3,4,7,10,11,15,16,17,18],"/home/valberg/code/bornhack/bornhack-website/src/sponsors/migrations/0010_populate_logo_filename.py":[3,5,11,14,18],"/home/valberg/code/bornhack/bornhack-website/src/sponsors/migrations/0001_initial.py":[3,5,6,9,11,13,17,18,20,21,22,23,24,25,26,29],"/home/valberg/code/bornhack/bornhack-website/src/sponsors/migrations/0003_sponsortier_camp.py":[3,5,6,9,12,13,17,18,19,20],"/home/valberg/code/bornhack/bornhack-website/src/sponsors/migrations/0007_auto_20180318_0906.py":[3,5,6,9,12,16,17,18,19,21,22,23,24],"/home/valberg/code/bornhack/bornhack-website/src/sponsors/migrations/0008_auto_20180815_1119.py":[3,6,9,13,14,15,16,18,19,20,21],"/home/valberg/code/bornhack/bornhack-website/src/sponsors/migrations/0002_auto_20170711_2341.py":[3,5,6,9,12,16,17,19,20,21,22,23,26,29,30,31,32],"/home/valberg/code/bornhack/bornhack-website/src/sponsors/migrations/0009_sponsor_logo_filename.py":[3,6,9,13,14,15,16],"/home/valberg/code/bornhack/bornhack-website/src/sponsors/migrations/0011_auto_20181118_1513.py":[3,6,9,13,14,15,17,18,19,20],"/home/valberg/code/bornhack/bornhack-website/src/sponsors/migrations/0004_sponsortier_weight.py":[3,5,8,11,15,16,17,18],"/home/valberg/code/bornhack/bornhack-website/src/sponsors/migrations/0006_auto_20170715_1110.py":[3,5,8,11,15,16,17,18,20,21,22,23],"/home/valberg/code/bornhack/bornhack-website/src/sponsors/migrations/0005_sponsor_url.py":[3,5,8,11,15,16,17,18],"/home/valberg/code/bornhack/bornhack-website/src/ircbot/migrations/0001_initial.py":[5,8,10,12,16,17,19,20,21,22,23,24,27],"/home/valberg/code/bornhack/bornhack-website/src/ircbot/migrations/0003_outgoingircmessage_expired.py":[3,5,8,11,15,16,17,18],"/home/valberg/code/bornhack/bornhack-website/src/ircbot/migrations/0002_outgoingircmessage_timeout.py":[3,5,6,7,10,13,17,18,19,20,21],"/home/valberg/code/bornhack/bornhack-website/src/teams/migrations/0003_auto_20170401_2227.py":[3,5,8,11,15,16,17,18],"/home/valberg/code/bornhack/bornhack-website/src/teams/migrations/0008_team_needs_members.py":[3,5,8,11,15,16,17,18],"/home/valberg/code/bornhack/bornhack-website/src/teams/migrations/0014_remove_teammember_deleted.py":[3,5,8,11,15,16,17],"/home/valberg/code/bornhack/bornhack-website/src/teams/migrations/0007_teamarea_description.py":[3,5,8,11,15,16,17,18],"/home/valberg/code/bornhack/bornhack-website/src/teams/migrations/0018_auto_20171122_2204.py":[3,5,6,9,12,16,17,18,19],"/home/valberg/code/bornhack/bornhack-website/src/teams/migrations/0005_auto_20170402_1331.py":[3,5,6,7,10,13,14,15,19,20,22,23,24,25,26,27,30,33,34,35,37,38,39,41,42,43,44,46,47,48,50,51,52,54,55,56,57,59,60,61,63,64,66,67,68],"/home/valberg/code/bornhack/bornhack-website/src/teams/migrations/0037_auto_20180408_1416.py":[3,5,6,7,10,13,17,18,19,20,22,23,24,25,27,28,29,30,32,33,34,35,37,38,39,40],"/home/valberg/code/bornhack/bornhack-website/src/teams/migrations/0028_auto_20180331_1416.py":[3,5,6,9,12,16,17,18,19],"/home/valberg/code/bornhack/bornhack-website/src/teams/migrations/0013_auto_20170523_2046.py":[3,5,6,9,12,16,17,18,19,20,22,23,24,25,27,28,29,30],"/home/valberg/code/bornhack/bornhack-website/src/teams/migrations/0011_auto_20170402_1608.py":[3,5,8,11,15,16,17,18],"/home/valberg/code/bornhack/bornhack-website/src/teams/migrations/0024_populate_shortslugs.py":[3,5,7,14,16,20],"/home/valberg/code/bornhack/bornhack-website/src/teams/migrations/0030_auto_20180402_1514.py":[3,5,8,11,15,16,17,18,20,21,22,23,25,26,27,28],"/home/valberg/code/bornhack/bornhack-website/src/teams/migrations/0029_remove_team_area.py":[3,5,8,11,15,16,17],"/home/valberg/code/bornhack/bornhack-website/src/teams/migrations/0031_auto_20180402_2146.py":[3,5,8,11,15,16,17,18,20,21,22,23],"/home/valberg/code/bornhack/bornhack-website/src/teams/migrations/0032_auto_20180402_2148.py":[3,5,6,9,12,16,17,18,19],"/home/valberg/code/bornhack/bornhack-website/src/teams/migrations/0017_auto_20171122_1928.py":[3,5,6,9,12,16,17,19,20,21,22,23,24,25,28,31,32,33],"/home/valberg/code/bornhack/bornhack-website/src/teams/migrations/0038_auto_20180412_1844.py":[3,5,8,11,15,16,17,18,20,21,22,23,25,26,27,28,30,31,32,33,35,36,37,38,40,41,42,43],"/home/valberg/code/bornhack/bornhack-website/src/teams/migrations/0039_fix_irc_channels.py":[3,5,7,24,27,31],"/home/valberg/code/bornhack/bornhack-website/src/teams/migrations/0050_team_guide.py":[3,6,9,13,14,15,16],"/home/valberg/code/bornhack/bornhack-website/src/teams/migrations/0022_auto_20180318_1135.py":[3,5,8,11,15,16,17,18,20,21,22,23,25,26,27,28,30,31,32,33],"/home/valberg/code/bornhack/bornhack-website/src/teams/migrations/0035_auto_20180402_2344.py":[3,5,8,11,15,16,17],"/home/valberg/code/bornhack/bornhack-website/src/teams/migrations/0025_auto_20180318_1318.py":[3,5,8,11,15,16,17,18],"/home/valberg/code/bornhack/bornhack-website/src/teams/migrations/0045_merge_20180805_1131.py":[3,6,9,10,13],"/home/valberg/code/bornhack/bornhack-website/src/teams/migrations/0002_auto_20170327_2208.py":[3,5,8,11,12,16,17,18,20,21,22,23,25,26,27],"/home/valberg/code/bornhack/bornhack-website/src/teams/migrations/0001_initial.py":[3,5,6,7,10,12,15,16,20,21,23,24,25,26,27,28,31,34,35,37,38,39,40,43,44,45,46],"/home/valberg/code/bornhack/bornhack-website/src/teams/migrations/0043_auto_20180702_1338.py":[3,4,5,8,11,15,16,18,19,20,21,22,25,28,29,30,31,33,34,35,36,38,39,40,41],"/home/valberg/code/bornhack/bornhack-website/src/teams/migrations/0027_fixup_teams.py":[3,5,7,18,50,53,57,58],"/home/valberg/code/bornhack/bornhack-website/src/teams/migrations/0046_auto_20180808_2154.py":[3,6,9,13,14,15],"/home/valberg/code/bornhack/bornhack-website/src/teams/migrations/0006_auto_20170402_1331.py":[3,5,6,9,12,16,17,18,19,21,22,23,24],"/home/valberg/code/bornhack/bornhack-website/src/teams/migrations/0015_team_mailing_list.py":[3,5,8,11,15,16,17,18],"/home/valberg/code/bornhack/bornhack-website/src/teams/migrations/0048_auto_20180814_1950.py":[3,6,9,13,14,15,16],"/home/valberg/code/bornhack/bornhack-website/src/teams/migrations/0026_team_camp.py":[3,5,6,9,12,13,17,18,19,20],"/home/valberg/code/bornhack/bornhack-website/src/teams/migrations/0033_auto_20180402_2204.py":[3,5,8,11,15,16,17,19,20,21,23,24,25,27,28],"/home/valberg/code/bornhack/bornhack-website/src/teams/migrations/0004_team_sub_team_of.py":[3,5,6,9,12,16,17,18,19],"/home/valberg/code/bornhack/bornhack-website/src/teams/migrations/0040_auto_20180412_2109.py":[3,5,8,11,15,16,17,19,20,21,23,24,25,27,28,29],"/home/valberg/code/bornhack/bornhack-website/src/teams/migrations/0016_auto_20170711_2247.py":[3,5,6,9,12,16,17,18,19],"/home/valberg/code/bornhack/bornhack-website/src/teams/migrations/0034_auto_20180402_2334.py":[3,5,8,11,15,16,17],"/home/valberg/code/bornhack/bornhack-website/src/teams/migrations/0019_auto_20180304_1019.py":[3,5,8,11,15,16,17,19,20,21],"/home/valberg/code/bornhack/bornhack-website/src/teams/migrations/0020_auto_20180304_1233.py":[3,5,6,9,12,16,17,18,19],"/home/valberg/code/bornhack/bornhack-website/src/teams/migrations/0042_auto_20180413_1933.py":[3,5,8,11,15,16,17,18,20,21,22,23,25,26,27,28],"/home/valberg/code/bornhack/bornhack-website/src/teams/migrations/0012_teammember_responsible.py":[3,5,8,11,15,16,17,18],"/home/valberg/code/bornhack/bornhack-website/src/teams/migrations/0043_auto_20180804_1641.py":[3,4,7,10,14,15,16,17,19,20,21,22],"/home/valberg/code/bornhack/bornhack-website/src/teams/migrations/0044_auto_20180702_1507.py":[3,6,9,13,14,15,16],"/home/valberg/code/bornhack/bornhack-website/src/teams/migrations/0047_taskcomment.py":[3,4,5,8,11,15,16,18,19,20,21,22,23,26],"/home/valberg/code/bornhack/bornhack-website/src/teams/migrations/0051_auto_20190312_1129.py":[3,6,9,13,14,15,16],"/home/valberg/code/bornhack/bornhack-website/src/teams/migrations/0036_auto_20180403_0201.py":[3,5,8,11,12,16,17,18],"/home/valberg/code/bornhack/bornhack-website/src/teams/migrations/0041_auto_20180412_2231.py":[3,5,8,11,15,16,17,19,20,21,22],"/home/valberg/code/bornhack/bornhack-website/src/teams/migrations/0021_auto_20180318_0906.py":[3,5,6,7,10,13,17,18,19,20,22,23,24,25,27,28,29,30],"/home/valberg/code/bornhack/bornhack-website/src/teams/migrations/0049_auto_20180815_1119.py":[3,6,9,13,14,15],"/home/valberg/code/bornhack/bornhack-website/src/teams/migrations/0010_remove_team_members.py":[3,5,8,11,15,16,17],"/home/valberg/code/bornhack/bornhack-website/src/teams/migrations/0009_auto_20170402_1607.py":[3,5,6,7,10,13,14,18,19,21,22,25,26,27,28,30,31,32,33,35,36,37,38,40,41,42,43],"/home/valberg/code/bornhack/bornhack-website/src/teams/migrations/0023_auto_20180318_1256.py":[3,5,8,11,15,16,17,18,20,21,22,23,25,26,27,28],"/home/valberg/code/bornhack/bornhack-website/src/tickets/migrations/0001_initial.py":[3,5,6,7,10,12,15,16,17,21,22,24,25,26,27,28,29,32,35,36,38,39,40,41,42,43,44,45,46,49,52,53,55,56,57,58,59,60,63,66,67,69,70,71,72,73,76,79,80,81,82,84,85,86,87,89,90,91,92],"/home/valberg/code/bornhack/bornhack-website/src/tickets/migrations/0005_auto_20180318_0906.py":[3,5,6,9,12,16,17,18,19,21,22,23,24,26,27,28,29,31,32,33,34,36,37,38,39,41,42,43,44,46,47,48,49],"/home/valberg/code/bornhack/bornhack-website/src/tickets/migrations/0004_auto_20170823_1228.py":[3,5,8,11,15,16,17,18,20,21,22,23,25,26,27,28],"/home/valberg/code/bornhack/bornhack-website/src/tickets/migrations/0002_auto_20170819_2222.py":[3,5,6,9,12,16,17,18,19,21,22,23,24,26,27,28,29,31,32,33,34],"/home/valberg/code/bornhack/bornhack-website/src/tickets/migrations/0003_auto_20170819_2309.py":[3,5,8,11,15,16,17,19,20,21,23,24,25],"/home/valberg/code/bornhack/bornhack-website/src/bar/migrations/0001_initial.py":[3,5,6,9,11,14,18,19,21,22,23,24,27,28,30,31,32,33,34,37,40,41,42,43],"/home/valberg/code/bornhack/bornhack-website/src/bar/migrations/0003_auto_20180318_0906.py":[3,5,6,9,12,16,17,18,19,21,22,23,24],"/home/valberg/code/bornhack/bornhack-website/src/bar/migrations/0002_auto_20170916_2128.py":[3,5,6,9,12,16,17,18,20,21,22,24,25,26,27],"/home/valberg/code/bornhack/bornhack-website/src/events/migrations/0002_create_eventtype.py":[3,5,7,11,14,18],"/home/valberg/code/bornhack/bornhack-website/src/events/migrations/0001_initial.py":[3,5,6,9,11,14,18,19,21,22,23,26,29,30,32,33,34,35,38,41,42,43,44,46,47,48,49],"/home/valberg/code/bornhack/bornhack-website/src/events/migrations/0003_create_another_eventtype.py":[3,5,7,12,15,19],"/home/valberg/code/bornhack/bornhack-website/src/events/migrations/0004_auto_20180403_1228.py":[3,5,8,11,15,16,17,18,20,21,22,23],"/home/valberg/code/bornhack/bornhack-website/src/rideshare/migrations/0001_initial.py":[3,4,5,6,9,11,14,15,19,20,22,23,24,25,26,27,28,29,30,33],"/home/valberg/code/bornhack/bornhack-website/src/rideshare/migrations/0002_auto_20180814_1942.py":[3,6,9,13,14,15,16],"/home/valberg/code/bornhack/bornhack-website/src/tokens/migrations/0004_auto_20180819_1743.py":[3,4,7,10,11,15,16,17],"/home/valberg/code/bornhack/bornhack-website/src/tokens/migrations/0001_initial.py":[3,4,7,9,12,16,17,19,20,21,22,23,24,27],"/home/valberg/code/bornhack/bornhack-website/src/tokens/migrations/0005_auto_20190327_2025.py":[3,6,9,13,14,15],"/home/valberg/code/bornhack/bornhack-website/src/tokens/migrations/0002_tokenfind.py":[3,4,5,8,11,12,16,17,19,20,21,22,23,26],"/home/valberg/code/bornhack/bornhack-website/src/tokens/migrations/0003_token_category.py":[3,6,9,13,14,15,16,17],"/home/valberg/code/bornhack/bornhack-website/src/feedback/migrations/0002_feedback_camp.py":[3,4,7,10,11,15,16,17,18,19],"/home/valberg/code/bornhack/bornhack-website/src/feedback/migrations/0001_initial.py":[3,4,5,6,9,11,14,18,19,21,22,23,24,25,28],"/home/valberg/code/bornhack/bornhack-website/src/economy/migrations/0001_initial.py":[3,4,5,6,9,11,14,15,16,20,21,23,24,25,26,27,28,29,30,31,32,35,38,39,41,42,43,44,45,46,47,48,51,54,55,56,57,59,60,61,62,64,65,66,67],"/home/valberg/code/bornhack/bornhack-website/src/economy/migrations/0005_auto_20190120_1532.py":[3,6,9,13,14,15,16,18,19,20,21],"/home/valberg/code/bornhack/bornhack-website/src/economy/migrations/0008_auto_20190327_1721.py":[3,4,5,8,11,15,16,18,19,20,21,22,23,26,29,30,32,33,34,35,36,37,38,39,42,45,46,47,48,50,51,52,53,55,56,57,58,60,61,62,63,65,66,67],"/home/valberg/code/bornhack/bornhack-website/src/economy/migrations/0006_auto_20190120_1642.py":[3,6,9,13,14,15,16,18,19,20,21],"/home/valberg/code/bornhack/bornhack-website/src/economy/migrations/0009_auto_20190328_0715.py":[3,6,9,13,14,15,16,18,19,20,21],"/home/valberg/code/bornhack/bornhack-website/src/economy/migrations/0002_revenue.py":[3,4,5,6,9,12,13,14,15,16,20,21,23,24,25,26,27,28,29,30,31,32,33,34,37],"/home/valberg/code/bornhack/bornhack-website/src/economy/migrations/0003_auto_20180917_1933.py":[3,4,7,10,14,15,16,17],"/home/valberg/code/bornhack/bornhack-website/src/economy/migrations/0007_auto_20190327_0936.py":[3,6,9,13,14,15,16,18,19,20,21],"/home/valberg/code/bornhack/bornhack-website/src/economy/migrations/0004_auto_20181120_1835.py":[3,4,5,8,11,15,16,17,18],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/allauth/account/migrations/__init__.py":[1],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/allauth/account/migrations/0001_initial.py":[2,4,5,6,8,11,14,18,19,21,22,23,24,25,28,29,31,33,34,36,37,38,39,40,43,44,46,50],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/allauth/account/migrations/0002_email_max_length.py":[2,4,5,7,8,11,14,18,19,20,21,25],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django_otp/plugins/otp_totp/migrations/__init__.py":[1],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django_otp/plugins/otp_totp/migrations/0001_initial.py":[2,4,5,6,9,12,16,17,19,20,21,22,23,24,25,26,27,28,29,32,33,35],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django_otp/plugins/otp_static/migrations/__init__.py":[1],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django_otp/plugins/otp_static/migrations/0001_initial.py":[2,4,5,8,11,15,16,18,19,20,21,24,26,28,29,31,32,33,35,37],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/reversion/migrations/__init__.py":[1],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/reversion/migrations/0001_squashed_0004_auto_20160611_1202.py":[3,5,6,7,10,12,15,16,20,21,23,24,25,26,29,32,33,35,36,37,38,39,40,41,42,45,48,49,50],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/db/models/sql/compiler.py":[1,2,3,4,5,7,8,9,10,11,14,15,16,17,18,20,23,24,38,44,58,135,181,251,358,368,385,395,439,590,634,659,689,702,737,910,969,979,1002,1013,1014,1027,1037,1103,1116,1127,1128,1130,1162,1185,1194,1229,1281,1302,1303,1318,1319,1376,1397,1440,1441,1460,25,26,27,28,33,34,35,36,1016,1017,1050,1051,1052,447,448,449,50,39,41,199,200,201,202,203,207,208,213,214,215,216,217,218,219,221,222,224,229,241,242,243,244,386,387,390,374,376,377,378,381,382,383,391,392,248,375,249,42,51,260,262,265,266,267,271,272,325,326,328,356,52,53,359,360,366,54,55,95,96,56,450,452,453,454,455,460,641,642,643,645,656,463,713,714,715,716,718,719,724,393,725,726,727,734,464,465,466,467,469,477,478,479,480,482,485,486,488,489,491,518,521,525,526,529,535,539,545,552,555,558,585,588,1053,1060,1063,1064,1065,1071,1074,1083,1087,1088,1089,1090,1092,1101,1018,1019,980,981,982,983,984,985,1000,1020,1021,1025,1465,1466,1467,1469,1283,1286,1287,1288,1232,1233,1234,1235,1236,1238,1240,1241,1190,1192,1167,1182,1183,1252,1254,1206,1212,1213,1218,1222,1139,1142,1145,1151,1158,1160,1225,1227,1256,1257,1258,1259,1263,1264,1267,1268,1269,1270,1289,1290,1292,1294,1295,1296,209,602,603,604,605,975,976,977,606,610,612,613,616,617,618,626,628,629,630,631,632,263,522,523,273,280,284,285,287,293,300,311,314,315,665,666,667,668,697,698,699,700,673,686,687,329,344,345,346,351,352,354,355,546,547,548,549,550,1033,1034,1035,40,204,205,206,481,553,1075,1076,1077,1078,1082,1055,1056,1057,1284,1293,1061,1079,1272,1273,1274,1291,225,226,227,717,986,987,988,998,999,1003,1004,1005,1006,1007,1008,1009,1010,1011,379,380,1383,1324,1406,1408,1409,1410,1411,1325,1327,1328,1329,1330,1336,1349,1352,1355,1356,1357,1361,1362,1363,1366,1368,1369,1371,1372,1373,1374,1073,1384,1385,1386,1388,1389,1390,1395],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/db/migrations/writer.py":[1,2,3,5,6,7,8,9,10,11,12,15,20,22,25,29,30,35,116,119,122,125,129,133,135,139,208,269,273,277,296,23,26],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/db/migrations/serializer.py":[1,2,3,4,5,6,7,8,9,10,12,13,14,15,16,17,18,21,22,25,29,30,33,44,45,49,50,62,63,70,71,75,76,90,101,105,106,118,119,127,128,134,135,139,140,161,162,180,181,194,195,200,201,210,211,218,219,232,233,237,238,244,245,249,250,254,255,262,263,269,270,285,286,290],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/core/serializers/xml_serializer.py":[3,5,6,7,9,10,11,12,13,18,19,21,25,33,41,57,64,87,110,139,149,150,152,158,162,169,218,247,269,287,304,309,310,315,318,322,326,329,338,339,340,344,345,346,352,357,358,359,368,373,374,375,382],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/utils/xmlutils.py":[3,5,6,7,10,11,14,15,24,31],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/core/serializers/pyyaml.py":[5,7,8,9,11],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/core/management/commands/createcachetable.py":[1,2,3,4,5,8,11,12,14,16,32,46,17,18,19,21,22,23,24,27,28,29,33,34,35,36,41,42,43],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/core/cache/backends/db.py":[1,2,3,4,6,7,8,9,10,13,17,18,31,32,41,49,97,102,107,112,202,213,238,257],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/core/cache/backends/locmem.py":[1,2,3,4,5,7,11,12,13,16,17,23,33,44,51,58,66,81,90,94,104,111,117,18,19,20,21],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/core/management/commands/check.py":[1,2,3,4,7,8,10,12,37,13,14,15,16,18,19,20,22,23,24,26,27,28,29,30,32,38,39,43,46,48,49,60,61,62,63,64,65],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/templatetags/cache.py":[1,2,3,7,10,11,18,52],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/core/cache/utils.py":[1,2,4,7],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/templatetags/l10n.py":[1,2,4,7,16,25,26,30,33,41],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/templatetags/tz.py":[1,3,5,6,8,13,14,19,29,37,83,86,87,91,99,102,103,107,113,116,117,120,125,148,173],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/contrib/admin/templatetags/admin_list.py":[1,3,4,7,10,11,12,13,14,15,16,17,18,19,20,22,24,26,29,45,93,103,192,198,210,301,306,307,312,321,328,344,354,428,438,449,454,464,473,478],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/contrib/admin/views/main.py":[1,2,4,5,6,9,12,15,18,19,20,21,22,23,24,27,28,29,30,31,32,35,38,39,91,104,188,206,239,247,269,316,356,401,413,426],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/contrib/admin/templatetags/base.py":[1,3,6,10,12,22],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/contrib/admin/templatetags/admin_modify.py":[1,3,4,6,8,11,43,48,84,89,99],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/contrib/admin/templatetags/admin_static.py":[1,3,4,5,7,10],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/contrib/admin/templatetags/log.py":[1,2,4,7,8,11,14,26],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/contrib/staticfiles/templatetags/__init__.py":[1],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/contrib/staticfiles/templatetags/staticfiles.py":[1,3,4,7,9,12,22],"/home/valberg/code/bornhack/bornhack-website/src/shop/templatetags/shop_tags.py":[1,2,4,6],"/home/valberg/code/bornhack/bornhack-website/src/utils/templatetags/bornhack.py":[1,3,4,6,9],"/home/valberg/code/bornhack/bornhack-website/src/utils/templatetags/commonmark.py":[1,2,4,5,6,8,11,18,19,27,28],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/commonmark/__init__.py":[2,4,5,6,7,8],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/commonmark/main.py":[12,14,15,16,17,20],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/commonmark/blocks.py":[1,3,4,5,6,7,8,9,12,14,15,16,17,18,19,20,21,28,29,30,31,34,35,36,37,38,39,41,42,43,44,45,46,47,48,49,50,51,54,59,63,70,84,151,162,163,165,166,169,170,173,178,179,181,182,185,186,189,194,195,197,198,201,202,220,225,226,228,229,240,241,244,249,250,252,253,269,270,273,278,279,281,282,286,287,290,295,296,298,299,303,304,307,312,313,315,316,344,345,360,365,366,368,369,376,377,382,387,388,390,391,394,395,409,414,421,423,424,425,426,427,428,429,430,433,434,448,449,472,473,493,494,510,511,530,531,541,542,561,562,575,576,598,609,628,637,667,672,703,847,862,878],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/commonmark/common.py":[1,3,4,6,7,11,12,13,14,22,24,25,26,27,28,30,31,32,33,34,35,36,37,38,40,41,42,43,44,45,46,47,48,51,58,69,98,99,100,101,105,109],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/commonmark/inlines.py":[1,3,4,5,6,7,9,10,11,12,22,24,25,52,57,58,59,60,62,63,64,65,66,67,68,69,72,73,74,75,76,77,78,79,80,81,82,83,85,88,97,103,124,130,132,139,151,159,169,192,219,246,257,320,353,362,368,486,498,534,547,562,583,693,706,709,718,735,758,826,867,882],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/commonmark/node.py":[1,3,6,7,12,16,18,23,50,52,55,66,71,72,96,99,103,115,118,129,140,155,166,177],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/commonmark/utils.py":[1],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/commonmark/dump.py":[1,3,4,5,8,50,56],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/commonmark/render/__init__.py":[1],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/commonmark/render/html.py":[1,4,5,6,7,10,11,12,13,16,21,22,32,35,53,56,59,63,77,95,98,101,115,125,130,145,151,162,178,186,192,200,206,216,219],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/commonmark/render/renderer.py":[1,4,5,24,32,36],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/commonmark/render/rst.py":[1,4,7,23,24,28,38,41,52,55,58,62,65,68,71,77,83,94,99,117,121,129,135],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/bleach/__init__.py":[3,5,7,11,21,23,24,27,30,31,32,87],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/bleach/linkifier.py":[1,2,3,5,6,7,11,26,29,32,56,45,52,53,59,62,69,70,73,86,87,88,136,166,178,179,180,208,228,255,308,356,441,484],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/bleach/callbacks.py":[1,2,5,23],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/bleach/html5lib_shim.py":[5,7,9,10,12,14,18,19,23,24,25,26,27,28,29,30,34,37,40,41,42,43,45,46,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,167,173,174,180,184,188,192,199,204,209,219,229,230,231,239,301,319,327,362,363,364,379,399,418,453,511,514,530,531,532,563],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/bleach/_vendor/__init__.py":[1],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/bleach/_vendor/html5lib/__init__.py":[21,23,25,26,27,28,30,31,35],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/bleach/_vendor/html5lib/html5parser.py":[1,2,4,5,7,8,10,11,13,14,27,50,75,87,92,94,125,139,173,183,193,196,263,267,292,320,328,339,342,345,348,352,396,412,2774,2782,2789,2790,2791],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/bleach/_vendor/html5lib/_inputstream.py":[1,3,4,6,7,9,11,12,13,15,17,18,23,24,25,26,29,31,36,37,38,39,43,44,45,46,47,48,49,51,54,57,62,64,69,76,85,94,97,104,131,154,160,162,164,196,210,224,235,240,255,293,297,320,367,384,390,394,434,438,457,519,535,569,584,587,588,592,596,599,607,611,620,625,633,635,638,640,652,663,674,688,689,691,696,719,723,759,762,766,789,792,869,870,874,908],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/webencodings/__init__.py":[13,15,17,19,22,27,28,29,30,32,35,61,91,109,123,124,128,133,74,58,75,76,78,79,80,83,85,86,125,126,87,88,135,136,139,161,172,186,214,246,262,272,282,283,295,323,339,340],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/webencodings/labels.py":[11,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/bleach/_vendor/html5lib/constants.py":[1,3,5,9,11,13,15,17,19,22,25,27,29,31,33,35,37,39,41,44,46,48,50,52,54,56,58,60,62,64,66,68,70,72,74,76,78,80,82,84,86,88,90,92,94,96,98,100,102,104,106,108,110,112,114,116,118,120,122,124,126,128,130,132,134,136,138,140,142,144,146,148,150,152,154,156,159,161,163,165,168,170,172,174,177,180,183,186,188,190,192,194,197,199,201,204,207,210,213,215,217,219,222,224,227,229,231,233,235,238,241,243,246,249,252,255,258,261,263,265,268,271,273,275,277,279,281,283,285,287,289,291,293,297,298,299,300,301,302,305,306,307,308,309,310,311,312,313,314,315,316,317,318,319,320,321,322,325,326,327,328,329,330,331,332,333,334,335,336,337,338,339,342,343,344,345,346,347,348,349,350,351,352,353,354,355,356,357,358,359,360,361,362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,380,381,382,383,386,387,388,389,390,391,392,393,394,395,396,397,398,399,400,401,402,403,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,422,425,426,427,428,429,432,433,434,435,436,437,441,442,443,444,445,446,447,448,449,450,451,452,453,454,455,456,457,458,459,460,461,462,463,464,465,466,467,468,469,470,471,472,473,474,475,476,477,478,479,480,481,482,483,484,485,486,487,488,489,490,491,492,493,494,495,496,497,498,499,500,501,502,505,508,509,510,511,512,513,514,515,516,517,518,519,522,523,525,526,527,528,529,530,533,534,535,536,537,538,541,542,543,544,545,547,548,557,560,561,562,563,564,565,566,567,568,569,570,571,572,573,574,575,578,580,581,582,583,584,585,586,587,591,592,593,594,595,596,597,598,599,600,601,602,603,604,605,606,607,608,609,646,649,652,653,654,655,656,657,658,659,660,661,662,663,664,665,666,667,668,669,670,671,672,673,674,675,676,677,678,679,680,681,682,683,684,685,686,687,688,689,690,691,692,693,694,695,696,697,698,699,700,701,702,703,704,705,706,707,708,709,710,711,712,713,714,715,716,717,718,719,720,721,722,723,724,725,726,727,728,729,730,731,732,733,734,735,736,737,738,739,740,741,742,743,744,745,746,747,748,749,750,751,752,753,754,755,756,757,758,759,760,761,762,763,764,765,766,767,768,769,770,771,772,773,774,775,776,777,778,779,780,781,782,783,784,785,786,787,788,789,790,791,792,793,794,795,796,797,798,799,800,801,802,803,804,805,806,807,808,809,810,811,812,813,814,815,816,817,818,819,820,821,822,823,824,825,826,827,828,829,830,831,832,833,834,835,836,837,838,839,840,841,842,843,844,845,846,847,848,849,850,851,852,853,854,855,856,857,858,859,860,861,862,863,864,865,866,867,868,869,870,871,872,873,874,875,876,877,878,879,880,881,882,883,884,885,886,887,888,889,890,891,892,893,894,895,896,897,898,899,900,901,902,903,904,905,906,907,908,909,910,911,912,913,914,915,916,917,918,919,920,921,922,923,924,925,926,927,928,929,930,931,932,933,934,935,936,937,938,939,940,941,942,943,944,945,946,947,948,949,950,951,952,953,954,955,956,957,958,959,960,961,962,963,964,965,966,967,968,969,970,971,972,973,974,975,976,977,978,979,980,981,982,983,984,985,986,987,988,989,990,991,992,993,994,995,996,997,998,999,1000,1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1011,1012,1013,1014,1015,1016,1017,1018,1019,1020,1021,1022,1023,1024,1025,1026,1027,1028,1029,1030,1031,1032,1033,1034,1035,1036,1037,1038,1039,1040,1041,1042,1043,1044,1045,1046,1047,1048,1049,1050,1051,1052,1053,1054,1055,1056,1057,1058,1059,1060,1061,1062,1063,1064,1065,1066,1067,1068,1069,1070,1071,1072,1073,1074,1075,1076,1077,1078,1079,1080,1081,1082,1083,1084,1085,1086,1087,1088,1089,1090,1091,1092,1093,1094,1095,1096,1097,1098,1099,1100,1101,1102,1103,1104,1105,1106,1107,1108,1109,1110,1111,1112,1113,1114,1115,1116,1117,1118,1119,1120,1121,1122,1123,1124,1125,1126,1127,1128,1129,1130,1131,1132,1133,1134,1135,1136,1137,1138,1139,1140,1141,1142,1143,1144,1145,1146,1147,1148,1149,1150,1151,1152,1153,1154,1155,1156,1157,1158,1159,1160,1161,1162,1163,1164,1165,1166,1167,1168,1169,1170,1171,1172,1173,1174,1175,1176,1177,1178,1179,1180,1181,1182,1183,1184,1185,1186,1187,1188,1189,1190,1191,1192,1193,1194,1195,1196,1197,1198,1199,1200,1201,1202,1203,1204,1205,1206,1207,1208,1209,1210,1211,1212,1213,1214,1215,1216,1217,1218,1219,1220,1221,1222,1223,1224,1225,1226,1227,1228,1229,1230,1231,1232,1233,1234,1235,1236,1237,1238,1239,1240,1241,1242,1243,1244,1245,1246,1247,1248,1249,1250,1251,1252,1253,1254,1255,1256,1257,1258,1259,1260,1261,1262,1263,1264,1265,1266,1267,1268,1269,1270,1271,1272,1273,1274,1275,1276,1277,1278,1279,1280,1281,1282,1283,1284,1285,1286,1287,1288,1289,1290,1291,1292,1293,1294,1295,1296,1297,1298,1299,1300,1301,1302,1303,1304,1305,1306,1307,1308,1309,1310,1311,1312,1313,1314,1315,1316,1317,1318,1319,1320,1321,1322,1323,1324,1325,1326,1327,1328,1329,1330,1331,1332,1333,1334,1335,1336,1337,1338,1339,1340,1341,1342,1343,1344,1345,1346,1347,1348,1349,1350,1351,1352,1353,1354,1355,1356,1357,1358,1359,1360,1361,1362,1363,1364,1365,1366,1367,1368,1369,1370,1371,1372,1373,1374,1375,1376,1377,1378,1379,1380,1381,1382,1383,1384,1385,1386,1387,1388,1389,1390,1391,1392,1393,1394,1395,1396,1397,1398,1399,1400,1401,1402,1403,1404,1405,1406,1407,1408,1409,1410,1411,1412,1413,1414,1415,1416,1417,1418,1419,1420,1421,1422,1423,1424,1425,1426,1427,1428,1429,1430,1431,1432,1433,1434,1435,1436,1437,1438,1439,1440,1441,1442,1443,1444,1445,1446,1447,1448,1449,1450,1451,1452,1453,1454,1455,1456,1457,1458,1459,1460,1461,1462,1463,1464,1465,1466,1467,1468,1469,1470,1471,1472,1473,1474,1475,1476,1477,1478,1479,1480,1481,1482,1483,1484,1485,1486,1487,1488,1489,1490,1491,1492,1493,1494,1495,1496,1497,1498,1499,1500,1501,1502,1503,1504,1505,1506,1507,1508,1509,1510,1511,1512,1513,1514,1515,1516,1517,1518,1519,1520,1521,1522,1523,1524,1525,1526,1527,1528,1529,1530,1531,1532,1533,1534,1535,1536,1537,1538,1539,1540,1541,1542,1543,1544,1545,1546,1547,1548,1549,1550,1551,1552,1553,1554,1555,1556,1557,1558,1559,1560,1561,1562,1563,1564,1565,1566,1567,1568,1569,1570,1571,1572,1573,1574,1575,1576,1577,1578,1579,1580,1581,1582,1583,1584,1585,1586,1587,1588,1589,1590,1591,1592,1593,1594,1595,1596,1597,1598,1599,1600,1601,1602,1603,1604,1605,1606,1607,1608,1609,1610,1611,1612,1613,1614,1615,1616,1617,1618,1619,1620,1621,1622,1623,1624,1625,1626,1627,1628,1629,1630,1631,1632,1633,1634,1635,1636,1637,1638,1639,1640,1641,1642,1643,1644,1645,1646,1647,1648,1649,1650,1651,1652,1653,1654,1655,1656,1657,1658,1659,1660,1661,1662,1663,1664,1665,1666,1667,1668,1669,1670,1671,1672,1673,1674,1675,1676,1677,1678,1679,1680,1681,1682,1683,1684,1685,1686,1687,1688,1689,1690,1691,1692,1693,1694,1695,1696,1697,1698,1699,1700,1701,1702,1703,1704,1705,1706,1707,1708,1709,1710,1711,1712,1713,1714,1715,1716,1717,1718,1719,1720,1721,1722,1723,1724,1725,1726,1727,1728,1729,1730,1731,1732,1733,1734,1735,1736,1737,1738,1739,1740,1741,1742,1743,1744,1745,1746,1747,1748,1749,1750,1751,1752,1753,1754,1755,1756,1757,1758,1759,1760,1761,1762,1763,1764,1765,1766,1767,1768,1769,1770,1771,1772,1773,1774,1775,1776,1777,1778,1779,1780,1781,1782,1783,1784,1785,1786,1787,1788,1789,1790,1791,1792,1793,1794,1795,1796,1797,1798,1799,1800,1801,1802,1803,1804,1805,1806,1807,1808,1809,1810,1811,1812,1813,1814,1815,1816,1817,1818,1819,1820,1821,1822,1823,1824,1825,1826,1827,1828,1829,1830,1831,1832,1833,1834,1835,1836,1837,1838,1839,1840,1841,1842,1843,1844,1845,1846,1847,1848,1849,1850,1851,1852,1853,1854,1855,1856,1857,1858,1859,1860,1861,1862,1863,1864,1865,1866,1867,1868,1869,1870,1871,1872,1873,1874,1875,1876,1877,1878,1879,1880,1881,1882,1883,1884,1885,1886,1887,1888,1889,1890,1891,1892,1893,1894,1895,1896,1897,1898,1899,1900,1901,1902,1903,1904,1905,1906,1907,1908,1909,1910,1911,1912,1913,1914,1915,1916,1917,1918,1919,1920,1921,1922,1923,1924,1925,1926,1927,1928,1929,1930,1931,1932,1933,1934,1935,1936,1937,1938,1939,1940,1941,1942,1943,1944,1945,1946,1947,1948,1949,1950,1951,1952,1953,1954,1955,1956,1957,1958,1959,1960,1961,1962,1963,1964,1965,1966,1967,1968,1969,1970,1971,1972,1973,1974,1975,1976,1977,1978,1979,1980,1981,1982,1983,1984,1985,1986,1987,1988,1989,1990,1991,1992,1993,1994,1995,1996,1997,1998,1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015,2016,2017,2018,2019,2020,2021,2022,2023,2024,2025,2026,2027,2028,2029,2030,2031,2032,2033,2034,2035,2036,2037,2038,2039,2040,2041,2042,2043,2044,2045,2046,2047,2048,2049,2050,2051,2052,2053,2054,2055,2056,2057,2058,2059,2060,2061,2062,2063,2064,2065,2066,2067,2068,2069,2070,2071,2072,2073,2074,2075,2076,2077,2078,2079,2080,2081,2082,2083,2084,2085,2086,2087,2088,2089,2090,2091,2092,2093,2094,2095,2096,2097,2098,2099,2100,2101,2102,2103,2104,2105,2106,2107,2108,2109,2110,2111,2112,2113,2114,2115,2116,2117,2118,2119,2120,2121,2122,2123,2124,2125,2126,2127,2128,2129,2130,2131,2132,2133,2134,2135,2136,2137,2138,2139,2140,2141,2142,2143,2144,2145,2146,2147,2148,2149,2150,2151,2152,2153,2154,2155,2156,2157,2158,2159,2160,2161,2162,2163,2164,2165,2166,2167,2168,2169,2170,2171,2172,2173,2174,2175,2176,2177,2178,2179,2180,2181,2182,2183,2184,2185,2186,2187,2188,2189,2190,2191,2192,2193,2194,2195,2196,2197,2198,2199,2200,2201,2202,2203,2204,2205,2206,2207,2208,2209,2210,2211,2212,2213,2214,2215,2216,2217,2218,2219,2220,2221,2222,2223,2224,2225,2226,2227,2228,2229,2230,2231,2232,2233,2234,2235,2236,2237,2238,2239,2240,2241,2242,2243,2244,2245,2246,2247,2248,2249,2250,2251,2252,2253,2254,2255,2256,2257,2258,2259,2260,2261,2262,2263,2264,2265,2266,2267,2268,2269,2270,2271,2272,2273,2274,2275,2276,2277,2278,2279,2280,2281,2282,2283,2284,2285,2286,2287,2288,2289,2290,2291,2292,2293,2294,2295,2296,2297,2298,2299,2300,2301,2302,2303,2304,2305,2306,2307,2308,2309,2310,2311,2312,2313,2314,2315,2316,2317,2318,2319,2320,2321,2322,2323,2324,2325,2326,2327,2328,2329,2330,2331,2332,2333,2334,2335,2336,2337,2338,2339,2340,2341,2342,2343,2344,2345,2346,2347,2348,2349,2350,2351,2352,2353,2354,2355,2356,2357,2358,2359,2360,2361,2362,2363,2364,2365,2366,2367,2368,2369,2370,2371,2372,2373,2374,2375,2376,2377,2378,2379,2380,2381,2382,2383,2384,2385,2386,2387,2388,2389,2390,2391,2392,2393,2394,2395,2396,2397,2398,2399,2400,2401,2402,2403,2404,2405,2406,2407,2408,2409,2410,2411,2412,2413,2414,2415,2416,2417,2418,2419,2420,2421,2422,2423,2424,2425,2426,2427,2428,2429,2430,2431,2432,2433,2434,2435,2436,2437,2438,2439,2440,2441,2442,2443,2444,2445,2446,2447,2448,2449,2450,2451,2452,2453,2454,2455,2456,2457,2458,2459,2460,2461,2462,2463,2464,2465,2466,2467,2468,2469,2470,2471,2472,2473,2474,2475,2476,2477,2478,2479,2480,2481,2482,2483,2484,2485,2486,2487,2488,2489,2490,2491,2492,2493,2494,2495,2496,2497,2498,2499,2500,2501,2502,2503,2504,2505,2506,2507,2508,2509,2510,2511,2512,2513,2514,2515,2516,2517,2518,2519,2520,2521,2522,2523,2524,2525,2526,2527,2528,2529,2530,2531,2532,2533,2534,2535,2536,2537,2538,2539,2540,2541,2542,2543,2544,2545,2546,2547,2548,2549,2550,2551,2552,2553,2554,2555,2556,2557,2558,2559,2560,2561,2562,2563,2564,2565,2566,2567,2568,2569,2570,2571,2572,2573,2574,2575,2576,2577,2578,2579,2580,2581,2582,2583,2584,2585,2586,2587,2588,2589,2590,2591,2592,2593,2594,2595,2596,2597,2598,2599,2600,2601,2602,2603,2604,2605,2606,2607,2608,2609,2610,2611,2612,2613,2614,2615,2616,2617,2618,2619,2620,2621,2622,2623,2624,2625,2626,2627,2628,2629,2630,2631,2632,2633,2634,2635,2636,2637,2638,2639,2640,2641,2642,2643,2644,2645,2646,2647,2648,2649,2650,2651,2652,2653,2654,2655,2656,2657,2658,2659,2660,2661,2662,2663,2664,2665,2666,2667,2668,2669,2670,2671,2672,2673,2674,2675,2676,2677,2678,2679,2680,2681,2682,2683,2684,2685,2686,2687,2688,2689,2690,2691,2692,2693,2694,2695,2696,2697,2698,2699,2700,2701,2702,2703,2704,2705,2706,2707,2708,2709,2710,2711,2712,2713,2714,2715,2716,2717,2718,2719,2720,2721,2722,2723,2724,2725,2726,2727,2728,2729,2730,2731,2732,2733,2734,2735,2736,2737,2738,2739,2740,2741,2742,2743,2744,2745,2746,2747,2748,2749,2750,2751,2752,2753,2754,2755,2756,2757,2758,2759,2760,2761,2762,2763,2764,2765,2766,2767,2768,2769,2770,2771,2772,2773,2774,2775,2776,2777,2778,2779,2780,2781,2782,2783,2784,2785,2786,2787,2788,2789,2790,2791,2792,2793,2794,2795,2796,2797,2798,2799,2800,2801,2802,2803,2804,2805,2806,2807,2808,2809,2810,2811,2812,2813,2814,2815,2816,2817,2818,2819,2820,2821,2822,2823,2824,2825,2826,2827,2828,2829,2830,2831,2832,2833,2834,2835,2836,2837,2838,2839,2840,2841,2842,2843,2844,2845,2846,2847,2848,2849,2850,2851,2852,2853,2854,2855,2856,2857,2858,2859,2860,2861,2862,2863,2864,2865,2866,2867,2868,2869,2870,2871,2872,2873,2874,2875,2876,2877,2878,2879,2880,2881,2882,2886,2887,2888,2889,2890,2891,2892,2893,2894,2895,2896,2897,2898,2899,2900,2901,2902,2903,2904,2905,2906,2907,2908,2909,2910,2911,2912,2913,2914,2915,2916,2917,2918,2919,2923,2924,2925,2926,2927,2928,2929,2930,2933,2934,2937,2938,2941,2942,2943,2946,2947],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/bleach/_vendor/html5lib/_utils.py":[1,3,5,7,8,13,14,15,24,25,26,33,36,47,49,64,71,77,86,115,116,118,124],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/bleach/_vendor/html5lib/_tokenizer.py":[1,3,5,7,8,9,10,11,12,14,16,18,21,32,34,49,65,137,217,222,242,271,276,305,310,328,346,361,396,420,442,453,464,492,503,514,542,556,567,595,605,615,635,655,677,692,703,731,747,768,791,816,827,843,873,927,959,993,1012,1031,1056,1076,1094,1109,1154,1177,1200,1218,1237,1268,1291,1308,1334,1359,1410,1430,1459,1483,1507,1537,1563,1583,1612,1636,1660,1679,1693],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/bleach/_vendor/html5lib/_trie/__init__.py":[1,3,5,8,9,10,11],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/bleach/_vendor/html5lib/_trie/py.py":[1,2,4,6,9,10,19,22,25,28,31,54,11,14,15,16,17],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/bleach/_vendor/html5lib/_trie/_base.py":[1,3,6,7,9,18,25,35],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/bleach/_vendor/html5lib/_trie/datrie.py":[1,3],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/bleach/_vendor/html5lib/treebuilders/__init__.py":[30,32,34,36,39],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/bleach/_vendor/html5lib/treebuilders/base.py":[1,2,4,9,12,13,14,15,16,17,18,19,23,24,25,45,54,57,65,77,89,97,110,116,122,123,136,146,154,158,161,164,167,170,172,184,196,218,264,269,283,288,296,301,309,312,321,323,333,349,364,390,400,404,411],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/bleach/_vendor/html5lib/treewalkers/__init__.py":[9,11,13,14,16,18,21,65,80],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/bleach/_vendor/html5lib/serializer.py":[1,2,4,6,8,9,10,11,13,14,15,16,25,26,27,29,30,32,33,36,37,39,42,72,75,104,107,108,109,112,113,114,115,118,119,120,123,124,125,126,133,135,224,231,238,375,400,407,408,409],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/bleach/_vendor/html5lib/filters/__init__.py":[1],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/bleach/_vendor/html5lib/filters/base.py":[1,4,5,8,11],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/bleach/_vendor/html5lib/filters/sanitizer.py":[1,3,4,6,8,9,11,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,178,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,305,306,307,308,309,310,311,312,313,314,315,316,317,318,319,320,322,323,324,325,326,327,328,329,330,331,332,333,334,335,336,337,338,339,340,341,342,343,344,345,346,347,348,349,350,351,352,353,354,355,356,357,358,359,360,361,362,363,364,366,367,368,369,370,371,372,373,374,375,376,377,378,379,380,381,382,383,384,385,386,387,388,389,390,391,392,393,394,395,396,397,398,399,400,401,402,403,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,422,423,424,425,426,427,428,429,430,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,450,451,452,453,454,455,456,457,458,459,460,461,462,463,464,465,466,467,468,469,470,471,472,473,474,475,476,477,478,479,480,481,482,483,484,485,486,487,488,489,490,491,492,493,494,495,496,497,498,499,500,501,502,503,504,507,508,509,510,511,512,513,514,515,516,517,518,519,520,523,534,537,552,555,601,604,643,646,654,657,680,683,689,693,703,704,707,708,711,712,713,714,715,716,717,718,719,720,764,781,799,849,869],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/bleach/utils.py":[1,3,6,18,28],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/bleach/sanitizer.py":[1,3,4,6,7,8,10,11,16,17,18,19,20,21,22,23,24,25,26,27,33,34,35,39,42,45,48,49,50,55,58,85,87,88,89,149,192,233,238,239,240,270,283,314,317,360,421,480,541,582],"/home/valberg/code/bornhack/bornhack-website/src/utils/templatetags/dateutils.py":[1,2,3,5],"/home/valberg/code/bornhack/bornhack-website/src/utils/templatetags/imageutils.py":[1,2,4,5],"/home/valberg/code/bornhack/bornhack-website/src/utils/templatetags/menubutton.py":[1,3,5],"/home/valberg/code/bornhack/bornhack-website/src/teams/templatetags/teams_tags.py":[1,2,3,4,7,14,15],"/home/valberg/code/bornhack/bornhack-website/src/tickets/templatetags/tickets_tags.py":[1,2,4,7],"/home/valberg/code/bornhack/bornhack-website/src/tokens/templatetags/token_tags.py":[1,3,5,8],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/allauth/account/templatetags/__init__.py":[1],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/allauth/account/templatetags/account.py":[1,3,6,9],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/bootstrap3/templatetags/__init__.py":[1],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/bootstrap3/templatetags/bootstrap3.py":[2,4,5,7,8,9,10,11,13,20,21,32,33,39,42,43,44,45,46,49,52,62,87,111,135,159,183,213,214,258,288,317,355,394,520,555,621,653,654,692,724,725,731,752,790,851,857],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/bootstrap3/bootstrap.py":[2,4,6,7,12,13,14,16,18,19,20,22,23,24,25,26,27,28,29,30,31,32,34,35,40,43,46,53,60,67,74,81,88,93,98],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/bootstrap3/components.py":[2,4,5,6,8,11,27],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/bootstrap3/utils.py":[2,4,5,7,9,11,12,13,14,16,17,18,19,21,22,23,24,25,26,27,29,32,35,54,78,86,99,108,116,128,143,152,174],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/bootstrap3/exceptions.py":[2,5,8,10,13,16,18],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/bootstrap3/text.py":[2,5,6,11,20],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/bootstrap3/forms.py":[2,4,5,16,17,19,25,26,27,28,30,33,34,35,36,37,41,49,57,65,73,81,106,158,179,188,199],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django_extensions/templatetags/__init__.py":[1],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django_extensions/templatetags/debugger_tags.py":[11,13,16,19,26,33],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django_extensions/templatetags/highlighting.py":[31,33,34,37,38,40,41,42,43,44,48,51,52,57,58,66,77],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/pygments/__init__.py":[27,28,30,32,33,35,38,53,77,88],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/pygments/util.py":[10,12,13,16,17,26,27,28,29,32,33,36,37,40,50,70,84,96,108,125,170,183,188,191,209,218,257,276,292,297,298,302,323,340,350,364,365,366,367,368,369,370,371,373,375,379],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/pygments/lexers/__init__.py":[10,12,13,14,15,16,18,19,20,21,24,25,27,28,31,39,47,57,75,97,118,152,195,209,225,237,288,312,313,315,325,326,327,328,329],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/pygments/lexers/_mapping.py":[14,16,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,305,306,307,308,309,310,311,312,313,314,315,316,317,318,319,320,321,322,323,324,325,326,327,328,329,330,331,332,333,334,335,336,337,338,339,340,341,342,343,344,345,346,347,348,349,350,351,352,353,354,355,356,357,358,359,360,361,362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,380,381,382,383,384,385,386,387,388,389,390,391,392,393,394,395,396,397,398,399,400,401,402,403,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,422,423,424,425,426,427,428,429,430,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,450,451,452,453,454,455,458],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/pygments/modeline.py":[10,12,14,17,20,23,29],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/pygments/plugin.py":[37,38,39,40,41,44,53,58,63,68],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/pygments/formatters/__init__.py":[10,12,13,14,15,16,18,19,20,22,23,25,26,29,37,45,56,71,82,117,136,137,139,149,150,151,152,153,140,141,142,39,40,41,42,143,144,145],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/pygments/formatters/_mapping.py":[14,16,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,37],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/pygments/formatters/html.py":[10,12,14,15,16,18,19,20,23,24,25,26,28,32,33,34,35,36,40,45,62,73,79,94,99,102,378,380,381,382,384,430,438,447,471,510,517,560,622,658,669,679,694,712,783,790,812,820],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/pygments/formatter.py":[10,12,14,15,17,20,26,51,54,57,60,64,66,77,87],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/pygments/styles/__init__.py":[10,12,13,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,50,74],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/pygments/token.py":[10,13,14,16,25,29,35,44,47,51,56,27,59,36,38,39,40,41,42,60,61,62,64,67,68,69,70,71,72,73,74,77,81,82,83,86,95,125,127,128,129,130,131,133,134,135,136,137,138,139,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,163,164,166,167,168,169,170,171,172,173,174,175,176,177,178,179,181,182,183,184,185,186,187,189,190,192,194,195,196,197,198,199,200,202,203,204,205,206,207,208,209,210,211,212],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django_extensions/templatetags/indent_text.py":[2,4,7,8,16,32],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django_extensions/templatetags/syntax_color.py":[33,34,36,37,38,40,41,42,43,44,48,51,54,65,66,56,62,71,78,84,85,86,87,94,95,96,97,104,105,106,107],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django_extensions/templatetags/truncate_letters.py":[2,3,5,8,9],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django_extensions/templatetags/widont.py":[2,3,5,6,9,10,11,14,15,38,61],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/betterforms/templatetags/__init__.py":[1],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/betterforms/templatetags/betterforms_tags.py":[1,2,4,7],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/debug_toolbar/templatetags/__init__.py":[1],"/home/valberg/code/bornhack/bornhack-website/src/bornhack/urls.py":[1,2,3,4,5,6,7,9,10,11,12,13,14,15,16,19,22,23,24,25,26,27,29,30,31,33,34,35,37,38,39,40,42,43,44,45,47,48,49,50,52,53,54,55,57,58,59,60,62,63,64,65,67,70,72,73,74,75,78,79,80,85,86,87,88,89,92,93,94,95,96,99,100,101,102,103,106,107,108,109,110,113,114,115,116,117,120,121,122,123,128,129,130,131,132,133,136,137,138,139,142,143,144,147,148,149,150,153,154,155,156,159,160,161,162,163,164,166,167,168,169,171,172,173,174,176,177,178,179,182,183,184,185,190,191,192,195,196,197,200,201,202,205,206,207,208,211,212,213,219],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/allauth/account/views.py":[1,2,3,4,9,10,11,12,13,14,16,17,18,19,20,30,31,43,44,47,48,51,68,70,83,90,92,99,109,117,123,127,128,129,130,131,132,133,135,139,144,147,154,161,177,180,182,184,194,197,205,206,207,208,209,210,212,216,219,227,239,261,264,266,268,278,302,340,352,357,364,369,372,373,374,375,377,380,384,389,403,424,442,471,513,520,532,535,537,538,539,541,546,551,557,562,574,582,585,586,587,588,590,595,601,605,610,621,629,632,633,634,635,636,638,643,647,659,662,664,667,670,672,673,674,676,681,715,723,729,747,750,752,753,756,759,761,762,764,774,781,789,798,807,810,812,815,818,820,823],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/contrib/auth/decorators.py":[1,2,4,5,6,7,10,38,53,43,44,45,46,17,35,48,49,18,34],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/allauth/account/forms.py":[1,3,4,6,7,8,9,10,11,13,14,19,20,21,22,35,37,51,54,55,66,68,77,79,83,89,91,69,70,71,72,73,74,92,93,95,98,101,104,107,140,160,164,172,194,208,210,217,259,229,230,260,261,262,264,265,266,267,268,270,323,328,335,338,349,362,363,373,401,411,413,418,420,421,422,423,424,425,426,428,447,454,456,457,80,81,458,460,464,470,474,476,477,479,483,487,489,490,491,492,493,494,495,499,508,544,546,547,549,555,559,561,562,564,565,568,571,579],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/graphene_django/views.py":[1,2,3,5,6,7,8,9,10,11,13,14,15,16,17,19,22,23,29,45,53,54,55,57,58,59,60,61,62,63,64,75,102,105,108,111,114,165,196,199,205,246,292,297,316,334,341],"/home/valberg/code/bornhack/bornhack-website/src/bar/views.py":[1,2,3,6,7,8,9,11],"/home/valberg/code/bornhack/bornhack-website/src/camps/mixins.py":[1,2,3,6,10,12,16],"/home/valberg/code/bornhack/bornhack-website/src/camps/views.py":[1,2,3,4,5,6,7,8,9,12,14,65,66,67,69,73,74,75,76],"/home/valberg/code/bornhack/bornhack-website/src/feedback/views.py":[1,2,3,4,5,7,8,9,12,13,14,16],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/contrib/auth/mixins.py":[1,2,3,4,7,11,12,13,14,15,17,29,35,41,47,48,49,55,56,57,59,75,82,88,92,94,99,105],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/contrib/auth/views.py":[1,3,5,9,10,13,14,15,16,17,18,19,20,21,22,23,24,25,26,28,31,32,34,38,41,42,43,44,45,46,47,49,50,51,63,67,80,83,88,93,105,108,109,110,111,112,114,123,127,152,164,172,194,195,197,206,207,208,209,210,211,212,213,214,215,216,218,222,237,238,241,242,243,246,247,248,249,250,251,252,253,255,256,284,293,298,305,318,319,320,322,328,329,330,331,332,334,335,336,340,345,353,354,355,357],"/home/valberg/code/bornhack/bornhack-website/src/info/views.py":[1,2,3,5,6,7,8,10],"/home/valberg/code/bornhack/bornhack-website/src/people/views.py":[1,2,5,6,7],"/home/valberg/code/bornhack/bornhack-website/src/program/views.py":[1,2,4,5,6,7,8,9,10,11,12,13,14,15,16,17,19,20,21,27,33,34,37,44,45,103,104,105,106,108,112,124,125,126,127,128,130,135,138,149,154,176,179,180,181,182,184,211,228,231,232,233,235,244,250,251,252,259,262,263,264,266,271,275,282,285,286,287,289,294,298,305,308,309,310,311,312,314,319,325,335,338,339,340,341,342,344,351,357,375,383,386,387,388,389,391,397,404,415,429,433,434,435,436,438,449,455,469,470,471,473,478,479,480,486,489,490,491,493,498,503,504,505,507,516,520,528,535,540,541,543,552,560,595,614,630,631,632,635,636,637,644,645,646,649,650,651,658,659,661,669,670,672,681,687,688,695,696,698,702,719,720,721,722,724,752,753,754,755,756,758,783,784,785,786,788],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/contrib/admin/views/decorators.py":[1,2,5,6,11,12,13,14,16,17],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/betterforms/multiform.py":[1,2,4,5,9,10,14,15,16,17,20,21,27,28,30,48,64,67,70,81,90,94,98,106,109,117,124,127,130,133,136,140,145,148,155,166,171,172,178,188],"/home/valberg/code/bornhack/bornhack-website/src/program/mixins.py":[1,2,3,4,5,6,9,10,22,23,33,34,44,45,57,60,61,75,86],"/home/valberg/code/bornhack/bornhack-website/src/program/forms.py":[1,3,4,6,8,11,14,15,16,17,19,156,159,161,162,163,164,167,168,169,171,177,182,204],"/home/valberg/code/bornhack/bornhack-website/src/sponsors/views.py":[1,2,4,7,8,9,10,12],"/home/valberg/code/bornhack/bornhack-website/src/villages/views.py":[1,2,3,4,5,6,7,8,9,10,13,14,15,16,18,22,23,24,25,27,31,32,33,34,36,45,49,50,52,63,64,65,66,68,74,77,81,82,83,84,86],"/home/valberg/code/bornhack/bornhack-website/src/villages/mixins.py":[1,2,3,4,7,8],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/allauth/urls.py":[1,3,5,7,10,12,15],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/allauth/socialaccount/__init__.py":[1],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/allauth/socialaccount/providers/__init__.py":[1,3,5,8,9,13,19,22,26,31,54,10,11,14,38,39,40,41,42,44,45,51,16,17],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/allauth/account/urls.py":[1,3,7,8,9,11,12,13,15,18,19,20,21,22,25,26,27,28,29,30,31,32,33],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/allauth_2fa/urls.py":[1,3,7,8,9,11,12,13,15,16,17,19,20,21,23,24,25],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/allauth_2fa/views.py":[1,2,3,7,8,9,11,12,13,14,15,16,17,18,21,23,24,26,27,29,30,35,36,37,39,50,56,91,92,93,94,96,108,118,124,129,134,140,141,142,143,145,156,160,166,167,169,180,191,201,202,203,205],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/qrcode/image/svg.py":[1,4,5,6,7,8,11,16,18,19,20,22,28,31,40,44,47,55,63,67,72,73,75,85,88,93,97,99,101,105,111,115,133,143,148,151,152,155,158,159],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/allauth_2fa/adapter.py":[1,2,6,7,9,10,11,16,17,21],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/allauth_2fa/forms.py":[1,2,4,5,8,9,10,13,21,26,27,28,31,37,47,57,59,63],"/home/valberg/code/bornhack/bornhack-website/src/profiles/urls.py":[1,3,8,10,11],"/home/valberg/code/bornhack/bornhack-website/src/profiles/views.py":[1,2,3,4,6,9,10,11,12,14,18,19,20,21,22,24,27],"/home/valberg/code/bornhack/bornhack-website/src/tickets/urls.py":[1,3,9,12,13,14,15,17,18,19,20,22,23,24,25],"/home/valberg/code/bornhack/bornhack-website/src/tickets/views.py":[1,3,4,5,6,12,17,18,21,22,23,24,26,32,33,35,41,51,52,53,54,55,57,61],"/home/valberg/code/bornhack/bornhack-website/src/shop/urls.py":[1,2,4,7,9,11,12,13,14,15,17,18,19,21,22,23,25,27,29,30],"/home/valberg/code/bornhack/bornhack-website/src/shop/views.py":[1,2,3,4,5,6,12,13,19,20,21,22,23,25,34,35,36,37,38,43,44,48,49,51,61,62,64,75,76,78,89,90,92,104,105,107,119,120,122,134,135,137,147,148,150,163,164,166,179,180,181,182,184,188,217,218,219,220,221,223,232,273,279,280,281,282,284,289,290,291,292,294,360,361,363,370,371,372,373,375,380,381,383,390,392,394,406,407,408,410,424,425,427,470,471,472,474,489,490,491,493,506,507,508,513,514,516,532,536,537,539,543,577,578,579],"/home/valberg/code/bornhack/bornhack-website/src/shop/forms.py":[1,4,5],"/home/valberg/code/bornhack/bornhack-website/src/shop/epay.py":[1,2,5,23],"/home/valberg/code/bornhack/bornhack-website/src/vendor/coinify/coinify_callback.py":[1,3,6,8,11,14],"/home/valberg/code/bornhack/bornhack-website/src/shop/coinify.py":[1,2,3,4,5,6,8,11,28,52,87,113,130],"/home/valberg/code/bornhack/bornhack-website/src/vendor/coinify/coinify_api.py":[1,4,5,8,11,14,16,27,46,79,89,106,121,134,157,176,197,207,217,231,245,256,263,280,300],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/requests/__init__.py":[41,43,44,45,46,49,74,86,87,50,51,54,58,59,61,62,63,66,67,69,70,71,94,95,101,102,105,106,108,109,110,112,113,114,115,116,117,118,125,126,128,131],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/urllib3/__init__.py":[3,5,6,8,14,15,16,17,18,19,20,21,25,26,28,29,30,46,49,52,71,78,80,82,83,85,88],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/urllib3/connectionpool.py":[1,2,3,4,5,7,8,11,26,27,28,29,35,36,38,39,40,41,42,43,44,47,49,51,55,59,61,62,64,72,76,79,84,92,95,153,155,156,157,159,160,161,162,199,212,250,280,286,290,302,319,404,407,425,446,447,448,449,736,752,754,755,757,758,759,760,761,762,763,764,782,799,807,831,850,878],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/urllib3/exceptions.py":[1,2,8,9,10,13,14,15,18,19,20,24,29,30,31,35,40,41,42,45,46,47,50,51,52,55,56,57,61,66,74,76,85,86,88,94,95,96,99,104,105,108,109,110,115,116,117,120,121,122,125,126,127,130,131,132,135,136,137,140,141,143,150,151,152,153,156,157,158,161,162,163,166,167,168,171,172,173,176,177,178,181,182,183,186,190,191,194,195,196,199,203,204,207,214,215,218,223,224,225,228,229,232,237,238,239,244,245,246],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/urllib3/packages/__init__.py":[1,3,5],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/urllib3/packages/ssl_match_hostname/__init__.py":[1,3,6,9,19],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/urllib3/packages/six.py":[1,23,25,26,27,28,29,31,32,36,37,38,40,41,42,43,44,45,47,75,80,86,88,91,103,105,114,117,124,126,130,136,139,141,159,164,171,173,177,181,184,189,195,209,218,224,226,174,175,229,231,232,236,142,89,143,144,146,147,148,151,152,237,238,239,240,149,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,106,107,108,109,110,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,303,308,309,310,311,178,179,312,314,316,127,128,317,320,322,326,327,328,329,330,331,332,333,334,335,336,337,338,339,340,341,342,343,344,345,346,347,348,350,351,352,354,356,357,360,362,366,367,368,370,371,372,374,376,377,380,382,386,387,388,389,390,391,392,393,394,395,396,397,398,399,400,401,402,403,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,420,421,422,424,426,427,430,432,436,437,438,439,441,442,443,445,447,448,451,453,457,459,460,461,463,465,466,469,471,472,473,182,474,475,476,477,479,482,483,486,491,502,503,504,506,507,508,509,520,521,525,528,529,535,536,539,541,544,561,562,77,565,566,567,568,569,570,573,574,577,580,583,586,588,590,610,611,612,613,614,615,618,619,622,624,625,626,627,628,629,630,631,632,633,634,635,639,640,662,663,666,670,674,678,679,92,115,82,83,93,94,97,100,681,706,712,713,715,721,722,776,786,788,797,800,812,828,849,850,851,852,856,857,862,863,866,868,185,186,216,190,191,196,198,199,200,201,202,205,206,207,118,119,203,160,161,187],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/urllib3/connection.py":[1,2,3,4,5,6,7,8,9,10,12,13,14,22,24,30,36,38,47,49,51,54,55,62,65,66,67,70,92,94,98,101,103,116,135,145,172,180,184,223,224,226,228,229,230,244,263,267,268,269,270,271,272,277,299,372,386,388,389],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/urllib3/util/__init__.py":[1,3,4,5,6,16,21,22,28,53],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/urllib3/util/connection.py":[1,2,3,4,7,33,34,85,93,104,134,106,107,113,116,122,123,124,125,129,130,131],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/urllib3/util/wait.py":[1,2,3,4,5,6,10,13,14,39,41,68,87,107,111,124,139,146],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/urllib3/contrib/__init__.py":[1],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/urllib3/contrib/_appengine_environ.py":[3,5,8,14,18,23,29,15,9,19,10,24,11,30],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/urllib3/util/request.py":[1,2,4,5,7,8,12,77,95],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/urllib3/util/response.py":[1,2,4,7,38,75],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/urllib3/util/ssl_.py":[1,2,3,4,5,7,8,10,11,14,15,16,17,21,22,23,27,40,41,44,45,46,47,52,53,61,62,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,112,113,163,190,213,230,294,360],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/urllib3/util/timeout.py":[1,4,5,7,11,15,18,88,91,93,99,103,140,156,171,182,195,213],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/urllib3/util/retry.py":[1,2,3,4,5,6,7,9,17,20,24,25,28,147,149,150,152,154,157,159,160,161,162,163,184,199,200,213,227,243,253,261,267,283,289,295,304,320,330,404,411,165,166,167,168,170,174,175,176,177,178,179,180,181,182],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/urllib3/util/url.py":[1,2,4,7,11,14,19,20,23,33,38,48,55,95,99,132,225],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/urllib3/_collections.py":[1,2,3,6,7,17,18,19,22,25,28,40,42,44,51,58,73,80,84,87,97,102,134,136,147,151,155,158,161,169,172,176,178,181,186,203,209,225,251,264,265,266,269,271,274,282,287,294,300,303],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/urllib3/request.py":[1,3,4,7,10,37,39,41,45,50,74,92],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/urllib3/filepost.py":[1,2,3,4,6,8,9,10,12,15,25,45,63],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/urllib3/fields.py":[1,2,3,5,8,22,50,62,63,71,105,116,138,158],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/urllib3/response.py":[1,2,3,4,5,6,7,9,10,14,15,16,17,19,22,24,29,32,55,57,58,59,62,64,68,71,93,100,102,105,108,114,124,155,157,158,164,211,224,231,240,244,247,255,303,318,336,347,404,473,499,529,532,536,540,547,558,567,571,575,584,593,607,629,696],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/urllib3/util/queue.py":[1,2,3,5,10,11,14,17,20],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/urllib3/poolmanager.py":[1,2,3,4,6,7,8,9,10,11,12,13,16,19,22,50,55,58,112,113,117,118,122,148,150,152,163,166,171,198,207,230,243,267,282,302,362,387,390,412,420,435,449],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/chardet/__init__.py":[19,20,21,24],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/chardet/compat.py":[22,25,31,32,33,34],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/chardet/universaldetector.py":[36,39,40,41,43,44,45,46,47,48,51,66,68,69,70,71,72,73,74,75,76,77,78,79,81,94,111,220],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/chardet/charsetgroupprober.py":[28,29,32,33,39,49,57,65,85],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/chardet/enums.py":[5,8,11,12,13,14,17,21,22,23,24,25,26,27,28,29,32,35,36,37,38,41,44,45,46,47,50,53,54,55,56,57,59,65,71,72,73,74,75,76],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/chardet/charsetprober.py":[29,30,32,35,37,39,44,47,51,54,58,61,66,103],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/chardet/escprober.py":[28,29,30,31,35,40,42,58,69,73,77,83],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/chardet/codingstatemachine.py":[28,30,33,54,55,63,66,80,83,86],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/chardet/escsm.py":[28,62,66,67,68,69,70,71,74,76,77,78,79,80,81,115,119,120,121,122,123,124,125,126,129,131,132,133,134,135,136,170,174,175,176,177,178,179,180,181,182,185,187,188,189,190,191,192,226,230,231,232,233,234,237,239,240,241,242,243,244],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/chardet/latin1prober.py":[29,30,32,34,35,36,37,38,39,40,41,42,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,92,96,97,103,108,112,116,130],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/chardet/mbcsgroupprober.py":[30,31,32,33,34,35,36,37,38,41,42],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/chardet/utf8prober.py":[28,29,30,31,35,36,38,44,49,53,57,76],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/chardet/mbcssm.py":[28,64,68,69,70,73,75,76,77,78,79,99,104,105,106,107,108,109,110,113,115,116,117,118,119,155,159,160,161,162,163,166,168,169,170,171,172,208,212,213,216,218,219,220,221,222,258,262,263,264,265,266,267,270,272,273,274,275,276,312,316,317,318,319,320,321,329,331,332,333,334,335,373,377,378,379,382,384,385,386,387,388,424,428,429,430,431,432,433,434,437,439,440,441,442,443,479,483,484,485,486,487,488,489,492,494,495,496,497,498,534,538,539,540,541,542,543,544,545,546,547,548,549,550,551,552,553,554,555,556,557,558,559,560,561,562,563,566,568,569,570,571,572],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/chardet/sjisprober.py":[28,29,30,31,32,33,36,37,44,48,52,56,89],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/chardet/mbcharsetprober.py":[30,31,34,37,39,45,53,57,61,90],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/chardet/chardistribution.py":[28,30,32,34,36,40,41,42,43,44,46,61,70,84,100,105,113,114,120,132,133,139,151,152,158,170,171,177,192,193,199,217,218,224],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/chardet/euctwfreq.py":[44,47,385],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/chardet/euckrfreq.py":[41,43,193],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/chardet/gb2312freq.py":[42,44,281],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/chardet/big5freq.py":[43,46,384],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/chardet/jisfreq.py":[44,47,322],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/chardet/jpcntx.py":[113,116,117,118,119,120,121,123,131,143,170,173,180,183,184,188,192,212,213],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/chardet/eucjpprober.py":[28,29,30,31,32,33,36,37,44,48,52,56,89],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/chardet/gb2312prober.py":[28,29,30,31,33,34,40,44],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/chardet/euckrprober.py":[28,29,30,31,34,35,41,45],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/chardet/cp949prober.py":[28,29,30,31,34,35,43,47],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/chardet/big5prober.py":[28,29,30,31,34,35,41,45],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/chardet/euctwprober.py":[28,29,30,31,33,34,40,44],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/chardet/sbcsgroupprober.py":[29,30,31,34,35,37,38,39,40,43,44],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/chardet/sbcharsetprober.py":[29,30,33,34,35,36,37,39,53,63,70,77,124],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/chardet/langcyrillicmodel.py":[46,65,84,103,122,141,278,282,283,284,285,286,287,291,292,293,294,295,296,300,301,302,303,304,305,309,310,311,312,313,314,318,319,320,321,322,323,327,328,329,330,331,332],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/chardet/langgreekmodel.py":[50,69,206,210,211,212,213,214,215,219,220,221,222,223,224],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/chardet/langbulgarianmodel.py":[53,72,209,213,214,215,216,217,218,222,223,224,225,226,227],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/chardet/langthaimodel.py":[52,189,193,194,195,196,197,198],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/chardet/langhebrewmodel.py":[53,190,194,195,196,197,198,199],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/chardet/hebrewprober.py":[28,29,128,130,131,132,133,134,135,136,137,138,139,144,149,151,152,154,164,174,178,182,196,255,282,286],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/chardet/langturkishmodel.py":[52,183,187,188,189,190,191,192],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/chardet/version.py":[6,8,9],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/requests/exceptions.py":[8,9,12,15,17,28,29,32,33,36,37,40,41,44,50,53,57,60,61,64,65,68,69,72,73,76,77,80,81,84,85,88,89,92,93,96,97,100,101,104,105,108,109,114,115,116,119,120,121,124,125,126],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/urllib3/contrib/pyopenssl.py":[43,44,46],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/requests/__version__.py":[5,6,7,8,9,10,11,12,13,14],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/requests/utils.py":[9,11,12,13,14,15,16,17,18,19,20,21,23,24,26,27,28,32,33,34,37,39,41,44,98,107,168,219,227,259,284,312,344,379,404,419,430,450,475,496,514,524,561,562,565,589,611,626,637,648,672,694,755,767,793,802,814,852,853,854,857,889,906,923,924,927,948,965],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/requests/certs.py":[14,15,17],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/certifi/__init__.py":[1,3],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/certifi/core.py":[8,9,12,13,15],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/requests/_internal_utils.py":[9,11,14,30],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/requests/compat.py":[9,11,13,20,23,26,28,29,30,31,37,56,57,58,59,60,61,62,63,65,66,67,68,69,70],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/requests/cookies.py":[10,12,13,14,16,17,19,20,25,35,37,42,45,48,51,65,68,71,74,78,81,84,88,92,97,102,104,111,114,118,135,146,165,168,171,187,189,201,218,227,235,244,252,261,270,278,286,299,315,321,330,337,343,348,356,376,401,408,414,421,426,441,477,508,529],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/requests/structures.py":[8,10,13,38,40,46,51,54,57,60,63,71,80,83,87,88,90,94,97,102,91,92],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/requests/packages.py":[1,6,7,10,11,12],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/idna/__init__.py":[1,2],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/idna/package_data.py":[1],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/idna/core.py":[1,2,3,4,5,6,8,9,10,12,13,14,16,17,18,21,22,23,26,27,28,31,32,33,36,43,46,49,53,60,67,127,134,143,149,193,234,266,291,312,340,371],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/idna/idnadata.py":[3,41,60,71,77,87,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,305,306,307,308,309,310,311,312,313,314,315,316,317,318,319,320,321,322,323,324,325,326,327,328,329,330,331,332,333,334,335,336,337,338,339,340,341,342,343,344,345,346,347,348,349,350,351,352,353,354,355,356,357,358,359,360,361,362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,380,381,382,383,384,385,386,387,388,389,390,391,392,393,394,395,396,397,398,399,400,401,402,403,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,422,423,424,425,426,427,428,429,430,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,450,451,452,453,454,455,456,457,458,459,460,461,462,463,464,465,466,467,468,469,470,471,472,473,474,475,476,477,478,479,480,481,482,483,484,485,486,487,488,489,490,491,492,493,494,495,496,497,498,499,500,501,502,503,504,505,506,507,508,509,510,511,512,513,514,515,516,517,518,519,520,521,522,523,524,525,526,527,528,529,530,531,532,533,534,535,536,537,538,539,540,541,542,543,544,545,546,547,548,549,550,551,552,553,554,555,556,557,558,559,560,561,562,563,564,565,566,567,568,569,570,571,572,573,574,575,576,577,578,579,580,581,582,583,584,585,586,587,588,589,590,591,592,593,594,595,596,597,598,599,600,601,602,603,604,605,606,607,608,609,610,611,612,613,614,615,616,617,618,619,620,621,622,623,624,625,626,627,628,629,630,631,632,633,634,635,636,637,638,639,640,641,642,643,644,645,646,647,648,649,650,651,652,653,654,655,656,657,658,659,660,661,662,663,664,665,666,667,668,669,670,671,672,673,674,675,676,677,678,679,680,681,682,683,684,685,686,687,688,689,690,691,692,693,694,695,696,697,698,699,700,701,702,703,704,705,706,707,708,709,710,711,712,713,714,715,716,717,718,719,720,721,722,723,724,725,726,727,728,729,730,731,732,733,734,735,736,737,738,739,740,741,742,743,744,745,746,747,748,749,750,751,752,753,754,755,756,757,758,759,760,761,762,763,764,765,766,767,768,769,770,771,772,773,774,775,776,777,778,779,780,781,782,783,784,785,786,787,788,789,790,791,792,793,794,795,796,797,798,799,800,801,802,803,804,805,806,807,808,809,810,811,812,813,814,815,816,817,818,819,820,821,822,823,824,825,826,1966,1969,1977],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/idna/intranges.py":[6,8,10,31,34,38],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/requests/models.py":[8,10,11,16,18,19,20,21,24,25,26,28,29,30,33,34,38,42,43,48,49,50,51,52,55,56,57,60,61,82,109,174,175,186,198,224,228,251,254,272,288,290,309,325,328,339,345,355,441,452,521,534,556,576,586,589,592,593,596,643,646,649,657,665,668,678,688,692,707,714,719,724,729,784,815,835,873,899,917,942],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/requests/hooks.py":[13,14,17,23],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/requests/auth.py":[8,10,11,12,13,14,15,17,19,20,21,22,24,25,28,72,73,75,79,80,82,86,92,95,100,101,103,108,109,111,117,127,229,234,278,298,304],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/requests/status_codes.py":[18,20,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,42,43,44,45,46,47,48,49,51,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,89,90,91,92,93,94,95,96,97,98,99,102,104,120,105,106,107,108,109,111,118,117,112,113],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/requests/api.py":[11,13,16,63,78,91,104,119,134,149],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/requests/sessions.py":[9,10,11,12,13,15,16,17,19,20,21,22,23,26,27,29,34,37,40,46,49,80,95,97,118,144,256,276,317,340,357,360,361,362,365,420,423,426,469,537,548,559,570,583,595,607,617,690,719,733,738,749,753,758],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/requests/adapters.py":[9,11,12,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,31,32,33,36,37,38,41,43,44,45,46,49,50,51,52,55,56,58,62,79,84,109,110,111,113,114,115,131,134,146,166,203,255,292,319,329,358,372,394],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/urllib3/contrib/socks.py":[23,24,26,27,28,29,30,32,33,37,39],"/home/valberg/code/bornhack/bornhack-website/src/news/urls.py":[1,2,4,6,7,8,9],"/home/valberg/code/bornhack/bornhack-website/src/news/views.py":[1,2,3,5,8,21,22,23,24,26,30,31,32,33,36,37,38,40,43,46],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/contrib/syndication/__init__.py":[1],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/contrib/syndication/views.py":[1,3,4,5,6,7,8,9,10,11,12,15,25,26,29,30,31,32,34,49,53,56,65,76,95,102,109,112,122],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/utils/feedgenerator.py":[23,24,25,26,27,29,30,31,32,35,41,47,60,61,64,86,87,88,89,117,120,127,134,140,146,153,161,180,181,182,188,189,191,201,205,211,227,231,232,234,241,243,245,293,295,296,298,306,312,334,340,391],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/contrib/contenttypes/views.py":[1,2,3,4,5,6,9],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/contrib/sites/requests.py":[1,8,9,12,15,18],"/home/valberg/code/bornhack/bornhack-website/src/tokens/urls.py":[1,2,4,7,8,9,10,11],"/home/valberg/code/bornhack/bornhack-website/src/tokens/views.py":[1,2,4,7,8,9,10,11,13,22,23,24,26],"/home/valberg/code/bornhack/bornhack-website/src/program/urls.py":[1,2,4,7,8,9,10,12,13,14,15,17,18,20,21,23,24,25,26,27,28,30,31,32,33,34,35,37,38,39,40,42,43,44,45,49,50,51,52,53,54,56,57,58,59,61,62,63,64,66,67,68,69,71,72,73,74,76,77,78,79,81,82,83,84,86,87,88,89,93,94,95,96,97,98,100,101,102,103,105,106,107,108,110,111,112,113,115,116,117,118,120,121,122,123,125,126,127,128,130,131,132,133,135,136,137,138,140,141,142,143,149,150,151,152,153,154,156,157,158,159,163,164,165,166,169,170,171,172,174,175,176,177,179,180,181,182,185,186,187,188],"/home/valberg/code/bornhack/bornhack-website/src/teams/urls.py":[1,3,10,18,25,32,43,48,51,52,53,54,56,57,58,59,61,62,63,64,65,66,68,69,70,71,73,74,75,76,78,79,80,81,83,84,85,86,88,89,90,91,93,94,95,96,98,99,100,101,102,103,105,106,107,108,110,111,112,113,117,118,119,120,121,122,124,125,126,127,129,130,131,132,133,134,136,137,138,139,146,147,148,149,150,151,152,154,155,156,157,158,159,161,162,163,164,165,166,168,169,170,171,179,180,181,182,183,185,186,187,188,190,191,192,193,195,196,197,198,199,201,202,203,204,206,207,208,209,211,212,213,214],"/home/valberg/code/bornhack/bornhack-website/src/teams/views/base.py":[1,2,3,4,5,6,7,8,10,11,13,14,17,18,19,20,22,29,30,31,32,33,34,36,43,44,45,46,47,48,49,50,52,55,60,61,62,63,64,66,90,109],"/home/valberg/code/bornhack/bornhack-website/src/teams/views/mixins.py":[1,2,3,5,8,11,12,23,26,27,29,39,41,44],"/home/valberg/code/bornhack/bornhack-website/src/teams/views/members.py":[1,3,4,5,6,8,9,10,12,13,15,18,19,20,21,22,23,26,27,28,29,30,31,33,51,57,58,59,60,61,62,64,71,77,78,79,80,81,83,95,96,97,98,99,101],"/home/valberg/code/bornhack/bornhack-website/src/teams/views/info.py":[1,2,3,4,6,7,8,9,12,13,14,15,16,18,25,26,27,28,29,30,32,38,45,48,57,58,59,60,61,62,63,65,71,78,79,80,81,82,83,85,91],"/home/valberg/code/bornhack/bornhack-website/src/teams/views/tasks.py":[1,2,3,4,5,6,8,9,10,13,14,15,16,17,18,21,22,23,24,27,28,29,30,31,33,38,55,56,57,58,60,72,73,74,75,76,78,84,92,96,97,98,99,100,102,107,115],"/home/valberg/code/bornhack/bornhack-website/src/teams/views/shifts.py":[1,2,3,4,5,14,15,16,18,20,22,29,30,31,32,33,35,39,48,85,86,87,89,90,91,94,106,107,109,116,123,129,135,136,137,138,139,141,146,154,160,169,170,171,172,173,175,180,187,193,194,195,196,198,206,214,216,221,223,224,227,228,231,234,235,236,237,239,244,276,282,291,293,295,334,336,338,359,360,362],"/home/valberg/code/bornhack/bornhack-website/src/teams/views/guide.py":[1,2,4,6,9,10,11,12,13,14,16,25,26],"/home/valberg/code/bornhack/bornhack-website/src/rideshare/urls.py":[1,3,11,14,15,16,17,19,20,21,22,24,25,26,27,28,29,31,32,33,34,36,37,38,39],"/home/valberg/code/bornhack/bornhack-website/src/rideshare/views.py":[1,2,3,4,11,12,14,15,17,20,21,22,23,24,28,29,32,33,35,40,62,63,64,66,75,76,80,81,82,85,86,88],"/home/valberg/code/bornhack/bornhack-website/src/backoffice/urls.py":[1,2,5,8,10,11,12,15,18,19,22,23,26,27,28,29,33,34,36,37,38,39,44,45,46,47,52,53,54,55,56,57,58,59,62,63],"/home/valberg/code/bornhack/bornhack-website/src/backoffice/views.py":[1,2,4,5,6,7,8,9,10,11,12,13,14,16,17,18,19,20,21,22,23,24,26,29,32,33,34,37,38,40,49,50,51,53,60,61,62,64,71,72,73,75,79,82,83,84,86,92,101,104,105,107,123,126,127,128,131,134,135,136,139,140,142,156,157,159,185,186,188,202,203,205,234,235,236,238,245,254,255,256,257,259,278,279,280,283,284,285,288,289,291,303,304,305,306,308,319,326,338,384,385,386,387,389,392,393,394,395,397,408,409,410,412,419,428,429,430,431,433],"/home/valberg/code/bornhack/bornhack-website/src/utils/mixins.py":[1,2,3,6,9,10,20,24,25],"/home/valberg/code/bornhack/bornhack-website/src/backoffice/mixins.py":[1,4,7,8,11,14,15,18,21,22,25,28,29],"/home/valberg/code/bornhack/bornhack-website/src/economy/urls.py":[1,2,4,7,8,9,10,14,15,16,17,18,19,21,22,23,24,26,27,28,29,30,31,32,34,35,36,37,39,40,41,42,43,44,45,47,48,49,50,60,61,62,63,64,65,66,68,69,70,71,72,73,74,76,77,78,79,81,82,83,84,86,87,88,89,97,98,99,100,101,102,103,105,106,107,108,114,115,116,117,118,119,120,122,123,124,125,126,127,128,130,131,132,133,135,136,137,138,140,141,142,143],"/home/valberg/code/bornhack/bornhack-website/src/economy/views.py":[1,3,4,5,6,7,8,9,10,11,13,14,15,16,17,18,19,22,23,25,60,61,62,63,64,66,81,82,83,84,87,88,89,90,91,93,101,118,119,120,121,123,135,136,137,139,144,145,146,149,150,151,152,153,155,164,189,190,191,192,194,201,210,215,216,217,218,220,230,234,238,239,241,261,262,263,265,270,271,272,278,279,280,282,287,288,289,292,293,294,295,296,298,307,332,333,334,335,337,344,352,357,358,359,360,362,372,376,380,381,383],"/home/valberg/code/bornhack/bornhack-website/src/economy/mixins.py":[1,2,4,7,10,11,20,23,24,33,36,37,46,49,50,59,62,63],"/home/valberg/code/bornhack/bornhack-website/src/economy/forms.py":[1,3,4,7,11,12,14,36,37,38,39,42,43,44,45,48,49,50,51,54,55,56,57],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/debug_toolbar/middleware.py":[3,5,7,8,10,11,12,13,14,15,17,18,20,23,33,44,48,50,52,77,90,146],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/debug_toolbar/settings.py":[1,3,5,6,7,18,19,20,21,22,23,24,26,27,29,30,31,32,33,34,35,36,37,38,40,41,42,43,47,117,118,119,120,121,122,123,124,125,126,127,128,132,134,135,141,142,143,144,145,146,147,148,149,150,151,152,154,155,156,163,49,53,54,55,57,58,66,73,81,82,84,113],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/debug_toolbar/toolbar.py":[3,5,7,8,10,11,12,13,14,15,17,20,21,34,41,48,56,77,79,85,97,104,106,116,118,135,136,120,121,126,129,108,111,113,114,130,131,132],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/debug_toolbar/views.py":[1,3,4,5,7,8,11],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/debug_toolbar/decorators.py":[1,3,6,7,17],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/debug_toolbar/panels/__init__.py":[1,3,5,7,8,11,14,16,21,25,47,54,61,69,78,88,102,111,125,138,146,152,161,169,177,185,199,212,224,225,107],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/debug_toolbar/utils.py":[1,3,4,5,6,7,8,10,11,12,13,14,15,16,18,20,21,27,30,43,44,31,32,36,37,39,38,48,52,70,90,118,133,141,156,211,228,229,237,248,254,230,235],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/debug_toolbar/panels/versions.py":[1,3,5,6,7,9,12,15,17,21,23,25,35,43,51],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/debug_toolbar/panels/timer.py":[1,3,5,6,8,10,11,16,19,21,35,37,39,41,56,61,89,99],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/debug_toolbar/panels/settings.py":[1,3,5,6,7,9,12,15,17,19,21,24],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/debug_toolbar/panels/headers.py":[1,3,5,7,10,13,16,33,37,39,41,55,60,66],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/debug_toolbar/panels/request.py":[1,3,4,5,6,8,9,12,15,17,19,21,29],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/debug_toolbar/panels/sql/__init__.py":[1],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/debug_toolbar/panels/sql/panel.py":[1,3,4,5,6,8,9,10,12,13,14,15,16,17,20,36,52,56,58,68,95,110,112,119,128,130,138,143,147,290,133,134,135],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/debug_toolbar/panels/sql/views.py":[1,3,4,5,7,8,11,12,37,38,74,75],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/debug_toolbar/panels/sql/forms.py":[1,3,4,5,7,8,9,10,11,12,13,15,18,27,29,30,31,32,33,34,36,47,55,63,71,79,82,88,92],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/debug_toolbar/panels/sql/utils.py":[1,3,5,6,7,10,11,13,24,31,42],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/sqlparse/__init__.py":[8,11,12,13,14,15,16,18,20,21,24,34,46,63],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/sqlparse/sql.py":[8,9,11,13,14,15,18,19,25,28,30,40,47,55,58,64,68,102,115,119,129,130,135,137,139,145,152,155,158,161,175,184,196,201,205,227,241,246,251,254,264,278,284,313,320,331,335,348,357,363,372,389,390,392,427,431,433,438,444,449,458,459,461,471,472,473,474,476,481,482,483,484,486,491,492,495,496,497,498,501,502,503,504,507,508,510,514,519,520,522,526,527,528,529,531,534,535,536,537,539,587,588,590,601,602,603,604,607,608],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/sqlparse/tokens.py":[12,15,16,18,21,27,32,35,22,23,24,25,36,37,38,40,43,44,45,46,47,48,49,50,51,52,53,56,60,61,62,65,66,67,68],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/sqlparse/compat.py":[16,18,19,21,22,25,26,29,30,31,32,33,27],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/sqlparse/utils.py":[8,9,10,11,12,22,32,34,37,55,64,82,106,111,112,118,119,70,79,71,77],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/sqlparse/cli.py":[20,22,23,24,25,27,28,29,34,139,145],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/sqlparse/exceptions.py":[8,11,12],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/sqlparse/engine/__init__.py":[8,9,10,13,14,15],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/sqlparse/engine/grouping.py":[8,9,10,12,13,14,17,52,56,60,64,68,72,76,90,115,132,149,173,183,203,223,244,257,274,287,307,318,329,362,363,364,365,366],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/sqlparse/engine/filter_stack.py":[8,10,11,12,15,16,22,25],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/sqlparse/lexer.py":[8,15,16,17,18,21,24,26,27,75],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/sqlparse/keywords.py":[8,10,13,22,23,24,26,27,29,30,32,33,35,37,38,39,41,42,43,49,51,56,59,60,61,62,63,64,65,67,71,72,73,74,75,76,77,78,80,82,83,84,87,88,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,120,121,122,123,124,125,126,127,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,275,276,277,278,279,280,281,282,283,285,286,287,288,289,291,292,293,294,295,296,298,299,300,301,302,304,305,306,307,308,309,310,311,312,313,314,315,316,317,318,319,320,321,324,325,326,328,329,330,331,332,333,334,335,336,337,338,339,340,341,342,343,344,345,346,349,350,351,352,353,354,355,356,357,358,359,360,361,362,363,364,365,366,367,369,370,371,372,373,374,375,376,377,378,379,380,381,382,383,384,385,386,387,388,389,390,392,393,394,395,396,397,398,399,400,401,402,403,404,405,406,407,408,409,410,411,412,413,415,416,417,418,419,420,421,422,423,424,425,426,427,428,429,430,431,432,433,434,435,436,437,438,439,440,441,442,444,445,446,447,448,449,450,451,452,453,454,455,456,457,458,459,460,461,462,463,464,465,466,467,468,469,470,471,472,473,474,475,476,477,478,479,480,482,483,484,485,486,487,488,489,490,491,492,493,494,495,496,497,498,499,500,501,502,503,504,505,506,507,508,509,510,511,512,513,514,515,516,517,518,519,521,522,523,524,525,526,527,528,529,530,531,532,533,534,535,536,537,538,539,541,542,543,544,545,546,547,548,549,550,551,552,553,554,555,556,557,558,559,560,561,562,563,564,565,566,567,568,569,570,571,573,574,575,576,577,578,579,580,581,582,583,584,585,586,587,588,589,590,591,593,594,595,596,597,598,599,600,601,602,604,605,606,607,608,610,612,615,616,617,618,619,620,621,622,623,624,625,626,627,628,629,630,631,632,633,634,635,636,637,638,639,640,641,642,643,644,645,646,647,648,652,653,654,655,656,657,658,659,660,662,663,664,665,666,667,668,669,670,671,672,674,675,676,677,678,679,681,682,683,684,685,686,687,688,690,691,692,693,694,698,699,701,702,703,704,706,707,708,709,710,712,713,714,715,716,718,719,720,721,722,724,725,726,731,732,733,735,736,737,738,740,741,742,743,744,745,746,747,748,749,750,752,753,754,755,756,757,758,759,760,762,763,765,766,767,768,769,770,771,773,775,776,777,778,779,781,782,783,784,785,786,787,788,789,790,792,793,794,795,796,797,798,800,801,806,807,808,809,810,811,812,814,815,816],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/sqlparse/engine/statement_splitter.py":[8,11,12,14,17,27,77],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/sqlparse/filters/__init__.py":[8,9,10,11,13,14,16,17,18,20,21,22,25,26,27,28,30,31,33,34,35,37,38,39],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/sqlparse/filters/others.py":[8,9,12,13,34,40,41,46,56,70,77,85,86,104,113,114],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/sqlparse/filters/output.py":[8,9,12,13,15,19,22,34,35,78,79,81],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/sqlparse/filters/tokens.py":[8,9,12,13,15,19,26,27,30,31,33,40,41,45],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/sqlparse/filters/reindent.py":[8,9,10,13,15,26,36,40,46,51,66,82,96,101,109,119,149,168,174],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/sqlparse/filters/right_margin.py":[8,10,11,15,16,20,24,46],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/sqlparse/filters/aligned_indent.py":[8,9,10,13,14,17,18,19,20,21,22,24,31,40,47,59,66,89,99,111,122,127],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/sqlparse/formatter.py":[8,10,11,14,118],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/debug_toolbar/panels/sql/tracking.py":[1,3,4,5,6,8,9,11,12,15,16,18,21,22,25,31,35,23,36,39,58,64,68,70,73,77,80,82,89,98,105,121,182,185,188,191,194,197,200],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/debug_toolbar/panels/staticfiles.py":[1,3,4,6,7,8,9,10,11,12,14,15,17,18,23,24,27,29,32,35,38,42,43,50,53,58,60,76,79,82,84,85,87,94,99,104,109,113,115,122,125,140,161,171],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/contrib/staticfiles/storage.py":[1,2,3,4,5,6,7,9,10,11,14,15,16,17,18,21,27,28,41,49,50,51,55,59,72,83,117,148,154,208,256,327,330,333,345,369,370,371,372,374,378,385,400,405,412,430,433,434,437,440,446,449,452,459,460,468,473,477,478,481,485,486,489,490,494],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/debug_toolbar/panels/templates/__init__.py":[1],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/debug_toolbar/panels/templates/panel.py":[1,3,4,5,6,8,9,10,11,12,13,14,15,16,17,19,20,21,29,38,63,66,69,71,85,171,173,180,186,188,194,197,200,191],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/debug_toolbar/panels/templates/views.py":[1,3,4,5,6,7,8,10,13],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/debug_toolbar/panels/cache.py":[1,3,4,5,6,8,9,10,11,12,13,14,16,17,18,25,26,30,58,59,61,64,67,72,75,78,31,55,82,86,90,94,98,104,108,112,116,120,124,128,133,134,139,142,145,147,149,184,216,218,227,236,242,249,261],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/debug_toolbar/panels/signals.py":[1,3,5,6,7,17,18,20,23,24,27,28,29,30,31,32,33,34,35,36,37,38,41,59,61,69],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/debug_toolbar/panels/logging.py":[1,3,4,6,8,9,11,12,16,19,20,28,29,33,53,54,30,31,55,58,59,61,65,67,75,77,80],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/debug_toolbar/panels/redirects.py":[1,3,4,6,9,12,14,16,18],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/corsheaders/middleware.py":[1,3,5,6,7,8,9,11,12,14,15,16,17,18,19,22,24,34,38,43,45,69,91,99,146,153,158,164,170],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/corsheaders/signals.py":[1,3,8],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/middleware/security.py":[1,3,4,5,8,9,20,30],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/contrib/sessions/middleware.py":[1,2,4,5,6,7,8,9,12,13,18,22],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/contrib/sessions/backends/__init__.py":[1],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/contrib/sessions/backends/base.py":[1,2,3,4,6,7,8,9,10,13,14,18,21,25,26,29,32,33,36,39,40,41,43,45,51,54,57,61,65,68,73,81,84,87,90,94,100,118,122,125,128,131,134,142,149,156,161,168,171,180,181,183,198,200,225,246,272,283,292,305,311,319,327,334,340],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/contrib/sessions/exceptions.py":[1,4,5,6,9,10,11],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/middleware/common.py":[1,2,4,5,6,7,8,9,10,13,30,32,34,62,75,98,117,119,140,148],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/contrib/auth/middleware.py":[1,2,3,4,5,6,7,10,16,17,27,39,44,45,47,85,98,113,122,123],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/contrib/auth/backends.py":[1,2,4,7,10,12,25,33,36,41,60,67,74,84,87,96,104,105,109,119,122,124,154,163,172,173],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django_otp/middleware.py":[1,3,5,6,10,12,13,16,20,30,31,38,59],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/contrib/messages/middleware.py":[1,2,3,6,9,11,14],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/django/middleware/clickjacking.py":[6,8,9,12,23,24,37],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/PIL/__init__.py":[15,17,22,23,25,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/PIL/_version.py":[2],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/PIL/Image.py":[30,31,33,34,35,37,38,43,44,45,47,48,49,50,51,54,55,57,64,65,67,70,71,74,75,78,80,85,88,94,95,139,140,141,142,143,145,146,147,156,173,176,177,178,179,180,181,182,185,186,187,188,189,192,193,194,195,196,197,200,201,202,203,206,207,209,210,211,212,215,216,217,219,220,221,222,223,224,230,231,232,233,234,235,236,237,247,248,249,250,251,252,253,254,255,256,257,258,266,267,273,274,275,276,277,278,279,280,281,282,283,284,285,287,288,289,290,291,292,293,294,295,296,297,298,302,310,314,317,330,342,357,371,374,415,440,461,485,489,490,493,496,500,524,534,535,536,537,539,551,555,559,563,578,581,584,612,613,621,627,633,657,668,672,679,689,705,713,725,768,772,793,819,823,861,872,873,1055,1100,1111,1113,1132,1152,1172,1178,1205,1215,1230,1252,1275,1293,1303,1320,1335,1347,1376,1380,1461,1509,1548,1602,1619,1650,1685,1761,1808,1809,1917,2000,2021,2043,2064,2086,2094,2143,2144,2218,2266,2280,2289,2296,2307,2309,2312,2314,2323,2329,2347,2378,2416,2421,2482,2539,2547,2558,2559,2560,2561,2562,2563,2564,2565,2566,2567,2568,2569,2570,2571,2572,2573,2574,2575,2579,2580,2583,2603,2693,2708,2731,2748,2764,2791,2806,2817,2828,2840,2851,2863,2873,2887,2904,2909,2917,2930,2941,2950,2962,2994,2963,2964,2966,2967,2968,2969,2971,2972,2995],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/PIL/_util.py":[1,2,4,6,7,10,21,25,26,29],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/PIL/ImageMode.py":[17,20,21,23,29,33],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/PIL/_binary.py":[14,15,17,18,21,32,42,52,62,72,76,81,85,89,93],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/faker/providers/address/en_US/__init__.py":[1,2,4,7,8,29,31,258,260,272,279,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,303,306,308,310,312,314,320,325,330,334,337,342,345,347,350,355,358,369,372,376,398,404,410,416,423,426,429,432,435],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/faker/providers/address/en/__init__.py":[1,2,5,53],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/faker/providers/automotive/en_US/__init__.py":[3,4,7,165],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/faker/providers/bank/en_GB/__init__.py":[1,4,5,6],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/faker/providers/color/en_US/__init__.py":[1,4,5],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/faker/providers/company/en_US/__init__.py":[1,2,5,6],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/faker/providers/date_time/en_US/__init__.py":[1,4,5],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/faker/providers/geo/en_US/__init__.py":[1,4,5],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/faker/providers/internet/en_US/__init__.py":[2,3,6,7],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/faker/providers/job/en_US/__init__.py":[1,4,5],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/faker/providers/lorem/en_US/__init__.py":[3,4,7,10,983],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/faker/providers/person/en_US/__init__.py":[1,2,4,7,8,12,15,19,26,27,33,414,417,739,742,743,748,1748,1751,1755,1757,1759,1762,1766,1770,1779],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/faker/providers/phone_number/en_US/__init__.py":[1,2,5,39],"/home/valberg/.virtualenvs/bornhack/lib/python3.6/site-packages/faker/providers/ssn/en_US/__init__.py":[2,4,5,8,9,10,11,13,35,142]}} \ No newline at end of file diff --git a/src/.ropeproject/config.py b/src/.ropeproject/config.py new file mode 100644 index 00000000..d8c8ce4e --- /dev/null +++ b/src/.ropeproject/config.py @@ -0,0 +1,122 @@ +# The default ``config.py`` +# flake8: noqa + + +def set_prefs(prefs): + """This function is called before opening the project""" + + # Specify which files and folders to ignore in the project. + # Changes to ignored resources are not added to the history and + # VCSs. Also they are not returned in `Project.get_files()`. + # Note that ``?`` and ``*`` match all characters but slashes. + # '*.pyc': matches 'test.pyc' and 'pkg/test.pyc' + # 'mod*.pyc': matches 'test/mod1.pyc' but not 'mod/1.pyc' + # '.svn': matches 'pkg/.svn' and all of its children + # 'build/*.o': matches 'build/lib.o' but not 'build/sub/lib.o' + # 'build//*.o': matches 'build/lib.o' and 'build/sub/lib.o' + prefs["ignored_resources"] = [ + "*.pyc", + "*~", + ".ropeproject", + ".hg", + ".svn", + "_svn", + ".git", + ".tox", + ] + + # Specifies which files should be considered python files. It is + # useful when you have scripts inside your project. Only files + # ending with ``.py`` are considered to be python files by + # default. + # prefs['python_files'] = ['*.py'] + + # Custom source folders: By default rope searches the project + # for finding source folders (folders that should be searched + # for finding modules). You can add paths to that list. Note + # that rope guesses project source folders correctly most of the + # time; use this if you have any problems. + # The folders should be relative to project root and use '/' for + # separating folders regardless of the platform rope is running on. + # 'src/my_source_folder' for instance. + # prefs.add('source_folders', 'src') + + # You can extend python path for looking up modules + # prefs.add('python_path', '~/python/') + + # Should rope save object information or not. + prefs["save_objectdb"] = True + prefs["compress_objectdb"] = False + + # If `True`, rope analyzes each module when it is being saved. + prefs["automatic_soa"] = True + # The depth of calls to follow in static object analysis + prefs["soa_followed_calls"] = 0 + + # If `False` when running modules or unit tests "dynamic object + # analysis" is turned off. This makes them much faster. + prefs["perform_doa"] = True + + # Rope can check the validity of its object DB when running. + prefs["validate_objectdb"] = True + + # How many undos to hold? + prefs["max_history_items"] = 32 + + # Shows whether to save history across sessions. + prefs["save_history"] = True + prefs["compress_history"] = False + + # Set the number spaces used for indenting. According to + # :PEP:`8`, it is best to use 4 spaces. Since most of rope's + # unit-tests use 4 spaces it is more reliable, too. + prefs["indent_size"] = 4 + + # Builtin and c-extension modules that are allowed to be imported + # and inspected by rope. + prefs["extension_modules"] = [] + + # Add all standard c-extensions to extension_modules list. + prefs["import_dynload_stdmods"] = True + + # If `True` modules with syntax errors are considered to be empty. + # The default value is `False`; When `False` syntax errors raise + # `rope.base.exceptions.ModuleSyntaxError` exception. + prefs["ignore_syntax_errors"] = False + + # If `True`, rope ignores unresolvable imports. Otherwise, they + # appear in the importing namespace. + prefs["ignore_bad_imports"] = False + + # If `True`, rope will insert new module imports as + # `from import ` by default. + prefs["prefer_module_from_imports"] = False + + # If `True`, rope will transform a comma list of imports into + # multiple separate import statements when organizing + # imports. + prefs["split_imports"] = False + + # If `True`, rope will remove all top-level import statements and + # reinsert them at the top of the module when making changes. + prefs["pull_imports_to_top"] = True + + # If `True`, rope will sort imports alphabetically by module name instead of + # alphabetically by import statement, with from imports after normal + # imports. + prefs["sort_imports_alphabetically"] = False + + # Location of implementation of rope.base.oi.type_hinting.interfaces.ITypeHintingFactory + # In general case, you don't have to change this value, unless you're an rope expert. + # Change this value to inject you own implementations of interfaces + # listed in module rope.base.oi.type_hinting.providers.interfaces + # For example, you can add you own providers for Django Models, or disable the search + # type-hinting in a class hierarchy, etc. + prefs[ + "type_hinting_factory" + ] = "rope.base.oi.type_hinting.factory.default_type_hinting_factory" + + +def project_opened(project): + """This function is called after opening the project""" + # Do whatever you like here! diff --git a/src/.ropeproject/globalnames b/src/.ropeproject/globalnames new file mode 100644 index 0000000000000000000000000000000000000000..da3d932c36983500be5e06c71f5fdf5e3fb295dd GIT binary patch literal 28985 zcmai7bzmdM^$s&L=fVy-V%tp$K3TqV&J;_&bJA|NI(u#F&Xzn+@B#@hxE;zc*r4#G?yD|{j1e_bt#ahIn*sa{?2m#g)K6;^em zXO8NdI|}@j#u6$wN6($&gja*r-GTVc>b_vX95Z)XJ9!~k30hzr8_XRCPOZM!=-*ch z_BYLOo;iN*1kj4r)wMCucYzgTCKjX zQJW7!%6xTYWp{OcuQ|~(C(RuT{6q*fCs*gve6Y;#ZnXMWLprNWW&Or_YYDY3fxQ|u zn`k#bIIva|yzwcXIdvK6tAMWKg*&i$zq;OP_?c9?kSe4H{q#^OV@~tT=^tJU^*%oP0QT2S4K-dS&=&(8DA`Fzrq0N8GBZ;qT#s^47SZU3jSXfE)~ zg@p8Vhh%fn7Y(Lzsf?e=W^?8u&s1N1T)e2Zr;31Qv8 zCw|&MD#P|GWQNS8p1F*$bMdr!3?+1wPJq>*-s+!ktm4-~(_HSEE9NeMNSCfm6xoo7yCTehYC7-J>$*q~0|BcDC%UN;n#B@Jy<0E=L0*J$E#o?Pj>i z1alYiRcu4FjrRC6v!2O?pSiJvGDA_P7E%LgbZR=AHF?hzLQI!7jE8n1oyny9bUIrw z1D+WqhBK1iQe9ZB)y+zS_zPCN;XzPO7_l=5E?vJ1xTu+hN*uyyfFLK8X36#^}!H%vR47S^Y(* zzN=P=+j+z@rLfI5wsSTcw{tp!c1{oE3ue?a+rqc+XlJwCGh;edoF??43eC-)*`d0% zXw~EJ^q3j1D#cE6jI*Yh@XVw_E7b4BMt!liWTvWW2ckyO0XprOTl$u-U&a`uO0px# zs_Yrhl>3&g>Mvr1%>)ZjmGdpt+?BbLAWrf~(5lu}lsFq{`0-lP%I&nB*=2;L3qGm- zLeQL-+8Q;#+2xtJusPOSwUuW7Vs*aNkXq0*w|eF_eaBg7w^1b@G8#(yFD|{CsL<&X@yig>I$iRIz9f%KA*_%Z%nbOcfqcfSdB$w=tZecHY0lF5bk2xp zngm_KR#fk(&1|CX#oB@OHPt{()AG!^b;ha-3sx(!lg&QW%cQN=noSHJ%afqF1_!6M zdj$h}Kg|VgPZwnozgpsZ4tVAuUyUw+*3*zqic zncI7r`pjU|py=~#+E3@w1#>^o+@JN)8FXVgGQQ>x&pcr6`k0fnM(Kf2ac`LN5A@7~ zSSQ`KjSZ2@g&5Mk0L0Cm$X`~ZAf9{Ija`>r@<;T zDv0y7wHn+K^JvdJh857Gu})*MaWP9mkLIzSc^n0)%GZL%+Dg!`_TcfJd4e^xN^}O{ ziPnv>uhjPJ{SAR1X`bYnC({DZ=q_2h_m6NT;%UV8ZaeIF9fl z%li^_iL~~FRQ(5yt&wPk)%n;70!^n!nA>4;O^AR0EPQ-fj zAN9<~*d3ZlSP80i%qViq$JKY6ogEvozdvESUt_d|*|i16oR;%R{cg7SOt2D@KV_$o z%Mg^Pfz77_H7q?oE*YQZ;7p`*sX_A@&wQ32M<=XncVuFR4~+pUlODlnn=g3giv(`z4UEmhmpt=j3e$cwgVI=BL|(;ZXujf^uZAOiYs8Fo z&(~BxOj~8Q9bq;shR(sSyP3MM1Qi~Wzo9duqK;^BIhfyDtE>1oReX32t+OwfL_}=o z`?s{iCUhj=Av(h>=iA|fm1ZThrtjzw>X?-Y{&($6OU}&%_j}2R#|8o4_skEXxJE~d z_4$A%^K;Mqf={B?)x~#0fEDG?Brxkivjv}|wcJ=Rzx2$nh@>mo z<%yZBeIhEAR&!;2$^67tap!SI_)SJ?U<0GjF{TPH6h! zD~L?Z-#zmWR+k6^TWFo8`KM?8wb`7H6Cci*Ol9)s-=6tTpLW7pV{M%}WrMfxudVN1 zsm(K=1aC(ZK~3|2RJEIUuI(OZ9$A)j%KX=pLk>OUknruDTd(6+4h6%L!%(V~3>{)Q zT1${)G*1>U~Zz;5Z^@+7*axrEz|jw9HaFfi<0l# zD+G?e6Twa@M=Oz+;}m+lgZ2oM;wS~W6oWRC%B1B4MV{!8Jr!{_ju{71q5hVW6nwG+ z-@xJ4E!m1FILZn7^+u}(MQW4Ra*Eb)>i>Lv9OB{K86Ib{DLGBSr#mpmMn_hNiR{P{ zkXJ)q*o`hZL(ykCG;K+@36as!=@R*gh*Zu}_}LE5G@dFI<~8IT<(-SNPlpH+9rJdm zlZ~Z==CYgzuKJ3a`Ov&6d0|dO&Ii9|#G5pW2>LbKD;MZfFGSff-c_&4MasSyCG{#* z6ZI;l1k{|S_hk!so8-*%7wU9Pw* zP^xZIcUVn_TnSoLXJZJFt5mp;!ZZa7!D4lNrG@O?8uT?Yb#k?Wdc>Hyc&1^p(5V{A zX5|{K^jef`DMn};4FX&btA8+H1G!ES*E>Y7xfy$Kg;WmRg7nmo^eglR2c@&PyCL;u zI1T;#n^;{*DL;);jUc`Zx=*KvWI(ifH?$&jFD0vp97^^iYpmD|mJL-U4^Gf4>c(UY zbq|tZd`YDGq@Yy}pk#}%rL8f>d|9K8ZdI3>GN?jBD0`a1lr@F$Bw@1aD+lFHin-BM zd^o?pDsq!j@64Kds+@e>noNm7NoF&7xr-w2>guD{U}vowOu3tKhgmNNct@|wR%I8- zP8c%_9Z_D1ydK?)m?CUBm&hMT=VVlI+fasDyPFz`)h9AU)Y=>w+Z8(IpuHO+wxi6o zXZ%zlKO{FRc!vWYhp*LShn-^M%A7!H^KIdpn4M;mpsQXA$zyd`dz;6VDKhEvk{K>P zaP>i^!LjPWIYAo(k$y}Wj280c7KnQ?!|Iq4Dca>GDT82Fkve(@%DUakAiaq+QbsCT z(JV@~Fc(@^^~thR8M{zw80b>ev8zM%AIBX`Y@^0ZW>Dr7c&n??sVKKd$jDP}Q-Qmq z?9<8MvM;04Q}86MiN6P!iNwTg9aED|`ogqxZLOHchrA<^2nmxf?PB+2Z5)%cqN@WI z?1LKUw}swGN7^kLW-wbdtYm7l-wPN|s(dV3tEWvyQ^YoTrM9%(^7kXYhSMjzwT5|D z1Jz6PbX7kK$`4Sgb}ze3qEkMLpxa)uuBR-i_%g+5CDlZ8HAQO5*n={$reY_L9mRW9 zV1)u!%OS&DsW$i8QM?MeU4sDGlIkRJ;#WYL(8YJlXn~6GIT2eoWWF z-De1>)pqM;^+Z!aEtK}9(2q23Hftp7tc*?O$TpakeIQ$7zShk_LQ*sCjQPe&Lu9`` z<^ak~)Jiti<+N__0|s+BIjGQkJ7{-jFcs?*uB7DYfey%h6nWoGk@>b61!Ou6ZFIXL z@8^(LpaG(cNc(&o@RJd_++T5bI2?N+Y#<$K4^Z|4QHG7mS?apzK_FM>1{0XJM)=<@^11bK~E%4^PaWld}F=dN;01m)>uZWHOY7~7(IQC#EKK52QD6A^<16; zh$l})$*=3#G=+3zb_Y`hs_;DgfTt<==?>h(`^(0ooZ25dQLr#0&rs+y9hA1IW!)!v zmU5nra*y>YIeFBqwvDXB%X1X`TvzQSKz7R&V3!256P)DhBF|II^Bsn} z6E?bCn&oTMSCKH57pVLTQQCbH5-cG?4@6!Bl7_1-SqEW(n>!rl#bmKR(UlvRF9Fkb zTep{uV@-S~vu_1B&o2eUlb4}nw=wDpM|!()!b)rCF2yUM@^VGL!lAiQpsU%Ak{R+! z1-!}udXAEWp%3HYbVgpS;MX{Ck5K|e5x%JPh|@#x5nij%*Ewi+Et*)h9Y_sfp&7eD z3i5hIzQG~sqFR-qNm+TLa^HlK&O5n9^jKq6!ytJx=yOMcXn($im86$5x&Wgj*cEP9 z(`+m@0mxekpyEm{6v*31W!+u{R&b!@qmFq5w^;g>52@sbQK}-H$LvF+_ziCKlaGLG zGrgV8yL?n}A0v+Li=Cg?oh2Vv#wSp+BRRps{aQXZZ((mAC*~)?4>VJacj=b(&+sM5 zNbc>BPif_!M#=ADgxa+^;?+#~j3Pek5bS3As%l3+r_9fz)KM|Z-6GD4egVWyv@d3T zI5{}41~9}kDfyz-_a&5kJ&p<6Zf)V>msRL1D0M`uf|0K(@oOYHXN(KS`v4Vf%z>KD>ODsQC#?MgpYK4RucL8uAmzSR_?ia4Yo~?kr zAmKpbQVs^v0N&=83jUP?UyHYiVvV+W5B2UC8tLp07_rE&75y8B?$vj39>Fy~+wivv z{hfpMd~0mxNW3*Y?0jZOey`v^I52I4Rc&qg_{5M&<+0+0JY81)sK`G#Bn|$?iPNtn zUsEoBR{6i6?AxO@o{_m*&0Man!Lx0xH|4M3+kx*qnRZJIpDF$b-O7|r4awiM>c6Ap z!0&G0xE$)X^3uTNkkQKKUu|5Eb5QO?~6TGu(4OIfEJOkMx+v9#UT zkCcy3h@9nc5bf%MRhl-z(6&vse|MwNYGO%v?fQjaA2Z2v1W=wFiE>XF zuVcf-$QiQX;!!GdG)n8D@3fmM!~Fts3^;0U9V6a-AjfvFV78H4*@;C4IgYIJ@Dc5s zK3p9(d2oCO+=ikGKcRy)qC3%*bs|{7T*mfaH+wY{*{eFdX6!cEr#q;*TUSm3*prh{ za!9d}opYx~=oICiiqbkPx{26Xq0>NhTczwOT$~6$U14Vs#)06RkI3^lQ<02~!U3l% zgmRX`&PGY|%$dggH0EjOKtw~(%AdmraHmZurmx;1bS{N1aYAkbc_gxK7tZYprJP4m z8gACtURS%|`4Dv5glrhnF?nNG_yS0Jav@4KFExQ1t&!f5i&W%dlwt0|rnT&(*`nM_ zP_j+v_95NGs8B8?g4tOReBX=y=0ryZcC{k7Y&qT33@qcUVbsO&f5`1@>|+$^07kPI4UybSp=z z`>-DtQ}udM*kab%##ffHQV7v!8jwIop}Mh2cdDNhYZNk&@+6DW83lf-^_1ohN>1zOY0(lZB3zY4 zrXimjki1q|K*^y+|3A>_nHY;QpfZCfd#)`c4NYE`7;^;~Qrw+f-N`J5RgpI;|0a|i zl^l2FD7g^n$vcCszF*7>H(9CPx(oT-IG^B0d#&ZJ;0CI7!WpA!-n)V9$uObJ?37#8 z#YLMoWbneHE>@Lpg~TR4a^k259ZOnCc!x!;d;}$%l+HwCu)mPP7ow(K@$LZc7(A`#p(vygMb?K%F&Oo1nwy9+aWJaDyY^zj$ON zOhq)H?ny>uDk8EU%4@eJD!LaLoZFL)vYvh@&o2iH>nqk5s*=kLNE>xGshrew6tMYl zx+?IEYw!t?HPJVp4{OB$aarY-G**hp3cw>=AeZk5Q<3P$AVE&_-eQ8B=(8n|?TQ(d zcS4sUw1alk+yfjPx7$^gA?`^HB{fD*4c@*Esab!x^LrG$*MS*H^-wplOCLp}Sy@r^ zszb9s-9ice$*v;hgrkmim1&@)?qK9Njm=J27+eFX=T?Pyxd8DV_r?z*_%&LUpyZd* zp$Y?+Hk0Rw*6KAC(?V&j-X3e{=v!#?WmDqoDzy)#T9PoY6z@-y{owTu^piU)(#+@; z5bzw(N)Mt8Uw31F;%o|3Epu}|_khX06>}elp)YJBJ?m}WSGl*NWLt8M(M`mE0S-av z!c`ODopUAc2Ql5wP8qwev5VCGDa8>_Df+n^>bV0FflgMusTu|3$(rkM+?(!6zy&Lx-=6_5vkV|%L0rx*M{x2NluH|4=v*F#X+jUjE!hl0$FAw7q8;xvU#6u_G1 z?xB)rDC(K6Zq8dfBeegXrOaoe zbW3eDjDCD`WK3%-CN04l=^E_ogUu!&ij#-Kd*zy7pG$7$G>+H!3Nuv`@ z8dsR*MWAdlMiY5CdVB?+I}PN;0D1Bflx#dI(P)e|kqt&-qbV;{nU|ro2k2JNNGm?h z3d+kt)44Zt^YG-hDSzv5x#Uj|SGLP5Le8%8wlRNrdU|}UI9wTQTTGVlT-t6$Ul3$z}Dao5i z<{Ql7b1S#WoB3NEitSS~6@O$HFFHCkGcjC|w~)mLCW&t)kzNLgm9dFP`fZ_flK6HK z8DmyT6Vu~Bl;s^H(RUl3t!yt%;_I|+(f-99rOA=9ypsYPj>E;`)a+!%?+~0QRklx! z$h#=U*%*qICWgnx{h87&vtu)*5qUTH)b#EAou!$v(XcutK1eZ+g01N4a%E zYR6c~FPDn5c+$to=64p$Gou~6PmssKj_*VxY?Dudu*sxOEbE3#9a!%C6hNMQ8YL$+ z!#Jz8+O!fjWrcZCyVi*_-g)_qLO+{;+U1TmX!5D{s55Gi&nfit4$36LMzf3EjMhQ& zjm$&m`Ma_FU&zT96#K=*W4pa^?C7{R#$i?Yl0v`ipmZW#PPOyAU!2TOtnGe9(O-3F z&Pn^y(OwDpno4{fr4ElU$6yuqHbGned#|d^Dij*3DhL?fZ-G2@BlaOIxqUK5YWaY z*SScJ^*6Hk@?`OBgQNc)^i32-F1a}5PL>bKKLGONpD6jRJqKYv9)#RPg6;U3Tw4C6 z;D0+Xn>q5oH1G2t<^LZ_ek)&j+WBWL@$+A>>}k40%1Aw|Ly+F}crp-=J-iavHO`Hho z>zYG22^4$Gr^5%9lNE6a5j|QCmu7_TpU|PFD(*Ct;e?ICcpKoJt^#MUVw%#Oc0I}N z_c{~Qs^-h>iuze9dp2deD~+~faGr~@aAf5ig`JC%@1Ry-L;50{3DXz4dxg7CvE_){ zOwLpE`3~Lvxov%yr~f>Z&&dUfywD-}bMW+QpV*lX}>tiDbtW3cWG`?PiZ-y@%0& zA}ME4g>q=dMAkk_%`RM6FmzQ&=u_e5e@-rZ<}O$TzVBCm5u&fkrS z0^17`I(DI2uQiwbebts+ui$zBec{g)+RrNw2H2<2MbmUF1{cjicahQ+kGs zc=<+mLRm-_oaGy>^4^D2Ydj$AFG^!oa>Q^DRUfy^Mf6_bLwPSl_V!SeiQ~Z8$Vnnu)!EY#TAD)Ew?~f1P zT0-Qw9rQgK&@vDx4o^(S0nK!2rih?T#)xIVP9W47_B9s0nKWj^%f;=bk=gN*j~Hcg zY}@vVKQ%g9#&>L=nnnFPD7Pgk$B?l+j=*`mG`X#^9k|I^#){*VyeuhM+KH$8lT(!_ zh>L_LD9pf;-#1>WAm-U#8XoZ(6Ej+qNeXZjP+)kbxP5G=i}pHex01oZ;26`hTagpN_vyHi+sID5^UkSp#O)=#R48$GO0em-4o~g~ z!{{;mkb98BH%fBKyT(QGwMVa@T?0Qz(n%Fio-X z5U%geD$5dOn1I-@1tbz#hDgt=$#BjG_X6qJLsnU5AW{RslRYTy?!OHJd%rKN8^{G6_Xlm0P^azMF1v>m z>*IH5bq_$v;d~8hj6&0>S9yXfo(l;#`GE?4kOT7@!y%!u&V!Zx5R@*~p{_^-M6s7A z4^`2Jq3q!!C)OjvJO6NY@8Jr21WLYrci$>;)Dp2QHh!iD;9EUXk&kjnes}ol@mt}$ z3(1ty0QRV-2e9$>(F%Ty15;Pqfo%Q#$13-6D0OzyVIf=nq2z3n$3tY3%Rk}UZ@m1o zRa*@}mM7>#o`{lPPMKp>5`y7`qxZ1ln3kt0`01NJ7vXCR&B8Ut+1NpOhC-j|px5DpbxyQ>EJvy4 z4se5@kGoIj?G(jTeDW-XKO3dpsn|>IIr@NJd6AA42fZ>NFVEGwpQp%8@0Lln2{RQK zOlf((qF><9H$;P}?aPqEO5CJl*A%0TDlgO;UgT=%(VL0=&(Z0hL3y!4U*e!Nj;j1r z)4Wu9FGET5MP*Y)0P2*@%R#o5b7M@B8;llVtupajOd`HQ>w6_i4q001hi1h+GVxn!-lC8jly@oY z-LCHI(a4?!T9>xV?ABg3sDIX}8Pg=`-a!QMR6ln(>w z$wyH3Sr;+9WTjK^qY$Ax<#LSbPT3IsV_L<>wF)}I9oxQa-2Dl#)fdvuI`ATNJGbS1 zvW*w+@3g#6kw*twak?MWGCth~3ioze-e<^TPgoG9w55NRbd87XWn-55IZ`#`b-O<; z`ST&!eUFRrzd$lojMi;MzZlj#Yq!T*>X%4829ls!%9lauodQU%k=O-x_zhnH#FMY0 z?Cm$S-Fy(#Pc@g|%|h{f zM{(bE)v>YNej&H4@IB>!pY?K%PdRr28HfpY*~kyT>*Y8l&TZ0lfU)Bp6+hHEe}s}v z$Bxj8lX;T+$IAK%N)5BNR>c{MpMqrXqoQn^DsD6OJiM2IvmigyntqOw51~fwG656N z0&bwCZ-&LQUnumKn?n;>Uw0`IZljf7DfHJ4+S3SN#V=NSSS-Y0EI87?QSfgam_u0& zqh84;zfRgr(&{GkaGsS{)V{7SXiltVC2d-)&ou68jR=9&LL(n0DE2qi?~8G9GFJxc}JQ337tgdm>7{j zecdh<%2_IMHbuIBD)eDIA2oJGZ_7CfI~QfxNL~ECxRKllp^`dJk>@)k#}}gB&W&a4 zoOpa;bYfc?ZYj&i1&Y4Vq2t-rrhF2M^B1Z7#fhhNk5Stu5iU}L*1=^KTNHhXL-*`Z z1RG%!!NH|#T)+;xOBH;X15+ET-m&Y5mn-uMly>*mB#%Aw!dkf!G<8ErvU{K9D$wi= zT2U8P^(LM^t>$X2#=1XxjkR@3u3=3~ZAJ_9fmqJ9S|9tnORvRR0e?V((K?mrb^4&| zQL?{#wgl!-*b)w$!GdbPf^Tr(0o&zWjEuXdgOM86W9C=Zv6ZD(w`ZpG20}?`O=(vX zHDx?_?Al;PC9)`Wvk3fAjxEW75FLZCqfPTec@;09borqklOWDRP{+c~XA!~-D0mQM zI0-feq6r;CBs3jv1d|~}-pL`kBBC}_ZdCeBDAjKbbzOgz_k-P8nRh|CC!?nfbHH_Z zqFazf%WwrtcwH;Dy6fMm!KPwnZtkiz-3=vQyoYa-NLnS*C&LQe>Y&|QE3p-z0Go(( z7pAim6*=ON+*Z>?yYt3bB}+-gM^QTUemoFNWbF@vy$iToZyQ)nxg)i;abFT!lz;1@ z?Ku5*t#u3~za0N)1Io=x-htBH_tC3O;-z}4(r_~Vl>7} zIDp2h@|G1``(I%E)qq%eyG=L)vPZ#t9e5LeFk$Ue&VuG-MbWDc&9;PEQq|wNQdL*U z21=&-F6VIO^~d2MU1tR}c>&k1$=hz~IOMnnfabW{rL7#&G5kAR5V5N+kvNUBq*OvA_eh@=f;CC0uMeReI}VP9CK7K3Kt3 zweW5{$wQR$P?S!E_nagNk2bM6=V6L}xT~3|;Vzz{JVK=&iL%#)^U0hXG)kC`dz1nn zjj|&hN4=NK+dT#%Ovmvo)JEfuu6FrsyXEn*TJ7T$V>gnx^b7uRXI&nzB2PexiN&)n z$D!tU2~3`-{3oH*jo)32a%~moqpekbvI;+imDy`3IAL1L>#Mu#*mEOK1!I#wO>9j~ z_?A!8I-ib`qnyjxc1~fMci!Fe3>AGQO10gTlV{;q^6D9DLRRe+&CgcAb5Qo_TDH9= zp@KG_iT|jKJ=^4n#BE%QJ+P|W Wmyyfm(3m@HZ?07K%fSxT`~M%~d~%oo literal 0 HcmV?d00001 diff --git a/src/.ropeproject/history b/src/.ropeproject/history new file mode 100644 index 0000000000000000000000000000000000000000..4490a5d97c960ec09c2666de3b6655a1b6755707 GIT binary patch literal 14 VcmZo*iY;W&h%ID{Eo4g70{|Rf1FHZ4 literal 0 HcmV?d00001 diff --git a/src/.ropeproject/objectdb b/src/.ropeproject/objectdb new file mode 100644 index 0000000000000000000000000000000000000000..0a47446c0ad231c193bdd44ff327ba2ab28bf3d8 GIT binary patch literal 6 NcmZo*sx4&D0{{kv0iOT> literal 0 HcmV?d00001 diff --git a/src/backoffice/apps.py b/src/backoffice/apps.py index c0cd7403..fc86b432 100644 --- a/src/backoffice/apps.py +++ b/src/backoffice/apps.py @@ -2,4 +2,4 @@ from django.apps import AppConfig class BackofficeConfig(AppConfig): - name = 'backoffice' + name = "backoffice" diff --git a/src/backoffice/mixins.py b/src/backoffice/mixins.py index 17361b74..fcf368ba 100644 --- a/src/backoffice/mixins.py +++ b/src/backoffice/mixins.py @@ -5,6 +5,7 @@ class OrgaTeamPermissionMixin(RaisePermissionRequiredMixin): """ Permission mixin for views used by Orga Team """ + permission_required = ("camps.backoffice_permission", "camps.orgateam_permission") @@ -12,13 +13,18 @@ class EconomyTeamPermissionMixin(RaisePermissionRequiredMixin): """ Permission mixin for views used by Economy Team """ - permission_required = ("camps.backoffice_permission", "camps.economyteam_permission") + + permission_required = ( + "camps.backoffice_permission", + "camps.economyteam_permission", + ) class InfoTeamPermissionMixin(RaisePermissionRequiredMixin): """ Permission mixin for views used by Info Team/InfoDesk """ + permission_required = ("camps.backoffice_permission", "camps.infoteam_permission") @@ -26,5 +32,8 @@ class ContentTeamPermissionMixin(RaisePermissionRequiredMixin): """ Permission mixin for views used by Content Team """ - permission_required = ("camps.backoffice_permission", "program.contentteam_permission") + permission_required = ( + "camps.backoffice_permission", + "program.contentteam_permission", + ) diff --git a/src/backoffice/urls.py b/src/backoffice/urls.py index 5bf4a7e3..aa5165f9 100644 --- a/src/backoffice/urls.py +++ b/src/backoffice/urls.py @@ -2,93 +2,156 @@ from django.urls import path, include from .views import * -app_name = 'backoffice' +app_name = "backoffice" urlpatterns = [ - path('', BackofficeIndexView.as_view(), name='index'), + path("", BackofficeIndexView.as_view(), name="index"), # infodesk - path('product_handout/', ProductHandoutView.as_view(), name='product_handout'), - path('badge_handout/', BadgeHandoutView.as_view(), name='badge_handout'), - path('ticket_checkin/', TicketCheckinView.as_view(), name='ticket_checkin'), - + path("product_handout/", ProductHandoutView.as_view(), name="product_handout"), + path("badge_handout/", BadgeHandoutView.as_view(), name="badge_handout"), + path("ticket_checkin/", TicketCheckinView.as_view(), name="ticket_checkin"), # public names - path('public_credit_names/', ApproveNamesView.as_view(), name='public_credit_names'), - + path( + "public_credit_names/", ApproveNamesView.as_view(), name="public_credit_names" + ), # merchandise orders - path('merchandise_orders/', MerchandiseOrdersView.as_view(), name='merchandise_orders'), - path('merchandise_to_order/', MerchandiseToOrderView.as_view(), name='merchandise_to_order'), - + path( + "merchandise_orders/", + MerchandiseOrdersView.as_view(), + name="merchandise_orders", + ), + path( + "merchandise_to_order/", + MerchandiseToOrderView.as_view(), + name="merchandise_to_order", + ), # village orders - path('village_orders/', VillageOrdersView.as_view(), name='village_orders'), - path('village_to_order/', VillageToOrderView.as_view(), name='village_to_order'), - + path("village_orders/", VillageOrdersView.as_view(), name="village_orders"), + path("village_to_order/", VillageToOrderView.as_view(), name="village_to_order"), # manage proposals - path('manage_proposals/', include([ - path('', ManageProposalsView.as_view(), name='manage_proposals'), - path('speakers//', SpeakerProposalManageView.as_view(), name='speakerproposal_manage'), - path('events//', EventProposalManageView.as_view(), name='eventproposal_manage'), - ])), - + path( + "manage_proposals/", + include( + [ + path("", ManageProposalsView.as_view(), name="manage_proposals"), + path( + "speakers//", + SpeakerProposalManageView.as_view(), + name="speakerproposal_manage", + ), + path( + "events//", + EventProposalManageView.as_view(), + name="eventproposal_manage", + ), + ] + ), + ), # economy - path('economy/', - include([ - # chains & credebtors - path('chains/', - include([ - path( - '', - ChainListView.as_view(), - name='chain_list' - ), - path('/', - include([ + path( + "economy/", + include( + [ + # chains & credebtors + path( + "chains/", + include( + [ + path("", ChainListView.as_view(), name="chain_list"), path( - '', - ChainDetailView.as_view(), - name='chain_detail' + "/", + include( + [ + path( + "", + ChainDetailView.as_view(), + name="chain_detail", + ), + path( + "/", + CredebtorDetailView.as_view(), + name="credebtor_detail", + ), + ] + ), + ), + ] + ), + ), + # expenses + path( + "expenses/", + include( + [ + path("", ExpenseListView.as_view(), name="expense_list"), + path( + "/", + ExpenseDetailView.as_view(), + name="expense_detail", + ), + ] + ), + ), + # revenues + path( + "revenues/", + include( + [ + path("", RevenueListView.as_view(), name="revenue_list"), + path( + "/", + RevenueDetailView.as_view(), + name="revenue_detail", + ), + ] + ), + ), + # reimbursements + path( + "reimbursements/", + include( + [ + path( + "", + ReimbursementListView.as_view(), + name="reimbursement_list", ), path( - '/', - CredebtorDetailView.as_view(), - name='credebtor_detail' + "/", + include( + [ + path( + "", + ReimbursementDetailView.as_view(), + name="reimbursement_detail", + ), + path( + "update/", + ReimbursementUpdateView.as_view(), + name="reimbursement_update", + ), + path( + "delete/", + ReimbursementDeleteView.as_view(), + name="reimbursement_delete", + ), + ] + ), ), - ]), + path( + "create/", + ReimbursementCreateUserSelectView.as_view(), + name="reimbursement_create_userselect", + ), + path( + "create//", + ReimbursementCreateView.as_view(), + name="reimbursement_create", + ), + ] ), - ]), - ), - - # expenses - path('expenses/', - include([ - path('', ExpenseListView.as_view(), name='expense_list'), - path('/', ExpenseDetailView.as_view(), name='expense_detail'), - ]), - ), - - # revenues - path('revenues/', - include([ - path('', RevenueListView.as_view(), name='revenue_list'), - path('/', RevenueDetailView.as_view(), name='revenue_detail'), - ]), - ), - - # reimbursements - path('reimbursements/', - include([ - path('', ReimbursementListView.as_view(), name='reimbursement_list'), - path('/', - include([ - path('', ReimbursementDetailView.as_view(), name='reimbursement_detail'), - path('update/', ReimbursementUpdateView.as_view(), name='reimbursement_update'), - path('delete/', ReimbursementDeleteView.as_view(), name='reimbursement_delete'), - ]), - ), - path('create/', ReimbursementCreateUserSelectView.as_view(), name='reimbursement_create_userselect'), - path('create//', ReimbursementCreateView.as_view(), name='reimbursement_create'), - ]), - ), - ]), + ), + ] + ), ), ] - diff --git a/src/backoffice/views.py b/src/backoffice/views.py index 1bcc82ed..76e121b4 100644 --- a/src/backoffice/views.py +++ b/src/backoffice/views.py @@ -30,7 +30,8 @@ class BackofficeIndexView(CampViewMixin, RaisePermissionRequiredMixin, TemplateV """ The Backoffice index view only requires camps.backoffice_permission so we use RaisePermissionRequiredMixin directly """ - permission_required = ("camps.backoffice_permission") + + permission_required = "camps.backoffice_permission" template_name = "index.html" @@ -42,13 +43,13 @@ class ProductHandoutView(CampViewMixin, InfoTeamPermissionMixin, ListView): handed_out=False, order__paid=True, order__refunded=False, - order__cancelled=False - ).order_by('order') + order__cancelled=False, + ).order_by("order") class BadgeHandoutView(CampViewMixin, InfoTeamPermissionMixin, ListView): template_name = "badge_handout.html" - context_object_name = 'tickets' + context_object_name = "tickets" def get_queryset(self, **kwargs): shoptickets = ShopTicket.objects.filter(badge_handed_out=False) @@ -59,7 +60,7 @@ class BadgeHandoutView(CampViewMixin, InfoTeamPermissionMixin, ListView): class TicketCheckinView(CampViewMixin, InfoTeamPermissionMixin, ListView): template_name = "ticket_checkin.html" - context_object_name = 'tickets' + context_object_name = "tickets" def get_queryset(self, **kwargs): shoptickets = ShopTicket.objects.filter(checked_in=False) @@ -70,30 +71,31 @@ class TicketCheckinView(CampViewMixin, InfoTeamPermissionMixin, ListView): class ApproveNamesView(CampViewMixin, OrgaTeamPermissionMixin, ListView): template_name = "approve_public_credit_names.html" - context_object_name = 'profiles' + context_object_name = "profiles" def get_queryset(self, **kwargs): - return Profile.objects.filter(public_credit_name_approved=False).exclude(public_credit_name='') + return Profile.objects.filter(public_credit_name_approved=False).exclude( + public_credit_name="" + ) class ManageProposalsView(CampViewMixin, ContentTeamPermissionMixin, ListView): """ This view shows a list of pending SpeakerProposal and EventProposals. """ + template_name = "manage_proposals.html" - context_object_name = 'speakerproposals' + context_object_name = "speakerproposals" def get_queryset(self, **kwargs): return SpeakerProposal.objects.filter( - camp=self.camp, - proposal_status=SpeakerProposal.PROPOSAL_PENDING + camp=self.camp, proposal_status=SpeakerProposal.PROPOSAL_PENDING ) def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) - context['eventproposals'] = EventProposal.objects.filter( - track__camp=self.camp, - proposal_status=EventProposal.PROPOSAL_PENDING + context["eventproposals"] = EventProposal.objects.filter( + track__camp=self.camp, proposal_status=EventProposal.PROPOSAL_PENDING ) return context @@ -102,6 +104,7 @@ class ProposalManageBaseView(CampViewMixin, ContentTeamPermissionMixin, UpdateVi """ This class contains the shared logic between SpeakerProposalManageView and EventProposalManageView """ + fields = [] def form_valid(self, form): @@ -109,21 +112,24 @@ class ProposalManageBaseView(CampViewMixin, ContentTeamPermissionMixin, UpdateVi We have two submit buttons in this form, Approve and Reject """ logger.debug(form.data) - if 'approve' in form.data: + if "approve" in form.data: # approve button was pressed form.instance.mark_as_approved(self.request) - elif 'reject' in form.data: + elif "reject" in form.data: # reject button was pressed form.instance.mark_as_rejected(self.request) else: messages.error(self.request, "Unknown submit action") - return redirect(reverse('backoffice:manage_proposals', kwargs={'camp_slug': self.camp.slug})) + return redirect( + reverse("backoffice:manage_proposals", kwargs={"camp_slug": self.camp.slug}) + ) class SpeakerProposalManageView(ProposalManageBaseView): """ This view allows an admin to approve/reject SpeakerProposals """ + model = SpeakerProposal template_name = "manage_speakerproposal.html" @@ -132,6 +138,7 @@ class EventProposalManageView(ProposalManageBaseView): """ This view allows an admin to approve/reject EventProposals """ + model = EventProposal template_name = "manage_eventproposal.html" @@ -140,34 +147,34 @@ class MerchandiseOrdersView(CampViewMixin, OrgaTeamPermissionMixin, ListView): template_name = "orders_merchandise.html" def get_queryset(self, **kwargs): - camp_prefix = 'BornHack {}'.format(timezone.now().year) + camp_prefix = "BornHack {}".format(timezone.now().year) - return OrderProductRelation.objects.filter( - handed_out=False, - order__paid=True, - order__refunded=False, - order__cancelled=False, - product__category__name='Merchandise', - ).filter( - product__name__startswith=camp_prefix - ).order_by('order') + return ( + OrderProductRelation.objects.filter( + handed_out=False, + order__paid=True, + order__refunded=False, + order__cancelled=False, + product__category__name="Merchandise", + ) + .filter(product__name__startswith=camp_prefix) + .order_by("order") + ) class MerchandiseToOrderView(CampViewMixin, OrgaTeamPermissionMixin, TemplateView): template_name = "merchandise_to_order.html" def get_context_data(self, **kwargs): - camp_prefix = 'BornHack {}'.format(timezone.now().year) + camp_prefix = "BornHack {}".format(timezone.now().year) order_relations = OrderProductRelation.objects.filter( handed_out=False, order__paid=True, order__refunded=False, order__cancelled=False, - product__category__name='Merchandise', - ).filter( - product__name__startswith=camp_prefix - ) + product__category__name="Merchandise", + ).filter(product__name__startswith=camp_prefix) merchandise_orders = {} for relation in order_relations: @@ -178,7 +185,7 @@ class MerchandiseToOrderView(CampViewMixin, OrgaTeamPermissionMixin, TemplateVie merchandise_orders[relation.product.name] = relation.quantity context = super().get_context_data(**kwargs) - context['merchandise'] = merchandise_orders + context["merchandise"] = merchandise_orders return context @@ -186,34 +193,34 @@ class VillageOrdersView(CampViewMixin, OrgaTeamPermissionMixin, ListView): template_name = "orders_village.html" def get_queryset(self, **kwargs): - camp_prefix = 'BornHack {}'.format(timezone.now().year) + camp_prefix = "BornHack {}".format(timezone.now().year) - return OrderProductRelation.objects.filter( - handed_out=False, - order__paid=True, - order__refunded=False, - order__cancelled=False, - product__category__name='Villages', - ).filter( - product__name__startswith=camp_prefix - ).order_by('order') + return ( + OrderProductRelation.objects.filter( + handed_out=False, + order__paid=True, + order__refunded=False, + order__cancelled=False, + product__category__name="Villages", + ) + .filter(product__name__startswith=camp_prefix) + .order_by("order") + ) class VillageToOrderView(CampViewMixin, OrgaTeamPermissionMixin, TemplateView): template_name = "village_to_order.html" def get_context_data(self, **kwargs): - camp_prefix = 'BornHack {}'.format(timezone.now().year) + camp_prefix = "BornHack {}".format(timezone.now().year) order_relations = OrderProductRelation.objects.filter( handed_out=False, order__paid=True, order__refunded=False, order__cancelled=False, - product__category__name='Villages', - ).filter( - product__name__startswith=camp_prefix - ) + product__category__name="Villages", + ).filter(product__name__startswith=camp_prefix) village_orders = {} for relation in order_relations: @@ -224,7 +231,7 @@ class VillageToOrderView(CampViewMixin, OrgaTeamPermissionMixin, TemplateView): village_orders[relation.product.name] = relation.quantity context = super().get_context_data(**kwargs) - context['village'] = village_orders + context["village"] = village_orders return context @@ -234,27 +241,28 @@ class VillageToOrderView(CampViewMixin, OrgaTeamPermissionMixin, TemplateView): class ChainListView(CampViewMixin, EconomyTeamPermissionMixin, ListView): model = Chain - template_name = 'chain_list_backoffice.html' + template_name = "chain_list_backoffice.html" class ChainDetailView(CampViewMixin, EconomyTeamPermissionMixin, DetailView): model = Chain - template_name = 'chain_detail_backoffice.html' - slug_url_kwarg = 'chain_slug' + template_name = "chain_detail_backoffice.html" + slug_url_kwarg = "chain_slug" class CredebtorDetailView(CampViewMixin, EconomyTeamPermissionMixin, DetailView): model = Credebtor - template_name = 'credebtor_detail_backoffice.html' - slug_url_kwarg = 'credebtor_slug' + template_name = "credebtor_detail_backoffice.html" + slug_url_kwarg = "credebtor_slug" ################################ ########### EXPENSES ########### + class ExpenseListView(CampViewMixin, EconomyTeamPermissionMixin, ListView): model = Expense - template_name = 'expense_list_backoffice.html' + template_name = "expense_list_backoffice.html" def get_queryset(self, **kwargs): """ @@ -268,46 +276,53 @@ class ExpenseListView(CampViewMixin, EconomyTeamPermissionMixin, ListView): Include unapproved expenses seperately """ context = super().get_context_data(**kwargs) - context['unapproved_expenses'] = Expense.objects.filter(camp=self.camp, approved__isnull=True) + context["unapproved_expenses"] = Expense.objects.filter( + camp=self.camp, approved__isnull=True + ) return context class ExpenseDetailView(CampViewMixin, EconomyTeamPermissionMixin, UpdateView): model = Expense - template_name = 'expense_detail_backoffice.html' - fields = ['notes'] + template_name = "expense_detail_backoffice.html" + fields = ["notes"] def form_valid(self, form): """ We have two submit buttons in this form, Approve and Reject """ expense = form.save() - if 'approve' in form.data: + if "approve" in form.data: # approve button was pressed expense.approve(self.request) - elif 'reject' in form.data: + elif "reject" in form.data: # reject button was pressed expense.reject(self.request) else: messages.error(self.request, "Unknown submit action") - return redirect(reverse('backoffice:expense_list', kwargs={'camp_slug': self.camp.slug})) + return redirect( + reverse("backoffice:expense_list", kwargs={"camp_slug": self.camp.slug}) + ) ###################################### ########### REIMBURSEMENTS ########### + class ReimbursementListView(CampViewMixin, EconomyTeamPermissionMixin, ListView): model = Reimbursement - template_name = 'reimbursement_list_backoffice.html' + template_name = "reimbursement_list_backoffice.html" class ReimbursementDetailView(CampViewMixin, EconomyTeamPermissionMixin, DetailView): model = Reimbursement - template_name = 'reimbursement_detail_backoffice.html' + template_name = "reimbursement_detail_backoffice.html" -class ReimbursementCreateUserSelectView(CampViewMixin, EconomyTeamPermissionMixin, ListView): - template_name = 'reimbursement_create_userselect.html' +class ReimbursementCreateUserSelectView( + CampViewMixin, EconomyTeamPermissionMixin, ListView +): + template_name = "reimbursement_create_userselect.html" def get_queryset(self): queryset = User.objects.filter( @@ -316,20 +331,22 @@ class ReimbursementCreateUserSelectView(CampViewMixin, EconomyTeamPermissionMixi reimbursement__isnull=True, paid_by_bornhack=False, approved=True, - ).values_list('user', flat=True).distinct() + ) + .values_list("user", flat=True) + .distinct() ) return queryset class ReimbursementCreateView(CampViewMixin, EconomyTeamPermissionMixin, CreateView): model = Reimbursement - template_name = 'reimbursement_create.html' - fields = ['notes', 'paid'] + template_name = "reimbursement_create.html" + fields = ["notes", "paid"] def dispatch(self, request, *args, **kwargs): """ Get the user from kwargs """ print("inside dispatch() with method %s" % request.method) - self.reimbursement_user = get_object_or_404(User, pk=kwargs['user_id']) + self.reimbursement_user = get_object_or_404(User, pk=kwargs["user_id"]) # get response now so we have self.camp available below response = super().dispatch(request, *args, **kwargs) @@ -339,21 +356,27 @@ class ReimbursementCreateView(CampViewMixin, EconomyTeamPermissionMixin, CreateV def get(self, request, *args, **kwargs): # does this user have any approved and un-reimbursed expenses? - if not self.reimbursement_user.expenses.filter(reimbursement__isnull=True, approved=True, paid_by_bornhack=False): - messages.error(request, "This user has no approved and unreimbursed expenses!") - return(redirect(reverse('backoffice:index', kwargs={'camp_slug': self.camp.slug}))) + if not self.reimbursement_user.expenses.filter( + reimbursement__isnull=True, approved=True, paid_by_bornhack=False + ): + messages.error( + request, "This user has no approved and unreimbursed expenses!" + ) + return redirect( + reverse("backoffice:index", kwargs={"camp_slug": self.camp.slug}) + ) return super().get(request, *args, **kwargs) def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) - context['expenses'] = Expense.objects.filter( + context["expenses"] = Expense.objects.filter( user=self.reimbursement_user, approved=True, reimbursement__isnull=True, paid_by_bornhack=False, ) - context['total_amount'] = context['expenses'].aggregate(Sum('amount')) - context['reimbursement_user'] = self.reimbursement_user + context["total_amount"] = context["expenses"].aggregate(Sum("amount")) + context["reimbursement_user"] = self.reimbursement_user return context def form_valid(self, form): @@ -361,17 +384,34 @@ class ReimbursementCreateView(CampViewMixin, EconomyTeamPermissionMixin, CreateV Set user and camp for the Reimbursement before saving """ # get the expenses for this user - expenses = Expense.objects.filter(user=self.reimbursement_user, approved=True, reimbursement__isnull=True, paid_by_bornhack=False) + expenses = Expense.objects.filter( + user=self.reimbursement_user, + approved=True, + reimbursement__isnull=True, + paid_by_bornhack=False, + ) if not expenses: messages.error(self.request, "No expenses found") - return redirect(reverse('backoffice:reimbursement_list', kwargs={'camp_slug': self.camp.slug})) + return redirect( + reverse( + "backoffice:reimbursement_list", + kwargs={"camp_slug": self.camp.slug}, + ) + ) # get the Economy team for this camp try: - economyteam = Team.objects.get(camp=self.camp, name=settings.ECONOMYTEAM_NAME) + economyteam = Team.objects.get( + camp=self.camp, name=settings.ECONOMYTEAM_NAME + ) except Team.DoesNotExist: messages.error(self.request, "No economy team found") - return redirect(reverse('backoffice:reimbursement_list', kwargs={'camp_slug': self.camp.slug})) + return redirect( + reverse( + "backoffice:reimbursement_list", + kwargs={"camp_slug": self.camp.slug}, + ) + ) # create reimbursement in database reimbursement = form.save(commit=False) @@ -387,50 +427,83 @@ class ReimbursementCreateView(CampViewMixin, EconomyTeamPermissionMixin, CreateV # create expense for this reimbursement expense = Expense() - expense.camp=self.camp - expense.user=self.request.user - expense.amount=reimbursement.amount - expense.description="Payment of reimbursement %s to %s" % (reimbursement.pk, reimbursement.reimbursement_user) - expense.paid_by_bornhack=True - expense.responsible_team=economyteam - expense.approved=True - expense.reimbursement=reimbursement - expense.invoice_date=timezone.now() - expense.creditor=Credebtor.objects.get(name='Reimbursement') - expense.invoice.save("na.jpg", File(open(os.path.join(settings.DJANGO_BASE_PATH, "static_src/img/na.jpg"), "rb"))) + expense.camp = self.camp + expense.user = self.request.user + expense.amount = reimbursement.amount + expense.description = "Payment of reimbursement %s to %s" % ( + reimbursement.pk, + reimbursement.reimbursement_user, + ) + expense.paid_by_bornhack = True + expense.responsible_team = economyteam + expense.approved = True + expense.reimbursement = reimbursement + expense.invoice_date = timezone.now() + expense.creditor = Credebtor.objects.get(name="Reimbursement") + expense.invoice.save( + "na.jpg", + File( + open( + os.path.join(settings.DJANGO_BASE_PATH, "static_src/img/na.jpg"), + "rb", + ) + ), + ) expense.save() - messages.success(self.request, "Reimbursement %s has been created with invoice_date %s" % (reimbursement.pk, timezone.now())) - return redirect(reverse('backoffice:reimbursement_detail', kwargs={'camp_slug': self.camp.slug, 'pk': reimbursement.pk})) + messages.success( + self.request, + "Reimbursement %s has been created with invoice_date %s" + % (reimbursement.pk, timezone.now()), + ) + return redirect( + reverse( + "backoffice:reimbursement_detail", + kwargs={"camp_slug": self.camp.slug, "pk": reimbursement.pk}, + ) + ) class ReimbursementUpdateView(CampViewMixin, EconomyTeamPermissionMixin, UpdateView): model = Reimbursement - template_name = 'reimbursement_form.html' - fields = ['notes', 'paid'] + template_name = "reimbursement_form.html" + fields = ["notes", "paid"] def get_success_url(self): - return reverse('backoffice:reimbursement_detail', kwargs={'camp_slug': self.camp.slug, 'pk': self.get_object().pk}) + return reverse( + "backoffice:reimbursement_detail", + kwargs={"camp_slug": self.camp.slug, "pk": self.get_object().pk}, + ) + class ReimbursementDeleteView(CampViewMixin, EconomyTeamPermissionMixin, DeleteView): model = Reimbursement - template_name = 'reimbursement_delete.html' - fields = ['notes', 'paid'] + template_name = "reimbursement_delete.html" + fields = ["notes", "paid"] def dispatch(self, request, *args, **kwargs): response = super().dispatch(request, *args, **kwargs) if self.get_object().paid: - messages.error(request, "This reimbursement has already been paid so it cannot be deleted") - return redirect(reverse('backoffice:reimbursement_list', kwargs={'camp_slug': self.camp.slug})) + messages.error( + request, + "This reimbursement has already been paid so it cannot be deleted", + ) + return redirect( + reverse( + "backoffice:reimbursement_list", + kwargs={"camp_slug": self.camp.slug}, + ) + ) return response ################################ ########### REVENUES ########### + class RevenueListView(CampViewMixin, EconomyTeamPermissionMixin, ListView): model = Revenue - template_name = 'revenue_list_backoffice.html' + template_name = "revenue_list_backoffice.html" def get_queryset(self, **kwargs): """ @@ -444,27 +517,30 @@ class RevenueListView(CampViewMixin, EconomyTeamPermissionMixin, ListView): Include unapproved revenues seperately """ context = super().get_context_data(**kwargs) - context['unapproved_revenues'] = Revenue.objects.filter(camp=self.camp, approved__isnull=True) + context["unapproved_revenues"] = Revenue.objects.filter( + camp=self.camp, approved__isnull=True + ) return context class RevenueDetailView(CampViewMixin, EconomyTeamPermissionMixin, UpdateView): model = Revenue - template_name = 'revenue_detail_backoffice.html' - fields = ['notes'] + template_name = "revenue_detail_backoffice.html" + fields = ["notes"] def form_valid(self, form): """ We have two submit buttons in this form, Approve and Reject """ revenue = form.save() - if 'approve' in form.data: + if "approve" in form.data: # approve button was pressed revenue.approve(self.request) - elif 'reject' in form.data: + elif "reject" in form.data: # reject button was pressed revenue.reject(self.request) else: messages.error(self.request, "Unknown submit action") - return redirect(reverse('backoffice:revenue_list', kwargs={'camp_slug': self.camp.slug})) - + return redirect( + reverse("backoffice:revenue_list", kwargs={"camp_slug": self.camp.slug}) + ) diff --git a/src/bar/admin.py b/src/bar/admin.py index ee04ed0f..4fd383da 100644 --- a/src/bar/admin.py +++ b/src/bar/admin.py @@ -9,5 +9,5 @@ class ProductCategoryAdmin(admin.ModelAdmin): @admin.register(Product) class ProductAdmin(admin.ModelAdmin): - list_display = ['name', 'price', 'category', 'in_stock'] - list_editable = ['in_stock'] + list_display = ["name", "price", "category", "in_stock"] + list_editable = ["in_stock"] diff --git a/src/bar/apps.py b/src/bar/apps.py index e24009a8..3b398f44 100644 --- a/src/bar/apps.py +++ b/src/bar/apps.py @@ -2,4 +2,4 @@ from django.apps import AppConfig class BarConfig(AppConfig): - name = 'bar' + name = "bar" diff --git a/src/bar/migrations/0001_initial.py b/src/bar/migrations/0001_initial.py index 3712a867..e7e39432 100644 --- a/src/bar/migrations/0001_initial.py +++ b/src/bar/migrations/0001_initial.py @@ -10,36 +10,55 @@ class Migration(migrations.Migration): initial = True - dependencies = [ - ('camps', '0022_camp_colour'), - ] + dependencies = [("camps", "0022_camp_colour")] operations = [ migrations.CreateModel( - name='Product', + name="Product", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('name', models.CharField(max_length=255)), - ('price', models.IntegerField()), - ('in_stock', models.BooleanField(default=True)), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("name", models.CharField(max_length=255)), + ("price", models.IntegerField()), + ("in_stock", models.BooleanField(default=True)), ], ), migrations.CreateModel( - name='ProductCategory', + name="ProductCategory", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('created', models.DateTimeField(auto_now_add=True)), - ('updated', models.DateTimeField(auto_now=True)), - ('name', models.CharField(max_length=255)), - ('camp', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='camps.Camp')), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("created", models.DateTimeField(auto_now_add=True)), + ("updated", models.DateTimeField(auto_now=True)), + ("name", models.CharField(max_length=255)), + ( + "camp", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, to="camps.Camp" + ), + ), ], - options={ - 'abstract': False, - }, + options={"abstract": False}, ), migrations.AddField( - model_name='product', - name='category', - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='bar.ProductCategory'), + model_name="product", + name="category", + field=models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, to="bar.ProductCategory" + ), ), ] diff --git a/src/bar/migrations/0002_auto_20170916_2128.py b/src/bar/migrations/0002_auto_20170916_2128.py index dcaaf778..c4796e43 100644 --- a/src/bar/migrations/0002_auto_20170916_2128.py +++ b/src/bar/migrations/0002_auto_20170916_2128.py @@ -8,22 +8,20 @@ import django.db.models.deletion class Migration(migrations.Migration): - dependencies = [ - ('bar', '0001_initial'), - ] + dependencies = [("bar", "0001_initial")] operations = [ + migrations.AlterModelOptions(name="product", options={"ordering": ("name",)}), migrations.AlterModelOptions( - name='product', - options={'ordering': ('name',)}, - ), - migrations.AlterModelOptions( - name='productcategory', - options={'ordering': ('name',)}, + name="productcategory", options={"ordering": ("name",)} ), migrations.AlterField( - model_name='product', - name='category', - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='products', to='bar.ProductCategory'), + model_name="product", + name="category", + field=models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="products", + to="bar.ProductCategory", + ), ), ] diff --git a/src/bar/migrations/0003_auto_20180318_0906.py b/src/bar/migrations/0003_auto_20180318_0906.py index 1c600524..eb353e6d 100644 --- a/src/bar/migrations/0003_auto_20180318_0906.py +++ b/src/bar/migrations/0003_auto_20180318_0906.py @@ -8,19 +8,23 @@ import django.db.models.deletion class Migration(migrations.Migration): - dependencies = [ - ('bar', '0002_auto_20170916_2128'), - ] + dependencies = [("bar", "0002_auto_20170916_2128")] operations = [ migrations.AlterField( - model_name='product', - name='category', - field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='products', to='bar.ProductCategory'), + model_name="product", + name="category", + field=models.ForeignKey( + on_delete=django.db.models.deletion.PROTECT, + related_name="products", + to="bar.ProductCategory", + ), ), migrations.AlterField( - model_name='productcategory', - name='camp', - field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='camps.Camp'), + model_name="productcategory", + name="camp", + field=models.ForeignKey( + on_delete=django.db.models.deletion.PROTECT, to="camps.Camp" + ), ), ] diff --git a/src/bar/models.py b/src/bar/models.py index ce82f445..30d315cf 100644 --- a/src/bar/models.py +++ b/src/bar/models.py @@ -4,7 +4,7 @@ from utils.models import CampRelatedModel class ProductCategory(CampRelatedModel): name = models.CharField(max_length=255) - camp = models.ForeignKey('camps.Camp', on_delete=models.PROTECT) + camp = models.ForeignKey("camps.Camp", on_delete=models.PROTECT) def __str__(self): return self.name @@ -17,9 +17,7 @@ class Product(models.Model): name = models.CharField(max_length=255) price = models.IntegerField() category = models.ForeignKey( - ProductCategory, - related_name="products", - on_delete=models.PROTECT + ProductCategory, related_name="products", on_delete=models.PROTECT ) in_stock = models.BooleanField(default=True) diff --git a/src/bornhack/asgi.py b/src/bornhack/asgi.py index 80b31c0c..71715143 100644 --- a/src/bornhack/asgi.py +++ b/src/bornhack/asgi.py @@ -9,4 +9,3 @@ from channels.routing import get_default_application os.environ.setdefault("DJANGO_SETTINGS_MODULE", "bornhack.settings") django.setup() application = get_default_application() - diff --git a/src/bornhack/routing.py b/src/bornhack/routing.py index d426b02c..67c41503 100644 --- a/src/bornhack/routing.py +++ b/src/bornhack/routing.py @@ -5,10 +5,10 @@ from channels.auth import AuthMiddlewareStack from program.consumers import ScheduleConsumer -application = ProtocolTypeRouter({ - "websocket": AuthMiddlewareStack( - URLRouter([ - url(r"^schedule/", ScheduleConsumer) - ]) - ) -}) +application = ProtocolTypeRouter( + { + "websocket": AuthMiddlewareStack( + URLRouter([url(r"^schedule/", ScheduleConsumer)]) + ) + } +) diff --git a/src/bornhack/schema.py b/src/bornhack/schema.py index 106de42f..87822abc 100644 --- a/src/bornhack/schema.py +++ b/src/bornhack/schema.py @@ -11,19 +11,17 @@ from program.schema import ProgramQuery class CampNode(DjangoObjectType): class Meta: model = Camp - interfaces = (relay.Node, ) - filter_fields = { - 'title': ['icontains', 'iexact'], - } + interfaces = (relay.Node,) + filter_fields = {"title": ["icontains", "iexact"]} only_fields = ( - 'title', - 'slug', - 'tagline', - 'shortslug', - 'buildup', - 'camp', - 'teardown', - 'colour', + "title", + "slug", + "tagline", + "shortslug", + "buildup", + "camp", + "teardown", + "colour", ) def resolve_buildup(self, info): diff --git a/src/bornhack/settings.py b/src/bornhack/settings.py index 980c5dcc..24834d92 100644 --- a/src/bornhack/settings.py +++ b/src/bornhack/settings.py @@ -2,6 +2,7 @@ import os from .environment_settings import * + def local_dir(entry): return os.path.join(os.path.dirname(os.path.dirname(__file__)), entry) diff --git a/src/bornhack/urls.py b/src/bornhack/urls.py index 9b411f1f..58dacb0f 100644 --- a/src/bornhack/urls.py +++ b/src/bornhack/urls.py @@ -19,206 +19,115 @@ from villages.views import * admin.site.login = login_required(admin.site.login) urlpatterns = [ - path('profile/', include('allauth.urls')), - path('profile/', include('allauth_2fa.urls')), - path('profile/', include('profiles.urls', namespace='profiles')), + path("profile/", include("allauth.urls")), + path("profile/", include("allauth_2fa.urls")), + path("profile/", include("profiles.urls", namespace="profiles")), + path("tickets/", include("tickets.urls", namespace="tickets")), + path("shop/", include("shop.urls", namespace="shop")), + path("news/", include("news.urls", namespace="news")), path( - 'tickets/', - include('tickets.urls', namespace='tickets') + "contact/", TemplateView.as_view(template_name="contact.html"), name="contact" + ), + path("conduct/", TemplateView.as_view(template_name="coc.html"), name="conduct"), + path("login/", LoginView.as_view(), name="account_login"), + path("logout/", LogoutView.as_view(), name="account_logout"), + path( + "privacy-policy/", + TemplateView.as_view(template_name="legal/privacy_policy.html"), + name="privacy-policy", ), path( - 'shop/', - include('shop.urls', namespace='shop') + "general-terms-and-conditions/", + TemplateView.as_view(template_name="legal/general_terms_and_conditions.html"), + name="general-terms", ), - path( - 'news/', - include('news.urls', namespace='news') - ), - path( - 'contact/', - TemplateView.as_view(template_name='contact.html'), - name='contact' - ), - path( - 'conduct/', - TemplateView.as_view(template_name='coc.html'), - name='conduct' - ), - path( - 'login/', - LoginView.as_view(), - name='account_login', - ), - path( - 'logout/', - LogoutView.as_view(), - name='account_logout', - ), - path( - 'privacy-policy/', - TemplateView.as_view(template_name='legal/privacy_policy.html'), - name='privacy-policy' - ), - path( - 'general-terms-and-conditions/', - TemplateView.as_view(template_name='legal/general_terms_and_conditions.html'), - name='general-terms' - ), - path('admin/', admin.site.urls), - + path("admin/", admin.site.urls), # We don't need CSRF checks for the API - path('api/', csrf_exempt(GraphQLView.as_view(graphiql=True))), - - path( - 'camps/', - CampListView.as_view(), - name='camp_list' - ), - - path( - 'token/', - include('tokens.urls', namespace='tokens'), - ), - + path("api/", csrf_exempt(GraphQLView.as_view(graphiql=True))), + path("camps/", CampListView.as_view(), name="camp_list"), + path("token/", include("tokens.urls", namespace="tokens")), # camp redirect views here - path( - '', + "", CampRedirectView.as_view(), - kwargs={'page': 'camp_detail'}, - name='camp_detail_redirect', + kwargs={"page": "camp_detail"}, + name="camp_detail_redirect", ), - path( - 'program/', + "program/", CampRedirectView.as_view(), - kwargs={'page': 'schedule_index'}, - name='schedule_index_redirect', + kwargs={"page": "schedule_index"}, + name="schedule_index_redirect", ), - path( - 'info/', + "info/", CampRedirectView.as_view(), - kwargs={'page': 'info'}, - name='info_redirect', + kwargs={"page": "info"}, + name="info_redirect", ), - path( - 'sponsors/', + "sponsors/", CampRedirectView.as_view(), - kwargs={'page': 'sponsors'}, - name='sponsors_redirect', + kwargs={"page": "sponsors"}, + name="sponsors_redirect", ), - path( - 'villages/', + "villages/", CampRedirectView.as_view(), - kwargs={'page': 'village_list'}, - name='village_list_redirect', + kwargs={"page": "village_list"}, + name="village_list_redirect", ), - - path( - 'people/', - PeopleView.as_view(), - name='people', - ), - + path("people/", PeopleView.as_view(), name="people"), # camp specific urls below here - path( - '/', include([ - path( - '', - CampDetailView.as_view(), - name='camp_detail' - ), - - path( - 'info/', - CampInfoView.as_view(), - name='info' - ), - - path( - 'program/', - include('program.urls', namespace='program'), - ), - - path( - 'sponsors/', - SponsorsView.as_view(), - name='sponsors' - ), - - path( - 'bar/menu/', - MenuView.as_view(), - name='menu' - ), - - path( - 'villages/', include([ - path( - '', - VillageListView.as_view(), - name='village_list' + "/", + include( + [ + path("", CampDetailView.as_view(), name="camp_detail"), + path("info/", CampInfoView.as_view(), name="info"), + path("program/", include("program.urls", namespace="program")), + path("sponsors/", SponsorsView.as_view(), name="sponsors"), + path("bar/menu/", MenuView.as_view(), name="menu"), + path( + "villages/", + include( + [ + path("", VillageListView.as_view(), name="village_list"), + path( + "create/", + VillageCreateView.as_view(), + name="village_create", + ), + path( + "/delete/", + VillageDeleteView.as_view(), + name="village_delete", + ), + path( + "/edit/", + VillageUpdateView.as_view(), + name="village_update", + ), + # this has to be the last url in the list + path( + "/", + VillageDetailView.as_view(), + name="village_detail", + ), + ] ), - path( - 'create/', - VillageCreateView.as_view(), - name='village_create' - ), - path( - '/delete/', - VillageDeleteView.as_view(), - name='village_delete' - ), - path( - '/edit/', - VillageUpdateView.as_view(), - name='village_update' - ), - # this has to be the last url in the list - path( - '/', - VillageDetailView.as_view(), - name='village_detail' - ), - ]) - ), - - path( - 'teams/', - include('teams.urls', namespace='teams') - ), - - path( - 'rideshare/', - include('rideshare.urls', namespace='rideshare') - ), - - path( - 'backoffice/', - include('backoffice.urls', namespace='backoffice') - ), - - path( - 'feedback/', - FeedbackCreate.as_view(), - name='feedback' - ), - - path( - 'economy/', - include('economy.urls', namespace='economy'), - ), - ]) - ) + ), + path("teams/", include("teams.urls", namespace="teams")), + path("rideshare/", include("rideshare.urls", namespace="rideshare")), + path("backoffice/", include("backoffice.urls", namespace="backoffice")), + path("feedback/", FeedbackCreate.as_view(), name="feedback"), + path("economy/", include("economy.urls", namespace="economy")), + ] + ), + ), ] if settings.DEBUG: import debug_toolbar - urlpatterns = [ - path('__debug__/', include(debug_toolbar.urls)), - ] + urlpatterns + urlpatterns = [path("__debug__/", include(debug_toolbar.urls))] + urlpatterns diff --git a/src/camps/admin.py b/src/camps/admin.py index f777d688..689f4d21 100644 --- a/src/camps/admin.py +++ b/src/camps/admin.py @@ -5,4 +5,3 @@ from . import models @admin.register(models.Camp) class CampModelAdmin(admin.ModelAdmin): pass - diff --git a/src/camps/context_processors.py b/src/camps/context_processors.py index bedd7ee2..cc66670b 100644 --- a/src/camps/context_processors.py +++ b/src/camps/context_processors.py @@ -7,19 +7,15 @@ def camp(request): Return it after adding the slug to request.session along with a "camps" queryset containing all camps (used to build the menu and such) """ - if request.resolver_match and 'camp_slug' in request.resolver_match.kwargs: + if request.resolver_match and "camp_slug" in request.resolver_match.kwargs: try: - camp = Camp.objects.get(slug=request.resolver_match.kwargs['camp_slug']) - request.session['campslug'] = camp.slug + camp = Camp.objects.get(slug=request.resolver_match.kwargs["camp_slug"]) + request.session["campslug"] = camp.slug except Camp.DoesNotExist: - request.session['campslug'] = None + request.session["campslug"] = None camp = None else: - request.session['campslug'] = None + request.session["campslug"] = None camp = None - return { - 'camps': Camp.objects.all().order_by('-camp'), - 'camp': camp - } - + return {"camps": Camp.objects.all().order_by("-camp"), "camp": camp} diff --git a/src/camps/management/commands/createcamp.py b/src/camps/management/commands/createcamp.py index 5eb66365..4a5ff757 100644 --- a/src/camps/management/commands/createcamp.py +++ b/src/camps/management/commands/createcamp.py @@ -6,64 +6,58 @@ import os class Command(BaseCommand): - help = 'Creates html files needed for a camp' + help = "Creates html files needed for a camp" def add_arguments(self, parser): - parser.add_argument('camp_slug', type=str) + parser.add_argument("camp_slug", type=str) def output(self, message): - self.stdout.write('{}: {}'.format( - timezone.now().strftime("%Y-%m-%d %H:%M:%S"), - message - ) + self.stdout.write( + "{}: {}".format(timezone.now().strftime("%Y-%m-%d %H:%M:%S"), message) ) def local_dir(self, entry): - return os.path.join( - settings.DJANGO_BASE_PATH, - entry - ) + return os.path.join(settings.DJANGO_BASE_PATH, entry) def handle(self, *args, **options): # files to create, relative to DJANGO_BASE_PATH - files = [ - 'camps/templates/{camp_slug}_camp_detail.html', - ] + files = ["camps/templates/{camp_slug}_camp_detail.html"] # directories to create, relative to DJANGO_BASE_PATH - dirs = [ - 'static_src/img/{camp_slug}/logo' - ] + dirs = ["static_src/img/{camp_slug}/logo"] - camp_slug = options['camp_slug'] + camp_slug = options["camp_slug"] for _file in files: path = self.local_dir(_file.format(camp_slug=camp_slug)) if os.path.isfile(_file): - self.output('File {} exists...'.format(path)) + self.output("File {} exists...".format(path)) else: - self.output('Creating {}'.format(path)) - with open(path, mode='w', encoding='utf-8') as f: + self.output("Creating {}".format(path)) + with open(path, mode="w", encoding="utf-8") as f: f.write(_file.format(camp_slug=camp_slug)) for _dir in dirs: path = self.local_dir(_file.format(camp_slug=camp_slug)) if os.path.exists(path): - self.output('Path {} exists...'.format(path)) + self.output("Path {} exists...".format(path)) else: - self.output('Creating {}'.format(path)) + self.output("Creating {}".format(path)) os.mkdir(path, mode=0o644) - self.output('All there is left is to create:') + self.output("All there is left is to create:") self.output( self.local_dir( - 'static_src/img/{camp_slug}/logo/{camp_slug}-logo-large.png'.format(camp_slug=camp_slug) + "static_src/img/{camp_slug}/logo/{camp_slug}-logo-large.png".format( + camp_slug=camp_slug + ) ) ) self.output( self.local_dir( - 'static_src/img/{camp_slug}/logo/{camp_slug}-logo-small.png'.format(camp_slug=camp_slug) + "static_src/img/{camp_slug}/logo/{camp_slug}-logo-small.png".format( + camp_slug=camp_slug + ) ) ) - diff --git a/src/camps/migrations/0001_initial.py b/src/camps/migrations/0001_initial.py index f715b265..f00a8c61 100644 --- a/src/camps/migrations/0001_initial.py +++ b/src/camps/migrations/0001_initial.py @@ -8,71 +8,196 @@ from django.conf import settings class Migration(migrations.Migration): - dependencies = [ - migrations.swappable_dependency(settings.AUTH_USER_MODEL), - ] + dependencies = [migrations.swappable_dependency(settings.AUTH_USER_MODEL)] operations = [ migrations.CreateModel( - name='Camp', + name="Camp", fields=[ - ('created', models.DateTimeField(auto_now_add=True)), - ('updated', models.DateTimeField(auto_now=True)), - ('uuid', models.UUIDField(default=uuid.uuid4, serialize=False, editable=False, primary_key=True)), - ('name', models.CharField(max_length=255, help_text='Name of the camp, ie. Bornhack.', verbose_name='Name')), - ('start', models.DateTimeField(help_text='When the camp starts.', unique=True, verbose_name='Start date')), - ('end', models.DateTimeField(help_text='When the camp ends.', unique=True, verbose_name='End date')), + ("created", models.DateTimeField(auto_now_add=True)), + ("updated", models.DateTimeField(auto_now=True)), + ( + "uuid", + models.UUIDField( + default=uuid.uuid4, + serialize=False, + editable=False, + primary_key=True, + ), + ), + ( + "name", + models.CharField( + max_length=255, + help_text="Name of the camp, ie. Bornhack.", + verbose_name="Name", + ), + ), + ( + "start", + models.DateTimeField( + help_text="When the camp starts.", + unique=True, + verbose_name="Start date", + ), + ), + ( + "end", + models.DateTimeField( + help_text="When the camp ends.", + unique=True, + verbose_name="End date", + ), + ), ], - options={ - 'verbose_name_plural': 'Camps', - 'verbose_name': 'Camp', - }, + options={"verbose_name_plural": "Camps", "verbose_name": "Camp"}, ), migrations.CreateModel( - name='Day', + name="Day", fields=[ - ('created', models.DateTimeField(auto_now_add=True)), - ('updated', models.DateTimeField(auto_now=True)), - ('uuid', models.UUIDField(default=uuid.uuid4, serialize=False, editable=False, primary_key=True)), - ('date', models.DateField(help_text='What date?', verbose_name='Date')), - ('camp', models.ForeignKey(on_delete=models.PROTECT, to='camps.Camp', help_text='Which camp does this day belong to.', verbose_name='Camp')), + ("created", models.DateTimeField(auto_now_add=True)), + ("updated", models.DateTimeField(auto_now=True)), + ( + "uuid", + models.UUIDField( + default=uuid.uuid4, + serialize=False, + editable=False, + primary_key=True, + ), + ), + ("date", models.DateField(help_text="What date?", verbose_name="Date")), + ( + "camp", + models.ForeignKey( + on_delete=models.PROTECT, + to="camps.Camp", + help_text="Which camp does this day belong to.", + verbose_name="Camp", + ), + ), ], - options={ - 'verbose_name_plural': 'Days', - 'verbose_name': 'Day', - }, + options={"verbose_name_plural": "Days", "verbose_name": "Day"}, ), migrations.CreateModel( - name='Expense', + name="Expense", fields=[ - ('created', models.DateTimeField(auto_now_add=True)), - ('updated', models.DateTimeField(auto_now=True)), - ('uuid', models.UUIDField(default=uuid.uuid4, serialize=False, editable=False, primary_key=True)), - ('description', models.CharField(max_length=255, help_text='What this expense covers.', verbose_name='Description')), - ('amount', models.DecimalField(max_digits=7, help_text='The amount of the expense.', verbose_name='Amount', decimal_places=2)), - ('currency', models.CharField(max_length=3, choices=[('btc', 'BTC'), ('dkk', 'DKK'), ('eur', 'EUR'), ('sek', 'SEK')], help_text='What currency the amount is in.', verbose_name='Currency')), - ('camp', models.ForeignKey(on_delete=models.PROTECT, to='camps.Camp', help_text='The camp to which this expense relates to.', verbose_name='Camp')), - ('covered_by', models.ForeignKey(on_delete=models.PROTECT, to=settings.AUTH_USER_MODEL, blank=True, help_text='Which user, if any, covered this expense.', verbose_name='Covered by', null=True)), + ("created", models.DateTimeField(auto_now_add=True)), + ("updated", models.DateTimeField(auto_now=True)), + ( + "uuid", + models.UUIDField( + default=uuid.uuid4, + serialize=False, + editable=False, + primary_key=True, + ), + ), + ( + "description", + models.CharField( + max_length=255, + help_text="What this expense covers.", + verbose_name="Description", + ), + ), + ( + "amount", + models.DecimalField( + max_digits=7, + help_text="The amount of the expense.", + verbose_name="Amount", + decimal_places=2, + ), + ), + ( + "currency", + models.CharField( + max_length=3, + choices=[ + ("btc", "BTC"), + ("dkk", "DKK"), + ("eur", "EUR"), + ("sek", "SEK"), + ], + help_text="What currency the amount is in.", + verbose_name="Currency", + ), + ), + ( + "camp", + models.ForeignKey( + on_delete=models.PROTECT, + to="camps.Camp", + help_text="The camp to which this expense relates to.", + verbose_name="Camp", + ), + ), + ( + "covered_by", + models.ForeignKey( + on_delete=models.PROTECT, + to=settings.AUTH_USER_MODEL, + blank=True, + help_text="Which user, if any, covered this expense.", + verbose_name="Covered by", + null=True, + ), + ), ], - options={ - 'verbose_name_plural': 'Expenses', - 'verbose_name': 'Expense', - }, + options={"verbose_name_plural": "Expenses", "verbose_name": "Expense"}, ), migrations.CreateModel( - name='Signup', + name="Signup", fields=[ - ('created', models.DateTimeField(auto_now_add=True)), - ('updated', models.DateTimeField(auto_now=True)), - ('uuid', models.UUIDField(default=uuid.uuid4, serialize=False, editable=False, primary_key=True)), - ('cost', models.DecimalField(default=1500.0, decimal_places=2, help_text='What the user should/is willing to pay for this signup.', verbose_name='Cost', max_digits=7)), - ('paid', models.BooleanField(help_text='Whether the user has paid.', verbose_name='Paid?', default=False)), - ('camp', models.ForeignKey(on_delete=models.PROTECT, to='camps.Camp', help_text='The camp that has been signed up for.', verbose_name='Camp')), - ('user', models.ForeignKey(on_delete=models.PROTECT, to=settings.AUTH_USER_MODEL, help_text='The user that has signed up.', verbose_name='User')), + ("created", models.DateTimeField(auto_now_add=True)), + ("updated", models.DateTimeField(auto_now=True)), + ( + "uuid", + models.UUIDField( + default=uuid.uuid4, + serialize=False, + editable=False, + primary_key=True, + ), + ), + ( + "cost", + models.DecimalField( + default=1500.0, + decimal_places=2, + help_text="What the user should/is willing to pay for this signup.", + verbose_name="Cost", + max_digits=7, + ), + ), + ( + "paid", + models.BooleanField( + help_text="Whether the user has paid.", + verbose_name="Paid?", + default=False, + ), + ), + ( + "camp", + models.ForeignKey( + on_delete=models.PROTECT, + to="camps.Camp", + help_text="The camp that has been signed up for.", + verbose_name="Camp", + ), + ), + ( + "user", + models.ForeignKey( + on_delete=models.PROTECT, + to=settings.AUTH_USER_MODEL, + help_text="The user that has signed up.", + verbose_name="User", + ), + ), ], - options={ - 'verbose_name_plural': 'Signups', - 'verbose_name': 'Signup', - }, + options={"verbose_name_plural": "Signups", "verbose_name": "Signup"}, ), ] diff --git a/src/camps/migrations/0002_auto_20160117_1718.py b/src/camps/migrations/0002_auto_20160117_1718.py index 7e5a4a63..347c60df 100644 --- a/src/camps/migrations/0002_auto_20160117_1718.py +++ b/src/camps/migrations/0002_auto_20160117_1718.py @@ -8,14 +8,18 @@ import django.db.models.deletion class Migration(migrations.Migration): - dependencies = [ - ('camps', '0001_initial'), - ] + dependencies = [("camps", "0001_initial")] operations = [ migrations.AlterField( - model_name='day', - name='camp', - field=models.ForeignKey(help_text='Which camp does this day belong to.', on_delete=django.db.models.deletion.CASCADE, related_name='days', to='camps.Camp', verbose_name='Camp'), - ), + model_name="day", + name="camp", + field=models.ForeignKey( + help_text="Which camp does this day belong to.", + on_delete=django.db.models.deletion.CASCADE, + related_name="days", + to="camps.Camp", + verbose_name="Camp", + ), + ) ] diff --git a/src/camps/migrations/0003_auto_20160422_2019.py b/src/camps/migrations/0003_auto_20160422_2019.py index 391b3097..132d2a02 100644 --- a/src/camps/migrations/0003_auto_20160422_2019.py +++ b/src/camps/migrations/0003_auto_20160422_2019.py @@ -7,20 +7,10 @@ from django.db import migrations class Migration(migrations.Migration): - dependencies = [ - ('camps', '0002_auto_20160117_1718'), - ] + dependencies = [("camps", "0002_auto_20160117_1718")] operations = [ - migrations.RemoveField( - model_name='signup', - name='camp', - ), - migrations.RemoveField( - model_name='signup', - name='user', - ), - migrations.DeleteModel( - name='Signup', - ), + migrations.RemoveField(model_name="signup", name="camp"), + migrations.RemoveField(model_name="signup", name="user"), + migrations.DeleteModel(name="Signup"), ] diff --git a/src/camps/migrations/0004_camp_ticket_sale_open.py b/src/camps/migrations/0004_camp_ticket_sale_open.py index 80e5d106..d5991f47 100644 --- a/src/camps/migrations/0004_camp_ticket_sale_open.py +++ b/src/camps/migrations/0004_camp_ticket_sale_open.py @@ -7,14 +7,16 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ - ('camps', '0003_auto_20160422_2019'), - ] + dependencies = [("camps", "0003_auto_20160422_2019")] operations = [ migrations.AddField( - model_name='camp', - name='ticket_sale_open', - field=models.BooleanField(default=False, help_text='Whether tickets are for sale or not.', verbose_name='Ticket sale open?'), - ), + model_name="camp", + name="ticket_sale_open", + field=models.BooleanField( + default=False, + help_text="Whether tickets are for sale or not.", + verbose_name="Ticket sale open?", + ), + ) ] diff --git a/src/camps/migrations/0005_auto_20160510_2011.py b/src/camps/migrations/0005_auto_20160510_2011.py index f361d396..95bc8cbb 100644 --- a/src/camps/migrations/0005_auto_20160510_2011.py +++ b/src/camps/migrations/0005_auto_20160510_2011.py @@ -7,18 +7,17 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ - ('camps', '0004_camp_ticket_sale_open'), - ] + dependencies = [("camps", "0004_camp_ticket_sale_open")] operations = [ - migrations.RemoveField( - model_name='camp', - name='ticket_sale_open', - ), + migrations.RemoveField(model_name="camp", name="ticket_sale_open"), migrations.AddField( - model_name='camp', - name='shop_open', - field=models.BooleanField(default=False, help_text='Whether the shop is open or not.', verbose_name='Shop open?'), + model_name="camp", + name="shop_open", + field=models.BooleanField( + default=False, + help_text="Whether the shop is open or not.", + verbose_name="Shop open?", + ), ), ] diff --git a/src/camps/migrations/0006_auto_20160804_1705.py b/src/camps/migrations/0006_auto_20160804_1705.py index cf2fd958..247e9a24 100644 --- a/src/camps/migrations/0006_auto_20160804_1705.py +++ b/src/camps/migrations/0006_auto_20160804_1705.py @@ -7,13 +7,15 @@ from django.db import migrations class Migration(migrations.Migration): - dependencies = [ - ('camps', '0005_auto_20160510_2011'), - ] + dependencies = [("camps", "0005_auto_20160510_2011")] operations = [ migrations.AlterModelOptions( - name='day', - options={'ordering': ['date'], 'verbose_name': 'Day', 'verbose_name_plural': 'Days'}, - ), + name="day", + options={ + "ordering": ["date"], + "verbose_name": "Day", + "verbose_name_plural": "Days", + }, + ) ] diff --git a/src/camps/migrations/0007_auto_20161212_1803.py b/src/camps/migrations/0007_auto_20161212_1803.py index 3dc81a7a..3d31a451 100644 --- a/src/camps/migrations/0007_auto_20161212_1803.py +++ b/src/camps/migrations/0007_auto_20161212_1803.py @@ -13,81 +13,101 @@ class Migration(migrations.Migration): dependencies = [ migrations.swappable_dependency(settings.AUTH_USER_MODEL), - ('camps', '0006_auto_20160804_1705'), + ("camps", "0006_auto_20160804_1705"), ] operations = [ - migrations.RemoveField( - model_name='day', - name='camp', - ), - migrations.RemoveField( - model_name='camp', - name='shop_open', - ), - migrations.RemoveField( - model_name='expense', - name='amount', - ), - migrations.RemoveField( - model_name='expense', - name='camp', - ), - migrations.RemoveField( - model_name='expense', - name='covered_by', - ), - migrations.RemoveField( - model_name='expense', - name='currency', - ), + migrations.RemoveField(model_name="day", name="camp"), + migrations.RemoveField(model_name="camp", name="shop_open"), + migrations.RemoveField(model_name="expense", name="amount"), + migrations.RemoveField(model_name="expense", name="camp"), + migrations.RemoveField(model_name="expense", name="covered_by"), + migrations.RemoveField(model_name="expense", name="currency"), migrations.AddField( - model_name='camp', - name='slug', - field=models.SlugField(default='', help_text=b'The url slug to use for this camp', verbose_name=b'Url Slug'), + model_name="camp", + name="slug", + field=models.SlugField( + default="", + help_text=b"The url slug to use for this camp", + verbose_name=b"Url Slug", + ), preserve_default=False, ), migrations.AddField( - model_name='expense', - name='dkk_amount', - field=models.DecimalField(decimal_places=2, default=0, help_text=b'The DKK amount of the expense.', max_digits=7, verbose_name=b'DKK Amount'), + model_name="expense", + name="dkk_amount", + field=models.DecimalField( + decimal_places=2, + default=0, + help_text=b"The DKK amount of the expense.", + max_digits=7, + verbose_name=b"DKK Amount", + ), preserve_default=False, ), migrations.AddField( - model_name='expense', - name='payment_time', - field=models.DateTimeField(default=datetime.datetime(2016, 12, 12, 18, 3, 10, 378604, tzinfo=utc), help_text=b'The date and time this expense was paid.', verbose_name=b'Expense date/time'), + model_name="expense", + name="payment_time", + field=models.DateTimeField( + default=datetime.datetime(2016, 12, 12, 18, 3, 10, 378604, tzinfo=utc), + help_text=b"The date and time this expense was paid.", + verbose_name=b"Expense date/time", + ), preserve_default=False, ), migrations.AddField( - model_name='expense', - name='receipt', - field=models.ImageField(default='', help_text=b'Upload a scan or image of the receipt', upload_to=b'', verbose_name=b'Image of receipt'), + model_name="expense", + name="receipt", + field=models.ImageField( + default="", + help_text=b"Upload a scan or image of the receipt", + upload_to=b"", + verbose_name=b"Image of receipt", + ), preserve_default=False, ), migrations.AddField( - model_name='expense', - name='refund_paid', - field=models.BooleanField(default=False, help_text=b'Has this expense been refunded to the user?', verbose_name=b'Refund paid?'), + model_name="expense", + name="refund_paid", + field=models.BooleanField( + default=False, + help_text=b"Has this expense been refunded to the user?", + verbose_name=b"Refund paid?", + ), ), migrations.AddField( - model_name='expense', - name='refund_user', - field=models.ForeignKey(blank=True, help_text=b'Which user, if any, covered this expense and should be refunded.', null=True, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL, verbose_name=b'Refund user'), + model_name="expense", + name="refund_user", + field=models.ForeignKey( + blank=True, + help_text=b"Which user, if any, covered this expense and should be refunded.", + null=True, + on_delete=django.db.models.deletion.CASCADE, + to=settings.AUTH_USER_MODEL, + verbose_name=b"Refund user", + ), ), migrations.AlterField( - model_name='camp', - name='end', - field=models.DateTimeField(help_text=b'When the camp ends.', verbose_name=b'End date'), + model_name="camp", + name="end", + field=models.DateTimeField( + help_text=b"When the camp ends.", verbose_name=b"End date" + ), ), migrations.AlterField( - model_name='camp', - name='name', - field=models.CharField(help_text=b'Name of the camp, ie. Bornhack 2016.', max_length=255, verbose_name=b'Name'), + model_name="camp", + name="name", + field=models.CharField( + help_text=b"Name of the camp, ie. Bornhack 2016.", + max_length=255, + verbose_name=b"Name", + ), ), migrations.AlterField( - model_name='camp', - name='start', - field=models.DateTimeField(help_text=b'When the camp starts.', verbose_name=b'Start date'), + model_name="camp", + name="start", + field=models.DateTimeField( + help_text=b"When the camp starts.", verbose_name=b"Start date" + ), ), ] diff --git a/src/camps/migrations/0008_delete_day.py b/src/camps/migrations/0008_delete_day.py index 3e6fc5c8..22bd0360 100644 --- a/src/camps/migrations/0008_delete_day.py +++ b/src/camps/migrations/0008_delete_day.py @@ -8,12 +8,8 @@ from django.db import migrations class Migration(migrations.Migration): dependencies = [ - ('program', '0010_auto_20161212_1809'), - ('camps', '0007_auto_20161212_1803'), + ("program", "0010_auto_20161212_1809"), + ("camps", "0007_auto_20161212_1803"), ] - operations = [ - migrations.DeleteModel( - name='Day', - ), - ] + operations = [migrations.DeleteModel(name="Day")] diff --git a/src/camps/migrations/0009_auto_20161220_1645.py b/src/camps/migrations/0009_auto_20161220_1645.py index 65bc33e4..02682fb2 100644 --- a/src/camps/migrations/0009_auto_20161220_1645.py +++ b/src/camps/migrations/0009_auto_20161220_1645.py @@ -9,31 +9,31 @@ from django.utils.timezone import utc class Migration(migrations.Migration): - dependencies = [ - ('camps', '0008_delete_day'), - ] + dependencies = [("camps", "0008_delete_day")] operations = [ + migrations.RenameField(model_name="camp", old_name="end", new_name="camp_end"), migrations.RenameField( - model_name='camp', - old_name='end', - new_name='camp_end', - ), - migrations.RenameField( - model_name='camp', - old_name='start', - new_name='camp_start', + model_name="camp", old_name="start", new_name="camp_start" ), migrations.AddField( - model_name='camp', - name='buildup_start', - field=models.DateTimeField(default=datetime.datetime(2016, 12, 20, 16, 45, 39, 609630, tzinfo=utc), help_text=b'When the camp buildup starts.', verbose_name=b'Buildup Start date'), + model_name="camp", + name="buildup_start", + field=models.DateTimeField( + default=datetime.datetime(2016, 12, 20, 16, 45, 39, 609630, tzinfo=utc), + help_text=b"When the camp buildup starts.", + verbose_name=b"Buildup Start date", + ), preserve_default=False, ), migrations.AddField( - model_name='camp', - name='teardown_end', - field=models.DateTimeField(default=datetime.datetime(2016, 12, 20, 16, 45, 44, 532143, tzinfo=utc), help_text=b'When the camp teardown ends.', verbose_name=b'Start date'), + model_name="camp", + name="teardown_end", + field=models.DateTimeField( + default=datetime.datetime(2016, 12, 20, 16, 45, 44, 532143, tzinfo=utc), + help_text=b"When the camp teardown ends.", + verbose_name=b"Start date", + ), preserve_default=False, ), ] diff --git a/src/camps/migrations/0010_auto_20161220_1714.py b/src/camps/migrations/0010_auto_20161220_1714.py index 8c6e605d..10f882d6 100644 --- a/src/camps/migrations/0010_auto_20161220_1714.py +++ b/src/camps/migrations/0010_auto_20161220_1714.py @@ -7,25 +7,30 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ - ('camps', '0009_auto_20161220_1645'), - ] + dependencies = [("camps", "0009_auto_20161220_1645")] operations = [ - migrations.RemoveField( - model_name='camp', - name='name', - ), + migrations.RemoveField(model_name="camp", name="name"), migrations.AddField( - model_name='camp', - name='tagline', - field=models.CharField(default='', help_text=b'Tagline of the camp, ie. "Initial Commit"', max_length=255, verbose_name=b'Tagline'), + model_name="camp", + name="tagline", + field=models.CharField( + default="", + help_text=b'Tagline of the camp, ie. "Initial Commit"', + max_length=255, + verbose_name=b"Tagline", + ), preserve_default=False, ), migrations.AddField( - model_name='camp', - name='title', - field=models.CharField(default='', help_text=b'Title of the camp, ie. Bornhack 2016.', max_length=255, verbose_name=b'Title'), + model_name="camp", + name="title", + field=models.CharField( + default="", + help_text=b"Title of the camp, ie. Bornhack 2016.", + max_length=255, + verbose_name=b"Title", + ), preserve_default=False, ), ] diff --git a/src/camps/migrations/0011_auto_20161228_1750.py b/src/camps/migrations/0011_auto_20161228_1750.py index 74e06705..5afe7705 100644 --- a/src/camps/migrations/0011_auto_20161228_1750.py +++ b/src/camps/migrations/0011_auto_20161228_1750.py @@ -7,21 +7,29 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ - ('camps', '0010_auto_20161220_1714'), - ] + dependencies = [("camps", "0010_auto_20161220_1714")] operations = [ migrations.AddField( - model_name='camp', - name='logo_large', - field=models.CharField(default='', help_text=b'The filename of the large logo to use on the frontpage of this camp', max_length=100, verbose_name=b'Large logo for this camp'), + model_name="camp", + name="logo_large", + field=models.CharField( + default="", + help_text=b"The filename of the large logo to use on the frontpage of this camp", + max_length=100, + verbose_name=b"Large logo for this camp", + ), preserve_default=False, ), migrations.AddField( - model_name='camp', - name='logo_small', - field=models.CharField(default='', help_text=b'The filename of the small logo to use in the top of the page for this camp', max_length=100, verbose_name=b'Small logo for this camp'), + model_name="camp", + name="logo_small", + field=models.CharField( + default="", + help_text=b"The filename of the small logo to use in the top of the page for this camp", + max_length=100, + verbose_name=b"Small logo for this camp", + ), preserve_default=False, ), ] diff --git a/src/camps/migrations/0012_auto_20161228_2312.py b/src/camps/migrations/0012_auto_20161228_2312.py index 0af78178..fc8aef45 100644 --- a/src/camps/migrations/0012_auto_20161228_2312.py +++ b/src/camps/migrations/0012_auto_20161228_2312.py @@ -7,17 +7,9 @@ from django.db import migrations class Migration(migrations.Migration): - dependencies = [ - ('camps', '0011_auto_20161228_1750'), - ] + dependencies = [("camps", "0011_auto_20161228_1750")] operations = [ - migrations.RemoveField( - model_name='camp', - name='logo_large', - ), - migrations.RemoveField( - model_name='camp', - name='logo_small', - ), + migrations.RemoveField(model_name="camp", name="logo_large"), + migrations.RemoveField(model_name="camp", name="logo_small"), ] diff --git a/src/camps/migrations/0013_auto_20161229_2201.py b/src/camps/migrations/0013_auto_20161229_2201.py index 28a3ef6e..2e638258 100644 --- a/src/camps/migrations/0013_auto_20161229_2201.py +++ b/src/camps/migrations/0013_auto_20161229_2201.py @@ -8,40 +8,36 @@ from django.db import migrations class Migration(migrations.Migration): - dependencies = [ - ('camps', '0012_auto_20161228_2312'), - ] + dependencies = [("camps", "0012_auto_20161228_2312")] operations = [ - migrations.RemoveField( - model_name='camp', - name='buildup_start', - ), - migrations.RemoveField( - model_name='camp', - name='camp_end', - ), - migrations.RemoveField( - model_name='camp', - name='camp_start', - ), - migrations.RemoveField( - model_name='camp', - name='teardown_end', + migrations.RemoveField(model_name="camp", name="buildup_start"), + migrations.RemoveField(model_name="camp", name="camp_end"), + migrations.RemoveField(model_name="camp", name="camp_start"), + migrations.RemoveField(model_name="camp", name="teardown_end"), + migrations.AddField( + model_name="camp", + name="buildup", + field=django.contrib.postgres.fields.ranges.DateTimeRangeField( + help_text=b"The camp buildup period.", + null=True, + verbose_name=b"Buildup Period", + ), ), migrations.AddField( - model_name='camp', - name='buildup', - field=django.contrib.postgres.fields.ranges.DateTimeRangeField(help_text=b'The camp buildup period.', null=True, verbose_name=b'Buildup Period'), + model_name="camp", + name="camp", + field=django.contrib.postgres.fields.ranges.DateTimeRangeField( + help_text=b"The camp period.", null=True, verbose_name=b"Camp Period" + ), ), migrations.AddField( - model_name='camp', - name='camp', - field=django.contrib.postgres.fields.ranges.DateTimeRangeField(help_text=b'The camp period.', null=True, verbose_name=b'Camp Period'), - ), - migrations.AddField( - model_name='camp', - name='teardown', - field=django.contrib.postgres.fields.ranges.DateTimeRangeField(help_text=b'The camp teardown period.', null=True, verbose_name=b'Teardown period'), + model_name="camp", + name="teardown", + field=django.contrib.postgres.fields.ranges.DateTimeRangeField( + help_text=b"The camp teardown period.", + null=True, + verbose_name=b"Teardown period", + ), ), ] diff --git a/src/camps/migrations/0014_auto_20161229_2202.py b/src/camps/migrations/0014_auto_20161229_2202.py index db266ef9..8c23eaca 100644 --- a/src/camps/migrations/0014_auto_20161229_2202.py +++ b/src/camps/migrations/0014_auto_20161229_2202.py @@ -9,24 +9,34 @@ from django.utils import timezone class Migration(migrations.Migration): - dependencies = [ - ('camps', '0013_auto_20161229_2201'), - ] + dependencies = [("camps", "0013_auto_20161229_2201")] operations = [ migrations.AlterField( - model_name='camp', - name='buildup', - field=django.contrib.postgres.fields.ranges.DateTimeRangeField(help_text=b'The camp buildup period.', verbose_name=b'Buildup Period', default=(timezone.now(),None)), + model_name="camp", + name="buildup", + field=django.contrib.postgres.fields.ranges.DateTimeRangeField( + help_text=b"The camp buildup period.", + verbose_name=b"Buildup Period", + default=(timezone.now(), None), + ), ), migrations.AlterField( - model_name='camp', - name='camp', - field=django.contrib.postgres.fields.ranges.DateTimeRangeField(help_text=b'The camp period.', verbose_name=b'Camp Period', default=(timezone.now(),None)), + model_name="camp", + name="camp", + field=django.contrib.postgres.fields.ranges.DateTimeRangeField( + help_text=b"The camp period.", + verbose_name=b"Camp Period", + default=(timezone.now(), None), + ), ), migrations.AlterField( - model_name='camp', - name='teardown', - field=django.contrib.postgres.fields.ranges.DateTimeRangeField(help_text=b'The camp teardown period.', verbose_name=b'Teardown period', default=(timezone.now(),None)), + model_name="camp", + name="teardown", + field=django.contrib.postgres.fields.ranges.DateTimeRangeField( + help_text=b"The camp teardown period.", + verbose_name=b"Teardown period", + default=(timezone.now(), None), + ), ), ] diff --git a/src/camps/migrations/0015_auto_20170116_1634.py b/src/camps/migrations/0015_auto_20170116_1634.py index aa7c4b5c..d7000277 100644 --- a/src/camps/migrations/0015_auto_20170116_1634.py +++ b/src/camps/migrations/0015_auto_20170116_1634.py @@ -7,16 +7,9 @@ from django.db import migrations class Migration(migrations.Migration): - dependencies = [ - ('camps', '0014_auto_20161229_2202'), - ] + dependencies = [("camps", "0014_auto_20161229_2202")] operations = [ - migrations.RemoveField( - model_name='expense', - name='refund_user', - ), - migrations.DeleteModel( - name='Expense', - ), + migrations.RemoveField(model_name="expense", name="refund_user"), + migrations.DeleteModel(name="Expense"), ] diff --git a/src/camps/migrations/0016_camp_description.py b/src/camps/migrations/0016_camp_description.py index 78c69f70..97a7532a 100644 --- a/src/camps/migrations/0016_camp_description.py +++ b/src/camps/migrations/0016_camp_description.py @@ -7,14 +7,16 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ - ('camps', '0015_auto_20170116_1634'), - ] + dependencies = [("camps", "0015_auto_20170116_1634")] operations = [ migrations.AddField( - model_name='camp', - name='description', - field=models.TextField(default=b'', help_text=b'Description of the camp, shown on the camp frontpage. HTML and markdown supported.', verbose_name=b'Description'), - ), + model_name="camp", + name="description", + field=models.TextField( + default=b"", + help_text=b"Description of the camp, shown on the camp frontpage. HTML and markdown supported.", + verbose_name=b"Description", + ), + ) ] diff --git a/src/camps/migrations/0017_remove_camp_description.py b/src/camps/migrations/0017_remove_camp_description.py index ed9032d7..cca3d569 100644 --- a/src/camps/migrations/0017_remove_camp_description.py +++ b/src/camps/migrations/0017_remove_camp_description.py @@ -7,13 +7,6 @@ from django.db import migrations class Migration(migrations.Migration): - dependencies = [ - ('camps', '0016_camp_description'), - ] + dependencies = [("camps", "0016_camp_description")] - operations = [ - migrations.RemoveField( - model_name='camp', - name='description', - ), - ] + operations = [migrations.RemoveField(model_name="camp", name="description")] diff --git a/src/camps/migrations/0018_auto_20170128_1841.py b/src/camps/migrations/0018_auto_20170128_1841.py index 5814441a..0d8d7470 100644 --- a/src/camps/migrations/0018_auto_20170128_1841.py +++ b/src/camps/migrations/0018_auto_20170128_1841.py @@ -8,24 +8,28 @@ from django.db import migrations class Migration(migrations.Migration): - dependencies = [ - ('camps', '0017_remove_camp_description'), - ] + dependencies = [("camps", "0017_remove_camp_description")] operations = [ migrations.AlterField( - model_name='camp', - name='buildup', - field=django.contrib.postgres.fields.ranges.DateTimeRangeField(help_text=b'The camp buildup period.', verbose_name=b'Buildup Period'), + model_name="camp", + name="buildup", + field=django.contrib.postgres.fields.ranges.DateTimeRangeField( + help_text=b"The camp buildup period.", verbose_name=b"Buildup Period" + ), ), migrations.AlterField( - model_name='camp', - name='camp', - field=django.contrib.postgres.fields.ranges.DateTimeRangeField(help_text=b'The camp period.', verbose_name=b'Camp Period'), + model_name="camp", + name="camp", + field=django.contrib.postgres.fields.ranges.DateTimeRangeField( + help_text=b"The camp period.", verbose_name=b"Camp Period" + ), ), migrations.AlterField( - model_name='camp', - name='teardown', - field=django.contrib.postgres.fields.ranges.DateTimeRangeField(help_text=b'The camp teardown period.', verbose_name=b'Teardown period'), + model_name="camp", + name="teardown", + field=django.contrib.postgres.fields.ranges.DateTimeRangeField( + help_text=b"The camp teardown period.", verbose_name=b"Teardown period" + ), ), ] diff --git a/src/camps/migrations/0019_auto_20170131_1849.py b/src/camps/migrations/0019_auto_20170131_1849.py index 1bbeeef5..c8e3b8fd 100644 --- a/src/camps/migrations/0019_auto_20170131_1849.py +++ b/src/camps/migrations/0019_auto_20170131_1849.py @@ -8,39 +8,53 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ - ('camps', '0018_auto_20170128_1841'), - ] + dependencies = [("camps", "0018_auto_20170128_1841")] operations = [ migrations.AlterField( - model_name='camp', - name='buildup', - field=django.contrib.postgres.fields.ranges.DateTimeRangeField(help_text='The camp buildup period.', verbose_name='Buildup Period'), + model_name="camp", + name="buildup", + field=django.contrib.postgres.fields.ranges.DateTimeRangeField( + help_text="The camp buildup period.", verbose_name="Buildup Period" + ), ), migrations.AlterField( - model_name='camp', - name='camp', - field=django.contrib.postgres.fields.ranges.DateTimeRangeField(help_text='The camp period.', verbose_name='Camp Period'), + model_name="camp", + name="camp", + field=django.contrib.postgres.fields.ranges.DateTimeRangeField( + help_text="The camp period.", verbose_name="Camp Period" + ), ), migrations.AlterField( - model_name='camp', - name='slug', - field=models.SlugField(help_text='The url slug to use for this camp', verbose_name='Url Slug'), + model_name="camp", + name="slug", + field=models.SlugField( + help_text="The url slug to use for this camp", verbose_name="Url Slug" + ), ), migrations.AlterField( - model_name='camp', - name='tagline', - field=models.CharField(help_text='Tagline of the camp, ie. "Initial Commit"', max_length=255, verbose_name='Tagline'), + model_name="camp", + name="tagline", + field=models.CharField( + help_text='Tagline of the camp, ie. "Initial Commit"', + max_length=255, + verbose_name="Tagline", + ), ), migrations.AlterField( - model_name='camp', - name='teardown', - field=django.contrib.postgres.fields.ranges.DateTimeRangeField(help_text='The camp teardown period.', verbose_name='Teardown period'), + model_name="camp", + name="teardown", + field=django.contrib.postgres.fields.ranges.DateTimeRangeField( + help_text="The camp teardown period.", verbose_name="Teardown period" + ), ), migrations.AlterField( - model_name='camp', - name='title', - field=models.CharField(help_text='Title of the camp, ie. Bornhack 2016.', max_length=255, verbose_name='Title'), + model_name="camp", + name="title", + field=models.CharField( + help_text="Title of the camp, ie. Bornhack 2016.", + max_length=255, + verbose_name="Title", + ), ), ] diff --git a/src/camps/migrations/0020_camp_read_only.py b/src/camps/migrations/0020_camp_read_only.py index 245ca9a3..e783c87a 100644 --- a/src/camps/migrations/0020_camp_read_only.py +++ b/src/camps/migrations/0020_camp_read_only.py @@ -7,14 +7,15 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ - ('camps', '0019_auto_20170131_1849'), - ] + dependencies = [("camps", "0019_auto_20170131_1849")] operations = [ migrations.AddField( - model_name='camp', - name='read_only', - field=models.BooleanField(default=False, help_text='Whether the camp is read only (i.e. in the past)'), - ), + model_name="camp", + name="read_only", + field=models.BooleanField( + default=False, + help_text="Whether the camp is read only (i.e. in the past)", + ), + ) ] diff --git a/src/camps/migrations/0021_auto_20170711_2247.py b/src/camps/migrations/0021_auto_20170711_2247.py index 8b97dfd5..0711a020 100644 --- a/src/camps/migrations/0021_auto_20170711_2247.py +++ b/src/camps/migrations/0021_auto_20170711_2247.py @@ -7,13 +7,15 @@ from django.db import migrations class Migration(migrations.Migration): - dependencies = [ - ('camps', '0020_camp_read_only'), - ] + dependencies = [("camps", "0020_camp_read_only")] operations = [ migrations.AlterModelOptions( - name='camp', - options={'ordering': ['-title'], 'verbose_name': 'Camp', 'verbose_name_plural': 'Camps'}, - ), + name="camp", + options={ + "ordering": ["-title"], + "verbose_name": "Camp", + "verbose_name_plural": "Camps", + }, + ) ] diff --git a/src/camps/migrations/0022_camp_colour.py b/src/camps/migrations/0022_camp_colour.py index aba2078f..f629904d 100644 --- a/src/camps/migrations/0022_camp_colour.py +++ b/src/camps/migrations/0022_camp_colour.py @@ -7,15 +7,18 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ - ('camps', '0021_auto_20170711_2247'), - ] + dependencies = [("camps", "0021_auto_20170711_2247")] operations = [ migrations.AddField( - model_name='camp', - name='colour', - field=models.CharField(default='#000000', help_text='The primary colour for the camp in hex', max_length=7, verbose_name='Colour'), + model_name="camp", + name="colour", + field=models.CharField( + default="#000000", + help_text="The primary colour for the camp in hex", + max_length=7, + verbose_name="Colour", + ), preserve_default=False, - ), + ) ] diff --git a/src/camps/migrations/0023_camp_shortslug.py b/src/camps/migrations/0023_camp_shortslug.py index 27f715aa..0df5443f 100644 --- a/src/camps/migrations/0023_camp_shortslug.py +++ b/src/camps/migrations/0023_camp_shortslug.py @@ -7,14 +7,16 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ - ('camps', '0022_camp_colour'), - ] + dependencies = [("camps", "0022_camp_colour")] operations = [ migrations.AddField( - model_name='camp', - name='shortslug', - field=models.SlugField(blank=True, help_text='Abbreviated version of the slug. Used in IRC channel names and other places with restricted name length.', verbose_name='Short Slug'), - ), + model_name="camp", + name="shortslug", + field=models.SlugField( + blank=True, + help_text="Abbreviated version of the slug. Used in IRC channel names and other places with restricted name length.", + verbose_name="Short Slug", + ), + ) ] diff --git a/src/camps/migrations/0024_populate_camp_shortslugs.py b/src/camps/migrations/0024_populate_camp_shortslugs.py index 2033c633..c63001c0 100644 --- a/src/camps/migrations/0024_populate_camp_shortslugs.py +++ b/src/camps/migrations/0024_populate_camp_shortslugs.py @@ -4,19 +4,16 @@ from __future__ import unicode_literals from django.db import migrations + def populate_camp_shortslugs(apps, schema_editor): - Camp = apps.get_model('camps', 'Camp') + Camp = apps.get_model("camps", "Camp") for camp in Camp.objects.all(): if not camp.shortslug: camp.shortslug = camp.slug camp.save() + class Migration(migrations.Migration): - dependencies = [ - ('camps', '0023_camp_shortslug'), - ] - - operations = [ - migrations.RunPython(populate_camp_shortslugs), - ] + dependencies = [("camps", "0023_camp_shortslug")] + operations = [migrations.RunPython(populate_camp_shortslugs)] diff --git a/src/camps/migrations/0025_auto_20180318_1250.py b/src/camps/migrations/0025_auto_20180318_1250.py index d7c596e1..7338b804 100644 --- a/src/camps/migrations/0025_auto_20180318_1250.py +++ b/src/camps/migrations/0025_auto_20180318_1250.py @@ -7,14 +7,15 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ - ('camps', '0024_populate_camp_shortslugs'), - ] + dependencies = [("camps", "0024_populate_camp_shortslugs")] operations = [ migrations.AlterField( - model_name='camp', - name='shortslug', - field=models.SlugField(help_text='Abbreviated version of the slug. Used in IRC channel names and other places with restricted name length.', verbose_name='Short Slug'), - ), + model_name="camp", + name="shortslug", + field=models.SlugField( + help_text="Abbreviated version of the slug. Used in IRC channel names and other places with restricted name length.", + verbose_name="Short Slug", + ), + ) ] diff --git a/src/camps/migrations/0026_auto_20180506_1633.py b/src/camps/migrations/0026_auto_20180506_1633.py index f99bcb1e..c7a94deb 100644 --- a/src/camps/migrations/0026_auto_20180506_1633.py +++ b/src/camps/migrations/0026_auto_20180506_1633.py @@ -5,19 +5,23 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ - ('camps', '0025_auto_20180318_1250'), - ] + dependencies = [("camps", "0025_auto_20180318_1250")] operations = [ migrations.AddField( - model_name='camp', - name='call_for_participation_open', - field=models.BooleanField(default=False, help_text='Check if the Call for Participation is open for this camp'), + model_name="camp", + name="call_for_participation_open", + field=models.BooleanField( + default=False, + help_text="Check if the Call for Participation is open for this camp", + ), ), migrations.AddField( - model_name='camp', - name='call_for_sponsors_open', - field=models.BooleanField(default=False, help_text='Check if the Call for Sponsors is open for this camp'), + model_name="camp", + name="call_for_sponsors_open", + field=models.BooleanField( + default=False, + help_text="Check if the Call for Sponsors is open for this camp", + ), ), ] diff --git a/src/camps/migrations/0027_auto_20180525_1019.py b/src/camps/migrations/0027_auto_20180525_1019.py index daf8db5b..e1ba253a 100644 --- a/src/camps/migrations/0027_auto_20180525_1019.py +++ b/src/camps/migrations/0027_auto_20180525_1019.py @@ -5,19 +5,21 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ - ('camps', '0026_auto_20180506_1633'), - ] + dependencies = [("camps", "0026_auto_20180506_1633")] operations = [ migrations.AddField( - model_name='camp', - name='call_for_participation', - field=models.TextField(blank=True, help_text='The CFP markdown for this Camp'), + model_name="camp", + name="call_for_participation", + field=models.TextField( + blank=True, help_text="The CFP markdown for this Camp" + ), ), migrations.AddField( - model_name='camp', - name='call_for_sponsors', - field=models.TextField(blank=True, help_text='The CFS markdown for this Camp'), + model_name="camp", + name="call_for_sponsors", + field=models.TextField( + blank=True, help_text="The CFS markdown for this Camp" + ), ), ] diff --git a/src/camps/migrations/0028_auto_20180525_1025.py b/src/camps/migrations/0028_auto_20180525_1025.py index e7976e32..646e483b 100644 --- a/src/camps/migrations/0028_auto_20180525_1025.py +++ b/src/camps/migrations/0028_auto_20180525_1025.py @@ -5,19 +5,25 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ - ('camps', '0027_auto_20180525_1019'), - ] + dependencies = [("camps", "0027_auto_20180525_1019")] operations = [ migrations.AlterField( - model_name='camp', - name='call_for_participation', - field=models.TextField(blank=True, default='The Call For Participation for this Camp has not been written yet', help_text='The CFP markdown for this Camp'), + model_name="camp", + name="call_for_participation", + field=models.TextField( + blank=True, + default="The Call For Participation for this Camp has not been written yet", + help_text="The CFP markdown for this Camp", + ), ), migrations.AlterField( - model_name='camp', - name='call_for_sponsors', - field=models.TextField(blank=True, default='The Call For Sponsors for this Camp has not been written yet', help_text='The CFS markdown for this Camp'), + model_name="camp", + name="call_for_sponsors", + field=models.TextField( + blank=True, + default="The Call For Sponsors for this Camp has not been written yet", + help_text="The CFS markdown for this Camp", + ), ), ] diff --git a/src/camps/migrations/0029_auto_20180815_2018.py b/src/camps/migrations/0029_auto_20180815_2018.py index e65b6d0c..4e7f73ab 100644 --- a/src/camps/migrations/0029_auto_20180815_2018.py +++ b/src/camps/migrations/0029_auto_20180815_2018.py @@ -5,13 +5,16 @@ from django.db import migrations class Migration(migrations.Migration): - dependencies = [ - ('camps', '0028_auto_20180525_1025'), - ] + dependencies = [("camps", "0028_auto_20180525_1025")] operations = [ migrations.AlterModelOptions( - name='camp', - options={'ordering': ['-title'], 'permissions': (('infodesk_permission', 'Infodesk permission'),), 'verbose_name': 'Camp', 'verbose_name_plural': 'Camps'}, - ), + name="camp", + options={ + "ordering": ["-title"], + "permissions": (("infodesk_permission", "Infodesk permission"),), + "verbose_name": "Camp", + "verbose_name_plural": "Camps", + }, + ) ] diff --git a/src/camps/migrations/0030_camp_light_text.py b/src/camps/migrations/0030_camp_light_text.py index 9663aba5..d4bce41b 100644 --- a/src/camps/migrations/0030_camp_light_text.py +++ b/src/camps/migrations/0030_camp_light_text.py @@ -5,14 +5,15 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ - ('camps', '0029_auto_20180815_2018'), - ] + dependencies = [("camps", "0029_auto_20180815_2018")] operations = [ migrations.AddField( - model_name='camp', - name='light_text', - field=models.BooleanField(default=True, help_text='Check if this camps colour requires white text, uncheck if black text is better'), - ), + model_name="camp", + name="light_text", + field=models.BooleanField( + default=True, + help_text="Check if this camps colour requires white text, uncheck if black text is better", + ), + ) ] diff --git a/src/camps/migrations/0031_auto_20180830_0014.py b/src/camps/migrations/0031_auto_20180830_0014.py index 07b06c4e..1b616bc1 100644 --- a/src/camps/migrations/0031_auto_20180830_0014.py +++ b/src/camps/migrations/0031_auto_20180830_0014.py @@ -5,24 +5,41 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ - ('camps', '0030_camp_light_text'), - ] + dependencies = [("camps", "0030_camp_light_text")] operations = [ migrations.CreateModel( - name='Permission', + name="Permission", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ) ], options={ - 'permissions': (('backoffice_permission', 'BackOffice access'), ('orgateam_permission', 'Orga Team permissions set'), ('infoteam_permission', 'Info Team permissions set'), ('economyteam_permission', 'Economy Team permissions set'), ('contentteam_permission', 'Content Team permissions set'), ('expense_create_permission', 'Expense Create permission')), - 'default_permissions': (), - 'managed': False, + "permissions": ( + ("backoffice_permission", "BackOffice access"), + ("orgateam_permission", "Orga Team permissions set"), + ("infoteam_permission", "Info Team permissions set"), + ("economyteam_permission", "Economy Team permissions set"), + ("contentteam_permission", "Content Team permissions set"), + ("expense_create_permission", "Expense Create permission"), + ), + "default_permissions": (), + "managed": False, }, ), migrations.AlterModelOptions( - name='camp', - options={'ordering': ['-title'], 'verbose_name': 'Camp', 'verbose_name_plural': 'Camps'}, + name="camp", + options={ + "ordering": ["-title"], + "verbose_name": "Camp", + "verbose_name_plural": "Camps", + }, ), ] diff --git a/src/camps/migrations/0032_auto_20180917_1754.py b/src/camps/migrations/0032_auto_20180917_1754.py index b4fe20a7..e68645a4 100644 --- a/src/camps/migrations/0032_auto_20180917_1754.py +++ b/src/camps/migrations/0032_auto_20180917_1754.py @@ -5,13 +5,23 @@ from django.db import migrations class Migration(migrations.Migration): - dependencies = [ - ('camps', '0031_auto_20180830_0014'), - ] + dependencies = [("camps", "0031_auto_20180830_0014")] operations = [ migrations.AlterModelOptions( - name='permission', - options={'default_permissions': (), 'managed': False, 'permissions': (('backoffice_permission', 'BackOffice access'), ('orgateam_permission', 'Orga Team permissions set'), ('infoteam_permission', 'Info Team permissions set'), ('economyteam_permission', 'Economy Team permissions set'), ('contentteam_permission', 'Content Team permissions set'), ('expense_create_permission', 'Expense Create permission'), ('revenue_create_permission', 'Revenue Create permission'))}, - ), + name="permission", + options={ + "default_permissions": (), + "managed": False, + "permissions": ( + ("backoffice_permission", "BackOffice access"), + ("orgateam_permission", "Orga Team permissions set"), + ("infoteam_permission", "Info Team permissions set"), + ("economyteam_permission", "Economy Team permissions set"), + ("contentteam_permission", "Content Team permissions set"), + ("expense_create_permission", "Expense Create permission"), + ("revenue_create_permission", "Revenue Create permission"), + ), + }, + ) ] diff --git a/src/camps/mixins.py b/src/camps/mixins.py index e02c3300..e91bcf97 100644 --- a/src/camps/mixins.py +++ b/src/camps/mixins.py @@ -21,7 +21,7 @@ class CampViewMixin(object): return queryset # do we have a camp_filter on this model - if not hasattr(self.model, 'camp_filter'): + if not hasattr(self.model, "camp_filter"): return queryset # get the camp_filter from the model @@ -36,14 +36,14 @@ class CampViewMixin(object): filter_dict = {_filter: self.camp} # get pk from kwargs if we have it - if hasattr(self, 'pk_url_kwarg'): + if hasattr(self, "pk_url_kwarg"): pk = self.kwargs.get(self.pk_url_kwarg) if pk is not None: # We should also filter for the pk of the object - filter_dict['pk'] = pk + filter_dict["pk"] = pk # get slug from kwargs if we have it - if hasattr(self, 'slug_url_kwarg'): + if hasattr(self, "slug_url_kwarg"): slug = self.kwargs.get(self.slug_url_kwarg) if slug is not None and (pk is None or self.query_pk_and_slug): # we should also filter for the slug of the object @@ -57,4 +57,3 @@ class CampViewMixin(object): # no camp_filter returned any results, return an empty queryset return result - diff --git a/src/camps/models.py b/src/camps/models.py index cb4b1c18..b0028495 100644 --- a/src/camps/models.py +++ b/src/camps/models.py @@ -8,6 +8,7 @@ from datetime import timedelta from django.utils import timezone from django.urls import reverse import logging + logger = logging.getLogger("bornhack.%s" % __name__) @@ -15,9 +16,10 @@ class Permission(models.Model): """ An unmanaged field-less model which holds our non-model permissions (such as team permission sets) """ + class Meta: managed = False - default_permissions=() + default_permissions = () permissions = ( ("backoffice_permission", "BackOffice access"), ("orgateam_permission", "Orga Team permissions set"), @@ -31,102 +33,94 @@ class Permission(models.Model): class Camp(CreatedUpdatedModel, UUIDModel): class Meta: - verbose_name = 'Camp' - verbose_name_plural = 'Camps' - ordering = ['-title'] + verbose_name = "Camp" + verbose_name_plural = "Camps" + ordering = ["-title"] title = models.CharField( - verbose_name='Title', - help_text='Title of the camp, ie. Bornhack 2016.', + verbose_name="Title", + help_text="Title of the camp, ie. Bornhack 2016.", max_length=255, ) tagline = models.CharField( - verbose_name='Tagline', + verbose_name="Tagline", help_text='Tagline of the camp, ie. "Initial Commit"', max_length=255, ) slug = models.SlugField( - verbose_name='Url Slug', - help_text='The url slug to use for this camp' + verbose_name="Url Slug", help_text="The url slug to use for this camp" ) shortslug = models.SlugField( - verbose_name='Short Slug', - help_text='Abbreviated version of the slug. Used in IRC channel names and other places with restricted name length.', + verbose_name="Short Slug", + help_text="Abbreviated version of the slug. Used in IRC channel names and other places with restricted name length.", ) buildup = DateTimeRangeField( - verbose_name='Buildup Period', - help_text='The camp buildup period.', + verbose_name="Buildup Period", help_text="The camp buildup period." ) - camp = DateTimeRangeField( - verbose_name='Camp Period', - help_text='The camp period.', - ) + camp = DateTimeRangeField(verbose_name="Camp Period", help_text="The camp period.") teardown = DateTimeRangeField( - verbose_name='Teardown period', - help_text='The camp teardown period.', + verbose_name="Teardown period", help_text="The camp teardown period." ) read_only = models.BooleanField( - help_text='Whether the camp is read only (i.e. in the past)', - default=False + help_text="Whether the camp is read only (i.e. in the past)", default=False ) colour = models.CharField( - verbose_name='Colour', - help_text='The primary colour for the camp in hex', - max_length=7 + verbose_name="Colour", + help_text="The primary colour for the camp in hex", + max_length=7, ) light_text = models.BooleanField( default=True, - help_text='Check if this camps colour requires white text, uncheck if black text is better', + help_text="Check if this camps colour requires white text, uncheck if black text is better", ) call_for_participation_open = models.BooleanField( - help_text='Check if the Call for Participation is open for this camp', + help_text="Check if the Call for Participation is open for this camp", default=False, ) call_for_participation = models.TextField( blank=True, - help_text='The CFP markdown for this Camp', - default='The Call For Participation for this Camp has not been written yet', + help_text="The CFP markdown for this Camp", + default="The Call For Participation for this Camp has not been written yet", ) call_for_sponsors_open = models.BooleanField( - help_text='Check if the Call for Sponsors is open for this camp', - default=False, + help_text="Check if the Call for Sponsors is open for this camp", default=False ) call_for_sponsors = models.TextField( blank=True, - help_text='The CFS markdown for this Camp', - default='The Call For Sponsors for this Camp has not been written yet', + help_text="The CFS markdown for this Camp", + default="The Call For Sponsors for this Camp has not been written yet", ) def get_absolute_url(self): - return reverse('camp_detail', kwargs={'camp_slug': self.slug}) + return reverse("camp_detail", kwargs={"camp_slug": self.slug}) def clean(self): - ''' Make sure the dates make sense - meaning no overlaps and buildup before camp before teardown ''' + """ Make sure the dates make sense - meaning no overlaps and buildup before camp before teardown """ errors = [] # check for overlaps buildup vs. camp if self.buildup.upper > self.camp.lower: msg = "End of buildup must not be after camp start" - errors.append(ValidationError({'buildup', msg})) - errors.append(ValidationError({'camp', msg})) + errors.append(ValidationError({"buildup", msg})) + errors.append(ValidationError({"camp", msg})) # check for overlaps camp vs. teardown if self.camp.upper > self.teardown.lower: msg = "End of camp must not be after teardown start" - errors.append(ValidationError({'camp', msg})) - errors.append(ValidationError({'teardown', msg})) + errors.append(ValidationError({"camp", msg})) + errors.append(ValidationError({"teardown", msg})) if errors: raise ValidationError(errors) @@ -137,40 +131,48 @@ class Camp(CreatedUpdatedModel, UUIDModel): @property def event_types(self): """ Return all event types with at least one event in this camp """ - return EventType.objects.filter(event__instances__isnull=False, event__camp=self).distinct() + return EventType.objects.filter( + event__instances__isnull=False, event__camp=self + ).distinct() @property def event_locations(self): - ''' Return all event locations with at least one event in this camp''' - return EventLocation.objects.filter(eventinstances__isnull=False, camp=self).distinct() + """ Return all event locations with at least one event in this camp""" + return EventLocation.objects.filter( + eventinstances__isnull=False, camp=self + ).distinct() @property def logo_small(self): - return 'img/%(slug)s/logo/%(slug)s-logo-s.png' % {'slug': self.slug} + return "img/%(slug)s/logo/%(slug)s-logo-s.png" % {"slug": self.slug} @property def logo_small_svg(self): - return 'img/%(slug)s/logo/%(slug)s-logo-small.svg' % {'slug': self.slug} + return "img/%(slug)s/logo/%(slug)s-logo-small.svg" % {"slug": self.slug} @property def logo_large(self): - return 'img/%(slug)s/logo/%(slug)s-logo-l.png' % {'slug': self.slug} + return "img/%(slug)s/logo/%(slug)s-logo-l.png" % {"slug": self.slug} @property def logo_large_svg(self): - return 'img/%(slug)s/logo/%(slug)s-logo-large.svg' % {'slug': self.slug} + return "img/%(slug)s/logo/%(slug)s-logo-large.svg" % {"slug": self.slug} def get_days(self, camppart): - ''' + """ Returns a list of DateTimeTZRanges representing the days during the specified part of the camp. - ''' + """ if not hasattr(self, camppart): logger.error("nonexistant field/attribute") return False field = getattr(self, camppart) - if not hasattr(field, '__class__') or not hasattr(field.__class__, '__name__') or not field.__class__.__name__ == 'DateTimeTZRange': + if ( + not hasattr(field, "__class__") + or not hasattr(field.__class__, "__name__") + or not field.__class__.__name__ == "DateTimeTZRange" + ): logger.error("this attribute is not a datetimetzrange field: %s" % field) return False @@ -182,45 +184,44 @@ class Camp(CreatedUpdatedModel, UUIDModel): days.append( DateTimeTZRange( field.lower, - (field.lower+timedelta(days=i+1)).replace(hour=0) + (field.lower + timedelta(days=i + 1)).replace(hour=0), ) ) - elif i == daycount-1: + elif i == daycount - 1: # on the last day use actual end time instead of midnight days.append( DateTimeTZRange( - (field.lower+timedelta(days=i)).replace(hour=0), - field.lower+timedelta(days=i+1) + (field.lower + timedelta(days=i)).replace(hour=0), + field.lower + timedelta(days=i + 1), ) ) else: # neither first nor last day, goes from midnight to midnight days.append( DateTimeTZRange( - (field.lower+timedelta(days=i)).replace(hour=0), - (field.lower+timedelta(days=i+1)).replace(hour=0) + (field.lower + timedelta(days=i)).replace(hour=0), + (field.lower + timedelta(days=i + 1)).replace(hour=0), ) ) return days @property def buildup_days(self): - ''' + """ Returns a list of DateTimeTZRanges representing the days during the buildup. - ''' - return self.get_days('buildup') + """ + return self.get_days("buildup") @property def camp_days(self): - ''' + """ Returns a list of DateTimeTZRanges representing the days during the camp. - ''' - return self.get_days('camp') + """ + return self.get_days("camp") @property def teardown_days(self): - ''' + """ Returns a list of DateTimeTZRanges representing the days during the buildup. - ''' - return self.get_days('teardown') - + """ + return self.get_days("teardown") diff --git a/src/camps/utils.py b/src/camps/utils.py index c4e2838e..81212b7f 100644 --- a/src/camps/utils.py +++ b/src/camps/utils.py @@ -15,8 +15,9 @@ class CampPropertyListFilter(admin.SimpleListFilter): SimpleListFilter to filter models by camp when camp is a property and not a real model field. """ - title = 'Camp' - parameter_name = 'camp' + + title = "Camp" + parameter_name = "camp" def lookups(self, request, model_admin): # get the current queryset diff --git a/src/camps/views.py b/src/camps/views.py index 9c2633cf..31083555 100644 --- a/src/camps/views.py +++ b/src/camps/views.py @@ -6,36 +6,37 @@ from .mixins import CampViewMixin from django.views import View from django.conf import settings import logging + logger = logging.getLogger("bornhack.%s" % __name__) class CampRedirectView(CampViewMixin, View): - def dispatch(self, request, *args, **kwargs): now = timezone.now() try: - camp = Camp.objects.get( - camp__contains=now + camp = Camp.objects.get(camp__contains=now) + logger.debug( + "Redirecting to camp '%s' for page '%s' because it is now!" + % (camp.slug, kwargs["page"]) ) - logger.debug("Redirecting to camp '%s' for page '%s' because it is now!" % (camp.slug, kwargs['page'])) - return redirect(kwargs['page'], camp_slug=camp.slug) + return redirect(kwargs["page"], camp_slug=camp.slug) except Camp.DoesNotExist: pass # no ongoing camp, find the closest camp in the past try: - prevcamp = Camp.objects.filter( - camp__endswith__lt=now - ).order_by('-camp').first() + prevcamp = ( + Camp.objects.filter(camp__endswith__lt=now).order_by("-camp").first() + ) except Camp.DoesNotExist: prevcamp = None # find the closest upcoming camp try: - nextcamp = Camp.objects.filter( - camp__startswith__gt=now - ).order_by('camp').first() + nextcamp = ( + Camp.objects.filter(camp__startswith__gt=now).order_by("camp").first() + ) except Camp.DoesNotExist: nextcamp = None @@ -59,19 +60,18 @@ class CampRedirectView(CampViewMixin, View): camp = prevcamp # do the redirect - return redirect(kwargs['page'], camp_slug=camp.slug) + return redirect(kwargs["page"], camp_slug=camp.slug) class CampDetailView(DetailView): model = Camp - slug_url_kwarg = 'camp_slug' + slug_url_kwarg = "camp_slug" def get_template_names(self): - return '%s_camp_detail.html' % self.get_object().slug + return "%s_camp_detail.html" % self.get_object().slug class CampListView(ListView): model = Camp - template_name = 'camp_list.html' - queryset = Camp.objects.all().order_by('camp') - + template_name = "camp_list.html" + queryset = Camp.objects.all().order_by("camp") diff --git a/src/economy/admin.py b/src/economy/admin.py index d7ef9051..d4d2741d 100644 --- a/src/economy/admin.py +++ b/src/economy/admin.py @@ -5,71 +5,108 @@ from .models import Chain, Credebtor, Expense, Reimbursement, Revenue ### chains and credebtors + @admin.register(Chain) class ChainAdmin(admin.ModelAdmin): - list_filter = ['name'] - list_display = ['name', 'notes'] - search_fields = ['name', 'notes'] + list_filter = ["name"] + list_display = ["name", "notes"] + search_fields = ["name", "notes"] @admin.register(Credebtor) class ChainAdmin(admin.ModelAdmin): - list_filter = ['chain', 'name'] - list_display = ['chain', 'name', 'notes'] - search_fields = ['chain', 'name', 'notes'] + list_filter = ["chain", "name"] + list_display = ["chain", "name", "notes"] + search_fields = ["chain", "name", "notes"] ### expenses + def approve_expenses(modeladmin, request, queryset): for expense in queryset.all(): expense.approve(request) + + approve_expenses.short_description = "Approve Expenses" def reject_expenses(modeladmin, request, queryset): for expense in queryset.all(): expense.reject(request) + + reject_expenses.short_description = "Reject Expenses" @admin.register(Expense) class ExpenseAdmin(admin.ModelAdmin): - list_filter = ['camp', 'creditor__chain', 'creditor', 'responsible_team', 'approved', 'user'] - list_display = ['user', 'description', 'invoice_date', 'amount', 'camp', 'creditor', 'responsible_team', 'approved', 'reimbursement'] - search_fields = ['description', 'amount', 'uuid'] + list_filter = [ + "camp", + "creditor__chain", + "creditor", + "responsible_team", + "approved", + "user", + ] + list_display = [ + "user", + "description", + "invoice_date", + "amount", + "camp", + "creditor", + "responsible_team", + "approved", + "reimbursement", + ] + search_fields = ["description", "amount", "uuid"] actions = [approve_expenses, reject_expenses] ### revenues + def approve_revenues(modeladmin, request, queryset): for revenue in queryset.all(): revenue.approve(request) + + approve_revenues.short_description = "Approve Revenues" def reject_revenues(modeladmin, request, queryset): for revenue in queryset.all(): revenue.reject(request) + + reject_revenues.short_description = "Reject Revenues" @admin.register(Revenue) class RevenueAdmin(admin.ModelAdmin): - list_filter = ['camp', 'responsible_team', 'approved', 'user'] - list_display = ['user', 'description', 'invoice_date', 'amount', 'camp', 'responsible_team', 'approved'] - search_fields = ['description', 'amount', 'user'] + list_filter = ["camp", "responsible_team", "approved", "user"] + list_display = [ + "user", + "description", + "invoice_date", + "amount", + "camp", + "responsible_team", + "approved", + ] + search_fields = ["description", "amount", "user"] actions = [approve_revenues, reject_revenues] ### reimbursements + @admin.register(Reimbursement) class ReimbursementAdmin(admin.ModelAdmin): def get_amount(self, obj): return obj.amount - list_filter = ['camp', 'user', 'reimbursement_user', 'paid'] - list_display = ['camp', 'user', 'reimbursement_user', 'paid', 'notes', 'get_amount'] - search_fields = ['user__username', 'reimbursement_user__username', 'notes'] + list_filter = ["camp", "user", "reimbursement_user", "paid"] + list_display = ["camp", "user", "reimbursement_user", "paid", "notes", "get_amount"] + search_fields = ["user__username", "reimbursement_user__username", "notes"] diff --git a/src/economy/apps.py b/src/economy/apps.py index 03724994..efc7a4e7 100644 --- a/src/economy/apps.py +++ b/src/economy/apps.py @@ -2,4 +2,4 @@ from django.apps import AppConfig class EconomyConfig(AppConfig): - name = 'economy' + name = "economy" diff --git a/src/economy/email.py b/src/economy/email.py index c3620bac..0a79e057 100644 --- a/src/economy/email.py +++ b/src/economy/email.py @@ -6,6 +6,7 @@ from utils.email import add_outgoing_email # expense emails + def send_accountingsystem_expense_email(expense): """ Sends an email to the accountingsystem with the invoice as an attachment, @@ -44,8 +45,10 @@ def send_expense_rejected_email(expense): to_recipients=[expense.user.emailaddress_set.get(primary=True).email], ) + # revenue emails + def send_accountingsystem_revenue_email(revenue): """ Sends an email to the accountingsystem with the invoice as an attachment, @@ -83,4 +86,3 @@ def send_revenue_rejected_email(revenue): subject="Your revenue for %s has been rejected." % revenue.camp.title, to_recipients=[revenue.user.emailaddress_set.get(primary=True).email], ) - diff --git a/src/economy/forms.py b/src/economy/forms.py index ef5c33e1..4e40e918 100644 --- a/src/economy/forms.py +++ b/src/economy/forms.py @@ -9,11 +9,12 @@ class CleanInvoiceForm(forms.ModelForm): We have to define this form explicitly because we want our ImageField to accept PDF files as well as images, and we cannot change the clean_* methods with an autogenerated form from inside views.py """ + invoice = forms.FileField() def clean_invoice(self): # get the uploaded file from cleaned_data - uploaded_file = self.cleaned_data['invoice'] + uploaded_file = self.cleaned_data["invoice"] # is this a valid image? try: # create an ImageField instance @@ -36,23 +37,41 @@ class CleanInvoiceForm(forms.ModelForm): class ExpenseCreateForm(CleanInvoiceForm): class Meta: model = Expense - fields = ['description', 'amount', 'invoice_date', 'invoice', 'paid_by_bornhack', 'responsible_team'] + fields = [ + "description", + "amount", + "invoice_date", + "invoice", + "paid_by_bornhack", + "responsible_team", + ] class ExpenseUpdateForm(forms.ModelForm): class Meta: model = Expense - fields = ['description', 'amount', 'invoice_date', 'paid_by_bornhack', 'responsible_team'] + fields = [ + "description", + "amount", + "invoice_date", + "paid_by_bornhack", + "responsible_team", + ] class RevenueCreateForm(CleanInvoiceForm): class Meta: model = Revenue - fields = ['description', 'amount', 'invoice_date', 'invoice', 'responsible_team'] + fields = [ + "description", + "amount", + "invoice_date", + "invoice", + "responsible_team", + ] class RevenueUpdateForm(forms.ModelForm): class Meta: model = Revenue - fields = ['description', 'amount', 'invoice_date', 'responsible_team'] - + fields = ["description", "amount", "invoice_date", "responsible_team"] diff --git a/src/economy/migrations/0001_initial.py b/src/economy/migrations/0001_initial.py index ca016507..346d4276 100644 --- a/src/economy/migrations/0001_initial.py +++ b/src/economy/migrations/0001_initial.py @@ -12,58 +12,168 @@ class Migration(migrations.Migration): dependencies = [ migrations.swappable_dependency(settings.AUTH_USER_MODEL), - ('teams', '0049_auto_20180815_1119'), - ('camps', '0031_auto_20180830_0014'), + ("teams", "0049_auto_20180815_1119"), + ("camps", "0031_auto_20180830_0014"), ] operations = [ migrations.CreateModel( - name='Expense', + name="Expense", fields=[ - ('uuid', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)), - ('created', models.DateTimeField(auto_now_add=True)), - ('updated', models.DateTimeField(auto_now=True)), - ('amount', models.DecimalField(decimal_places=2, help_text='The amount of this expense in DKK. Must match the amount on the invoice uploaded below.', max_digits=12)), - ('description', models.CharField(help_text='A short description of this expense. Please keep it meningful as it helps the Economy team a lot when categorising expenses. 200 characters or fewer.', max_length=200)), - ('paid_by_bornhack', models.BooleanField(default=True, help_text='Leave checked if this expense was paid by BornHack. Uncheck if you need a reimbursement for this expense.')), - ('invoice', models.ImageField(help_text='The invoice for this expense. Please make sure the amount on the invoice matches the amount you entered above. All common image formats are accepted.', upload_to='expenses/')), - ('approved', models.NullBooleanField(default=None, help_text='True if this expense has been approved by the responsible team. False if it has been rejected. Blank if noone has decided yet.')), - ('notes', models.TextField(blank=True, help_text='Economy Team notes for this expense. Only visible to the Economy team and the submitting user.')), - ('camp', models.ForeignKey(help_text='The camp to which this expense belongs', on_delete=django.db.models.deletion.PROTECT, related_name='expenses', to='camps.Camp')), + ( + "uuid", + models.UUIDField( + default=uuid.uuid4, + editable=False, + primary_key=True, + serialize=False, + ), + ), + ("created", models.DateTimeField(auto_now_add=True)), + ("updated", models.DateTimeField(auto_now=True)), + ( + "amount", + models.DecimalField( + decimal_places=2, + help_text="The amount of this expense in DKK. Must match the amount on the invoice uploaded below.", + max_digits=12, + ), + ), + ( + "description", + models.CharField( + help_text="A short description of this expense. Please keep it meningful as it helps the Economy team a lot when categorising expenses. 200 characters or fewer.", + max_length=200, + ), + ), + ( + "paid_by_bornhack", + models.BooleanField( + default=True, + help_text="Leave checked if this expense was paid by BornHack. Uncheck if you need a reimbursement for this expense.", + ), + ), + ( + "invoice", + models.ImageField( + help_text="The invoice for this expense. Please make sure the amount on the invoice matches the amount you entered above. All common image formats are accepted.", + upload_to="expenses/", + ), + ), + ( + "approved", + models.NullBooleanField( + default=None, + help_text="True if this expense has been approved by the responsible team. False if it has been rejected. Blank if noone has decided yet.", + ), + ), + ( + "notes", + models.TextField( + blank=True, + help_text="Economy Team notes for this expense. Only visible to the Economy team and the submitting user.", + ), + ), + ( + "camp", + models.ForeignKey( + help_text="The camp to which this expense belongs", + on_delete=django.db.models.deletion.PROTECT, + related_name="expenses", + to="camps.Camp", + ), + ), ], - options={ - 'abstract': False, - }, + options={"abstract": False}, ), migrations.CreateModel( - name='Reimbursement', + name="Reimbursement", fields=[ - ('uuid', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)), - ('created', models.DateTimeField(auto_now_add=True)), - ('updated', models.DateTimeField(auto_now=True)), - ('notes', models.TextField(blank=True, help_text='Economy Team notes for this reimbursement. Only visible to the Economy team and the related user.')), - ('paid', models.BooleanField(default=False, help_text='Check when this reimbursement has been paid to the user')), - ('camp', models.ForeignKey(help_text='The camp to which this reimbursement belongs', on_delete=django.db.models.deletion.PROTECT, related_name='reimbursements', to='camps.Camp')), - ('reimbursement_user', models.ForeignKey(help_text='The user this reimbursement belongs to.', on_delete=django.db.models.deletion.PROTECT, related_name='reimbursements', to=settings.AUTH_USER_MODEL)), - ('user', models.ForeignKey(help_text='The user who created this reimbursement.', on_delete=django.db.models.deletion.PROTECT, related_name='created_reimbursements', to=settings.AUTH_USER_MODEL)), + ( + "uuid", + models.UUIDField( + default=uuid.uuid4, + editable=False, + primary_key=True, + serialize=False, + ), + ), + ("created", models.DateTimeField(auto_now_add=True)), + ("updated", models.DateTimeField(auto_now=True)), + ( + "notes", + models.TextField( + blank=True, + help_text="Economy Team notes for this reimbursement. Only visible to the Economy team and the related user.", + ), + ), + ( + "paid", + models.BooleanField( + default=False, + help_text="Check when this reimbursement has been paid to the user", + ), + ), + ( + "camp", + models.ForeignKey( + help_text="The camp to which this reimbursement belongs", + on_delete=django.db.models.deletion.PROTECT, + related_name="reimbursements", + to="camps.Camp", + ), + ), + ( + "reimbursement_user", + models.ForeignKey( + help_text="The user this reimbursement belongs to.", + on_delete=django.db.models.deletion.PROTECT, + related_name="reimbursements", + to=settings.AUTH_USER_MODEL, + ), + ), + ( + "user", + models.ForeignKey( + help_text="The user who created this reimbursement.", + on_delete=django.db.models.deletion.PROTECT, + related_name="created_reimbursements", + to=settings.AUTH_USER_MODEL, + ), + ), ], - options={ - 'abstract': False, - }, + options={"abstract": False}, ), migrations.AddField( - model_name='expense', - name='reimbursement', - field=models.ForeignKey(blank=True, help_text='The reimbursement for this expense, if any. This is a dual-purpose field. If expense.paid_by_bornhack is true then expense.reimbursement references the reimbursement which this expense is created to cover. If expense.paid_by_bornhack is false then expense.reimbursement references the reimbursement which reimbursed this expense.', null=True, on_delete=django.db.models.deletion.PROTECT, related_name='expenses', to='economy.Reimbursement'), + model_name="expense", + name="reimbursement", + field=models.ForeignKey( + blank=True, + help_text="The reimbursement for this expense, if any. This is a dual-purpose field. If expense.paid_by_bornhack is true then expense.reimbursement references the reimbursement which this expense is created to cover. If expense.paid_by_bornhack is false then expense.reimbursement references the reimbursement which reimbursed this expense.", + null=True, + on_delete=django.db.models.deletion.PROTECT, + related_name="expenses", + to="economy.Reimbursement", + ), ), migrations.AddField( - model_name='expense', - name='responsible_team', - field=models.ForeignKey(help_text='The team to which this Expense belongs. A team responsible will need to approve the expense. When in doubt pick the Economy team.', on_delete=django.db.models.deletion.PROTECT, related_name='expenses', to='teams.Team'), + model_name="expense", + name="responsible_team", + field=models.ForeignKey( + help_text="The team to which this Expense belongs. A team responsible will need to approve the expense. When in doubt pick the Economy team.", + on_delete=django.db.models.deletion.PROTECT, + related_name="expenses", + to="teams.Team", + ), ), migrations.AddField( - model_name='expense', - name='user', - field=models.ForeignKey(help_text='The user to which this expense belongs', on_delete=django.db.models.deletion.PROTECT, related_name='expenses', to=settings.AUTH_USER_MODEL), + model_name="expense", + name="user", + field=models.ForeignKey( + help_text="The user to which this expense belongs", + on_delete=django.db.models.deletion.PROTECT, + related_name="expenses", + to=settings.AUTH_USER_MODEL, + ), ), ] diff --git a/src/economy/migrations/0002_revenue.py b/src/economy/migrations/0002_revenue.py index 216f28eb..275e08d7 100644 --- a/src/economy/migrations/0002_revenue.py +++ b/src/economy/migrations/0002_revenue.py @@ -9,32 +9,101 @@ import uuid class Migration(migrations.Migration): dependencies = [ - ('shop', '0057_order_notes'), - ('teams', '0049_auto_20180815_1119'), - ('camps', '0031_auto_20180830_0014'), + ("shop", "0057_order_notes"), + ("teams", "0049_auto_20180815_1119"), + ("camps", "0031_auto_20180830_0014"), migrations.swappable_dependency(settings.AUTH_USER_MODEL), - ('economy', '0001_initial'), + ("economy", "0001_initial"), ] operations = [ migrations.CreateModel( - name='Revenue', + name="Revenue", fields=[ - ('uuid', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)), - ('created', models.DateTimeField(auto_now_add=True)), - ('updated', models.DateTimeField(auto_now=True)), - ('amount', models.DecimalField(decimal_places=2, help_text='The amount of this revenue in DKK. Must match the amount on the documentation uploaded below.', max_digits=12)), - ('description', models.CharField(help_text='A short description of this revenue. Please keep it meningful as it helps the Economy team a lot when categorising revenue. 200 characters or fewer.', max_length=200)), - ('invoice', models.ImageField(help_text='The invoice file for this revenue. Please make sure the amount on the invoice matches the amount you entered above. All common image formats are accepted, as well as PDF.', upload_to='revenues/')), - ('approved', models.NullBooleanField(default=None, help_text='True if this Revenue has been approved by the responsible team. False if it has been rejected. Blank if noone has decided yet.')), - ('notes', models.TextField(blank=True, help_text='Economy Team notes for this revenue. Only visible to the Economy team and the submitting user.')), - ('camp', models.ForeignKey(help_text='The camp to which this revenue belongs', on_delete=django.db.models.deletion.PROTECT, related_name='revenues', to='camps.Camp')), - ('invoice_fk', models.ForeignKey(help_text='The Invoice object to which this Revenue object relates. Can be None if this revenue does not have a related BornHack Invoice.', on_delete=django.db.models.deletion.PROTECT, related_name='revenues', to='shop.Invoice')), - ('responsible_team', models.ForeignKey(help_text='The team to which this revenue belongs. When in doubt pick the Economy team.', on_delete=django.db.models.deletion.PROTECT, related_name='revenues', to='teams.Team')), - ('user', models.ForeignKey(help_text='The user who submitted this revenue', on_delete=django.db.models.deletion.PROTECT, related_name='revenues', to=settings.AUTH_USER_MODEL)), + ( + "uuid", + models.UUIDField( + default=uuid.uuid4, + editable=False, + primary_key=True, + serialize=False, + ), + ), + ("created", models.DateTimeField(auto_now_add=True)), + ("updated", models.DateTimeField(auto_now=True)), + ( + "amount", + models.DecimalField( + decimal_places=2, + help_text="The amount of this revenue in DKK. Must match the amount on the documentation uploaded below.", + max_digits=12, + ), + ), + ( + "description", + models.CharField( + help_text="A short description of this revenue. Please keep it meningful as it helps the Economy team a lot when categorising revenue. 200 characters or fewer.", + max_length=200, + ), + ), + ( + "invoice", + models.ImageField( + help_text="The invoice file for this revenue. Please make sure the amount on the invoice matches the amount you entered above. All common image formats are accepted, as well as PDF.", + upload_to="revenues/", + ), + ), + ( + "approved", + models.NullBooleanField( + default=None, + help_text="True if this Revenue has been approved by the responsible team. False if it has been rejected. Blank if noone has decided yet.", + ), + ), + ( + "notes", + models.TextField( + blank=True, + help_text="Economy Team notes for this revenue. Only visible to the Economy team and the submitting user.", + ), + ), + ( + "camp", + models.ForeignKey( + help_text="The camp to which this revenue belongs", + on_delete=django.db.models.deletion.PROTECT, + related_name="revenues", + to="camps.Camp", + ), + ), + ( + "invoice_fk", + models.ForeignKey( + help_text="The Invoice object to which this Revenue object relates. Can be None if this revenue does not have a related BornHack Invoice.", + on_delete=django.db.models.deletion.PROTECT, + related_name="revenues", + to="shop.Invoice", + ), + ), + ( + "responsible_team", + models.ForeignKey( + help_text="The team to which this revenue belongs. When in doubt pick the Economy team.", + on_delete=django.db.models.deletion.PROTECT, + related_name="revenues", + to="teams.Team", + ), + ), + ( + "user", + models.ForeignKey( + help_text="The user who submitted this revenue", + on_delete=django.db.models.deletion.PROTECT, + related_name="revenues", + to=settings.AUTH_USER_MODEL, + ), + ), ], - options={ - 'abstract': False, - }, - ), + options={"abstract": False}, + ) ] diff --git a/src/economy/migrations/0003_auto_20180917_1933.py b/src/economy/migrations/0003_auto_20180917_1933.py index f5b9036c..fb68778e 100644 --- a/src/economy/migrations/0003_auto_20180917_1933.py +++ b/src/economy/migrations/0003_auto_20180917_1933.py @@ -6,14 +6,19 @@ import django.db.models.deletion class Migration(migrations.Migration): - dependencies = [ - ('economy', '0002_revenue'), - ] + dependencies = [("economy", "0002_revenue")] operations = [ migrations.AlterField( - model_name='revenue', - name='invoice_fk', - field=models.ForeignKey(blank=True, help_text='The Invoice object to which this Revenue object relates. Can be None if this revenue does not have a related BornHack Invoice.', null=True, on_delete=django.db.models.deletion.PROTECT, related_name='revenues', to='shop.Invoice'), - ), + model_name="revenue", + name="invoice_fk", + field=models.ForeignKey( + blank=True, + help_text="The Invoice object to which this Revenue object relates. Can be None if this revenue does not have a related BornHack Invoice.", + null=True, + on_delete=django.db.models.deletion.PROTECT, + related_name="revenues", + to="shop.Invoice", + ), + ) ] diff --git a/src/economy/migrations/0004_auto_20181120_1835.py b/src/economy/migrations/0004_auto_20181120_1835.py index bfc9c5b6..0f3b2106 100644 --- a/src/economy/migrations/0004_auto_20181120_1835.py +++ b/src/economy/migrations/0004_auto_20181120_1835.py @@ -7,14 +7,17 @@ import django.db.models.deletion class Migration(migrations.Migration): - dependencies = [ - ('economy', '0003_auto_20180917_1933'), - ] + dependencies = [("economy", "0003_auto_20180917_1933")] operations = [ migrations.AlterField( - model_name='reimbursement', - name='user', - field=models.ForeignKey(help_text='The economy team member who created this reimbursement.', on_delete=django.db.models.deletion.PROTECT, related_name='created_reimbursements', to=settings.AUTH_USER_MODEL), - ), + model_name="reimbursement", + name="user", + field=models.ForeignKey( + help_text="The economy team member who created this reimbursement.", + on_delete=django.db.models.deletion.PROTECT, + related_name="created_reimbursements", + to=settings.AUTH_USER_MODEL, + ), + ) ] diff --git a/src/economy/migrations/0005_auto_20190120_1532.py b/src/economy/migrations/0005_auto_20190120_1532.py index 8e2792b9..7fef3739 100644 --- a/src/economy/migrations/0005_auto_20190120_1532.py +++ b/src/economy/migrations/0005_auto_20190120_1532.py @@ -5,19 +5,25 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ - ('economy', '0004_auto_20181120_1835'), - ] + dependencies = [("economy", "0004_auto_20181120_1835")] operations = [ migrations.AddField( - model_name='expense', - name='invoice_date', - field=models.DateTimeField(blank=True, help_text='The invoice date for this Expense. This must match the invoice date on the documentation uploaded below.', null=True), + model_name="expense", + name="invoice_date", + field=models.DateTimeField( + blank=True, + help_text="The invoice date for this Expense. This must match the invoice date on the documentation uploaded below.", + null=True, + ), ), migrations.AddField( - model_name='revenue', - name='invoice_date', - field=models.DateTimeField(blank=True, help_text='The invoice date for this Revenue. This must match the invoice date on the documentation uploaded below.', null=True), + model_name="revenue", + name="invoice_date", + field=models.DateTimeField( + blank=True, + help_text="The invoice date for this Revenue. This must match the invoice date on the documentation uploaded below.", + null=True, + ), ), ] diff --git a/src/economy/migrations/0006_auto_20190120_1642.py b/src/economy/migrations/0006_auto_20190120_1642.py index 8483a5f2..6c0a6449 100644 --- a/src/economy/migrations/0006_auto_20190120_1642.py +++ b/src/economy/migrations/0006_auto_20190120_1642.py @@ -5,19 +5,25 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ - ('economy', '0005_auto_20190120_1532'), - ] + dependencies = [("economy", "0005_auto_20190120_1532")] operations = [ migrations.AlterField( - model_name='expense', - name='invoice_date', - field=models.DateField(blank=True, help_text='The invoice date for this Expense. This must match the invoice date on the documentation uploaded below.', null=True), + model_name="expense", + name="invoice_date", + field=models.DateField( + blank=True, + help_text="The invoice date for this Expense. This must match the invoice date on the documentation uploaded below.", + null=True, + ), ), migrations.AlterField( - model_name='revenue', - name='invoice_date', - field=models.DateField(blank=True, help_text='The invoice date for this Revenue. This must match the invoice date on the documentation uploaded below.', null=True), + model_name="revenue", + name="invoice_date", + field=models.DateField( + blank=True, + help_text="The invoice date for this Revenue. This must match the invoice date on the documentation uploaded below.", + null=True, + ), ), ] diff --git a/src/economy/migrations/0007_auto_20190327_0936.py b/src/economy/migrations/0007_auto_20190327_0936.py index 0d6572d6..5e8b2d2f 100644 --- a/src/economy/migrations/0007_auto_20190327_0936.py +++ b/src/economy/migrations/0007_auto_20190327_0936.py @@ -5,19 +5,25 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ - ('economy', '0006_auto_20190120_1642'), - ] + dependencies = [("economy", "0006_auto_20190120_1642")] operations = [ migrations.AlterField( - model_name='expense', - name='invoice_date', - field=models.DateField(blank=True, help_text='The invoice date for this Expense. This must match the invoice date on the documentation uploaded below. Format is YYYY-MM-DD.', null=True), + model_name="expense", + name="invoice_date", + field=models.DateField( + blank=True, + help_text="The invoice date for this Expense. This must match the invoice date on the documentation uploaded below. Format is YYYY-MM-DD.", + null=True, + ), ), migrations.AlterField( - model_name='revenue', - name='invoice_date', - field=models.DateField(blank=True, help_text='The invoice date for this Revenue. This must match the invoice date on the documentation uploaded below. Format is YYYY-MM-DD.', null=True), + model_name="revenue", + name="invoice_date", + field=models.DateField( + blank=True, + help_text="The invoice date for this Revenue. This must match the invoice date on the documentation uploaded below. Format is YYYY-MM-DD.", + null=True, + ), ), ] diff --git a/src/economy/migrations/0008_auto_20190327_1721.py b/src/economy/migrations/0008_auto_20190327_1721.py index f820d02e..3cc12c4e 100644 --- a/src/economy/migrations/0008_auto_20190327_1721.py +++ b/src/economy/migrations/0008_auto_20190327_1721.py @@ -7,63 +7,136 @@ import uuid class Migration(migrations.Migration): - dependencies = [ - ('economy', '0007_auto_20190327_0936'), - ] + dependencies = [("economy", "0007_auto_20190327_0936")] operations = [ migrations.CreateModel( - name='Chain', + name="Chain", fields=[ - ('uuid', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)), - ('created', models.DateTimeField(auto_now_add=True)), - ('updated', models.DateTimeField(auto_now=True)), - ('name', models.CharField(help_text='A short name for this Chain, like "Netto" or "XL Byg". 100 characters or fewer.', max_length=100, unique=True)), - ('slug', models.SlugField(help_text='The url slug for this Chain. Leave blank to auto generate a slug.', unique=True)), - ('notes', models.TextField(blank=True, help_text='Any notes for this Chain. Will be shown to anyone creating Expenses or Revenues for this Chain.')), + ( + "uuid", + models.UUIDField( + default=uuid.uuid4, + editable=False, + primary_key=True, + serialize=False, + ), + ), + ("created", models.DateTimeField(auto_now_add=True)), + ("updated", models.DateTimeField(auto_now=True)), + ( + "name", + models.CharField( + help_text='A short name for this Chain, like "Netto" or "XL Byg". 100 characters or fewer.', + max_length=100, + unique=True, + ), + ), + ( + "slug", + models.SlugField( + help_text="The url slug for this Chain. Leave blank to auto generate a slug.", + unique=True, + ), + ), + ( + "notes", + models.TextField( + blank=True, + help_text="Any notes for this Chain. Will be shown to anyone creating Expenses or Revenues for this Chain.", + ), + ), ], - options={ - 'ordering': ['name'], - }, + options={"ordering": ["name"]}, ), migrations.CreateModel( - name='Credebtor', + name="Credebtor", fields=[ - ('uuid', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)), - ('created', models.DateTimeField(auto_now_add=True)), - ('updated', models.DateTimeField(auto_now=True)), - ('name', models.CharField(help_text='The name of this Credebtor, like "XL Byg Rønne" or "Netto Gelsted". 100 characters or fewer.', max_length=100, unique=True)), - ('slug', models.SlugField(help_text='The url slug for this Credebtor. Leave blank to auto generate a slug.')), - ('address', models.TextField(help_text='The address of this Credebtor.')), - ('notes', models.TextField(blank=True, help_text='Any notes for this Credebtor. Shown when creating an Expense or Revenue for this Credebtor.')), - ('chain', models.ForeignKey(help_text='The Chain to which this Credebtor belongs.', on_delete=django.db.models.deletion.PROTECT, related_name='credebtors', to='economy.Chain')), + ( + "uuid", + models.UUIDField( + default=uuid.uuid4, + editable=False, + primary_key=True, + serialize=False, + ), + ), + ("created", models.DateTimeField(auto_now_add=True)), + ("updated", models.DateTimeField(auto_now=True)), + ( + "name", + models.CharField( + help_text='The name of this Credebtor, like "XL Byg Rønne" or "Netto Gelsted". 100 characters or fewer.', + max_length=100, + unique=True, + ), + ), + ( + "slug", + models.SlugField( + help_text="The url slug for this Credebtor. Leave blank to auto generate a slug." + ), + ), + ( + "address", + models.TextField(help_text="The address of this Credebtor."), + ), + ( + "notes", + models.TextField( + blank=True, + help_text="Any notes for this Credebtor. Shown when creating an Expense or Revenue for this Credebtor.", + ), + ), + ( + "chain", + models.ForeignKey( + help_text="The Chain to which this Credebtor belongs.", + on_delete=django.db.models.deletion.PROTECT, + related_name="credebtors", + to="economy.Chain", + ), + ), ], - options={ - 'ordering': ['name'], - }, + options={"ordering": ["name"]}, ), migrations.AlterField( - model_name='expense', - name='invoice_date', - field=models.DateField(help_text='The invoice date for this Expense. This must match the invoice date on the documentation uploaded below. Format is YYYY-MM-DD.'), + model_name="expense", + name="invoice_date", + field=models.DateField( + help_text="The invoice date for this Expense. This must match the invoice date on the documentation uploaded below. Format is YYYY-MM-DD." + ), ), migrations.AlterField( - model_name='revenue', - name='invoice_date', - field=models.DateField(help_text='The invoice date for this Revenue. This must match the invoice date on the documentation uploaded below. Format is YYYY-MM-DD.'), + model_name="revenue", + name="invoice_date", + field=models.DateField( + help_text="The invoice date for this Revenue. This must match the invoice date on the documentation uploaded below. Format is YYYY-MM-DD." + ), ), migrations.AddField( - model_name='expense', - name='creditor', - field=models.ForeignKey(help_text='The Creditor to which this expense belongs', null=True, on_delete=django.db.models.deletion.PROTECT, related_name='expenses', to='economy.Credebtor'), + model_name="expense", + name="creditor", + field=models.ForeignKey( + help_text="The Creditor to which this expense belongs", + null=True, + on_delete=django.db.models.deletion.PROTECT, + related_name="expenses", + to="economy.Credebtor", + ), ), migrations.AddField( - model_name='revenue', - name='debtor', - field=models.ForeignKey(help_text='The Debtor to which this revenue belongs', null=True, on_delete=django.db.models.deletion.PROTECT, related_name='revenues', to='economy.Credebtor'), + model_name="revenue", + name="debtor", + field=models.ForeignKey( + help_text="The Debtor to which this revenue belongs", + null=True, + on_delete=django.db.models.deletion.PROTECT, + related_name="revenues", + to="economy.Credebtor", + ), ), migrations.AlterUniqueTogether( - name='credebtor', - unique_together={('chain', 'slug')}, + name="credebtor", unique_together={("chain", "slug")} ), ] diff --git a/src/economy/migrations/0009_auto_20190328_0715.py b/src/economy/migrations/0009_auto_20190328_0715.py index 0f7ea4c3..dfacd6e5 100644 --- a/src/economy/migrations/0009_auto_20190328_0715.py +++ b/src/economy/migrations/0009_auto_20190328_0715.py @@ -5,19 +5,24 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ - ('economy', '0008_auto_20190327_1721'), - ] + dependencies = [("economy", "0008_auto_20190327_1721")] operations = [ migrations.AlterField( - model_name='chain', - name='slug', - field=models.SlugField(blank=True, help_text='The url slug for this Chain. Leave blank to auto generate a slug.', unique=True), + model_name="chain", + name="slug", + field=models.SlugField( + blank=True, + help_text="The url slug for this Chain. Leave blank to auto generate a slug.", + unique=True, + ), ), migrations.AlterField( - model_name='credebtor', - name='slug', - field=models.SlugField(blank=True, help_text='The url slug for this Credebtor. Leave blank to auto generate a slug.'), + model_name="credebtor", + name="slug", + field=models.SlugField( + blank=True, + help_text="The url slug for this Credebtor. Leave blank to auto generate a slug.", + ), ), ] diff --git a/src/economy/migrations/0010_auto_20190330_1045.py b/src/economy/migrations/0010_auto_20190330_1045.py index d231c102..6790f971 100644 --- a/src/economy/migrations/0010_auto_20190330_1045.py +++ b/src/economy/migrations/0010_auto_20190330_1045.py @@ -6,19 +6,27 @@ import django.db.models.deletion class Migration(migrations.Migration): - dependencies = [ - ('economy', '0009_auto_20190328_0715'), - ] + dependencies = [("economy", "0009_auto_20190328_0715")] operations = [ migrations.AlterField( - model_name='expense', - name='creditor', - field=models.ForeignKey(help_text='The Creditor to which this expense belongs', on_delete=django.db.models.deletion.PROTECT, related_name='expenses', to='economy.Credebtor'), + model_name="expense", + name="creditor", + field=models.ForeignKey( + help_text="The Creditor to which this expense belongs", + on_delete=django.db.models.deletion.PROTECT, + related_name="expenses", + to="economy.Credebtor", + ), ), migrations.AlterField( - model_name='revenue', - name='debtor', - field=models.ForeignKey(help_text='The Debtor to which this revenue belongs', on_delete=django.db.models.deletion.PROTECT, related_name='revenues', to='economy.Credebtor'), + model_name="revenue", + name="debtor", + field=models.ForeignKey( + help_text="The Debtor to which this revenue belongs", + on_delete=django.db.models.deletion.PROTECT, + related_name="revenues", + to="economy.Credebtor", + ), ), ] diff --git a/src/economy/models.py b/src/economy/models.py index d3a9ea17..df00ee24 100644 --- a/src/economy/models.py +++ b/src/economy/models.py @@ -10,14 +10,16 @@ from django.utils.text import slugify from utils.models import CampRelatedModel, CreatedUpdatedModel, UUIDModel from .email import * + class ChainManager(models.Manager): """ ChainManager adds 'expenses_total' and 'revenues_total' to the Chain qs """ + def get_queryset(self): qs = super().get_queryset() - qs = qs.annotate(expenses_total=models.Sum('credebtors__expenses__amount')) - qs = qs.annotate(revenues_total=models.Sum('credebtors__revenues__amount')) + qs = qs.annotate(expenses_total=models.Sum("credebtors__expenses__amount")) + qs = qs.annotate(revenues_total=models.Sum("credebtors__revenues__amount")) return qs @@ -26,25 +28,26 @@ class Chain(CreatedUpdatedModel, UUIDModel): A chain of Credebtors. Used to group when several Creditors/Debtors belong to the same Chain/company, like XL Byg stores or Netto stores. """ + class Meta: - ordering = ['name'] + ordering = ["name"] objects = ChainManager() name = models.CharField( max_length=100, unique=True, - help_text='A short name for this Chain, like "Netto" or "XL Byg". 100 characters or fewer.' + help_text='A short name for this Chain, like "Netto" or "XL Byg". 100 characters or fewer.', ) slug = models.SlugField( unique=True, blank=True, - help_text='The url slug for this Chain. Leave blank to auto generate a slug.' + help_text="The url slug for this Chain. Leave blank to auto generate a slug.", ) notes = models.TextField( - help_text='Any notes for this Chain. Will be shown to anyone creating Expenses or Revenues for this Chain.', + help_text="Any notes for this Chain. Will be shown to anyone creating Expenses or Revenues for this Chain.", blank=True, ) @@ -69,10 +72,11 @@ class CredebtorManager(models.Manager): """ CredebtorManager adds 'expenses_total' and 'revenues_total' to the Credebtor qs """ + def get_queryset(self): qs = super().get_queryset() - qs = qs.annotate(expenses_total=models.Sum('expenses__amount')) - qs = qs.annotate(revenues_total=models.Sum('revenues__amount')) + qs = qs.annotate(expenses_total=models.Sum("expenses__amount")) + qs = qs.annotate(revenues_total=models.Sum("revenues__amount")) return qs @@ -83,37 +87,36 @@ class Credebtor(CreatedUpdatedModel, UUIDModel): The model is used for both creditors and debtors, since there is a lot of overlap between them. """ + class Meta: - ordering = ['name'] - unique_together=('chain', 'slug') + ordering = ["name"] + unique_together = ("chain", "slug") objects = CredebtorManager() chain = models.ForeignKey( - 'economy.Chain', + "economy.Chain", on_delete=models.PROTECT, - related_name='credebtors', - help_text='The Chain to which this Credebtor belongs.', + related_name="credebtors", + help_text="The Chain to which this Credebtor belongs.", ) name = models.CharField( max_length=100, unique=True, - help_text='The name of this Credebtor, like "XL Byg Rønne" or "Netto Gelsted". 100 characters or fewer.' + help_text='The name of this Credebtor, like "XL Byg Rønne" or "Netto Gelsted". 100 characters or fewer.', ) slug = models.SlugField( blank=True, - help_text='The url slug for this Credebtor. Leave blank to auto generate a slug.' + help_text="The url slug for this Credebtor. Leave blank to auto generate a slug.", ) - address = models.TextField( - help_text='The address of this Credebtor.', - ) + address = models.TextField(help_text="The address of this Credebtor.") notes = models.TextField( blank=True, - help_text='Any notes for this Credebtor. Shown when creating an Expense or Revenue for this Credebtor.', + help_text="Any notes for this Credebtor. Shown when creating an Expense or Revenue for this Credebtor.", ) def __str__(self): @@ -138,76 +141,77 @@ class Revenue(CampRelatedModel, UUIDModel): Other Revenue objects (such as money returned from bottle deposits) will not have a related BornHack Invoice object. """ + camp = models.ForeignKey( - 'camps.Camp', + "camps.Camp", on_delete=models.PROTECT, - related_name='revenues', - help_text='The camp to which this revenue belongs', + related_name="revenues", + help_text="The camp to which this revenue belongs", ) debtor = models.ForeignKey( - 'economy.Credebtor', + "economy.Credebtor", on_delete=models.PROTECT, - related_name='revenues', - help_text='The Debtor to which this revenue belongs', + related_name="revenues", + help_text="The Debtor to which this revenue belongs", ) user = models.ForeignKey( - 'auth.User', + "auth.User", on_delete=models.PROTECT, - related_name='revenues', - help_text='The user who submitted this revenue', + related_name="revenues", + help_text="The user who submitted this revenue", ) amount = models.DecimalField( decimal_places=2, max_digits=12, - help_text='The amount of this revenue in DKK. Must match the amount on the documentation uploaded below.', + help_text="The amount of this revenue in DKK. Must match the amount on the documentation uploaded below.", ) description = models.CharField( max_length=200, - help_text='A short description of this revenue. Please keep it meningful as it helps the Economy team a lot when categorising revenue. 200 characters or fewer.', + help_text="A short description of this revenue. Please keep it meningful as it helps the Economy team a lot when categorising revenue. 200 characters or fewer.", ) invoice = models.ImageField( - help_text='The invoice file for this revenue. Please make sure the amount on the invoice matches the amount you entered above. All common image formats are accepted, as well as PDF.', - upload_to='revenues/', + help_text="The invoice file for this revenue. Please make sure the amount on the invoice matches the amount you entered above. All common image formats are accepted, as well as PDF.", + upload_to="revenues/", ) invoice_date = models.DateField( - help_text='The invoice date for this Revenue. This must match the invoice date on the documentation uploaded below. Format is YYYY-MM-DD.', + help_text="The invoice date for this Revenue. This must match the invoice date on the documentation uploaded below. Format is YYYY-MM-DD." ) invoice_fk = models.ForeignKey( - 'shop.Invoice', + "shop.Invoice", on_delete=models.PROTECT, - related_name='revenues', - help_text='The Invoice object to which this Revenue object relates. Can be None if this revenue does not have a related BornHack Invoice.', + related_name="revenues", + help_text="The Invoice object to which this Revenue object relates. Can be None if this revenue does not have a related BornHack Invoice.", blank=True, null=True, ) responsible_team = models.ForeignKey( - 'teams.Team', + "teams.Team", on_delete=models.PROTECT, - related_name='revenues', - help_text='The team to which this revenue belongs. When in doubt pick the Economy team.' + related_name="revenues", + help_text="The team to which this revenue belongs. When in doubt pick the Economy team.", ) approved = models.NullBooleanField( default=None, - help_text='True if this Revenue has been approved by the responsible team. False if it has been rejected. Blank if noone has decided yet.' + help_text="True if this Revenue has been approved by the responsible team. False if it has been rejected. Blank if noone has decided yet.", ) notes = models.TextField( blank=True, - help_text='Economy Team notes for this revenue. Only visible to the Economy team and the submitting user.' + help_text="Economy Team notes for this revenue. Only visible to the Economy team and the submitting user.", ) def clean(self): if self.amount < 0: - raise ValidationError('Amount of a Revenue object can not be negative') + raise ValidationError("Amount of a Revenue object can not be negative") @property def invoice_filename(self): @@ -228,7 +232,10 @@ class Revenue(CampRelatedModel, UUIDModel): Approving a revenue triggers an email to the economy system, and another email to the user who submitted the revenue """ if request.user == self.user: - messages.error(request, "You cannot approve your own revenues, aka. the anti-stein-bagger defense") + messages.error( + request, + "You cannot approve your own revenues, aka. the anti-stein-bagger defense", + ) return # mark as approved and save @@ -262,35 +269,35 @@ class Revenue(CampRelatedModel, UUIDModel): class Expense(CampRelatedModel, UUIDModel): camp = models.ForeignKey( - 'camps.Camp', + "camps.Camp", on_delete=models.PROTECT, - related_name='expenses', - help_text='The camp to which this expense belongs', + related_name="expenses", + help_text="The camp to which this expense belongs", ) creditor = models.ForeignKey( - 'economy.Credebtor', + "economy.Credebtor", on_delete=models.PROTECT, - related_name='expenses', - help_text='The Creditor to which this expense belongs', + related_name="expenses", + help_text="The Creditor to which this expense belongs", ) user = models.ForeignKey( - 'auth.User', + "auth.User", on_delete=models.PROTECT, - related_name='expenses', - help_text='The user to which this expense belongs', + related_name="expenses", + help_text="The user to which this expense belongs", ) amount = models.DecimalField( decimal_places=2, max_digits=12, - help_text='The amount of this expense in DKK. Must match the amount on the invoice uploaded below.', + help_text="The amount of this expense in DKK. Must match the amount on the invoice uploaded below.", ) description = models.CharField( max_length=200, - help_text='A short description of this expense. Please keep it meningful as it helps the Economy team a lot when categorising expenses. 200 characters or fewer.', + help_text="A short description of this expense. Please keep it meningful as it helps the Economy team a lot when categorising expenses. 200 characters or fewer.", ) paid_by_bornhack = models.BooleanField( @@ -299,43 +306,43 @@ class Expense(CampRelatedModel, UUIDModel): ) invoice = models.ImageField( - help_text='The invoice for this expense. Please make sure the amount on the invoice matches the amount you entered above. All common image formats are accepted.', - upload_to='expenses/', + help_text="The invoice for this expense. Please make sure the amount on the invoice matches the amount you entered above. All common image formats are accepted.", + upload_to="expenses/", ) invoice_date = models.DateField( - help_text='The invoice date for this Expense. This must match the invoice date on the documentation uploaded below. Format is YYYY-MM-DD.', + help_text="The invoice date for this Expense. This must match the invoice date on the documentation uploaded below. Format is YYYY-MM-DD." ) responsible_team = models.ForeignKey( - 'teams.Team', + "teams.Team", on_delete=models.PROTECT, - related_name='expenses', - help_text='The team to which this Expense belongs. A team responsible will need to approve the expense. When in doubt pick the Economy team.' + related_name="expenses", + help_text="The team to which this Expense belongs. A team responsible will need to approve the expense. When in doubt pick the Economy team.", ) approved = models.NullBooleanField( default=None, - help_text='True if this expense has been approved by the responsible team. False if it has been rejected. Blank if noone has decided yet.' + help_text="True if this expense has been approved by the responsible team. False if it has been rejected. Blank if noone has decided yet.", ) reimbursement = models.ForeignKey( - 'economy.Reimbursement', + "economy.Reimbursement", on_delete=models.PROTECT, - related_name='expenses', + related_name="expenses", null=True, blank=True, - help_text='The reimbursement for this expense, if any. This is a dual-purpose field. If expense.paid_by_bornhack is true then expense.reimbursement references the reimbursement which this expense is created to cover. If expense.paid_by_bornhack is false then expense.reimbursement references the reimbursement which reimbursed this expense.' + help_text="The reimbursement for this expense, if any. This is a dual-purpose field. If expense.paid_by_bornhack is true then expense.reimbursement references the reimbursement which this expense is created to cover. If expense.paid_by_bornhack is false then expense.reimbursement references the reimbursement which reimbursed this expense.", ) notes = models.TextField( blank=True, - help_text='Economy Team notes for this expense. Only visible to the Economy team and the submitting user.' + help_text="Economy Team notes for this expense. Only visible to the Economy team and the submitting user.", ) def clean(self): if self.amount < 0: - raise ValidationError('Amount of an expense can not be negative') + raise ValidationError("Amount of an expense can not be negative") @property def invoice_filename(self): @@ -356,7 +363,10 @@ class Expense(CampRelatedModel, UUIDModel): Approving an expense triggers an email to the economy system, and another email to the user who submitted the expense in the first place. """ if request.user == self.user: - messages.error(request, "You cannot approve your own expenses, aka. the anti-stein-bagger defense") + messages.error( + request, + "You cannot approve your own expenses, aka. the anti-stein-bagger defense", + ) return # mark as approved and save @@ -392,30 +402,31 @@ class Reimbursement(CampRelatedModel, UUIDModel): """ A reimbursement covers one or more expenses. """ + camp = models.ForeignKey( - 'camps.Camp', + "camps.Camp", on_delete=models.PROTECT, - related_name='reimbursements', - help_text='The camp to which this reimbursement belongs', + related_name="reimbursements", + help_text="The camp to which this reimbursement belongs", ) user = models.ForeignKey( - 'auth.User', + "auth.User", on_delete=models.PROTECT, - related_name='created_reimbursements', - help_text='The economy team member who created this reimbursement.' + related_name="created_reimbursements", + help_text="The economy team member who created this reimbursement.", ) reimbursement_user = models.ForeignKey( - 'auth.User', + "auth.User", on_delete=models.PROTECT, - related_name='reimbursements', - help_text='The user this reimbursement belongs to.' + related_name="reimbursements", + help_text="The user this reimbursement belongs to.", ) notes = models.TextField( blank=True, - help_text='Economy Team notes for this reimbursement. Only visible to the Economy team and the related user.' + help_text="Economy Team notes for this reimbursement. Only visible to the Economy team and the related user.", ) paid = models.BooleanField( @@ -439,5 +450,3 @@ class Reimbursement(CampRelatedModel, UUIDModel): for expense in self.expenses.filter(paid_by_bornhack=False): amount += expense.amount return amount - - diff --git a/src/economy/urls.py b/src/economy/urls.py index c766e72c..c17be40e 100644 --- a/src/economy/urls.py +++ b/src/economy/urls.py @@ -1,150 +1,132 @@ from django.urls import path, include from .views import * -app_name = 'economy' +app_name = "economy" urlpatterns = [ - path( - '', - EconomyDashboardView.as_view(), - name='dashboard' - ), - + path("", EconomyDashboardView.as_view(), name="dashboard"), # chains - path('chains/', - include([ - path( - '', - ChainListView.as_view(), - name='chain_list', - ), - path( - 'add/', - ChainCreateView.as_view(), - name='chain_create', - ), - path( - '/', - include([ - path( - '', - CredebtorListView.as_view(), - name='credebtor_list', - ), - path( - 'add/', - CredebtorCreateView.as_view(), - name='credebtor_create', - ), - path( - '/', - include([ + path( + "chains/", + include( + [ + path("", ChainListView.as_view(), name="chain_list"), + path("add/", ChainCreateView.as_view(), name="chain_create"), + path( + "/", + include( + [ path( - 'add_expense/', - ExpenseCreateView.as_view(), - name='expense_create', + "", CredebtorListView.as_view(), name="credebtor_list" ), path( - 'add_revenue/', - RevenueCreateView.as_view(), - name='revenue_create', + "add/", + CredebtorCreateView.as_view(), + name="credebtor_create", ), - ]), + path( + "/", + include( + [ + path( + "add_expense/", + ExpenseCreateView.as_view(), + name="expense_create", + ), + path( + "add_revenue/", + RevenueCreateView.as_view(), + name="revenue_create", + ), + ] + ), + ), + ] ), - ]), - ), - ]), + ), + ] + ), ), - # expenses path( - 'expenses/', - include([ - path( - '', - ExpenseListView.as_view(), - name='expense_list', - ), - path( - '/', - include([ - path( - '', - ExpenseDetailView.as_view(), - name='expense_detail' + "expenses/", + include( + [ + path("", ExpenseListView.as_view(), name="expense_list"), + path( + "/", + include( + [ + path( + "", ExpenseDetailView.as_view(), name="expense_detail" + ), + path( + "update/", + ExpenseUpdateView.as_view(), + name="expense_update", + ), + path( + "delete/", + ExpenseDeleteView.as_view(), + name="expense_delete", + ), + path( + "invoice/", + ExpenseInvoiceView.as_view(), + name="expense_invoice", + ), + ] ), - path( - 'update/', - ExpenseUpdateView.as_view(), - name='expense_update' - ), - path( - 'delete/', - ExpenseDeleteView.as_view(), - name='expense_delete' - ), - path( - 'invoice/', - ExpenseInvoiceView.as_view(), - name='expense_invoice' - ), - ]), - ), - ]), + ), + ] + ), ), - # reimbursements path( - 'reimbursements/', - include([ - path( - '', - ReimbursementListView.as_view(), - name='reimbursement_list' - ), - path( - '/', - ReimbursementDetailView.as_view(), - name='reimbursement_detail' - ), - ]), + "reimbursements/", + include( + [ + path("", ReimbursementListView.as_view(), name="reimbursement_list"), + path( + "/", + ReimbursementDetailView.as_view(), + name="reimbursement_detail", + ), + ] + ), ), - # revenue path( - 'revenues/', - include([ - path( - '', - RevenueListView.as_view(), - name='revenue_list' - ), - path( - '/', - include([ - path( - '', - RevenueDetailView.as_view(), - name='revenue_detail' + "revenues/", + include( + [ + path("", RevenueListView.as_view(), name="revenue_list"), + path( + "/", + include( + [ + path( + "", RevenueDetailView.as_view(), name="revenue_detail" + ), + path( + "update/", + RevenueUpdateView.as_view(), + name="revenue_update", + ), + path( + "delete/", + RevenueDeleteView.as_view(), + name="revenue_delete", + ), + path( + "invoice/", + RevenueInvoiceView.as_view(), + name="revenue_invoice", + ), + ] ), - path( - 'update/', - RevenueUpdateView.as_view(), - name='revenue_update' - ), - path( - 'delete/', - RevenueDeleteView.as_view(), - name='revenue_delete' - ), - path( - 'invoice/', - RevenueInvoiceView.as_view(), - name='revenue_invoice' - ), - ]), - ), - ]), + ), + ] + ), ), ] - diff --git a/src/events/admin.py b/src/events/admin.py index b0d4fd2d..39044e4b 100644 --- a/src/events/admin.py +++ b/src/events/admin.py @@ -1,12 +1,12 @@ from django.contrib import admin from .models import Type, Routing + @admin.register(Type) class TypeAdmin(admin.ModelAdmin): pass + @admin.register(Routing) class RoutingAdmin(admin.ModelAdmin): pass - - diff --git a/src/events/apps.py b/src/events/apps.py index 38546443..60b376ce 100644 --- a/src/events/apps.py +++ b/src/events/apps.py @@ -2,4 +2,4 @@ from django.apps import AppConfig class EventsConfig(AppConfig): - name = 'events' + name = "events" diff --git a/src/events/handler.py b/src/events/handler.py index ab1e0cd5..87e4adfa 100644 --- a/src/events/handler.py +++ b/src/events/handler.py @@ -2,19 +2,27 @@ from django.utils import timezone from datetime import timedelta from ircbot.utils import add_irc_message import logging + logger = logging.getLogger("bornhack.%s" % __name__) -def handle_team_event(eventtype, irc_message=None, irc_timeout=60, email_template=None, email_formatdict=None): +def handle_team_event( + eventtype, + irc_message=None, + irc_timeout=60, + email_template=None, + email_formatdict=None, +): """ This method is our basic event handler. The type of event determines which teams receive notifications. TODO: Add some sort of priority to messages """ - #logger.info("Inside handle_team_event, eventtype %s" % eventtype) + # logger.info("Inside handle_team_event, eventtype %s" % eventtype) # get event type from database from .models import Type + try: eventtype = Type.objects.get(name=eventtype) except Type.DoesNotExist: @@ -24,14 +32,21 @@ def handle_team_event(eventtype, irc_message=None, irc_timeout=60, email_templat if not eventtype.teams: # no routes found for this eventtype, do nothing - #logger.error("No routes round for eventtype %s" % eventtype) + # logger.error("No routes round for eventtype %s" % eventtype) return # loop over routes (teams) for this eventtype for team in eventtype.teams: logger.info("Handling eventtype %s for team %s" % (eventtype, team)) - team_irc_notification(team=team, eventtype=eventtype, irc_message=irc_message, irc_timeout=irc_timeout) - team_email_notification(team=team, eventtype=eventtype, email_template=None, email_formatdict=None) + team_irc_notification( + team=team, + eventtype=eventtype, + irc_message=irc_message, + irc_timeout=irc_timeout, + ) + team_email_notification( + team=team, eventtype=eventtype, email_template=None, email_formatdict=None + ) # handle any future notification types here.. @@ -54,14 +69,14 @@ def team_irc_notification(team, eventtype, irc_message=None, irc_timeout=60): # send an IRC message to the the channel for this team add_irc_message( - target=team.private_irc_channel_name, - message=irc_message, - timeout=60 + target=team.private_irc_channel_name, message=irc_message, timeout=60 ) logger.info("Added new IRC message for channel %s" % team.irc_channel_name) -def team_email_notification(team, eventtype, email_template=None, email_formatdict=None): +def team_email_notification( + team, eventtype, email_template=None, email_formatdict=None +): """ Sends email notifications for events to team mailinglists (if possible, otherwise directly to the team responsibles) @@ -78,4 +93,3 @@ def team_email_notification(team, eventtype, email_template=None, email_formatdi recipient_list = [resp.email for resp in team.responsible_members.all()] # TODO: actually send the email here - diff --git a/src/events/migrations/0001_initial.py b/src/events/migrations/0001_initial.py index 3c3c00f8..16449291 100644 --- a/src/events/migrations/0001_initial.py +++ b/src/events/migrations/0001_initial.py @@ -10,42 +10,62 @@ class Migration(migrations.Migration): initial = True - dependencies = [ - ('teams', '0025_auto_20180318_1318'), - ] + dependencies = [("teams", "0025_auto_20180318_1318")] operations = [ migrations.CreateModel( - name='Routing', + name="Routing", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('created', models.DateTimeField(auto_now_add=True)), - ('updated', models.DateTimeField(auto_now=True)), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("created", models.DateTimeField(auto_now_add=True)), + ("updated", models.DateTimeField(auto_now=True)), ], - options={ - 'abstract': False, - }, + options={"abstract": False}, ), migrations.CreateModel( - name='Type', + name="Type", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('created', models.DateTimeField(auto_now_add=True)), - ('updated', models.DateTimeField(auto_now=True)), - ('name', models.TextField(help_text='The type of event', unique=True)), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("created", models.DateTimeField(auto_now_add=True)), + ("updated", models.DateTimeField(auto_now=True)), + ("name", models.TextField(help_text="The type of event", unique=True)), ], - options={ - 'abstract': False, - }, + options={"abstract": False}, ), migrations.AddField( - model_name='routing', - name='eventtype', - field=models.ForeignKey(help_text='The type of event to route', on_delete=django.db.models.deletion.PROTECT, related_name='eventroutes', to='events.Type'), + model_name="routing", + name="eventtype", + field=models.ForeignKey( + help_text="The type of event to route", + on_delete=django.db.models.deletion.PROTECT, + related_name="eventroutes", + to="events.Type", + ), ), migrations.AddField( - model_name='routing', - name='team', - field=models.ForeignKey(help_text='The team which should receive events of this type.', on_delete=django.db.models.deletion.PROTECT, related_name='eventroutes', to='teams.Team'), + model_name="routing", + name="team", + field=models.ForeignKey( + help_text="The team which should receive events of this type.", + on_delete=django.db.models.deletion.PROTECT, + related_name="eventroutes", + to="teams.Team", + ), ), ] diff --git a/src/events/migrations/0002_create_eventtype.py b/src/events/migrations/0002_create_eventtype.py index a84eb0ef..12022bba 100644 --- a/src/events/migrations/0002_create_eventtype.py +++ b/src/events/migrations/0002_create_eventtype.py @@ -4,17 +4,14 @@ from __future__ import unicode_literals from django.db import migrations + def create_eventtypes(apps, schema_editor): - Type = apps.get_model('events', 'Type') - Type.objects.create(name='public_credit_name_changed') + Type = apps.get_model("events", "Type") + Type.objects.create(name="public_credit_name_changed") + class Migration(migrations.Migration): - dependencies = [ - ('events', '0001_initial'), - ] - - operations = [ - migrations.RunPython(create_eventtypes), - ] + dependencies = [("events", "0001_initial")] + operations = [migrations.RunPython(create_eventtypes)] diff --git a/src/events/migrations/0003_create_another_eventtype.py b/src/events/migrations/0003_create_another_eventtype.py index 1259799c..f66318d3 100644 --- a/src/events/migrations/0003_create_another_eventtype.py +++ b/src/events/migrations/0003_create_another_eventtype.py @@ -4,17 +4,14 @@ from __future__ import unicode_literals from django.db import migrations + def create_eventtype(apps, schema_editor): - Type = apps.get_model('events', 'Type') - Type.objects.create(name='ticket_created') + Type = apps.get_model("events", "Type") + Type.objects.create(name="ticket_created") class Migration(migrations.Migration): - dependencies = [ - ('events', '0002_create_eventtype'), - ] + dependencies = [("events", "0002_create_eventtype")] - operations = [ - migrations.RunPython(create_eventtype), - ] + operations = [migrations.RunPython(create_eventtype)] diff --git a/src/events/migrations/0004_auto_20180403_1228.py b/src/events/migrations/0004_auto_20180403_1228.py index 23fe4e15..3a84b54f 100644 --- a/src/events/migrations/0004_auto_20180403_1228.py +++ b/src/events/migrations/0004_auto_20180403_1228.py @@ -7,19 +7,23 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ - ('events', '0003_create_another_eventtype'), - ] + dependencies = [("events", "0003_create_another_eventtype")] operations = [ migrations.AddField( - model_name='type', - name='email_notification', - field=models.BooleanField(default=False, help_text='Check to send email notifications for this type of event.'), + model_name="type", + name="email_notification", + field=models.BooleanField( + default=False, + help_text="Check to send email notifications for this type of event.", + ), ), migrations.AddField( - model_name='type', - name='irc_notification', - field=models.BooleanField(default=False, help_text='Check to send IRC notifications for this type of event.'), + model_name="type", + name="irc_notification", + field=models.BooleanField( + default=False, + help_text="Check to send IRC notifications for this type of event.", + ), ), ] diff --git a/src/events/models.py b/src/events/models.py index 74ba03a8..79f9e85e 100644 --- a/src/events/models.py +++ b/src/events/models.py @@ -2,6 +2,7 @@ from django.db import models from utils.models import CreatedUpdatedModel from teams.models import Team + class Type(CreatedUpdatedModel): """ The events.Type model contains different types of system events which can happen. @@ -10,20 +11,19 @@ class Type(CreatedUpdatedModel): - ticket_created: Whenever a new ShopTicket is created - public_credit_name_changed: Whenever a user changes public_credit_name in the profile """ - name = models.TextField( - unique=True, - help_text='The type of event' - ) + + name = models.TextField(unique=True, help_text="The type of event") irc_notification = models.BooleanField( default=False, - help_text='Check to send IRC notifications for this type of event.', + help_text="Check to send IRC notifications for this type of event.", ) email_notification = models.BooleanField( default=False, - help_text='Check to send email notifications for this type of event.', + help_text="Check to send email notifications for this type of event.", ) + def __str__(self): return self.name @@ -32,7 +32,7 @@ class Type(CreatedUpdatedModel): """ This property returns a queryset with all the teams that should receive this type of events """ - team_ids = Routing.objects.filter(eventtype=self).values_list('team', flat=True) + team_ids = Routing.objects.filter(eventtype=self).values_list("team", flat=True) return Team.objects.filter(pk__in=team_ids) @@ -42,20 +42,20 @@ class Routing(CreatedUpdatedModel): Add a new entry to route events of a certain type to a team. Several teams can receive the same type of event. """ + eventtype = models.ForeignKey( - 'events.Type', - related_name='eventroutes', + "events.Type", + related_name="eventroutes", on_delete=models.PROTECT, - help_text='The type of event to route', + help_text="The type of event to route", ) team = models.ForeignKey( - 'teams.Team', - related_name='eventroutes', + "teams.Team", + related_name="eventroutes", on_delete=models.PROTECT, - help_text='The team which should receive events of this type.' + help_text="The team which should receive events of this type.", ) def __str__(self): return "%s -> %s" % (self.eventtype, self.team) - diff --git a/src/feedback/admin.py b/src/feedback/admin.py index 2f87a6ea..bb84c90f 100644 --- a/src/feedback/admin.py +++ b/src/feedback/admin.py @@ -5,4 +5,4 @@ from .models import Feedback @admin.register(Feedback) class FeedbackAdmin(admin.ModelAdmin): - list_display = ('user', 'camp', 'feedback') + list_display = ("user", "camp", "feedback") diff --git a/src/feedback/apps.py b/src/feedback/apps.py index 63cb2219..7bd4774b 100644 --- a/src/feedback/apps.py +++ b/src/feedback/apps.py @@ -2,4 +2,4 @@ from django.apps import AppConfig class FeedbackConfig(AppConfig): - name = 'feedback' + name = "feedback" diff --git a/src/feedback/migrations/0001_initial.py b/src/feedback/migrations/0001_initial.py index 4e401ab1..85fc5d88 100644 --- a/src/feedback/migrations/0001_initial.py +++ b/src/feedback/migrations/0001_initial.py @@ -10,22 +10,32 @@ class Migration(migrations.Migration): initial = True - dependencies = [ - migrations.swappable_dependency(settings.AUTH_USER_MODEL), - ] + dependencies = [migrations.swappable_dependency(settings.AUTH_USER_MODEL)] operations = [ migrations.CreateModel( - name='Feedback', + name="Feedback", fields=[ - ('uuid', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)), - ('created', models.DateTimeField(auto_now_add=True)), - ('updated', models.DateTimeField(auto_now=True)), - ('feedback', models.TextField()), - ('user', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to=settings.AUTH_USER_MODEL)), + ( + "uuid", + models.UUIDField( + default=uuid.uuid4, + editable=False, + primary_key=True, + serialize=False, + ), + ), + ("created", models.DateTimeField(auto_now_add=True)), + ("updated", models.DateTimeField(auto_now=True)), + ("feedback", models.TextField()), + ( + "user", + models.ForeignKey( + on_delete=django.db.models.deletion.PROTECT, + to=settings.AUTH_USER_MODEL, + ), + ), ], - options={ - 'abstract': False, - }, - ), + options={"abstract": False}, + ) ] diff --git a/src/feedback/migrations/0002_feedback_camp.py b/src/feedback/migrations/0002_feedback_camp.py index 19e2dfae..9c0fbe90 100644 --- a/src/feedback/migrations/0002_feedback_camp.py +++ b/src/feedback/migrations/0002_feedback_camp.py @@ -6,16 +6,17 @@ import django.db.models.deletion class Migration(migrations.Migration): - dependencies = [ - ('camps', '0030_camp_light_text'), - ('feedback', '0001_initial'), - ] + dependencies = [("camps", "0030_camp_light_text"), ("feedback", "0001_initial")] operations = [ migrations.AddField( - model_name='feedback', - name='camp', - field=models.ForeignKey(default='30fd754f-dae4-460f-8128-6638fb29ab2d', on_delete=django.db.models.deletion.PROTECT, to='camps.Camp'), + model_name="feedback", + name="camp", + field=models.ForeignKey( + default="30fd754f-dae4-460f-8128-6638fb29ab2d", + on_delete=django.db.models.deletion.PROTECT, + to="camps.Camp", + ), preserve_default=False, - ), + ) ] diff --git a/src/feedback/models.py b/src/feedback/models.py index 611dc25b..d30cc631 100644 --- a/src/feedback/models.py +++ b/src/feedback/models.py @@ -4,6 +4,6 @@ from utils.models import UUIDModel, CreatedUpdatedModel, CampRelatedModel class Feedback(CampRelatedModel, UUIDModel): - camp = models.ForeignKey('camps.Camp', on_delete=models.PROTECT) - user = models.ForeignKey('auth.User', on_delete=models.PROTECT) + camp = models.ForeignKey("camps.Camp", on_delete=models.PROTECT) + user = models.ForeignKey("auth.User", on_delete=models.PROTECT) feedback = models.TextField() diff --git a/src/feedback/views.py b/src/feedback/views.py index 750356b8..d5559a64 100644 --- a/src/feedback/views.py +++ b/src/feedback/views.py @@ -11,7 +11,7 @@ from .models import Feedback class FeedbackCreate(LoginRequiredMixin, CampViewMixin, CreateView): model = Feedback - fields = ['feedback'] + fields = ["feedback"] def form_valid(self, form): feedback = form.save(commit=False) @@ -20,14 +20,15 @@ class FeedbackCreate(LoginRequiredMixin, CampViewMixin, CreateView): feedback.save() thanks_message = "Thank you! Your feedback is highly appreciated!" try: - token = Token.objects.get( - camp=self.camp, - description="Feedback thanks" + token = Token.objects.get(camp=self.camp, description="Feedback thanks") + thanks_message += " And for your efforts, here is a token: {}".format( + token.token ) - thanks_message += " And for your efforts, here is a token: {}".format(token.token) except Token.DoesNotExist: pass messages.success(self.request, thanks_message) - return HttpResponseRedirect(reverse("feedback", kwargs={"camp_slug": self.camp.slug})) + return HttpResponseRedirect( + reverse("feedback", kwargs={"camp_slug": self.camp.slug}) + ) diff --git a/src/info/admin.py b/src/info/admin.py index b2287b77..b630843e 100644 --- a/src/info/admin.py +++ b/src/info/admin.py @@ -1,26 +1,23 @@ from django.contrib import admin from reversion.admin import VersionAdmin -from .models import ( - InfoItem, - InfoCategory -) +from .models import InfoItem, InfoCategory @admin.register(InfoItem) class InfoItemAdmin(VersionAdmin): - list_filter = ['category', 'category__team__camp',] - list_display = ['headline',] + list_filter = ["category", "category__team__camp"] + list_display = ["headline"] class InfoItemInlineAdmin(admin.StackedInline): model = InfoItem - list_filter = ['category', 'category__team__camp',] - list_display = ['headline',] + list_filter = ["category", "category__team__camp"] + list_display = ["headline"] @admin.register(InfoCategory) class InfoCategorydmin(admin.ModelAdmin): - list_filter = ['team__camp',] - list_display = ['headline',] - search_fields = ['headline', 'body'] + list_filter = ["team__camp"] + list_display = ["headline"] + search_fields = ["headline", "body"] inlines = [InfoItemInlineAdmin] diff --git a/src/info/apps.py b/src/info/apps.py index 3891f47e..ae9027ec 100644 --- a/src/info/apps.py +++ b/src/info/apps.py @@ -2,4 +2,4 @@ from django.apps import AppConfig class InfoConfig(AppConfig): - name = 'info' + name = "info" diff --git a/src/info/migrations/0001_initial.py b/src/info/migrations/0001_initial.py index 0ea46e89..599ea194 100644 --- a/src/info/migrations/0001_initial.py +++ b/src/info/migrations/0001_initial.py @@ -10,48 +10,107 @@ class Migration(migrations.Migration): initial = True - dependencies = [ - ('camps', '0010_auto_20161220_1714'), - ] + dependencies = [("camps", "0010_auto_20161220_1714")] operations = [ migrations.CreateModel( - name='InfoCategory', + name="InfoCategory", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('created', models.DateTimeField(auto_now_add=True)), - ('updated', models.DateTimeField(auto_now=True)), - ('headline', models.CharField(help_text='The headline of this info category', max_length=100)), - ('anchor', models.SlugField(help_text='The HTML anchor to use for this info category.')), - ('weight', models.PositiveIntegerField(help_text='Determines sorting/ordering. Heavier categories sink to the bottom. Categories with the same weight are ordered alphabetically.')), - ('camp', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='infocategories', to='camps.Camp')), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("created", models.DateTimeField(auto_now_add=True)), + ("updated", models.DateTimeField(auto_now=True)), + ( + "headline", + models.CharField( + help_text="The headline of this info category", max_length=100 + ), + ), + ( + "anchor", + models.SlugField( + help_text="The HTML anchor to use for this info category." + ), + ), + ( + "weight", + models.PositiveIntegerField( + help_text="Determines sorting/ordering. Heavier categories sink to the bottom. Categories with the same weight are ordered alphabetically." + ), + ), + ( + "camp", + models.ForeignKey( + on_delete=django.db.models.deletion.PROTECT, + related_name="infocategories", + to="camps.Camp", + ), + ), ], - options={ - 'ordering': ['-weight', 'headline'], - }, + options={"ordering": ["-weight", "headline"]}, ), migrations.CreateModel( - name='InfoItem', + name="InfoItem", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('created', models.DateTimeField(auto_now_add=True)), - ('updated', models.DateTimeField(auto_now=True)), - ('headline', models.CharField(help_text='Headline of this info item.', max_length=100)), - ('anchor', models.SlugField(help_text='The HTML anchor to use for this info item.')), - ('body', models.TextField(help_text='Body of this info item. Markdown is supported.')), - ('weight', models.PositiveIntegerField(help_text='Determines sorting/ordering. Heavier items sink to the bottom. Items with the same weight are ordered alphabetically.')), - ('category', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='infoitems', to='info.InfoCategory')), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("created", models.DateTimeField(auto_now_add=True)), + ("updated", models.DateTimeField(auto_now=True)), + ( + "headline", + models.CharField( + help_text="Headline of this info item.", max_length=100 + ), + ), + ( + "anchor", + models.SlugField( + help_text="The HTML anchor to use for this info item." + ), + ), + ( + "body", + models.TextField( + help_text="Body of this info item. Markdown is supported." + ), + ), + ( + "weight", + models.PositiveIntegerField( + help_text="Determines sorting/ordering. Heavier items sink to the bottom. Items with the same weight are ordered alphabetically." + ), + ), + ( + "category", + models.ForeignKey( + on_delete=django.db.models.deletion.PROTECT, + related_name="infoitems", + to="info.InfoCategory", + ), + ), ], - options={ - 'ordering': ['-weight', 'headline'], - }, + options={"ordering": ["-weight", "headline"]}, ), migrations.AlterUniqueTogether( - name='infoitem', - unique_together=set([('headline', 'category'), ('anchor', 'category')]), + name="infoitem", + unique_together=set([("headline", "category"), ("anchor", "category")]), ), migrations.AlterUniqueTogether( - name='infocategory', - unique_together=set([('headline', 'camp'), ('anchor', 'camp')]), + name="infocategory", + unique_together=set([("headline", "camp"), ("anchor", "camp")]), ), ] diff --git a/src/info/migrations/0002_auto_20161228_2312.py b/src/info/migrations/0002_auto_20161228_2312.py index 3a7b5b47..b3f19974 100644 --- a/src/info/migrations/0002_auto_20161228_2312.py +++ b/src/info/migrations/0002_auto_20161228_2312.py @@ -7,23 +7,30 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ - ('info', '0001_initial'), - ] + dependencies = [("info", "0001_initial")] operations = [ migrations.AlterModelOptions( - name='infocategory', - options={'ordering': ['-weight', 'headline'], 'verbose_name_plural': 'Info Categories'}, + name="infocategory", + options={ + "ordering": ["-weight", "headline"], + "verbose_name_plural": "Info Categories", + }, ), migrations.AlterField( - model_name='infocategory', - name='weight', - field=models.PositiveIntegerField(default=100, help_text='Determines sorting/ordering. Heavier categories sink to the bottom. Categories with the same weight are ordered alphabetically. Defaults to 100.'), + model_name="infocategory", + name="weight", + field=models.PositiveIntegerField( + default=100, + help_text="Determines sorting/ordering. Heavier categories sink to the bottom. Categories with the same weight are ordered alphabetically. Defaults to 100.", + ), ), migrations.AlterField( - model_name='infoitem', - name='weight', - field=models.PositiveIntegerField(default=100, help_text='Determines sorting/ordering. Heavier items sink to the bottom. Items with the same weight are ordered alphabetically. Defaults to 100.'), + model_name="infoitem", + name="weight", + field=models.PositiveIntegerField( + default=100, + help_text="Determines sorting/ordering. Heavier items sink to the bottom. Items with the same weight are ordered alphabetically. Defaults to 100.", + ), ), ] diff --git a/src/info/migrations/0003_auto_20170218_1148.py b/src/info/migrations/0003_auto_20170218_1148.py index d12c8b53..f83e98f6 100644 --- a/src/info/migrations/0003_auto_20170218_1148.py +++ b/src/info/migrations/0003_auto_20170218_1148.py @@ -7,17 +7,17 @@ from django.db import migrations class Migration(migrations.Migration): - dependencies = [ - ('info', '0002_auto_20161228_2312'), - ] + dependencies = [("info", "0002_auto_20161228_2312")] operations = [ migrations.AlterModelOptions( - name='infocategory', - options={'ordering': ['weight', 'headline'], 'verbose_name_plural': 'Info Categories'}, + name="infocategory", + options={ + "ordering": ["weight", "headline"], + "verbose_name_plural": "Info Categories", + }, ), migrations.AlterModelOptions( - name='infoitem', - options={'ordering': ['weight', 'headline']}, + name="infoitem", options={"ordering": ["weight", "headline"]} ), ] diff --git a/src/info/migrations/0004_infocategory_team.py b/src/info/migrations/0004_infocategory_team.py index d7d2acd2..12660760 100644 --- a/src/info/migrations/0004_infocategory_team.py +++ b/src/info/migrations/0004_infocategory_team.py @@ -7,14 +7,20 @@ import django.db.models.deletion class Migration(migrations.Migration): dependencies = [ - ('teams', '0042_auto_20180413_1933'), - ('info', '0003_auto_20170218_1148'), + ("teams", "0042_auto_20180413_1933"), + ("info", "0003_auto_20170218_1148"), ] operations = [ migrations.AddField( - model_name='infocategory', - name='team', - field=models.ForeignKey(blank=True, help_text='The team responsible for this info category.', null=True, on_delete=django.db.models.deletion.PROTECT, to='teams.Team'), - ), + model_name="infocategory", + name="team", + field=models.ForeignKey( + blank=True, + help_text="The team responsible for this info category.", + null=True, + on_delete=django.db.models.deletion.PROTECT, + to="teams.Team", + ), + ) ] diff --git a/src/info/migrations/0005_add_teams_to_categories.py b/src/info/migrations/0005_add_teams_to_categories.py index 404cb176..60240be1 100644 --- a/src/info/migrations/0005_add_teams_to_categories.py +++ b/src/info/migrations/0005_add_teams_to_categories.py @@ -69,10 +69,6 @@ def add_teams_to_categories(apps, schema_editor): class Migration(migrations.Migration): - dependencies = [ - ('info', '0004_infocategory_team'), - ] + dependencies = [("info", "0004_infocategory_team")] - operations = [ - migrations.RunPython(add_teams_to_categories) - ] + operations = [migrations.RunPython(add_teams_to_categories)] diff --git a/src/info/migrations/0006_auto_20180520_1113.py b/src/info/migrations/0006_auto_20180520_1113.py index d7cef8ba..66a3329c 100644 --- a/src/info/migrations/0006_auto_20180520_1113.py +++ b/src/info/migrations/0006_auto_20180520_1113.py @@ -6,22 +6,21 @@ import django.db.models.deletion class Migration(migrations.Migration): - dependencies = [ - ('info', '0005_add_teams_to_categories'), - ] + dependencies = [("info", "0005_add_teams_to_categories")] operations = [ migrations.AlterField( - model_name='infocategory', - name='team', - field=models.ForeignKey(blank=True, help_text='The team responsible for this info category.', null=True, on_delete=django.db.models.deletion.PROTECT, related_name='info_categories', to='teams.Team'), - ), - migrations.AlterUniqueTogether( - name='infocategory', - unique_together=set(), - ), - migrations.RemoveField( - model_name='infocategory', - name='camp', + model_name="infocategory", + name="team", + field=models.ForeignKey( + blank=True, + help_text="The team responsible for this info category.", + null=True, + on_delete=django.db.models.deletion.PROTECT, + related_name="info_categories", + to="teams.Team", + ), ), + migrations.AlterUniqueTogether(name="infocategory", unique_together=set()), + migrations.RemoveField(model_name="infocategory", name="camp"), ] diff --git a/src/info/migrations/0007_auto_20180520_1511.py b/src/info/migrations/0007_auto_20180520_1511.py index c2511a93..6fcef49a 100644 --- a/src/info/migrations/0007_auto_20180520_1511.py +++ b/src/info/migrations/0007_auto_20180520_1511.py @@ -6,14 +6,17 @@ import django.db.models.deletion class Migration(migrations.Migration): - dependencies = [ - ('info', '0006_auto_20180520_1113'), - ] + dependencies = [("info", "0006_auto_20180520_1113")] operations = [ migrations.AlterField( - model_name='infocategory', - name='team', - field=models.ForeignKey(help_text='The team responsible for this info category.', on_delete=django.db.models.deletion.PROTECT, related_name='info_categories', to='teams.Team'), - ), + model_name="infocategory", + name="team", + field=models.ForeignKey( + help_text="The team responsible for this info category.", + on_delete=django.db.models.deletion.PROTECT, + related_name="info_categories", + to="teams.Team", + ), + ) ] diff --git a/src/info/models.py b/src/info/models.py index 3888a53f..031b4c47 100644 --- a/src/info/models.py +++ b/src/info/models.py @@ -7,12 +7,11 @@ import reversion class InfoCategory(CampRelatedModel): class Meta: - ordering = ['weight', 'headline'] + ordering = ["weight", "headline"] verbose_name_plural = "Info Categories" headline = models.CharField( - max_length=100, - help_text="The headline of this info category" + max_length=100, help_text="The headline of this info category" ) anchor = models.SlugField( @@ -20,62 +19,55 @@ class InfoCategory(CampRelatedModel): ) weight = models.PositiveIntegerField( - help_text='Determines sorting/ordering. Heavier categories sink to the bottom. Categories with the same weight are ordered alphabetically. Defaults to 100.', + help_text="Determines sorting/ordering. Heavier categories sink to the bottom. Categories with the same weight are ordered alphabetically. Defaults to 100.", default=100, ) team = models.ForeignKey( - 'teams.Team', - help_text='The team responsible for this info category.', + "teams.Team", + help_text="The team responsible for this info category.", on_delete=models.PROTECT, - related_name='info_categories' + related_name="info_categories", ) def clean(self): - if InfoItem.objects.filter(category__team__camp=self.camp, anchor=self.anchor).exists(): + if InfoItem.objects.filter( + category__team__camp=self.camp, anchor=self.anchor + ).exists(): # this anchor is already in use on an item, so it cannot be used (must be unique on the page) raise ValidationError( - {'anchor': 'Anchor is already in use on an info item for this camp'} + {"anchor": "Anchor is already in use on an info item for this camp"} ) @property def camp(self): return self.team.camp - camp_filter = 'team__camp' + camp_filter = "team__camp" def __str__(self): - return '%s (%s)' % (self.headline, self.camp) + return "%s (%s)" % (self.headline, self.camp) # We want to have info items under version control @reversion.register() class InfoItem(CampRelatedModel): class Meta: - ordering = ['weight', 'headline'] - unique_together = (('anchor', 'category'), ('headline', 'category')) + ordering = ["weight", "headline"] + unique_together = (("anchor", "category"), ("headline", "category")) category = models.ForeignKey( - 'info.InfoCategory', - related_name='infoitems', - on_delete=models.PROTECT + "info.InfoCategory", related_name="infoitems", on_delete=models.PROTECT ) - headline = models.CharField( - max_length=100, - help_text="Headline of this info item." - ) + headline = models.CharField(max_length=100, help_text="Headline of this info item.") - anchor = models.SlugField( - help_text="The HTML anchor to use for this info item." - ) + anchor = models.SlugField(help_text="The HTML anchor to use for this info item.") - body = models.TextField( - help_text='Body of this info item. Markdown is supported.' - ) + body = models.TextField(help_text="Body of this info item. Markdown is supported.") weight = models.PositiveIntegerField( - help_text='Determines sorting/ordering. Heavier items sink to the bottom. Items with the same weight are ordered alphabetically. Defaults to 100.', + help_text="Determines sorting/ordering. Heavier items sink to the bottom. Items with the same weight are ordered alphabetically. Defaults to 100.", default=100, ) @@ -83,12 +75,19 @@ class InfoItem(CampRelatedModel): def camp(self): return self.category.camp - camp_filter = 'category__team__camp' + camp_filter = "category__team__camp" def clean(self): - if hasattr(self, 'category') and InfoCategory.objects.filter(team__camp=self.category.team.camp, anchor=self.anchor).exists(): + if ( + hasattr(self, "category") + and InfoCategory.objects.filter( + team__camp=self.category.team.camp, anchor=self.anchor + ).exists() + ): # this anchor is already in use on a category, so it cannot be used here (they must be unique on the entire page) - raise ValidationError({'anchor': 'Anchor is already in use on an info category for this camp'}) + raise ValidationError( + {"anchor": "Anchor is already in use on an info category for this camp"} + ) def __str__(self): - return '%s (%s)' % (self.headline, self.category) + return "%s (%s)" % (self.headline, self.category) diff --git a/src/info/views.py b/src/info/views.py index a9db1920..15b98587 100644 --- a/src/info/views.py +++ b/src/info/views.py @@ -2,13 +2,13 @@ from django.views.generic import ListView from .models import * from camps.mixins import CampViewMixin + class CampInfoView(CampViewMixin, ListView): model = InfoCategory - template_name = 'info.html' - context_object_name = 'categories' + template_name = "info.html" + context_object_name = "categories" def get_queryset(self): queryset = super(CampInfoView, self).get_queryset() # do not show categories with 0 items return queryset.exclude(infoitems__isnull=True) - diff --git a/src/ircbot/admin.py b/src/ircbot/admin.py index eff2cb89..ac9622bb 100644 --- a/src/ircbot/admin.py +++ b/src/ircbot/admin.py @@ -2,4 +2,3 @@ from django.contrib import admin from .models import OutgoingIrcMessage admin.site.register(OutgoingIrcMessage) - diff --git a/src/ircbot/apps.py b/src/ircbot/apps.py index 54a5147b..a0f8c1b6 100644 --- a/src/ircbot/apps.py +++ b/src/ircbot/apps.py @@ -2,4 +2,4 @@ from django.apps import AppConfig class IrcbotConfig(AppConfig): - name = 'ircbot' + name = "ircbot" diff --git a/src/ircbot/irc3module.py b/src/ircbot/irc3module.py index d6b2367a..5909734d 100644 --- a/src/ircbot/irc3module.py +++ b/src/ircbot/irc3module.py @@ -7,6 +7,7 @@ from events.models import Routing from teams.utils import get_team_from_irc_channel import logging + logger = logging.getLogger("bornhack.%s" % __name__) @@ -15,14 +16,13 @@ class Plugin(object): """BornHack IRC3 class""" requires = [ - 'irc3.plugins.core', # makes the bot able to connect to an irc server and do basic irc stuff - 'irc3.plugins.userlist', # maintains a convenient list of the channels the bot is in and their users + "irc3.plugins.core", # makes the bot able to connect to an irc server and do basic irc stuff + "irc3.plugins.userlist", # maintains a convenient list of the channels the bot is in and their users ] def __init__(self, bot): self.bot = bot - ############################################################################################### ### builtin irc3 event methods @@ -31,22 +31,28 @@ class Plugin(object): logger.debug("inside server_ready(), kwargs: %s" % kwargs) logger.info("Identifying with %s" % settings.IRCBOT_NICKSERV_MASK) - self.bot.privmsg(settings.IRCBOT_NICKSERV_MASK, "identify %s %s" % (settings.IRCBOT_NICK, settings.IRCBOT_NICKSERV_PASSWORD)) - - logger.info("Calling self.bot.do_stuff() in %s seconds.." % settings.IRCBOT_CHECK_MESSAGE_INTERVAL_SECONDS) - self.bot.loop.call_later(settings.IRCBOT_CHECK_MESSAGE_INTERVAL_SECONDS, self.bot.do_stuff) + self.bot.privmsg( + settings.IRCBOT_NICKSERV_MASK, + "identify %s %s" + % (settings.IRCBOT_NICK, settings.IRCBOT_NICKSERV_PASSWORD), + ) + logger.info( + "Calling self.bot.do_stuff() in %s seconds.." + % settings.IRCBOT_CHECK_MESSAGE_INTERVAL_SECONDS + ) + self.bot.loop.call_later( + settings.IRCBOT_CHECK_MESSAGE_INTERVAL_SECONDS, self.bot.do_stuff + ) def connection_lost(self, **kwargs): """triggered when connection is lost""" logger.debug("inside connection_lost(), kwargs: %s" % kwargs) - def connection_made(self, **kwargs): """triggered when connection is up""" logger.debug("inside connection_made(), kwargs: %s" % kwargs) - ############################################################################################### ### decorated irc3 event methods @@ -59,41 +65,44 @@ class Plugin(object): # if so, check if the channel should be managed, and if so, part and join the channel # to gain @ and register with ChanServ - @irc3.event(irc3.rfc.JOIN) def on_join(self, mask, channel, **kwargs): """Triggered when a channel is joined by someone, including the bot itself""" if mask.nick == self.bot.nick: # the bot just joined a channel - if channel in self.get_managed_team_channels() or channel == settings.IRCBOT_PUBLIC_CHANNEL or channel == settings.IRCBOT_VOLUNTEER_CHANNEL: - logger.debug("Just joined a channel I am supposed to be managing, asking ChanServ for info about %s" % channel) + if ( + channel in self.get_managed_team_channels() + or channel == settings.IRCBOT_PUBLIC_CHANNEL + or channel == settings.IRCBOT_VOLUNTEER_CHANNEL + ): + logger.debug( + "Just joined a channel I am supposed to be managing, asking ChanServ for info about %s" + % channel + ) self.bot.privmsg(settings.IRCBOT_CHANSERV_MASK, "info %s" % channel) return - @irc3.event(irc3.rfc.PRIVMSG) def on_privmsg(self, **kwargs): """triggered when a privmsg is sent to the bot or to a channel the bot is in""" # we only handle NOTICEs for now - if kwargs['event'] != "NOTICE": + if kwargs["event"] != "NOTICE": return logger.debug("inside on_privmsg(), kwargs: %s" % kwargs) # check if this is a message from nickserv - if kwargs['mask'] == "NickServ!%s" % settings.IRCBOT_NICKSERV_MASK: + if kwargs["mask"] == "NickServ!%s" % settings.IRCBOT_NICKSERV_MASK: self.bot.handle_nickserv_privmsg(**kwargs) # check if this is a message from chanserv - if kwargs['mask'] == "ChanServ!%s" % settings.IRCBOT_CHANSERV_MASK: + if kwargs["mask"] == "ChanServ!%s" % settings.IRCBOT_CHANSERV_MASK: self.bot.handle_chanserv_privmsg(**kwargs) - @irc3.event(irc3.rfc.KICK) def on_kick(self, **kwargs): logger.debug("inside on_kick(), kwargs: %s" % kwargs) - ############################################################################################### ### custom irc3 methods below here @@ -102,7 +111,7 @@ class Plugin(object): """ Main periodic method called every N seconds. """ - #logger.debug("inside do_stuff()") + # logger.debug("inside do_stuff()") # call the methods we need to self.bot.check_irc_channels() @@ -110,8 +119,9 @@ class Plugin(object): self.bot.get_outgoing_messages() # schedule a call of this function again in N seconds - self.bot.loop.call_later(settings.IRCBOT_CHECK_MESSAGE_INTERVAL_SECONDS, self.bot.do_stuff) - + self.bot.loop.call_later( + settings.IRCBOT_CHECK_MESSAGE_INTERVAL_SECONDS, self.bot.do_stuff + ) @irc3.extend def get_outgoing_messages(self): @@ -119,13 +129,17 @@ class Plugin(object): This method gets unprocessed OutgoingIrcMessage objects and attempts to send them to the target channel. Messages are skipped if the bot is not in the channel. """ - for msg in OutgoingIrcMessage.objects.filter(processed=False).order_by('created'): + for msg in OutgoingIrcMessage.objects.filter(processed=False).order_by( + "created" + ): logger.info("processing irc message to %s: %s" % (msg.target, msg.message)) # if this message expired mark it as expired and processed without doing anything if msg.timeout < timezone.now(): - logger.info("this message is expired, marking it as such instead of sending it to irc") - msg.expired=True - msg.processed=True + logger.info( + "this message is expired, marking it as such instead of sending it to irc" + ) + msg.expired = True + msg.processed = True msg.save() continue @@ -133,17 +147,16 @@ class Plugin(object): if msg.target[0] == "#" and msg.target in self.bot.channels: logger.info("sending privmsg to %s: %s" % (msg.target, msg.message)) self.bot.privmsg(msg.target, msg.message) - msg.processed=True + msg.processed = True msg.save() elif msg.target: logger.info("sending privmsg to %s: %s" % (msg.target, msg.message)) self.bot.privmsg(msg.target, msg.message) - msg.processed=True + msg.processed = True msg.save() else: logger.warning("skipping message to %s" % msg.target) - ############################################################################################### ### irc channel methods @@ -154,12 +167,14 @@ class Plugin(object): Join or part channels as needed. """ desired_channel_list = self.bot.get_desired_channel_list() - #logger.debug("Inside check_irc_channels(), desired_channel_list is: %s and self.bot.channels is: %s" % (desired_channel_list, self.bot.channels.keys())) + # logger.debug("Inside check_irc_channels(), desired_channel_list is: %s and self.bot.channels is: %s" % (desired_channel_list, self.bot.channels.keys())) # loop over desired_channel_list, join as needed for channel in desired_channel_list: if channel not in self.bot.channels: - logger.debug("I should be in %s but I am not, attempting to join..." % channel) + logger.debug( + "I should be in %s but I am not, attempting to join..." % channel + ) self.bot.join(channel) # loop over self.bot.channels, part as needed @@ -168,7 +183,6 @@ class Plugin(object): logger.debug("I am in %s but I shouldn't be, parting..." % channel) self.bot.part(channel, "I am no longer needed here") - @irc3.extend def get_desired_channel_list(self): """ @@ -180,7 +194,6 @@ class Plugin(object): desired_channel_list.append(settings.IRCBOT_VOLUNTEER_CHANNEL) return desired_channel_list - @irc3.extend def get_managed_team_channels(self): """ @@ -189,18 +202,17 @@ class Plugin(object): pubchans = Team.objects.filter( public_irc_channel_name__isnull=False, public_irc_channel_bot=True, - public_irc_channel_managed=True + public_irc_channel_managed=True, ).values_list("public_irc_channel_name", flat=True) privchans = Team.objects.filter( private_irc_channel_name__isnull=False, private_irc_channel_bot=True, - private_irc_channel_managed=True + private_irc_channel_managed=True, ).values_list("private_irc_channel_name", flat=True) return list(pubchans) + list(privchans) - @irc3.extend def get_unmanaged_team_channels(self): """ @@ -209,18 +221,17 @@ class Plugin(object): pubchans = Team.objects.filter( public_irc_channel_name__isnull=False, public_irc_channel_bot=True, - public_irc_channel_managed=False + public_irc_channel_managed=False, ).values_list("public_irc_channel_name", flat=True) privchans = Team.objects.filter( private_irc_channel_name__isnull=False, private_irc_channel_bot=True, - private_irc_channel_managed=False + private_irc_channel_managed=False, ).values_list("private_irc_channel_name", flat=True) return list(pubchans) + list(privchans) - @irc3.extend def setup_private_channel(self, channel): """ @@ -231,13 +242,13 @@ class Plugin(object): # basic private channel modes self.bot.privmsg(settings.IRCBOT_CHANSERV_MASK, "SET %s mlock +inpst" % channel) self.bot.privmsg(settings.IRCBOT_CHANSERV_MASK, "SET %s SECURE on" % channel) - self.bot.privmsg(settings.IRCBOT_CHANSERV_MASK, "SET %s RESTRICTED on" % channel) + self.bot.privmsg( + settings.IRCBOT_CHANSERV_MASK, "SET %s RESTRICTED on" % channel + ) # add the bot to the ACL self.bot.add_user_to_channel_acl( - username=settings.IRCBOT_NICK, - channel=channel, - invite=True + username=settings.IRCBOT_NICK, channel=channel, invite=True ) team = get_team_from_irc_channel(channel) @@ -245,10 +256,9 @@ class Plugin(object): # this is a team channel, add team members to channel ACL self.bot.add_team_members_to_channel_acl(team) # make sure private_irc_channel_fix_needed is set to False and save - team.private_irc_channel_fix_needed=False + team.private_irc_channel_fix_needed = False team.save() - @irc3.extend def setup_public_channel(self, channel): """ @@ -259,17 +269,18 @@ class Plugin(object): # basic private channel modes self.bot.privmsg(settings.IRCBOT_CHANSERV_MASK, "SET %s mlock +nt-lk" % channel) self.bot.privmsg(settings.IRCBOT_CHANSERV_MASK, "SET %s SECURE off" % channel) - self.bot.privmsg(settings.IRCBOT_CHANSERV_MASK, "SET %s RESTRICTED off" % channel) + self.bot.privmsg( + settings.IRCBOT_CHANSERV_MASK, "SET %s RESTRICTED off" % channel + ) team = get_team_from_irc_channel(channel) if team: # add members to ACL self.bot.add_team_members_to_channel_acl(team) # make sure public_irc_channel_fix_needed is set to False and save - team.public_irc_channel_fix_needed=False + team.public_irc_channel_fix_needed = False team.save() - @irc3.extend def add_team_members_to_channel_acl(self, team): """ @@ -279,10 +290,9 @@ class Plugin(object): # add all members to the acl for membership in team.memberships.all(): if membership.approved and membership.user.profile.nickserv_username: - membership.irc_acl_fix_needed=True + membership.irc_acl_fix_needed = True membership.save() - @irc3.extend def add_user_to_channel_acl(self, username, channel, invite): """ @@ -291,16 +301,12 @@ class Plugin(object): # set autoop for this username self.bot.privmsg( settings.IRCBOT_CHANSERV_MASK, - "flags %(channel)s %(user)s +oO" % { - 'channel': channel, - 'user': username, - }, + "flags %(channel)s %(user)s +oO" % {"channel": channel, "user": username}, ) if invite: # also add autoinvite for this username - self.bot.mode(channel, '+I', '$a:%s' % username) - + self.bot.mode(channel, "+I", "$a:%s" % username) @irc3.extend def fix_missing_acls(self): @@ -310,54 +316,66 @@ class Plugin(object): Loops over Team objects and fixes permissions and ACLS as needed """ # first find all TeamMember objects which needs a loving hand - missing_acls = TeamMember.objects.filter( - irc_acl_fix_needed=True - ).exclude( - user__profile__nickserv_username='' + missing_acls = TeamMember.objects.filter(irc_acl_fix_needed=True).exclude( + user__profile__nickserv_username="" ) # loop over them and fix what needs to be fixed if missing_acls: - logger.debug("Found %s memberships which need IRC ACL fixing.." % missing_acls.count()) + logger.debug( + "Found %s memberships which need IRC ACL fixing.." + % missing_acls.count() + ) for membership in missing_acls: # add to team public channel? - if membership.team.public_irc_channel_name and membership.team.public_irc_channel_managed: + if ( + membership.team.public_irc_channel_name + and membership.team.public_irc_channel_managed + ): self.bot.add_user_to_channel_acl( username=membership.user.profile.nickserv_username, channel=membership.team.public_irc_channel_name, - invite=False + invite=False, ) # add to team private channel? - if membership.team.private_irc_channel_name and membership.team.private_irc_channel_managed: + if ( + membership.team.private_irc_channel_name + and membership.team.private_irc_channel_managed + ): self.bot.add_user_to_channel_acl( username=membership.user.profile.nickserv_username, channel=membership.team.private_irc_channel_name, - invite=True + invite=True, ) # add to volunteer channel self.bot.add_user_to_channel_acl( username=membership.user.profile.nickserv_username, channel=settings.IRCBOT_VOLUNTEER_CHANNEL, - invite=True + invite=True, ) # mark membership as irc_acl_fix_needed=False and save - membership.irc_acl_fix_needed=False + membership.irc_acl_fix_needed = False membership.save() # loop over teams where the private channel needs fixing for team in Team.objects.filter(private_irc_channel_fix_needed=True): - logger.debug("Team %s private IRC channel %s needs ACL fixing" % (team, team.private_irc_channel_name)) + logger.debug( + "Team %s private IRC channel %s needs ACL fixing" + % (team, team.private_irc_channel_name) + ) self.bot.setup_private_channel(team.private_irc_channel_name) # loop over teams where the public channel needs fixing for team in Team.objects.filter(public_irc_channel_fix_needed=True): - logger.debug("Team %s public IRC channel %s needs ACL fixing" % (team, team.public_irc_channel_name)) + logger.debug( + "Team %s public IRC channel %s needs ACL fixing" + % (team, team.public_irc_channel_name) + ) self.bot.setup_public_channel(team.public_irc_channel_name) - ############################################################################################### ### services (ChanServ & NickServ) methods @@ -371,30 +389,50 @@ class Plugin(object): ############################################### # handle "Channel \x02#example\x02 is not registered." message ############################################### - match = re.compile("Channel (#[a-zA-Z0-9-]+) is not registered.").match(kwargs['data'].replace("\x02", "")) + match = re.compile("Channel (#[a-zA-Z0-9-]+) is not registered.").match( + kwargs["data"].replace("\x02", "") + ) if match: # the irc channel is not registered channel = match.group(1) # get a list of the channels we are supposed to be managing - if channel in self.bot.get_managed_team_channels() or channel == settings.IRCBOT_VOLUNTEER_CHANNEL: + if ( + channel in self.bot.get_managed_team_channels() + or channel == settings.IRCBOT_VOLUNTEER_CHANNEL + ): # we want to register this channel! though we can only do so if we have a @ in the channel - if self.bot.nick in self.bot.channels[channel].modes['@']: - logger.debug("ChanServ says channel %s is not registered, bot is supposed to be managing this channel, registering it with chanserv" % channel) - self.bot.privmsg(settings.IRCBOT_CHANSERV_MASK, "register %s" % channel) + if self.bot.nick in self.bot.channels[channel].modes["@"]: + logger.debug( + "ChanServ says channel %s is not registered, bot is supposed to be managing this channel, registering it with chanserv" + % channel + ) + self.bot.privmsg( + settings.IRCBOT_CHANSERV_MASK, "register %s" % channel + ) else: - logger.debug("ChanServ says channel %s is not registered, bot is supposed to be managing this channel, but the bot cannot register without @ in the channel" % channel) - self.bot.privmsg(channel, "I need @ before I can register this channel with ChanServ") + logger.debug( + "ChanServ says channel %s is not registered, bot is supposed to be managing this channel, but the bot cannot register without @ in the channel" + % channel + ) + self.bot.privmsg( + channel, + "I need @ before I can register this channel with ChanServ", + ) return ############################################### # handle "\x02#example\x02 is now registered to \x02tykbhdev\x02" message ############################################### - match = re.compile("(#[a-zA-Z0-9-]+) is now registered to ([a-zA-Z0-9-]+)\\.").match(kwargs['data'].replace("\x02", "")) + match = re.compile( + "(#[a-zA-Z0-9-]+) is now registered to ([a-zA-Z0-9-]+)\\." + ).match(kwargs["data"].replace("\x02", "")) if match: # the irc channel is now registered channel = match.group(1) botnick = match.group(2) - logger.debug("Channel %s was registered with ChanServ, looking up Team..." % channel) + logger.debug( + "Channel %s was registered with ChanServ, looking up Team..." % channel + ) team = get_team_from_irc_channel(channel) if team: @@ -414,8 +452,7 @@ class Plugin(object): # lets handle the volunteer channels initial ACL manually.. return - logger.debug("Unhandled ChanServ message: %s" % kwargs['data']) - + logger.debug("Unhandled ChanServ message: %s" % kwargs["data"]) @irc3.extend def handle_nickserv_privmsg(self, **kwargs): @@ -425,10 +462,13 @@ class Plugin(object): logger.debug("Got a message from NickServ") # handle "\x02botnick\x02 is not a registered nickname." message - if kwargs['data'] == '\x02%s\x02 is not a registered nickname.' % self.bot.nick: + if kwargs["data"] == "\x02%s\x02 is not a registered nickname." % self.bot.nick: # the bots nickname is not registered, register new account with nickserv - self.bot.privmsg(settings.IRCBOT_NICKSERV_MASK, "register %s %s" % (settings.IRCBOT_NICKSERV_PASSWORD, settings.IRCBOT_NICKSERV_EMAIL)) + self.bot.privmsg( + settings.IRCBOT_NICKSERV_MASK, + "register %s %s" + % (settings.IRCBOT_NICKSERV_PASSWORD, settings.IRCBOT_NICKSERV_EMAIL), + ) return - logger.debug("Unhandled NickServ message: %s" % kwargs['data']) - + logger.debug("Unhandled NickServ message: %s" % kwargs["data"]) diff --git a/src/ircbot/ircworker.py b/src/ircbot/ircworker.py index 5e5fb8d2..38e05d43 100644 --- a/src/ircbot/ircworker.py +++ b/src/ircbot/ircworker.py @@ -2,31 +2,32 @@ from django.conf import settings import logging import irc3 from events.models import Routing + logging.basicConfig(level=logging.INFO) -logger = logging.getLogger('bornhack.%s' % __name__) +logger = logging.getLogger("bornhack.%s" % __name__) def do_work(): """ Run irc3 module code, wait for events on IRC and wait for messages in OutgoingIrcMessage """ - if hasattr(settings, 'IRCBOT_CHANNELS'): - logger.error("settings.IRCBOT_CHANNELS is deprecated. Please define settings.IRCBOT_PUBLIC_CHANNEL and use team channels for the rest.") + if hasattr(settings, "IRCBOT_CHANNELS"): + logger.error( + "settings.IRCBOT_CHANNELS is deprecated. Please define settings.IRCBOT_PUBLIC_CHANNEL and use team channels for the rest." + ) return False config = { - 'nick': settings.IRCBOT_NICK, - 'autojoins': [], - 'host': settings.IRCBOT_SERVER_HOSTNAME, - 'port': settings.IRCBOT_SERVER_PORT, - 'ssl': settings.IRCBOT_SERVER_USETLS, - 'timeout': 30, - 'flood_burst': 2, - 'flood_rate': 1, - 'flood_rate_delay': 2, - 'includes': [ - 'ircbot.irc3module', - ], + "nick": settings.IRCBOT_NICK, + "autojoins": [], + "host": settings.IRCBOT_SERVER_HOSTNAME, + "port": settings.IRCBOT_SERVER_PORT, + "ssl": settings.IRCBOT_SERVER_USETLS, + "timeout": 30, + "flood_burst": 2, + "flood_rate": 1, + "flood_rate_delay": 2, + "includes": ["ircbot.irc3module"], } logger.debug("Connecting to IRC with the following config: %s" % config) try: @@ -34,4 +35,3 @@ def do_work(): except Exception as E: logger.exception("Got exception inside do_work for %s" % self.workermodule) raise E - diff --git a/src/ircbot/migrations/0001_initial.py b/src/ircbot/migrations/0001_initial.py index 538b591e..714a03e9 100644 --- a/src/ircbot/migrations/0001_initial.py +++ b/src/ircbot/migrations/0001_initial.py @@ -9,22 +9,27 @@ class Migration(migrations.Migration): initial = True - dependencies = [ - ] + dependencies = [] operations = [ migrations.CreateModel( - name='OutgoingIrcMessage', + name="OutgoingIrcMessage", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('created', models.DateTimeField(auto_now_add=True)), - ('updated', models.DateTimeField(auto_now=True)), - ('target', models.CharField(max_length=100)), - ('message', models.CharField(max_length=200)), - ('processed', models.BooleanField(default=False)), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("created", models.DateTimeField(auto_now_add=True)), + ("updated", models.DateTimeField(auto_now=True)), + ("target", models.CharField(max_length=100)), + ("message", models.CharField(max_length=200)), + ("processed", models.BooleanField(default=False)), ], - options={ - 'abstract': False, - }, - ), + options={"abstract": False}, + ) ] diff --git a/src/ircbot/migrations/0002_outgoingircmessage_timeout.py b/src/ircbot/migrations/0002_outgoingircmessage_timeout.py index 16e455bc..9ee22912 100644 --- a/src/ircbot/migrations/0002_outgoingircmessage_timeout.py +++ b/src/ircbot/migrations/0002_outgoingircmessage_timeout.py @@ -9,15 +9,15 @@ from django.utils.timezone import utc class Migration(migrations.Migration): - dependencies = [ - ('ircbot', '0001_initial'), - ] + dependencies = [("ircbot", "0001_initial")] operations = [ migrations.AddField( - model_name='outgoingircmessage', - name='timeout', - field=models.DateTimeField(default=datetime.datetime(2017, 1, 31, 17, 49, 36, 925459, tzinfo=utc)), + model_name="outgoingircmessage", + name="timeout", + field=models.DateTimeField( + default=datetime.datetime(2017, 1, 31, 17, 49, 36, 925459, tzinfo=utc) + ), preserve_default=False, - ), + ) ] diff --git a/src/ircbot/migrations/0003_outgoingircmessage_expired.py b/src/ircbot/migrations/0003_outgoingircmessage_expired.py index 83d1c666..69718d2b 100644 --- a/src/ircbot/migrations/0003_outgoingircmessage_expired.py +++ b/src/ircbot/migrations/0003_outgoingircmessage_expired.py @@ -7,14 +7,12 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ - ('ircbot', '0002_outgoingircmessage_timeout'), - ] + dependencies = [("ircbot", "0002_outgoingircmessage_timeout")] operations = [ migrations.AddField( - model_name='outgoingircmessage', - name='expired', + model_name="outgoingircmessage", + name="expired", field=models.BooleanField(default=False), - ), + ) ] diff --git a/src/ircbot/models.py b/src/ircbot/models.py index 05b56ead..c52e78ff 100644 --- a/src/ircbot/models.py +++ b/src/ircbot/models.py @@ -12,11 +12,14 @@ class OutgoingIrcMessage(CreatedUpdatedModel): expired = models.BooleanField(default=False) def __str__(self): - return "PRIVMSG %s %s (%s)" % (self.target, self.message, 'processed' if self.processed else 'unprocessed') + return "PRIVMSG %s %s (%s)" % ( + self.target, + self.message, + "processed" if self.processed else "unprocessed", + ) def clean(self): if not self.pk: # this is a new outgoing message being saved if self.timeout < timezone.now(): - raise ValidationError({'timeout': 'The timeout can not be in the past'}) - + raise ValidationError({"timeout": "The timeout can not be in the past"}) diff --git a/src/ircbot/utils.py b/src/ircbot/utils.py index dfb27b69..a5388f00 100644 --- a/src/ircbot/utils.py +++ b/src/ircbot/utils.py @@ -2,6 +2,7 @@ from django.conf import settings from django.utils import timezone from datetime import timedelta import logging + logger = logging.getLogger("bornhack.%s" % __name__) @@ -11,11 +12,9 @@ def add_irc_message(target, message, timeout=10): Defaults to a message timeout of 10 minutes """ from .models import OutgoingIrcMessage + OutgoingIrcMessage.objects.create( target=target, message=message, - timeout=timezone.now()+timedelta(minutes=timeout), + timeout=timezone.now() + timedelta(minutes=timeout), ) - - - diff --git a/src/manage.py b/src/manage.py index 1e3fe86b..9a63df75 100755 --- a/src/manage.py +++ b/src/manage.py @@ -5,10 +5,7 @@ import sys sys.path.append(os.path.dirname(__file__)) if __name__ == "__main__": - os.environ.setdefault( - "DJANGO_SETTINGS_MODULE", - "bornhack.settings" - ) + os.environ.setdefault("DJANGO_SETTINGS_MODULE", "bornhack.settings") from django.core.management import execute_from_command_line diff --git a/src/news/admin.py b/src/news/admin.py index ea5a22a9..0480665f 100644 --- a/src/news/admin.py +++ b/src/news/admin.py @@ -5,15 +5,15 @@ from . import models @admin.register(models.NewsItem) class NewsItemModelAdmin(admin.ModelAdmin): - list_display = ['title', 'published_at', 'archived'] - actions = ['archive_news_items', 'unarchive_news_items'] + list_display = ["title", "published_at", "archived"] + actions = ["archive_news_items", "unarchive_news_items"] def archive_news_items(self, request, queryset): queryset.filter(archived=False).update(archived=True) - archive_news_items.description = 'Mark newsitem(s) as archived' + + archive_news_items.description = "Mark newsitem(s) as archived" def unarchive_news_items(self, request, queryset): queryset.filter(archived=True).update(archived=False) - unarchive_news_items.description = 'Mark newsitem(s) as not archived' - + unarchive_news_items.description = "Mark newsitem(s) as not archived" diff --git a/src/news/apps.py b/src/news/apps.py index 5a7b92d0..42c63baa 100644 --- a/src/news/apps.py +++ b/src/news/apps.py @@ -2,4 +2,4 @@ from django.apps import AppConfig class NewsConfig(AppConfig): - name = 'news' + name = "news" diff --git a/src/news/migrations/0001_initial.py b/src/news/migrations/0001_initial.py index 24e2a719..c263802e 100644 --- a/src/news/migrations/0001_initial.py +++ b/src/news/migrations/0001_initial.py @@ -9,23 +9,28 @@ class Migration(migrations.Migration): initial = True - dependencies = [ - ] + dependencies = [] operations = [ migrations.CreateModel( - name='NewsItem', + name="NewsItem", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('created', models.DateTimeField(auto_now_add=True)), - ('updated', models.DateTimeField(auto_now=True)), - ('title', models.CharField(max_length=100)), - ('content', models.TextField()), - ('public', models.BooleanField(default=False)), - ('published_at', models.DateTimeField()), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("created", models.DateTimeField(auto_now_add=True)), + ("updated", models.DateTimeField(auto_now=True)), + ("title", models.CharField(max_length=100)), + ("content", models.TextField()), + ("public", models.BooleanField(default=False)), + ("published_at", models.DateTimeField()), ], - options={ - 'abstract': False, - }, - ), + options={"abstract": False}, + ) ] diff --git a/src/news/migrations/0002_auto_20160530_2223.py b/src/news/migrations/0002_auto_20160530_2223.py index 2814320d..96e46eda 100644 --- a/src/news/migrations/0002_auto_20160530_2223.py +++ b/src/news/migrations/0002_auto_20160530_2223.py @@ -7,13 +7,10 @@ from django.db import migrations class Migration(migrations.Migration): - dependencies = [ - ('news', '0001_initial'), - ] + dependencies = [("news", "0001_initial")] operations = [ migrations.AlterModelOptions( - name='newsitem', - options={'ordering': ['-published_at']}, - ), + name="newsitem", options={"ordering": ["-published_at"]} + ) ] diff --git a/src/news/migrations/0003_newsitem_slug.py b/src/news/migrations/0003_newsitem_slug.py index af57db5e..bb798ba8 100644 --- a/src/news/migrations/0003_newsitem_slug.py +++ b/src/news/migrations/0003_newsitem_slug.py @@ -7,15 +7,13 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ - ('news', '0002_auto_20160530_2223'), - ] + dependencies = [("news", "0002_auto_20160530_2223")] operations = [ migrations.AddField( - model_name='newsitem', - name='slug', - field=models.SlugField(default=''), + model_name="newsitem", + name="slug", + field=models.SlugField(default=""), preserve_default=False, - ), + ) ] diff --git a/src/news/migrations/0004_auto_20160610_1743.py b/src/news/migrations/0004_auto_20160610_1743.py index 18b6285e..0aba1bb8 100644 --- a/src/news/migrations/0004_auto_20160610_1743.py +++ b/src/news/migrations/0004_auto_20160610_1743.py @@ -7,14 +7,10 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ - ('news', '0003_newsitem_slug'), - ] + dependencies = [("news", "0003_newsitem_slug")] operations = [ migrations.AlterField( - model_name='newsitem', - name='slug', - field=models.SlugField(max_length=255), - ), + model_name="newsitem", name="slug", field=models.SlugField(max_length=255) + ) ] diff --git a/src/news/migrations/0005_auto_20160618_1902.py b/src/news/migrations/0005_auto_20160618_1902.py index d80a85f8..b93370e0 100644 --- a/src/news/migrations/0005_auto_20160618_1902.py +++ b/src/news/migrations/0005_auto_20160618_1902.py @@ -7,14 +7,12 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ - ('news', '0004_auto_20160610_1743'), - ] + dependencies = [("news", "0004_auto_20160610_1743")] operations = [ migrations.AlterField( - model_name='newsitem', - name='slug', + model_name="newsitem", + name="slug", field=models.SlugField(blank=True, max_length=255), - ), + ) ] diff --git a/src/news/migrations/0006_remove_newsitem_public.py b/src/news/migrations/0006_remove_newsitem_public.py index 32333cec..0ffeff62 100644 --- a/src/news/migrations/0006_remove_newsitem_public.py +++ b/src/news/migrations/0006_remove_newsitem_public.py @@ -7,13 +7,6 @@ from django.db import migrations class Migration(migrations.Migration): - dependencies = [ - ('news', '0005_auto_20160618_1902'), - ] + dependencies = [("news", "0005_auto_20160618_1902")] - operations = [ - migrations.RemoveField( - model_name='newsitem', - name='public', - ), - ] + operations = [migrations.RemoveField(model_name="newsitem", name="public")] diff --git a/src/news/migrations/0007_auto_20161220_1136.py b/src/news/migrations/0007_auto_20161220_1136.py index 16cd134c..7e22352a 100644 --- a/src/news/migrations/0007_auto_20161220_1136.py +++ b/src/news/migrations/0007_auto_20161220_1136.py @@ -7,14 +7,12 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ - ('news', '0006_remove_newsitem_public'), - ] + dependencies = [("news", "0006_remove_newsitem_public")] operations = [ migrations.AlterField( - model_name='newsitem', - name='published_at', + model_name="newsitem", + name="published_at", field=models.DateTimeField(blank=True, null=True), - ), + ) ] diff --git a/src/news/migrations/0008_newsitem_archived.py b/src/news/migrations/0008_newsitem_archived.py index 3569e1bb..75b63f46 100644 --- a/src/news/migrations/0008_newsitem_archived.py +++ b/src/news/migrations/0008_newsitem_archived.py @@ -7,14 +7,12 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ - ('news', '0007_auto_20161220_1136'), - ] + dependencies = [("news", "0007_auto_20161220_1136")] operations = [ migrations.AddField( - model_name='newsitem', - name='archived', + model_name="newsitem", + name="archived", field=models.BooleanField(default=False), - ), + ) ] diff --git a/src/news/models.py b/src/news/models.py index 31322fea..933d312b 100644 --- a/src/news/models.py +++ b/src/news/models.py @@ -9,7 +9,7 @@ from utils.models import CreatedUpdatedModel @encoding.python_2_unicode_compatible class NewsItem(CreatedUpdatedModel): class Meta: - ordering = ['-published_at'] + ordering = ["-published_at"] title = models.CharField(max_length=100) content = models.TextField() @@ -23,20 +23,23 @@ class NewsItem(CreatedUpdatedModel): def save(self, **kwargs): if self.published_at: # if this is a new newsitem, or it doesn't have a slug, or the slug is in use on another item, create a new slug - if (not self.pk or not self.slug or NewsItem.objects.filter(slug=self.slug).count() > 1): - published_at_string = self.published_at.strftime('%Y-%m-%d') + if ( + not self.pk + or not self.slug + or NewsItem.objects.filter(slug=self.slug).count() > 1 + ): + published_at_string = self.published_at.strftime("%Y-%m-%d") base_slug = slugify(self.title) - slug = '{}-{}'.format(published_at_string, base_slug) + slug = "{}-{}".format(published_at_string, base_slug) incrementer = 1 # We have to make sure that the slug won't clash with current slugs while NewsItem.objects.filter(slug=slug).exists(): if incrementer == 1: - slug = '{}-1'.format(slug) + slug = "{}-1".format(slug) else: - slug = '{}-{}'.format( - '-'.join(slug.split('-')[:-1]), - incrementer + slug = "{}-{}".format( + "-".join(slug.split("-")[:-1]), incrementer ) incrementer += 1 self.slug = slug @@ -44,4 +47,4 @@ class NewsItem(CreatedUpdatedModel): super(NewsItem, self).save(**kwargs) def get_absolute_url(self): - return reverse('news:detail', kwargs={"slug": self.slug}) + return reverse("news:detail", kwargs={"slug": self.slug}) diff --git a/src/news/urls.py b/src/news/urls.py index af6127ad..a9786537 100644 --- a/src/news/urls.py +++ b/src/news/urls.py @@ -1,11 +1,12 @@ from django.urls import path from . import views -app_name = 'news' +app_name = "news" urlpatterns = [ - path('', views.NewsIndex.as_view(), kwargs={'archived': False}, name='index'), - path('archive/', views.NewsIndex.as_view(), kwargs={'archived': True}, name='archive'), - path('feed/', views.NewsFeed(), name='feed'), - path('/', views.NewsDetail.as_view(), name='detail'), + path("", views.NewsIndex.as_view(), kwargs={"archived": False}, name="index"), + path( + "archive/", views.NewsIndex.as_view(), kwargs={"archived": True}, name="archive" + ), + path("feed/", views.NewsFeed(), name="feed"), + path("/", views.NewsDetail.as_view(), name="detail"), ] - diff --git a/src/news/views.py b/src/news/views.py index 79220bc4..a2a48385 100644 --- a/src/news/views.py +++ b/src/news/views.py @@ -9,19 +9,17 @@ def news_items_queryset(kwargs=None): if not kwargs: archived = False else: - archived = kwargs['archived'] + archived = kwargs["archived"] return NewsItem.objects.filter( - published_at__isnull=False, - published_at__lt=timezone.now(), - archived=archived + published_at__isnull=False, published_at__lt=timezone.now(), archived=archived ) class NewsIndex(ListView): model = NewsItem - template_name = 'news_index.html' - context_object_name = 'news_items' + template_name = "news_index.html" + context_object_name = "news_items" def get_queryset(self): return news_items_queryset(self.kwargs) @@ -29,8 +27,8 @@ class NewsIndex(ListView): class NewsDetail(DetailView): model = NewsItem - template_name = 'news_detail.html' - context_object_name = 'news_item' + template_name = "news_detail.html" + context_object_name = "news_item" class NewsFeed(Feed): diff --git a/src/people/apps.py b/src/people/apps.py index 3eae75ac..6f0c0bdf 100644 --- a/src/people/apps.py +++ b/src/people/apps.py @@ -2,4 +2,4 @@ from django.apps import AppConfig class PeopleConfig(AppConfig): - name = 'people' + name = "people" diff --git a/src/people/views.py b/src/people/views.py index 570e3e7e..c79eb27f 100644 --- a/src/people/views.py +++ b/src/people/views.py @@ -3,6 +3,5 @@ from camps.models import Camp class PeopleView(ListView): - template_name = 'people.html' + template_name = "people.html" model = Camp - diff --git a/src/profiles/__init__.py b/src/profiles/__init__.py index 562016c4..0f62d3a7 100644 --- a/src/profiles/__init__.py +++ b/src/profiles/__init__.py @@ -1,2 +1 @@ -default_app_config = 'profiles.apps.ProfilesConfig' - +default_app_config = "profiles.apps.ProfilesConfig" diff --git a/src/profiles/admin.py b/src/profiles/admin.py index 795ccad4..7fe243a1 100644 --- a/src/profiles/admin.py +++ b/src/profiles/admin.py @@ -4,23 +4,20 @@ from .models import Profile @admin.register(Profile) class OrderAdmin(admin.ModelAdmin): - actions = ['approve_public_credit_names'] + actions = ["approve_public_credit_names"] list_display = [ - 'user', - 'name', - 'description', - 'public_credit_name', - 'public_credit_name_approved', + "user", + "name", + "description", + "public_credit_name", + "public_credit_name_approved", ] - list_filter = [ - 'public_credit_name_approved', - ] + list_filter = ["public_credit_name_approved"] def approve_public_credit_names(self, request, queryset): for profile in queryset.filter(public_credit_name_approved=False): profile.approve_public_credit_name() - approve_public_credit_names.description = 'Approve Public Credit Name(s)' - + approve_public_credit_names.description = "Approve Public Credit Name(s)" diff --git a/src/profiles/apps.py b/src/profiles/apps.py index 307b5f7c..dcd296dd 100644 --- a/src/profiles/apps.py +++ b/src/profiles/apps.py @@ -2,15 +2,22 @@ from django.apps import AppConfig from django.db.models.signals import pre_save, post_save from .signal_handlers import create_profile, profile_pre_save import logging + logger = logging.getLogger("bornhack.%s" % __name__) class ProfilesConfig(AppConfig): - name = 'profiles' + name = "profiles" def ready(self): # remember to include a dispatch_uid to prevent signals being called multiple times in certain corner cases from django.contrib.auth.models import User - post_save.connect(create_profile, sender=User, dispatch_uid='user_post_save_signal') - pre_save.connect(profile_pre_save, sender='profiles.Profile', dispatch_uid='profile_pre_save_signal') + post_save.connect( + create_profile, sender=User, dispatch_uid="user_post_save_signal" + ) + pre_save.connect( + profile_pre_save, + sender="profiles.Profile", + dispatch_uid="profile_pre_save_signal", + ) diff --git a/src/profiles/migrations/0001_initial.py b/src/profiles/migrations/0001_initial.py index e4617e2c..0f1b8e02 100644 --- a/src/profiles/migrations/0001_initial.py +++ b/src/profiles/migrations/0001_initial.py @@ -8,22 +8,33 @@ import uuid class Migration(migrations.Migration): - dependencies = [ - migrations.swappable_dependency(settings.AUTH_USER_MODEL), - ] + dependencies = [migrations.swappable_dependency(settings.AUTH_USER_MODEL)] operations = [ migrations.CreateModel( - name='Profile', + name="Profile", fields=[ - ('created', models.DateTimeField(auto_now_add=True)), - ('updated', models.DateTimeField(auto_now=True)), - ('uuid', models.UUIDField(serialize=False, editable=False, primary_key=True, default=uuid.uuid4)), - ('user', models.OneToOneField(on_delete=models.PROTECT, to=settings.AUTH_USER_MODEL, help_text='The django user this profile belongs to.', verbose_name='User')), + ("created", models.DateTimeField(auto_now_add=True)), + ("updated", models.DateTimeField(auto_now=True)), + ( + "uuid", + models.UUIDField( + serialize=False, + editable=False, + primary_key=True, + default=uuid.uuid4, + ), + ), + ( + "user", + models.OneToOneField( + on_delete=models.PROTECT, + to=settings.AUTH_USER_MODEL, + help_text="The django user this profile belongs to.", + verbose_name="User", + ), + ), ], - options={ - 'verbose_name_plural': 'Profiles', - 'verbose_name': 'Profile', - }, - ), + options={"verbose_name_plural": "Profiles", "verbose_name": "Profile"}, + ) ] diff --git a/src/profiles/migrations/0002_profile_description.py b/src/profiles/migrations/0002_profile_description.py index f53796c4..19785700 100644 --- a/src/profiles/migrations/0002_profile_description.py +++ b/src/profiles/migrations/0002_profile_description.py @@ -7,14 +7,15 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ - ('profiles', '0001_initial'), - ] + dependencies = [("profiles", "0001_initial")] operations = [ migrations.AddField( - model_name='profile', - name='description', - field=models.TextField(default='', help_text='Please include any info you think could be relevant, like drivers license, first aid certificates, crafts, skills and previous experience.'), - ), + model_name="profile", + name="description", + field=models.TextField( + default="", + help_text="Please include any info you think could be relevant, like drivers license, first aid certificates, crafts, skills and previous experience.", + ), + ) ] diff --git a/src/profiles/migrations/0003_auto_20170413_1703.py b/src/profiles/migrations/0003_auto_20170413_1703.py index 6025455d..2a607029 100644 --- a/src/profiles/migrations/0003_auto_20170413_1703.py +++ b/src/profiles/migrations/0003_auto_20170413_1703.py @@ -7,19 +7,23 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ - ('profiles', '0002_profile_description'), - ] + dependencies = [("profiles", "0002_profile_description")] operations = [ migrations.AddField( - model_name='profile', - name='name', - field=models.CharField(blank=True, default='', help_text='Your name or handle', max_length=200), + model_name="profile", + name="name", + field=models.CharField( + blank=True, default="", help_text="Your name or handle", max_length=200 + ), ), migrations.AlterField( - model_name='profile', - name='description', - field=models.TextField(blank=True, default='', help_text='Please include any info you think could be relevant, like drivers license, first aid certificates, crafts, skills and previous experience.'), + model_name="profile", + name="description", + field=models.TextField( + blank=True, + default="", + help_text="Please include any info you think could be relevant, like drivers license, first aid certificates, crafts, skills and previous experience.", + ), ), ] diff --git a/src/profiles/migrations/0004_auto_20170430_1408.py b/src/profiles/migrations/0004_auto_20170430_1408.py index 78107471..35c40403 100644 --- a/src/profiles/migrations/0004_auto_20170430_1408.py +++ b/src/profiles/migrations/0004_auto_20170430_1408.py @@ -7,14 +7,16 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ - ('profiles', '0003_auto_20170413_1703'), - ] + dependencies = [("profiles", "0003_auto_20170413_1703")] operations = [ migrations.AlterField( - model_name='profile', - name='description', - field=models.TextField(blank=True, default='', help_text='Please include any info you think could be relevant, like drivers license, first aid certificates, crafts, skills and previous experience. Please also include availability if you are not there for the full week.'), - ), + model_name="profile", + name="description", + field=models.TextField( + blank=True, + default="", + help_text="Please include any info you think could be relevant, like drivers license, first aid certificates, crafts, skills and previous experience. Please also include availability if you are not there for the full week.", + ), + ) ] diff --git a/src/profiles/migrations/0005_auto_20170711_1721.py b/src/profiles/migrations/0005_auto_20170711_1721.py index 533bd84e..a385ff4b 100644 --- a/src/profiles/migrations/0005_auto_20170711_1721.py +++ b/src/profiles/migrations/0005_auto_20170711_1721.py @@ -7,19 +7,24 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ - ('profiles', '0004_auto_20170430_1408'), - ] + dependencies = [("profiles", "0004_auto_20170430_1408")] operations = [ migrations.AddField( - model_name='profile', - name='public_credit_name', - field=models.CharField(blank=True, help_text='The name used on the public list of volunteers for this event. Only used if public_credits is True. Not editable by users (to avoid getting junk on the website).', max_length=100), + model_name="profile", + name="public_credit_name", + field=models.CharField( + blank=True, + help_text="The name used on the public list of volunteers for this event. Only used if public_credits is True. Not editable by users (to avoid getting junk on the website).", + max_length=100, + ), ), migrations.AddField( - model_name='profile', - name='public_credits', - field=models.BooleanField(default=False, help_text='Check this box if you want your name to appear in the list of volunteers for this event. Please inform your team responsible what you would like to be credited as.'), + model_name="profile", + name="public_credits", + field=models.BooleanField( + default=False, + help_text="Check this box if you want your name to appear in the list of volunteers for this event. Please inform your team responsible what you would like to be credited as.", + ), ), ] diff --git a/src/profiles/migrations/0006_auto_20170711_1757.py b/src/profiles/migrations/0006_auto_20170711_1757.py index 967d3740..aeee3424 100644 --- a/src/profiles/migrations/0006_auto_20170711_1757.py +++ b/src/profiles/migrations/0006_auto_20170711_1757.py @@ -7,28 +7,35 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ - ('profiles', '0005_auto_20170711_1721'), - ] + dependencies = [("profiles", "0005_auto_20170711_1721")] operations = [ - migrations.RemoveField( - model_name='profile', - name='public_credits', - ), + migrations.RemoveField(model_name="profile", name="public_credits"), migrations.AddField( - model_name='profile', - name='public_credit_name_approved', - field=models.BooleanField(default=False, help_text='Check this box to approve this users public_credit_name. This will be unchecked automatically when the user edits public_credit_name'), + model_name="profile", + name="public_credit_name_approved", + field=models.BooleanField( + default=False, + help_text="Check this box to approve this users public_credit_name. This will be unchecked automatically when the user edits public_credit_name", + ), ), migrations.AlterField( - model_name='profile', - name='name', - field=models.CharField(blank=True, default='', help_text='Your name or handle (only visible to team responsible and organisers)', max_length=200), + model_name="profile", + name="name", + field=models.CharField( + blank=True, + default="", + help_text="Your name or handle (only visible to team responsible and organisers)", + max_length=200, + ), ), migrations.AlterField( - model_name='profile', - name='public_credit_name', - field=models.CharField(blank=True, help_text='The name you want to appear on in the credits section of the public website (the People pages). Leave empty if you want no public credit.', max_length=100), + model_name="profile", + name="public_credit_name", + field=models.CharField( + blank=True, + help_text="The name you want to appear on in the credits section of the public website (the People pages). Leave empty if you want no public credit.", + max_length=100, + ), ), ] diff --git a/src/profiles/migrations/0007_auto_20170711_2025.py b/src/profiles/migrations/0007_auto_20170711_2025.py index 1c2aa69c..25ac5cf3 100644 --- a/src/profiles/migrations/0007_auto_20170711_2025.py +++ b/src/profiles/migrations/0007_auto_20170711_2025.py @@ -4,17 +4,16 @@ from __future__ import unicode_literals from django.db import migrations + def populate_team_responsible_public_credit_names(apps, schema_editor): pass + class Migration(migrations.Migration): dependencies = [ - ('profiles', '0006_auto_20170711_1757'), - ('teams', '0014_remove_teammember_deleted'), - ] - - operations = [ - migrations.RunPython(populate_team_responsible_public_credit_names), + ("profiles", "0006_auto_20170711_1757"), + ("teams", "0014_remove_teammember_deleted"), ] + operations = [migrations.RunPython(populate_team_responsible_public_credit_names)] diff --git a/src/profiles/migrations/0008_auto_20180325_2022.py b/src/profiles/migrations/0008_auto_20180325_2022.py index efe72731..2a6f25a3 100644 --- a/src/profiles/migrations/0008_auto_20180325_2022.py +++ b/src/profiles/migrations/0008_auto_20180325_2022.py @@ -7,14 +7,16 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ - ('profiles', '0007_auto_20170711_2025'), - ] + dependencies = [("profiles", "0007_auto_20170711_2025")] operations = [ migrations.AlterField( - model_name='profile', - name='public_credit_name', - field=models.CharField(blank=True, help_text='The name you want to appear on in the credits section of the public website (on Team and People pages). Leave this empty if you want your name hidden on the public webpages.', max_length=100), - ), + model_name="profile", + name="public_credit_name", + field=models.CharField( + blank=True, + help_text="The name you want to appear on in the credits section of the public website (on Team and People pages). Leave this empty if you want your name hidden on the public webpages.", + max_length=100, + ), + ) ] diff --git a/src/profiles/migrations/0009_profile_nickserv_username.py b/src/profiles/migrations/0009_profile_nickserv_username.py index 0b5bca3c..e24cd105 100644 --- a/src/profiles/migrations/0009_profile_nickserv_username.py +++ b/src/profiles/migrations/0009_profile_nickserv_username.py @@ -7,14 +7,16 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ - ('profiles', '0008_auto_20180325_2022'), - ] + dependencies = [("profiles", "0008_auto_20180325_2022")] operations = [ migrations.AddField( - model_name='profile', - name='nickserv_username', - field=models.CharField(blank=True, help_text='Your NickServ username is used to manage team IRC channel access lists.', max_length=50), - ), + model_name="profile", + name="nickserv_username", + field=models.CharField( + blank=True, + help_text="Your NickServ username is used to manage team IRC channel access lists.", + max_length=50, + ), + ) ] diff --git a/src/profiles/migrations/0010_auto_20180411_2305.py b/src/profiles/migrations/0010_auto_20180411_2305.py index b92f0d9a..7f74dcd6 100644 --- a/src/profiles/migrations/0010_auto_20180411_2305.py +++ b/src/profiles/migrations/0010_auto_20180411_2305.py @@ -7,14 +7,16 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ - ('profiles', '0009_profile_nickserv_username'), - ] + dependencies = [("profiles", "0009_profile_nickserv_username")] operations = [ migrations.AlterField( - model_name='profile', - name='nickserv_username', - field=models.CharField(blank=True, help_text='Your NickServ username is used to manage team IRC channel access lists. Make sure you register with NickServ _before_ you enter the username here!', max_length=50), - ), + model_name="profile", + name="nickserv_username", + field=models.CharField( + blank=True, + help_text="Your NickServ username is used to manage team IRC channel access lists. Make sure you register with NickServ _before_ you enter the username here!", + max_length=50, + ), + ) ] diff --git a/src/profiles/models.py b/src/profiles/models.py index 44a2af88..597ad371 100644 --- a/src/profiles/models.py +++ b/src/profiles/models.py @@ -7,44 +7,44 @@ from utils.models import UUIDModel, CreatedUpdatedModel class Profile(CreatedUpdatedModel, UUIDModel): class Meta: - verbose_name = _('Profile') - verbose_name_plural = _('Profiles') + verbose_name = _("Profile") + verbose_name_plural = _("Profiles") user = models.OneToOneField( User, - verbose_name=_('User'), - help_text=_('The django user this profile belongs to.'), - on_delete=models.PROTECT + verbose_name=_("User"), + help_text=_("The django user this profile belongs to."), + on_delete=models.PROTECT, ) name = models.CharField( max_length=200, - default='', + default="", blank=True, - help_text='Your name or handle (only visible to team responsible and organisers)' + help_text="Your name or handle (only visible to team responsible and organisers)", ) description = models.TextField( - default='', + default="", blank=True, - help_text='Please include any info you think could be relevant, like drivers license, first aid certificates, crafts, skills and previous experience. Please also include availability if you are not there for the full week.', + help_text="Please include any info you think could be relevant, like drivers license, first aid certificates, crafts, skills and previous experience. Please also include availability if you are not there for the full week.", ) public_credit_name = models.CharField( blank=True, max_length=100, - help_text='The name you want to appear on in the credits section of the public website (on Team and People pages). Leave this empty if you want your name hidden on the public webpages.' + help_text="The name you want to appear on in the credits section of the public website (on Team and People pages). Leave this empty if you want your name hidden on the public webpages.", ) public_credit_name_approved = models.BooleanField( default=False, - help_text='Check this box to approve this users public_credit_name. This will be unchecked automatically when the user edits public_credit_name' + help_text="Check this box to approve this users public_credit_name. This will be unchecked automatically when the user edits public_credit_name", ) nickserv_username = models.CharField( blank=True, max_length=50, - help_text='Your NickServ username is used to manage team IRC channel access lists. Make sure you register with NickServ _before_ you enter the username here!', + help_text="Your NickServ username is used to manage team IRC channel access lists. Make sure you register with NickServ _before_ you enter the username here!", ) @property @@ -72,4 +72,3 @@ class Profile(CreatedUpdatedModel, UUIDModel): return self.public_credit_name else: return "Unnamed" - diff --git a/src/profiles/signal_handlers.py b/src/profiles/signal_handlers.py index ea963897..c25b9901 100644 --- a/src/profiles/signal_handlers.py +++ b/src/profiles/signal_handlers.py @@ -1,9 +1,7 @@ -from django.db.models.signals import ( - post_save, - pre_save -) +from django.db.models.signals import post_save, pre_save from events.handler import handle_team_event import logging + logger = logging.getLogger("bornhack.%s" % __name__) @@ -13,6 +11,7 @@ def create_profile(sender, created, instance, **kwargs): Creates a Profile object when the User object was just created. """ from .models import Profile + if created: Profile.objects.create(user=instance) @@ -38,21 +37,21 @@ def public_credit_name_changed(instance, original): # public_credit_name has not been changed return - if original and original.public_credit_name and not original.public_credit_name_approved: + if ( + original + and original.public_credit_name + and not original.public_credit_name_approved + ): # the original.public_credit_name was not approved, no need to notify again return # put the message together - message='User {username} changed public credit name. please review and act accordingly: https://bornhack.dk/admin/profiles/profile/{uuid}/change/'.format( - username=instance.name, - uuid=instance.uuid + message = "User {username} changed public credit name. please review and act accordingly: https://bornhack.dk/admin/profiles/profile/{uuid}/change/".format( + username=instance.name, uuid=instance.uuid ) # trigger the event - handle_team_event( - eventtype='public_credit_name_changed', - irc_message=message, - ) + handle_team_event(eventtype="public_credit_name_changed", irc_message=message) def nickserv_username_changed(instance, original): @@ -60,26 +59,36 @@ def nickserv_username_changed(instance, original): Check if profile.nickserv_username was changed, and check irc_acl_fix_needed if so This will be picked up by the IRC bot and fixed as needed """ - if instance.nickserv_username and original and instance.nickserv_username != original.nickserv_username: - logger.debug("profile.nickserv_username changed for user %s, setting membership.irc_acl_fix_needed=True" % instance.user.username) + if ( + instance.nickserv_username + and original + and instance.nickserv_username != original.nickserv_username + ): + logger.debug( + "profile.nickserv_username changed for user %s, setting membership.irc_acl_fix_needed=True" + % instance.user.username + ) # find team memberships for this user from teams.models import TeamMember - memberships = TeamMember.objects.filter( - user=instance.user, - approved=True, - ) + + memberships = TeamMember.objects.filter(user=instance.user, approved=True) # loop over memberships for membership in memberships: - if not membership.team.public_irc_channel_name and not membership.team.private_irc_channel_name: + if ( + not membership.team.public_irc_channel_name + and not membership.team.private_irc_channel_name + ): # no irc channels for this team continue - if not membership.team.public_irc_channel_managed and not membership.team.private_irc_channel_managed: + if ( + not membership.team.public_irc_channel_managed + and not membership.team.private_irc_channel_managed + ): # irc channel(s) are not managed for this team continue # ok, mark this membership as in need of fixing membership.irc_acl_fix_needed = True membership.save() - diff --git a/src/profiles/urls.py b/src/profiles/urls.py index aefa71f1..b873bae9 100644 --- a/src/profiles/urls.py +++ b/src/profiles/urls.py @@ -1,12 +1,9 @@ from django.urls import path -from .views import ( - ProfileDetail, - ProfileUpdate, -) +from .views import ProfileDetail, ProfileUpdate -app_name = 'profiles' +app_name = "profiles" urlpatterns = [ - path('', ProfileDetail.as_view(), name='detail'), - path('edit', ProfileUpdate.as_view(), name='update'), + path("", ProfileDetail.as_view(), name="detail"), + path("edit", ProfileUpdate.as_view(), name="update"), ] diff --git a/src/profiles/views.py b/src/profiles/views.py index 1f7064d8..6b3ef9a9 100644 --- a/src/profiles/views.py +++ b/src/profiles/views.py @@ -8,8 +8,8 @@ from . import models class ProfileDetail(LoginRequiredMixin, DetailView): model = models.Profile - template_name = 'profile_detail.html' - active_menu = 'profile' + template_name = "profile_detail.html" + active_menu = "profile" def get_object(self, queryset=None): return models.Profile.objects.get(user=self.request.user) @@ -17,17 +17,20 @@ class ProfileDetail(LoginRequiredMixin, DetailView): class ProfileUpdate(LoginRequiredMixin, UpdateView): model = models.Profile - fields = ['name', 'description', 'public_credit_name', 'nickserv_username'] - success_url = reverse_lazy('profiles:detail') - template_name = 'profile_form.html' + fields = ["name", "description", "public_credit_name", "nickserv_username"] + success_url = reverse_lazy("profiles:detail") + template_name = "profile_form.html" def get_object(self, queryset=None): return models.Profile.objects.get(user=self.request.user) def form_valid(self, form, **kwargs): - if 'public_credit_name' in form.changed_data and form.cleaned_data['public_credit_name']: + if ( + "public_credit_name" in form.changed_data + and form.cleaned_data["public_credit_name"] + ): # user changed the name (to something non blank) form.instance.public_credit_name_approved = False form.instance.save() - messages.success(self.request, 'Your profile has been updated.') + messages.success(self.request, "Your profile has been updated.") return super().form_valid(form, **kwargs) diff --git a/src/program/__init__.py b/src/program/__init__.py index 9bdc00f8..0da99381 100644 --- a/src/program/__init__.py +++ b/src/program/__init__.py @@ -1,2 +1 @@ -default_app_config = 'program.apps.ProgramConfig' - +default_app_config = "program.apps.ProgramConfig" diff --git a/src/program/admin.py b/src/program/admin.py index 430c1417..285bb8f3 100644 --- a/src/program/admin.py +++ b/src/program/admin.py @@ -1,7 +1,4 @@ -from django.contrib import ( - admin, - messages -) +from django.contrib import admin, messages from django.core.exceptions import ValidationError @@ -16,7 +13,7 @@ from .models import ( EventProposal, Favorite, UrlType, - Url + Url, ) @@ -25,15 +22,20 @@ class SpeakerProposalAdmin(admin.ModelAdmin): def mark_speakerproposal_as_approved(self, request, queryset): for sp in queryset: sp.mark_as_approved(request) - mark_speakerproposal_as_approved.description = 'Approve and create Speaker object(s)' - actions = ['mark_speakerproposal_as_approved'] - list_filter = ('camp', 'proposal_status', 'user') + mark_speakerproposal_as_approved.description = ( + "Approve and create Speaker object(s)" + ) + + actions = ["mark_speakerproposal_as_approved"] + list_filter = ("camp", "proposal_status", "user") def get_speakers_string(event_proposal): - return ', '.join(event_proposal.speakers.all().values_list('email', flat=True)) -get_speakers_string.short_description = 'Speakers' + return ", ".join(event_proposal.speakers.all().values_list("email", flat=True)) + + +get_speakers_string.short_description = "Speakers" @admin.register(EventProposal) @@ -42,8 +44,7 @@ class EventProposalAdmin(admin.ModelAdmin): for ep in queryset: if not ep.speakers.all(): messages.error( - request, - 'Event cant be approved as it has no speaker(s).' + request, "Event cant be approved as it has no speaker(s)." ) return False else: @@ -52,32 +53,34 @@ class EventProposalAdmin(admin.ModelAdmin): except ValidationError as e: messages.error(request, e) return False - mark_eventproposal_as_approved.description = 'Approve and create Event object(s)' + + mark_eventproposal_as_approved.description = "Approve and create Event object(s)" def get_speakers(self): return - actions = ['mark_eventproposal_as_approved'] - list_filter = ('event_type', 'proposal_status', 'track', 'user',) - list_display = ['title', get_speakers_string, 'event_type', 'proposal_status',] + actions = ["mark_eventproposal_as_approved"] + list_filter = ("event_type", "proposal_status", "track", "user") + list_display = ["title", get_speakers_string, "event_type", "proposal_status"] @admin.register(EventLocation) class EventLocationAdmin(admin.ModelAdmin): - list_filter = ('camp',) - list_display = ('name', 'camp') + list_filter = ("camp",) + list_display = ("name", "camp") @admin.register(EventTrack) class EventTrackAdmin(admin.ModelAdmin): - list_filter = ('camp',) - list_display = ('name', 'camp') + list_filter = ("camp",) + list_display = ("name", "camp") + @admin.register(EventInstance) class EventInstanceAdmin(admin.ModelAdmin): - list_display = ('event', 'when', 'location') - list_filter = ('event__track__camp', 'event') - search_fields = ['event__title'] + list_display = ("event", "when", "location") + list_filter = ("event__track__camp", "event") + search_fields = ["event__title"] @admin.register(EventType) @@ -87,13 +90,13 @@ class EventTypeAdmin(admin.ModelAdmin): @admin.register(Speaker) class SpeakerAdmin(admin.ModelAdmin): - list_filter = ('camp',) - readonly_fields = ['proposal'] + list_filter = ("camp",) + readonly_fields = ["proposal"] @admin.register(Favorite) class FavoriteAdmin(admin.ModelAdmin): - raw_id_fields = ('event_instance',) + raw_id_fields = ("event_instance",) class SpeakerInline(admin.StackedInline): @@ -102,23 +105,19 @@ class SpeakerInline(admin.StackedInline): @admin.register(Event) class EventAdmin(admin.ModelAdmin): - list_filter = ('track', 'speakers') - list_display = [ - 'title', - 'event_type', - ] + list_filter = ("track", "speakers") + list_display = ["title", "event_type"] - inlines = [ - SpeakerInline - ] + inlines = [SpeakerInline] + + readonly_fields = ["proposal"] - readonly_fields = ['proposal'] @admin.register(UrlType) class UrlTypeAdmin(admin.ModelAdmin): pass + @admin.register(Url) class UrlAdmin(admin.ModelAdmin): pass - diff --git a/src/program/apps.py b/src/program/apps.py index 8a5ef090..63b93945 100644 --- a/src/program/apps.py +++ b/src/program/apps.py @@ -3,21 +3,16 @@ from django.db.models.signals import m2m_changed, pre_save class ProgramConfig(AppConfig): - name = 'program' + name = "program" def ready(self): - from .models import ( - Speaker, - SpeakerProposal, - EventProposal - ) + from .models import Speaker, SpeakerProposal, EventProposal from .signal_handlers import ( check_speaker_event_camp_consistency, check_speaker_camp_change, ) + m2m_changed.connect( - check_speaker_event_camp_consistency, - sender=Speaker.events.through + check_speaker_event_camp_consistency, sender=Speaker.events.through ) pre_save.connect(check_speaker_camp_change, sender=Speaker) - diff --git a/src/program/consumers.py b/src/program/consumers.py index c4bdeaaa..bfcf6b7f 100644 --- a/src/program/consumers.py +++ b/src/program/consumers.py @@ -8,32 +8,33 @@ from .models import ( EventLocation, EventType, EventTrack, - Speaker + Speaker, ) class ScheduleConsumer(JsonWebsocketConsumer): - groups = ['schedule_users'] + groups = ["schedule_users"] def receive(self, text_data, **kwargs): - user = self.scope['user'] + user = self.scope["user"] content = self.decode_json(text_data) - action = content.get('action') + action = content.get("action") data = {} - if action == 'init': - camp_slug = content.get('camp_slug') + if action == "init": + camp_slug = content.get("camp_slug") try: camp = Camp.objects.get(slug=camp_slug) - days = list(map( - lambda day: - { - 'repr': day.lower.strftime('%A %Y-%m-%d'), - 'iso': day.lower.strftime('%Y-%m-%d'), - 'day_name': day.lower.strftime('%A'), + days = list( + map( + lambda day: { + "repr": day.lower.strftime("%A %Y-%m-%d"), + "iso": day.lower.strftime("%Y-%m-%d"), + "day_name": day.lower.strftime("%A"), }, - camp.get_days('camp') - )) + camp.get_days("camp"), + ) + ) events_query_set = Event.objects.filter(track__camp=camp) events = list([x.serialize() for x in events_query_set]) @@ -41,32 +42,20 @@ class ScheduleConsumer(JsonWebsocketConsumer): event_instances_query_set = EventInstance.objects.filter( event__track__camp=camp ) - event_instances = list([ - x.serialize(user=user) - for x in event_instances_query_set - ]) - - event_locations_query_set = EventLocation.objects.filter( - camp=camp + event_instances = list( + [x.serialize(user=user) for x in event_instances_query_set] + ) + + event_locations_query_set = EventLocation.objects.filter(camp=camp) + event_locations = list( + [x.serialize() for x in event_locations_query_set] ) - event_locations = list([ - x.serialize() - for x in event_locations_query_set - ]) event_types_query_set = EventType.objects.filter() - event_types = list([ - x.serialize() - for x in event_types_query_set - ]) + event_types = list([x.serialize() for x in event_types_query_set]) - event_tracks_query_set = EventTrack.objects.filter( - camp=camp - ) - event_tracks = list([ - x.serialize() - for x in event_tracks_query_set - ]) + event_tracks_query_set = EventTrack.objects.filter(camp=camp) + event_tracks = list([x.serialize() for x in event_tracks_query_set]) speakers_query_set = Speaker.objects.filter(camp=camp) speakers = list([x.serialize() for x in speakers_query_set]) @@ -84,23 +73,17 @@ class ScheduleConsumer(JsonWebsocketConsumer): except Camp.DoesNotExist: pass - if action == 'favorite': - event_instance_id = content.get('event_instance_id') + if action == "favorite": + event_instance_id = content.get("event_instance_id") event_instance = EventInstance.objects.get(id=event_instance_id) - Favorite.objects.create( - user=user, - event_instance=event_instance - ) + Favorite.objects.create(user=user, event_instance=event_instance) - if action == 'unfavorite': + if action == "unfavorite": try: - event_instance_id = content.get('event_instance_id') - event_instance = EventInstance.objects.get( - id=event_instance_id - ) + event_instance_id = content.get("event_instance_id") + event_instance = EventInstance.objects.get(id=event_instance_id) favorite = Favorite.objects.get( - event_instance=event_instance, - user=user + event_instance=event_instance, user=user ) favorite.delete() except Favorite.DoesNotExist: diff --git a/src/program/email.py b/src/program/email.py index 661ba9c6..9de5facb 100644 --- a/src/program/email.py +++ b/src/program/email.py @@ -3,100 +3,79 @@ from django.core.exceptions import ObjectDoesNotExist from utils.email import add_outgoing_email from teams.models import Team import logging + logger = logging.getLogger("bornhack.%s" % __name__) def add_new_speakerproposal_email(speakerproposal): - formatdict = { - 'proposal': speakerproposal - } + formatdict = {"proposal": speakerproposal} try: - content_team = Team.objects.get( - camp=speakerproposal.camp, name='Content' - ) + content_team = Team.objects.get(camp=speakerproposal.camp, name="Content") return add_outgoing_email( - text_template='emails/new_speakerproposal.txt', - html_template='emails/new_speakerproposal.html', + text_template="emails/new_speakerproposal.txt", + html_template="emails/new_speakerproposal.html", to_recipients=content_team.mailing_list, formatdict=formatdict, - subject='New speaker proposal for {}'.format( - speakerproposal.camp.title - ) + subject="New speaker proposal for {}".format(speakerproposal.camp.title), ) except ObjectDoesNotExist as e: - logger.info('There is no team with name Content: {}'.format(e)) + logger.info("There is no team with name Content: {}".format(e)) return False def add_new_eventproposal_email(eventproposal): - formatdict = { - 'proposal': eventproposal - } + formatdict = {"proposal": eventproposal} try: - content_team = Team.objects.get( - camp=eventproposal.camp, name='Content' - ) + content_team = Team.objects.get(camp=eventproposal.camp, name="Content") return add_outgoing_email( - text_template='emails/new_eventproposal.txt', - html_template='emails/new_eventproposal.html', + text_template="emails/new_eventproposal.txt", + html_template="emails/new_eventproposal.html", to_recipients=content_team.mailing_list, formatdict=formatdict, - subject='New event proposal for {}'.format( - eventproposal.camp.title - ) + subject="New event proposal for {}".format(eventproposal.camp.title), ) except ObjectDoesNotExist as e: - logger.info('There is no team with name Content: {}'.format(e)) + logger.info("There is no team with name Content: {}".format(e)) return False def add_speakerproposal_updated_email(speakerproposal): - formatdict = { - 'proposal': speakerproposal - } + formatdict = {"proposal": speakerproposal} try: - content_team = Team.objects.get( - camp=speakerproposal.camp, name='Content' - ) + content_team = Team.objects.get(camp=speakerproposal.camp, name="Content") return add_outgoing_email( - text_template='emails/update_speakerproposal.txt', - html_template='emails/update_speakerproposal.html', + text_template="emails/update_speakerproposal.txt", + html_template="emails/update_speakerproposal.html", to_recipients=content_team.mailing_list, formatdict=formatdict, - subject='Updated speaker proposal for {}'.format( + subject="Updated speaker proposal for {}".format( speakerproposal.camp.title - ) + ), ) except ObjectDoesNotExist as e: - logger.info('There is no team with name Content: {}'.format(e)) + logger.info("There is no team with name Content: {}".format(e)) return False def add_eventproposal_updated_email(eventproposal): - formatdict = { - 'proposal': eventproposal - } + formatdict = {"proposal": eventproposal} try: - content_team = Team.objects.get( - camp=eventproposal.camp, name='Content' - ) + content_team = Team.objects.get(camp=eventproposal.camp, name="Content") return add_outgoing_email( - text_template='emails/update_eventproposal.txt', - html_template='emails/update_eventproposal.html', + text_template="emails/update_eventproposal.txt", + html_template="emails/update_eventproposal.html", to_recipients=content_team.mailing_list, formatdict=formatdict, - subject='New event proposal for {}'.format( - eventproposal.camp.title - ) + subject="New event proposal for {}".format(eventproposal.camp.title), ) except ObjectDoesNotExist as e: - logger.info('There is no team with name Content: {}'.format(e)) + logger.info("There is no team with name Content: {}".format(e)) return False diff --git a/src/program/forms.py b/src/program/forms.py index cfa34c39..5bf7be07 100644 --- a/src/program/forms.py +++ b/src/program/forms.py @@ -12,9 +12,16 @@ class SpeakerProposalForm(forms.ModelForm): """ The SpeakerProposalForm. Takes an EventType in __init__ and changes fields accordingly. """ + class Meta: model = SpeakerProposal - fields = ['name', 'email', 'biography', 'needs_oneday_ticket', 'submission_notes'] + fields = [ + "name", + "email", + "biography", + "needs_oneday_ticket", + "submission_notes", + ] def __init__(self, camp, eventtype=None, *args, **kwargs): # initialise the form @@ -24,133 +31,167 @@ class SpeakerProposalForm(forms.ModelForm): if not eventtype: return - if eventtype.name == 'Debate': + if eventtype.name == "Debate": # fix label and help_text for the name field - self.fields['name'].label = 'Guest Name' - self.fields['name'].help_text = 'The name of a debate guest. Can be a real name or an alias.' + self.fields["name"].label = "Guest Name" + self.fields[ + "name" + ].help_text = "The name of a debate guest. Can be a real name or an alias." # fix label and help_text for the biograpy field - self.fields['biography'].label = 'Guest Biography' - self.fields['biography'].help_text = 'The biography of the guest.' + self.fields["biography"].label = "Guest Biography" + self.fields["biography"].help_text = "The biography of the guest." # fix label and help_text for the submission_notes field - self.fields['submission_notes'].label = 'Guest Notes' - self.fields['submission_notes'].help_text = 'Private notes regarding this guest. Only visible to yourself and the BornHack organisers.' + self.fields["submission_notes"].label = "Guest Notes" + self.fields[ + "submission_notes" + ].help_text = "Private notes regarding this guest. Only visible to yourself and the BornHack organisers." # no free tickets for workshops - del(self.fields['needs_oneday_ticket']) + del self.fields["needs_oneday_ticket"] - elif eventtype.name == 'Lightning Talk': + elif eventtype.name == "Lightning Talk": # fix label and help_text for the name field - self.fields['name'].label = 'Speaker Name' - self.fields['name'].help_text = 'The name of the speaker. Can be a real name or an alias.' + self.fields["name"].label = "Speaker Name" + self.fields[ + "name" + ].help_text = "The name of the speaker. Can be a real name or an alias." # fix label and help_text for the biograpy field - self.fields['biography'].label = 'Speaker Biography' - self.fields['biography'].help_text = 'The biography of the speaker.' + self.fields["biography"].label = "Speaker Biography" + self.fields["biography"].help_text = "The biography of the speaker." # fix label and help_text for the submission_notes field - self.fields['submission_notes'].label = 'Speaker Notes' - self.fields['submission_notes'].help_text = 'Private notes regarding this speaker. Only visible to yourself and the BornHack organisers.' + self.fields["submission_notes"].label = "Speaker Notes" + self.fields[ + "submission_notes" + ].help_text = "Private notes regarding this speaker. Only visible to yourself and the BornHack organisers." # no free tickets for lightning talks - del(self.fields['needs_oneday_ticket']) + del self.fields["needs_oneday_ticket"] - elif eventtype.name == 'Music Act': + elif eventtype.name == "Music Act": # fix label and help_text for the name field - self.fields['name'].label = 'Artist Name' - self.fields['name'].help_text = 'The name of the artist. Can be a real name or artist alias.' + self.fields["name"].label = "Artist Name" + self.fields[ + "name" + ].help_text = "The name of the artist. Can be a real name or artist alias." # fix label and help_text for the biograpy field - self.fields['biography'].label = 'Artist Description' - self.fields['biography'].help_text = 'The description of the artist.' + self.fields["biography"].label = "Artist Description" + self.fields["biography"].help_text = "The description of the artist." # fix label and help_text for the submission_notes field - self.fields['submission_notes'].label = 'Artist Notes' - self.fields['submission_notes'].help_text = 'Private notes regarding this artist. Only visible to yourself and the BornHack organisers.' + self.fields["submission_notes"].label = "Artist Notes" + self.fields[ + "submission_notes" + ].help_text = "Private notes regarding this artist. Only visible to yourself and the BornHack organisers." # no oneday tickets for music acts - del(self.fields['needs_oneday_ticket']) + del self.fields["needs_oneday_ticket"] - elif eventtype.name == 'Recreational Event': + elif eventtype.name == "Recreational Event": # fix label and help_text for the name field - self.fields['name'].label = 'Host Name' - self.fields['name'].help_text = 'The name of the event host. Can be a real name or an alias.' + self.fields["name"].label = "Host Name" + self.fields[ + "name" + ].help_text = "The name of the event host. Can be a real name or an alias." # fix label and help_text for the biograpy field - self.fields['biography'].label = 'Host Biography' - self.fields['biography'].help_text = 'The biography of the host.' + self.fields["biography"].label = "Host Biography" + self.fields["biography"].help_text = "The biography of the host." # fix label and help_text for the submission_notes field - self.fields['submission_notes'].label = 'Host Notes' - self.fields['submission_notes'].help_text = 'Private notes regarding this host. Only visible to yourself and the BornHack organisers.' + self.fields["submission_notes"].label = "Host Notes" + self.fields[ + "submission_notes" + ].help_text = "Private notes regarding this host. Only visible to yourself and the BornHack organisers." # no oneday tickets for music acts - del(self.fields['needs_oneday_ticket']) + del self.fields["needs_oneday_ticket"] - elif eventtype.name == 'Talk': + elif eventtype.name == "Talk": # fix label and help_text for the name field - self.fields['name'].label = 'Speaker Name' - self.fields['name'].help_text = 'The name of the speaker. Can be a real name or an alias.' + self.fields["name"].label = "Speaker Name" + self.fields[ + "name" + ].help_text = "The name of the speaker. Can be a real name or an alias." # fix label and help_text for the biograpy field - self.fields['biography'].label = 'Speaker Biography' - self.fields['biography'].help_text = 'The biography of the speaker.' + self.fields["biography"].label = "Speaker Biography" + self.fields["biography"].help_text = "The biography of the speaker." # fix label and help_text for the submission_notes field - self.fields['submission_notes'].label = 'Speaker Notes' - self.fields['submission_notes'].help_text = 'Private notes regarding this speaker. Only visible to yourself and the BornHack organisers.' + self.fields["submission_notes"].label = "Speaker Notes" + self.fields[ + "submission_notes" + ].help_text = "Private notes regarding this speaker. Only visible to yourself and the BornHack organisers." - elif eventtype.name == 'Workshop': + elif eventtype.name == "Workshop": # fix label and help_text for the name field - self.fields['name'].label = 'Host Name' - self.fields['name'].help_text = 'The name of the workshop host. Can be a real name or an alias.' + self.fields["name"].label = "Host Name" + self.fields[ + "name" + ].help_text = ( + "The name of the workshop host. Can be a real name or an alias." + ) # fix label and help_text for the biograpy field - self.fields['biography'].label = 'Host Biography' - self.fields['biography'].help_text = 'The biography of the host.' + self.fields["biography"].label = "Host Biography" + self.fields["biography"].help_text = "The biography of the host." # fix label and help_text for the submission_notes field - self.fields['submission_notes'].label = 'Host Notes' - self.fields['submission_notes'].help_text = 'Private notes regarding this host. Only visible to yourself and the BornHack organisers.' + self.fields["submission_notes"].label = "Host Notes" + self.fields[ + "submission_notes" + ].help_text = "Private notes regarding this host. Only visible to yourself and the BornHack organisers." # no free tickets for workshops - del(self.fields['needs_oneday_ticket']) + del self.fields["needs_oneday_ticket"] - elif eventtype.name == 'Slacking Off': + elif eventtype.name == "Slacking Off": # fix label and help_text for the name field - self.fields['name'].label = 'Host Name' - self.fields['name'].help_text = 'Can be a real name or an alias.' + self.fields["name"].label = "Host Name" + self.fields["name"].help_text = "Can be a real name or an alias." # fix label and help_text for the biograpy field - self.fields['biography'].label = 'Host Biography' - self.fields['biography'].help_text = 'The biography of the host.' + self.fields["biography"].label = "Host Biography" + self.fields["biography"].help_text = "The biography of the host." # fix label and help_text for the submission_notes field - self.fields['submission_notes'].label = 'Host Notes' - self.fields['submission_notes'].help_text = 'Private notes regarding this host. Only visible to yourself and the BornHack organisers.' + self.fields["submission_notes"].label = "Host Notes" + self.fields[ + "submission_notes" + ].help_text = "Private notes regarding this host. Only visible to yourself and the BornHack organisers." # no free tickets for workshops - del(self.fields['needs_oneday_ticket']) + del self.fields["needs_oneday_ticket"] - elif eventtype.name == 'Meetup': + elif eventtype.name == "Meetup": # fix label and help_text for the name field - self.fields['name'].label = 'Host Name' - self.fields['name'].help_text = 'The name of the meetup host. Can be a real name or an alias.' + self.fields["name"].label = "Host Name" + self.fields[ + "name" + ].help_text = "The name of the meetup host. Can be a real name or an alias." # fix label and help_text for the biograpy field - self.fields['biography'].label = 'Host Biography' - self.fields['biography'].help_text = 'The biography of the host.' + self.fields["biography"].label = "Host Biography" + self.fields["biography"].help_text = "The biography of the host." # fix label and help_text for the submission_notes field - self.fields['submission_notes'].label = 'Host Notes' - self.fields['submission_notes'].help_text = 'Private notes regarding this host. Only visible to yourself and the BornHack organisers.' + self.fields["submission_notes"].label = "Host Notes" + self.fields[ + "submission_notes" + ].help_text = "Private notes regarding this host. Only visible to yourself and the BornHack organisers." # no free tickets for workshops - del(self.fields['needs_oneday_ticket']) + del self.fields["needs_oneday_ticket"] else: - raise ImproperlyConfigured("Unsupported event type, don't know which form class to use") + raise ImproperlyConfigured( + "Unsupported event type, don't know which form class to use" + ) class EventProposalForm(forms.ModelForm): @@ -159,23 +200,31 @@ class EventProposalForm(forms.ModelForm): """ slides_url = forms.URLField( - label="Slides URL", - help_text="Add a URL to your slides.", - required=False + label="Slides URL", help_text="Add a URL to your slides.", required=False ) class Meta: model = EventProposal - fields = ['title', 'abstract', 'allow_video_recording', 'duration', 'slides_url', 'submission_notes', 'track'] + fields = [ + "title", + "abstract", + "allow_video_recording", + "duration", + "slides_url", + "submission_notes", + "track", + ] def clean_duration(self): - duration = self.cleaned_data['duration'] + duration = self.cleaned_data["duration"] if not duration or duration < 60 or duration > 180: - raise forms.ValidationError("Please keep duration between 60 and 180 minutes.") + raise forms.ValidationError( + "Please keep duration between 60 and 180 minutes." + ) return duration def clean_track(self): - track = self.cleaned_data['track'] + track = self.cleaned_data["track"] # TODO: make sure the track is part of the current camp, needs camp as form kwarg to verify return track @@ -187,11 +236,14 @@ class EventProposalForm(forms.ModelForm): eventproposal.event_type = event_type eventproposal.save() - if not event_type and hasattr(eventproposal, 'event_type'): + if not event_type and hasattr(eventproposal, "event_type"): event_type = eventproposal.event_type - if self.cleaned_data.get('slides_url') and event_type.name in ['Talk', 'Lightning Talk']: - url = self.cleaned_data.get('slides_url') + if self.cleaned_data.get("slides_url") and event_type.name in [ + "Talk", + "Lightning Talk", + ]: + url = self.cleaned_data.get("slides_url") if not eventproposal.urls.filter(url=url).exists(): slides_url = Url() slides_url.eventproposal = eventproposal @@ -206,150 +258,185 @@ class EventProposalForm(forms.ModelForm): super().__init__(*args, **kwargs) # disable the empty_label for the track select box - self.fields['track'].empty_label = None - self.fields['track'].queryset = EventTrack.objects.filter(camp=camp) + self.fields["track"].empty_label = None + self.fields["track"].queryset = EventTrack.objects.filter(camp=camp) # make sure video_recording checkbox defaults to checked - self.fields['allow_video_recording'].initial = True + self.fields["allow_video_recording"].initial = True - if not (eventtype.name == 'Talk' or eventtype.name == 'Lightning Talk'): + if not (eventtype.name == "Talk" or eventtype.name == "Lightning Talk"): # Only talk or lightning talk should show the slides_url field - del(self.fields['slides_url']) + del self.fields["slides_url"] - if eventtype.name == 'Debate': + if eventtype.name == "Debate": # fix label and help_text for the title field - self.fields['title'].label = 'Title of debate' - self.fields['title'].help_text = 'The title of this debate' + self.fields["title"].label = "Title of debate" + self.fields["title"].help_text = "The title of this debate" # fix label and help_text for the abstract field - self.fields['abstract'].label = 'Description' - self.fields['abstract'].help_text = 'The description of this debate' + self.fields["abstract"].label = "Description" + self.fields["abstract"].help_text = "The description of this debate" # fix label and help_text for the submission_notes field - self.fields['submission_notes'].label = 'Debate Act Notes' - self.fields['submission_notes'].help_text = 'Private notes regarding this debate. Only visible to yourself and the BornHack organisers.' + self.fields["submission_notes"].label = "Debate Act Notes" + self.fields[ + "submission_notes" + ].help_text = "Private notes regarding this debate. Only visible to yourself and the BornHack organisers." # better placeholder text for duration field - self.fields['duration'].widget.attrs['placeholder'] = 'Debate Duration (minutes)' + self.fields["duration"].widget.attrs[ + "placeholder" + ] = "Debate Duration (minutes)" - elif eventtype.name == 'Music Act': + elif eventtype.name == "Music Act": # fix label and help_text for the title field - self.fields['title'].label = 'Title of music act' - self.fields['title'].help_text = 'The title of this music act/concert/set.' + self.fields["title"].label = "Title of music act" + self.fields["title"].help_text = "The title of this music act/concert/set." # fix label and help_text for the abstract field - self.fields['abstract'].label = 'Description' - self.fields['abstract'].help_text = 'The description of this music act' + self.fields["abstract"].label = "Description" + self.fields["abstract"].help_text = "The description of this music act" # fix label and help_text for the submission_notes field - self.fields['submission_notes'].label = 'Music Act Notes' - self.fields['submission_notes'].help_text = 'Private notes regarding this music act. Only visible to yourself and the BornHack organisers.' + self.fields["submission_notes"].label = "Music Act Notes" + self.fields[ + "submission_notes" + ].help_text = "Private notes regarding this music act. Only visible to yourself and the BornHack organisers." # no video recording for music acts - del(self.fields['allow_video_recording']) + del self.fields["allow_video_recording"] # better placeholder text for duration field - self.fields['duration'].widget.attrs['placeholder'] = 'Duration (minutes)' + self.fields["duration"].widget.attrs["placeholder"] = "Duration (minutes)" - elif eventtype.name == 'Recreational Event': + elif eventtype.name == "Recreational Event": # fix label and help_text for the title field - self.fields['title'].label = 'Event Title' - self.fields['title'].help_text = 'The title of this recreational event' + self.fields["title"].label = "Event Title" + self.fields["title"].help_text = "The title of this recreational event" # fix label and help_text for the abstract field - self.fields['abstract'].label = 'Event Abstract' - self.fields['abstract'].help_text = 'The description/abstract of this recreational event.' + self.fields["abstract"].label = "Event Abstract" + self.fields[ + "abstract" + ].help_text = "The description/abstract of this recreational event." # fix label and help_text for the submission_notes field - self.fields['submission_notes'].label = 'Event Notes' - self.fields['submission_notes'].help_text = 'Private notes regarding this recreational event. Only visible to yourself and the BornHack organisers.' + self.fields["submission_notes"].label = "Event Notes" + self.fields[ + "submission_notes" + ].help_text = "Private notes regarding this recreational event. Only visible to yourself and the BornHack organisers." # no video recording for music acts - del(self.fields['allow_video_recording']) + del self.fields["allow_video_recording"] # better placeholder text for duration field - self.fields['duration'].label = 'Event Duration' - self.fields['duration'].widget.attrs['placeholder'] = 'Duration (minutes)' + self.fields["duration"].label = "Event Duration" + self.fields["duration"].widget.attrs["placeholder"] = "Duration (minutes)" - elif eventtype.name == 'Talk' or eventtype.name == 'Lightning Talk': + elif eventtype.name == "Talk" or eventtype.name == "Lightning Talk": # fix label and help_text for the title field - self.fields['title'].label = 'Title of Talk' - self.fields['title'].help_text = 'The title of this talk/presentation.' + self.fields["title"].label = "Title of Talk" + self.fields["title"].help_text = "The title of this talk/presentation." # fix label and help_text for the abstract field - self.fields['abstract'].label = 'Abstract of Talk' - self.fields['abstract'].help_text = 'The description/abstract of this talk/presentation. Explain what the audience will experience.' + self.fields["abstract"].label = "Abstract of Talk" + self.fields[ + "abstract" + ].help_text = "The description/abstract of this talk/presentation. Explain what the audience will experience." # fix label and help_text for the submission_notes field - self.fields['submission_notes'].label = 'Talk Notes' - self.fields['submission_notes'].help_text = 'Private notes regarding this talk. Only visible to yourself and the BornHack organisers.' + self.fields["submission_notes"].label = "Talk Notes" + self.fields[ + "submission_notes" + ].help_text = "Private notes regarding this talk. Only visible to yourself and the BornHack organisers." - if self.fields.get('slides_url') and eventtype.name == "Lightning Talk": - self.fields['slides_url'].help_text += " You will only get assigned a slot if you have provided slides (a title slide is enough if you don't use slides for the talk). You can add an URL later if need be." + if self.fields.get("slides_url") and eventtype.name == "Lightning Talk": + self.fields[ + "slides_url" + ].help_text += " You will only get assigned a slot if you have provided slides (a title slide is enough if you don't use slides for the talk). You can add an URL later if need be." # no duration for talks - del(self.fields['duration']) + del self.fields["duration"] - elif eventtype.name == 'Workshop': + elif eventtype.name == "Workshop": # fix label and help_text for the title field - self.fields['title'].label = 'Workshop Title' - self.fields['title'].help_text = 'The title of this workshop.' + self.fields["title"].label = "Workshop Title" + self.fields["title"].help_text = "The title of this workshop." # fix label and help_text for the submission_notes field - self.fields['submission_notes'].label = 'Workshop Notes' - self.fields['submission_notes'].help_text = 'Private notes regarding this workshop. Only visible to yourself and the BornHack organisers.' + self.fields["submission_notes"].label = "Workshop Notes" + self.fields[ + "submission_notes" + ].help_text = "Private notes regarding this workshop. Only visible to yourself and the BornHack organisers." # fix label and help_text for the abstract field - self.fields['abstract'].label = 'Workshop Abstract' - self.fields['abstract'].help_text = 'The description/abstract of this workshop. Explain what the participants will learn.' + self.fields["abstract"].label = "Workshop Abstract" + self.fields[ + "abstract" + ].help_text = "The description/abstract of this workshop. Explain what the participants will learn." # no video recording for workshops - del(self.fields['allow_video_recording']) + del self.fields["allow_video_recording"] # duration field - self.fields['duration'].label = 'Workshop Duration' - self.fields['duration'].help_text = 'How much time (in minutes) should we set aside for this workshop? Please keep it between 60 and 180 minutes (1-3 hours).' + self.fields["duration"].label = "Workshop Duration" + self.fields[ + "duration" + ].help_text = "How much time (in minutes) should we set aside for this workshop? Please keep it between 60 and 180 minutes (1-3 hours)." - elif eventtype.name == 'Slacking Off': + elif eventtype.name == "Slacking Off": # fix label and help_text for the title field - self.fields['title'].label = 'Event Title' - self.fields['title'].help_text = 'The title of this recreational event.' + self.fields["title"].label = "Event Title" + self.fields["title"].help_text = "The title of this recreational event." # fix label and help_text for the submission_notes field - self.fields['submission_notes'].label = 'Event Notes' - self.fields['submission_notes'].help_text = 'Private notes regarding this recreational event. Only visible to yourself and the BornHack organisers.' + self.fields["submission_notes"].label = "Event Notes" + self.fields[ + "submission_notes" + ].help_text = "Private notes regarding this recreational event. Only visible to yourself and the BornHack organisers." # fix label and help_text for the abstract field - self.fields['abstract'].label = 'Event Abstract' - self.fields['abstract'].help_text = 'The description/abstract of this event. Explain what the participants will experience.' + self.fields["abstract"].label = "Event Abstract" + self.fields[ + "abstract" + ].help_text = "The description/abstract of this event. Explain what the participants will experience." # no video recording for recreational events - del(self.fields['allow_video_recording']) + del self.fields["allow_video_recording"] # duration field - self.fields['duration'].label = 'Event Duration' - self.fields['duration'].help_text = 'How much time (in minutes) should we set aside for this event? Please keep it between 60 and 180 minutes (1-3 hours).' + self.fields["duration"].label = "Event Duration" + self.fields[ + "duration" + ].help_text = "How much time (in minutes) should we set aside for this event? Please keep it between 60 and 180 minutes (1-3 hours)." - elif eventtype.name == 'Meetup': + elif eventtype.name == "Meetup": # fix label and help_text for the title field - self.fields['title'].label = 'Meetup Title' - self.fields['title'].help_text = 'The title of this meetup.' + self.fields["title"].label = "Meetup Title" + self.fields["title"].help_text = "The title of this meetup." # fix label and help_text for the submission_notes field - self.fields['submission_notes'].label = 'Meetup Notes' - self.fields['submission_notes'].help_text = 'Private notes regarding this meetup. Only visible to yourself and the BornHack organisers.' + self.fields["submission_notes"].label = "Meetup Notes" + self.fields[ + "submission_notes" + ].help_text = "Private notes regarding this meetup. Only visible to yourself and the BornHack organisers." # fix label and help_text for the abstract field - self.fields['abstract'].label = 'Meetup Abstract' - self.fields['abstract'].help_text = 'The description/abstract of this meetup. Explain what the meetup is about and who should attend.' + self.fields["abstract"].label = "Meetup Abstract" + self.fields[ + "abstract" + ].help_text = "The description/abstract of this meetup. Explain what the meetup is about and who should attend." # no video recording for meetups - del(self.fields['allow_video_recording']) + del self.fields["allow_video_recording"] # duration field - self.fields['duration'].label = 'Meetup Duration' - self.fields['duration'].help_text = 'How much time (in minutes) should we set aside for this meetup? Please keep it between 60 and 180 minutes (1-3 hours).' + self.fields["duration"].label = "Meetup Duration" + self.fields[ + "duration" + ].help_text = "How much time (in minutes) should we set aside for this meetup? Please keep it between 60 and 180 minutes (1-3 hours)." else: - raise ImproperlyConfigured("Unsupported event type, don't know which form class to use") - + raise ImproperlyConfigured( + "Unsupported event type, don't know which form class to use" + ) diff --git a/src/program/management/commands/notification_worker.py b/src/program/management/commands/notification_worker.py index 57115ea7..e90ab5c6 100644 --- a/src/program/management/commands/notification_worker.py +++ b/src/program/management/commands/notification_worker.py @@ -9,19 +9,21 @@ from django.utils import timezone from program.models import EventInstance from datetime import timedelta import logging + logger = logging.getLogger("bornhack.%s" % __name__) - class Command(BaseCommand): - args = 'none' - help = 'Queue notifications for channels and users for upcoming event instances.' + args = "none" + help = "Queue notifications for channels and users for upcoming event instances." def output(self, message): - self.stdout.write('%s: %s' % (timezone.now().strftime("%Y-%m-%d %H:%M:%S"), message)) + self.stdout.write( + "%s: %s" % (timezone.now().strftime("%Y-%m-%d %H:%M:%S"), message) + ) def handle(self, *args, **options): - self.output('Schedule notification worker running...') + self.output("Schedule notification worker running...") while True: camp = get_current_camp() if camp: @@ -30,19 +32,23 @@ class Command(BaseCommand): event__camp=camp, event__event_type__notifications=True, notifications_sent=False, - when__startswith__lt=timezone.now()+timedelta(minutes=settings.SCHEDULE_EVENT_NOTIFICATION_MINUTES), # start of event is less than X minutes away - when__startswith__gt=timezone.now() # but event has not started yet + when__startswith__lt=timezone.now() + + timedelta( + minutes=settings.SCHEDULE_EVENT_NOTIFICATION_MINUTES + ), # start of event is less than X minutes away + when__startswith__gt=timezone.now(), # but event has not started yet ): # this event is less than settings.SCHEDULE_EVENT_NOTIFICATION_MINUTES minutes from starting, queue an IRC notificatio oim = OutgoingIrcMessage.objects.create( target=settings.IRCBOT_SCHEDULE_ANNOUNCE_CHANNEL, message="starting soon: %s" % ei, - timeout=ei.when.lower + timeout=ei.when.lower, ) - logger.info("added irc message id %s for eventinstance %s" % (oim.id, ei)) - ei.notifications_sent=True + logger.info( + "added irc message id %s for eventinstance %s" % (oim.id, ei) + ) + ei.notifications_sent = True ei.save() # check once per minute sleep(60) - diff --git a/src/program/migrations/0001_initial.py b/src/program/migrations/0001_initial.py index 76f0b785..3fee01c5 100644 --- a/src/program/migrations/0001_initial.py +++ b/src/program/migrations/0001_initial.py @@ -10,58 +10,83 @@ class Migration(migrations.Migration): initial = True - dependencies = [ - ('camps', '0005_auto_20160510_2011'), - ] + dependencies = [("camps", "0005_auto_20160510_2011")] operations = [ migrations.CreateModel( - name='Event', + name="Event", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('created', models.DateTimeField(auto_now_add=True)), - ('updated', models.DateTimeField(auto_now=True)), - ('title', models.CharField(max_length=255)), - ('description', models.TextField()), - ('start', models.TimeField()), - ('end', models.TimeField()), - ('days', models.ManyToManyField(to='camps.Day')), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("created", models.DateTimeField(auto_now_add=True)), + ("updated", models.DateTimeField(auto_now=True)), + ("title", models.CharField(max_length=255)), + ("description", models.TextField()), + ("start", models.TimeField()), + ("end", models.TimeField()), + ("days", models.ManyToManyField(to="camps.Day")), ], - options={ - 'abstract': False, - }, + options={"abstract": False}, ), migrations.CreateModel( - name='EventType', + name="EventType", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('created', models.DateTimeField(auto_now_add=True)), - ('updated', models.DateTimeField(auto_now=True)), - ('name', models.CharField(max_length=100)), - ('slug', models.SlugField()), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("created", models.DateTimeField(auto_now_add=True)), + ("updated", models.DateTimeField(auto_now=True)), + ("name", models.CharField(max_length=100)), + ("slug", models.SlugField()), ], - options={ - 'abstract': False, - }, + options={"abstract": False}, ), migrations.CreateModel( - name='Speaker', + name="Speaker", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('created', models.DateTimeField(auto_now_add=True)), - ('updated', models.DateTimeField(auto_now=True)), - ('name', models.CharField(max_length=150)), - ('biography', models.TextField()), - ('picture', models.ImageField(blank=True, null=True, upload_to=b'')), - ('events', models.ManyToManyField(related_name='speakers', related_query_name='speaker', to='program.Event')), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("created", models.DateTimeField(auto_now_add=True)), + ("updated", models.DateTimeField(auto_now=True)), + ("name", models.CharField(max_length=150)), + ("biography", models.TextField()), + ("picture", models.ImageField(blank=True, null=True, upload_to=b"")), + ( + "events", + models.ManyToManyField( + related_name="speakers", + related_query_name="speaker", + to="program.Event", + ), + ), ], - options={ - 'abstract': False, - }, + options={"abstract": False}, ), migrations.AddField( - model_name='event', - name='event_type', - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='program.EventType'), + model_name="event", + name="event_type", + field=models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, to="program.EventType" + ), ), ] diff --git a/src/program/migrations/0002_eventtype_color.py b/src/program/migrations/0002_eventtype_color.py index b8328db1..7bfe55c6 100644 --- a/src/program/migrations/0002_eventtype_color.py +++ b/src/program/migrations/0002_eventtype_color.py @@ -7,15 +7,13 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ - ('program', '0001_initial'), - ] + dependencies = [("program", "0001_initial")] operations = [ migrations.AddField( - model_name='eventtype', - name='color', - field=models.CharField(default='#ff0000', max_length=50), + model_name="eventtype", + name="color", + field=models.CharField(default="#ff0000", max_length=50), preserve_default=False, - ), + ) ] diff --git a/src/program/migrations/0003_eventtype_light_writing.py b/src/program/migrations/0003_eventtype_light_writing.py index 32b8c740..50d5f9be 100644 --- a/src/program/migrations/0003_eventtype_light_writing.py +++ b/src/program/migrations/0003_eventtype_light_writing.py @@ -7,14 +7,12 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ - ('program', '0002_eventtype_color'), - ] + dependencies = [("program", "0002_eventtype_color")] operations = [ migrations.AddField( - model_name='eventtype', - name='light_writing', + model_name="eventtype", + name="light_writing", field=models.BooleanField(default=False), - ), + ) ] diff --git a/src/program/migrations/0004_auto_20160804_1712.py b/src/program/migrations/0004_auto_20160804_1712.py index 603219b2..fe26a4be 100644 --- a/src/program/migrations/0004_auto_20160804_1712.py +++ b/src/program/migrations/0004_auto_20160804_1712.py @@ -7,14 +7,10 @@ from django.db import migrations class Migration(migrations.Migration): - dependencies = [ - ('program', '0003_eventtype_light_writing'), - ] + dependencies = [("program", "0003_eventtype_light_writing")] operations = [ migrations.RenameField( - model_name='eventtype', - old_name='light_writing', - new_name='light_text', - ), + model_name="eventtype", old_name="light_writing", new_name="light_text" + ) ] diff --git a/src/program/migrations/0005_auto_20160807_1312.py b/src/program/migrations/0005_auto_20160807_1312.py index 69719ef8..53509a8d 100644 --- a/src/program/migrations/0005_auto_20160807_1312.py +++ b/src/program/migrations/0005_auto_20160807_1312.py @@ -7,20 +7,23 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ - ('program', '0004_auto_20160804_1712'), - ] + dependencies = [("program", "0004_auto_20160804_1712")] operations = [ migrations.AddField( - model_name='event', - name='slug', - field=models.SlugField(default='', blank=True), + model_name="event", + name="slug", + field=models.SlugField(default="", blank=True), preserve_default=False, ), migrations.AlterField( - model_name='speaker', - name='events', - field=models.ManyToManyField(blank=True, related_name='speakers', related_query_name='speaker', to='program.Event'), + model_name="speaker", + name="events", + field=models.ManyToManyField( + blank=True, + related_name="speakers", + related_query_name="speaker", + to="program.Event", + ), ), ] diff --git a/src/program/migrations/0006_auto_20160807_1320.py b/src/program/migrations/0006_auto_20160807_1320.py index 74a6add4..5bff1497 100644 --- a/src/program/migrations/0006_auto_20160807_1320.py +++ b/src/program/migrations/0006_auto_20160807_1320.py @@ -7,14 +7,12 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ - ('program', '0005_auto_20160807_1312'), - ] + dependencies = [("program", "0005_auto_20160807_1312")] operations = [ migrations.AlterField( - model_name='event', - name='slug', + model_name="event", + name="slug", field=models.SlugField(blank=True, max_length=255), - ), + ) ] diff --git a/src/program/migrations/0007_auto_20160807_1333.py b/src/program/migrations/0007_auto_20160807_1333.py index 68e38ec4..d93110dc 100644 --- a/src/program/migrations/0007_auto_20160807_1333.py +++ b/src/program/migrations/0007_auto_20160807_1333.py @@ -7,15 +7,10 @@ from django.db import migrations class Migration(migrations.Migration): - dependencies = [ - ('program', '0006_auto_20160807_1320'), - ] + dependencies = [("program", "0006_auto_20160807_1320")] operations = [ migrations.RenameField( - model_name='event', - old_name='description', - new_name='abstract', - ), + model_name="event", old_name="description", new_name="abstract" + ) ] - diff --git a/src/program/migrations/0008_auto_20160808_1747.py b/src/program/migrations/0008_auto_20160808_1747.py index f6c8b506..62aff28a 100644 --- a/src/program/migrations/0008_auto_20160808_1747.py +++ b/src/program/migrations/0008_auto_20160808_1747.py @@ -7,37 +7,29 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ - ('program', '0007_auto_20160807_1333'), - ] + dependencies = [("program", "0007_auto_20160807_1333")] operations = [ - migrations.AlterModelOptions( - name='event', - options={'ordering': ['title']}, - ), - migrations.AlterModelOptions( - name='speaker', - options={'ordering': ['name']}, - ), + migrations.AlterModelOptions(name="event", options={"ordering": ["title"]}), + migrations.AlterModelOptions(name="speaker", options={"ordering": ["name"]}), migrations.AddField( - model_name='speaker', - name='slug', + model_name="speaker", + name="slug", field=models.SlugField(blank=True, max_length=255), ), migrations.AlterField( - model_name='event', - name='days', - field=models.ManyToManyField(blank=True, null=True, to='camps.Day'), + model_name="event", + name="days", + field=models.ManyToManyField(blank=True, null=True, to="camps.Day"), ), migrations.AlterField( - model_name='event', - name='end', + model_name="event", + name="end", field=models.TimeField(blank=True, null=True), ), migrations.AlterField( - model_name='event', - name='start', + model_name="event", + name="start", field=models.TimeField(blank=True, null=True), ), ] diff --git a/src/program/migrations/0009_auto_20160827_0752.py b/src/program/migrations/0009_auto_20160827_0752.py index 2c473742..0dcb37f9 100644 --- a/src/program/migrations/0009_auto_20160827_0752.py +++ b/src/program/migrations/0009_auto_20160827_0752.py @@ -7,14 +7,12 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ - ('program', '0008_auto_20160808_1747'), - ] + dependencies = [("program", "0008_auto_20160808_1747")] operations = [ migrations.AlterField( - model_name='event', - name='days', - field=models.ManyToManyField(blank=True, to='camps.Day'), - ), + model_name="event", + name="days", + field=models.ManyToManyField(blank=True, to="camps.Day"), + ) ] diff --git a/src/program/migrations/0010_auto_20161212_1809.py b/src/program/migrations/0010_auto_20161212_1809.py index 19642387..1019ba9d 100644 --- a/src/program/migrations/0010_auto_20161212_1809.py +++ b/src/program/migrations/0010_auto_20161212_1809.py @@ -9,44 +9,47 @@ import django.db.models.deletion class Migration(migrations.Migration): dependencies = [ - ('camps', '0007_auto_20161212_1803'), - ('program', '0009_auto_20160827_0752'), + ("camps", "0007_auto_20161212_1803"), + ("program", "0009_auto_20160827_0752"), ] operations = [ migrations.CreateModel( - name='EventInstance', + name="EventInstance", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('created', models.DateTimeField(auto_now_add=True)), - ('updated', models.DateTimeField(auto_now=True)), - ('start', models.DateTimeField()), - ('end', models.DateTimeField()), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("created", models.DateTimeField(auto_now_add=True)), + ("updated", models.DateTimeField(auto_now=True)), + ("start", models.DateTimeField()), + ("end", models.DateTimeField()), ], - options={ - 'ordering': ['start'], - }, + options={"ordering": ["start"]}, ), - migrations.RemoveField( - model_name='event', - name='days', - ), - migrations.RemoveField( - model_name='event', - name='end', - ), - migrations.RemoveField( - model_name='event', - name='start', + migrations.RemoveField(model_name="event", name="days"), + migrations.RemoveField(model_name="event", name="end"), + migrations.RemoveField(model_name="event", name="start"), + migrations.AddField( + model_name="event", + name="camp", + field=models.ForeignKey( + null=True, on_delete=django.db.models.deletion.CASCADE, to="camps.Camp" + ), ), migrations.AddField( - model_name='event', - name='camp', - field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='camps.Camp'), - ), - migrations.AddField( - model_name='eventinstance', - name='event', - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='instances', to='program.Event'), + model_name="eventinstance", + name="event", + field=models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="instances", + to="program.Event", + ), ), ] diff --git a/src/program/migrations/0011_auto_20161229_2149.py b/src/program/migrations/0011_auto_20161229_2149.py index ac4da61a..5ca18b59 100644 --- a/src/program/migrations/0011_auto_20161229_2149.py +++ b/src/program/migrations/0011_auto_20161229_2149.py @@ -8,26 +8,17 @@ from django.db import migrations class Migration(migrations.Migration): - dependencies = [ - ('program', '0010_auto_20161212_1809'), - ] + dependencies = [("program", "0010_auto_20161212_1809")] operations = [ migrations.AlterModelOptions( - name='eventinstance', - options={'ordering': ['when']}, - ), - migrations.RemoveField( - model_name='eventinstance', - name='end', - ), - migrations.RemoveField( - model_name='eventinstance', - name='start', + name="eventinstance", options={"ordering": ["when"]} ), + migrations.RemoveField(model_name="eventinstance", name="end"), + migrations.RemoveField(model_name="eventinstance", name="start"), migrations.AddField( - model_name='eventinstance', - name='when', + model_name="eventinstance", + name="when", field=django.contrib.postgres.fields.ranges.DateTimeRangeField(null=True), ), ] diff --git a/src/program/migrations/0012_auto_20161229_2150.py b/src/program/migrations/0012_auto_20161229_2150.py index 1acc7768..8df0be14 100644 --- a/src/program/migrations/0012_auto_20161229_2150.py +++ b/src/program/migrations/0012_auto_20161229_2150.py @@ -8,14 +8,12 @@ from django.db import migrations class Migration(migrations.Migration): - dependencies = [ - ('program', '0011_auto_20161229_2149'), - ] + dependencies = [("program", "0011_auto_20161229_2149")] operations = [ migrations.AlterField( - model_name='eventinstance', - name='when', + model_name="eventinstance", + name="when", field=django.contrib.postgres.fields.ranges.DateTimeRangeField(), - ), + ) ] diff --git a/src/program/migrations/0013_auto_20170121_1312.py b/src/program/migrations/0013_auto_20170121_1312.py index 62ffacfa..dd8daabb 100644 --- a/src/program/migrations/0013_auto_20170121_1312.py +++ b/src/program/migrations/0013_auto_20170121_1312.py @@ -8,14 +8,17 @@ import django.db.models.deletion class Migration(migrations.Migration): - dependencies = [ - ('program', '0012_auto_20161229_2150'), - ] + dependencies = [("program", "0012_auto_20161229_2150")] operations = [ migrations.AlterField( - model_name='event', - name='camp', - field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='events', to='camps.Camp'), - ), + model_name="event", + name="camp", + field=models.ForeignKey( + null=True, + on_delete=django.db.models.deletion.CASCADE, + related_name="events", + to="camps.Camp", + ), + ) ] diff --git a/src/program/migrations/0014_speaker_camp.py b/src/program/migrations/0014_speaker_camp.py index 704d3a12..6f41290e 100644 --- a/src/program/migrations/0014_speaker_camp.py +++ b/src/program/migrations/0014_speaker_camp.py @@ -9,14 +9,19 @@ import django.db.models.deletion class Migration(migrations.Migration): dependencies = [ - ('camps', '0017_remove_camp_description'), - ('program', '0013_auto_20170121_1312'), + ("camps", "0017_remove_camp_description"), + ("program", "0013_auto_20170121_1312"), ] operations = [ migrations.AddField( - model_name='speaker', - name='camp', - field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='speakers', to='camps.Camp'), - ), + model_name="speaker", + name="camp", + field=models.ForeignKey( + null=True, + on_delete=django.db.models.deletion.CASCADE, + related_name="speakers", + to="camps.Camp", + ), + ) ] diff --git a/src/program/migrations/0015_auto_20170128_1841.py b/src/program/migrations/0015_auto_20170128_1841.py index 6fb2c8b9..fd97e75e 100644 --- a/src/program/migrations/0015_auto_20170128_1841.py +++ b/src/program/migrations/0015_auto_20170128_1841.py @@ -8,27 +8,25 @@ from django.db import migrations, models class Migration(migrations.Migration): dependencies = [ - ('camps', '0018_auto_20170128_1841'), - ('program', '0014_speaker_camp'), + ("camps", "0018_auto_20170128_1841"), + ("program", "0014_speaker_camp"), ] operations = [ migrations.AlterField( - model_name='eventtype', - name='name', + model_name="eventtype", + name="name", field=models.CharField(max_length=100, unique=True), ), migrations.AlterField( - model_name='speaker', - name='events', - field=models.ManyToManyField(blank=True, to='program.Event'), + model_name="speaker", + name="events", + field=models.ManyToManyField(blank=True, to="program.Event"), ), migrations.AlterUniqueTogether( - name='event', - unique_together=set([('camp', 'title'), ('camp', 'slug')]), + name="event", unique_together=set([("camp", "title"), ("camp", "slug")]) ), migrations.AlterUniqueTogether( - name='speaker', - unique_together=set([('camp', 'name'), ('camp', 'slug')]), + name="speaker", unique_together=set([("camp", "name"), ("camp", "slug")]) ), ] diff --git a/src/program/migrations/0016_auto_20170131_1849.py b/src/program/migrations/0016_auto_20170131_1849.py index 11891ca0..b9b8debb 100644 --- a/src/program/migrations/0016_auto_20170131_1849.py +++ b/src/program/migrations/0016_auto_20170131_1849.py @@ -7,14 +7,12 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ - ('program', '0015_auto_20170128_1841'), - ] + dependencies = [("program", "0015_auto_20170128_1841")] operations = [ migrations.AlterField( - model_name='speaker', - name='picture', - field=models.ImageField(blank=True, null=True, upload_to=''), - ), + model_name="speaker", + name="picture", + field=models.ImageField(blank=True, null=True, upload_to=""), + ) ] diff --git a/src/program/migrations/0017_eventinstance_notifications_sent.py b/src/program/migrations/0017_eventinstance_notifications_sent.py index 28a07713..ffa4d614 100644 --- a/src/program/migrations/0017_eventinstance_notifications_sent.py +++ b/src/program/migrations/0017_eventinstance_notifications_sent.py @@ -7,14 +7,12 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ - ('program', '0016_auto_20170131_1849'), - ] + dependencies = [("program", "0016_auto_20170131_1849")] operations = [ migrations.AddField( - model_name='eventinstance', - name='notifications_sent', + model_name="eventinstance", + name="notifications_sent", field=models.BooleanField(default=False), - ), + ) ] diff --git a/src/program/migrations/0018_eventtype_notifications.py b/src/program/migrations/0018_eventtype_notifications.py index d519d42f..f0888540 100644 --- a/src/program/migrations/0018_eventtype_notifications.py +++ b/src/program/migrations/0018_eventtype_notifications.py @@ -7,14 +7,12 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ - ('program', '0017_eventinstance_notifications_sent'), - ] + dependencies = [("program", "0017_eventinstance_notifications_sent")] operations = [ migrations.AddField( - model_name='eventtype', - name='notifications', + model_name="eventtype", + name="notifications", field=models.BooleanField(default=False), - ), + ) ] diff --git a/src/program/migrations/0019_auto_20170205_1940.py b/src/program/migrations/0019_auto_20170205_1940.py index 3d4ce550..5743b48b 100644 --- a/src/program/migrations/0019_auto_20170205_1940.py +++ b/src/program/migrations/0019_auto_20170205_1940.py @@ -9,29 +9,49 @@ import django.db.models.deletion class Migration(migrations.Migration): dependencies = [ - ('camps', '0019_auto_20170131_1849'), - ('program', '0018_eventtype_notifications'), + ("camps", "0019_auto_20170131_1849"), + ("program", "0018_eventtype_notifications"), ] operations = [ migrations.CreateModel( - name='EventLocation', + name="EventLocation", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('created', models.DateTimeField(auto_now_add=True)), - ('updated', models.DateTimeField(auto_now=True)), - ('name', models.CharField(max_length=100, unique=True)), - ('slug', models.SlugField()), - ('icon', models.URLField()), - ('camp', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='eventlocations', to='camps.Camp')), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("created", models.DateTimeField(auto_now_add=True)), + ("updated", models.DateTimeField(auto_now=True)), + ("name", models.CharField(max_length=100, unique=True)), + ("slug", models.SlugField()), + ("icon", models.URLField()), + ( + "camp", + models.ForeignKey( + null=True, + on_delete=django.db.models.deletion.CASCADE, + related_name="eventlocations", + to="camps.Camp", + ), + ), ], - options={ - 'abstract': False, - }, + options={"abstract": False}, ), migrations.AddField( - model_name='eventinstance', - name='location', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='eventinstances', to='program.EventLocation'), + model_name="eventinstance", + name="location", + field=models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.CASCADE, + related_name="eventinstances", + to="program.EventLocation", + ), ), ] diff --git a/src/program/migrations/0020_auto_20170205_1940.py b/src/program/migrations/0020_auto_20170205_1940.py index 8d196893..ec96fe07 100644 --- a/src/program/migrations/0020_auto_20170205_1940.py +++ b/src/program/migrations/0020_auto_20170205_1940.py @@ -8,14 +8,16 @@ import django.db.models.deletion class Migration(migrations.Migration): - dependencies = [ - ('program', '0019_auto_20170205_1940'), - ] + dependencies = [("program", "0019_auto_20170205_1940")] operations = [ migrations.AlterField( - model_name='eventinstance', - name='location', - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='eventinstances', to='program.EventLocation'), - ), + model_name="eventinstance", + name="location", + field=models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="eventinstances", + to="program.EventLocation", + ), + ) ] diff --git a/src/program/migrations/0021_auto_20170205_2130.py b/src/program/migrations/0021_auto_20170205_2130.py index d85af26c..558e6108 100644 --- a/src/program/migrations/0021_auto_20170205_2130.py +++ b/src/program/migrations/0021_auto_20170205_2130.py @@ -8,23 +8,23 @@ from django.db import migrations, models class Migration(migrations.Migration): dependencies = [ - ('camps', '0019_auto_20170131_1849'), - ('program', '0020_auto_20170205_1940'), + ("camps", "0019_auto_20170131_1849"), + ("program", "0020_auto_20170205_1940"), ] operations = [ migrations.AlterField( - model_name='eventlocation', - name='icon', + model_name="eventlocation", + name="icon", field=models.CharField(max_length=100), ), migrations.AlterField( - model_name='eventlocation', - name='name', + model_name="eventlocation", + name="name", field=models.CharField(max_length=100), ), migrations.AlterUniqueTogether( - name='eventlocation', - unique_together=set([('camp', 'slug'), ('camp', 'name')]), + name="eventlocation", + unique_together=set([("camp", "slug"), ("camp", "name")]), ), ] diff --git a/src/program/migrations/0022_auto_20170218_1148.py b/src/program/migrations/0022_auto_20170218_1148.py index 0bc892d9..79665e9c 100644 --- a/src/program/migrations/0022_auto_20170218_1148.py +++ b/src/program/migrations/0022_auto_20170218_1148.py @@ -7,19 +7,15 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ - ('program', '0021_auto_20170205_2130'), - ] + dependencies = [("program", "0021_auto_20170205_2130")] operations = [ migrations.RenameField( - model_name='speaker', - old_name='picture', - new_name='picture_large', + model_name="speaker", old_name="picture", new_name="picture_large" ), migrations.AddField( - model_name='speaker', - name='picture_small', - field=models.ImageField(blank=True, null=True, upload_to=''), + model_name="speaker", + name="picture_small", + field=models.ImageField(blank=True, null=True, upload_to=""), ), ] diff --git a/src/program/migrations/0023_auto_20170218_1243.py b/src/program/migrations/0023_auto_20170218_1243.py index 9c90eb91..8d3d6f02 100644 --- a/src/program/migrations/0023_auto_20170218_1243.py +++ b/src/program/migrations/0023_auto_20170218_1243.py @@ -8,19 +8,25 @@ import program.models class Migration(migrations.Migration): - dependencies = [ - ('program', '0022_auto_20170218_1148'), - ] + dependencies = [("program", "0022_auto_20170218_1148")] operations = [ migrations.AlterField( - model_name='speaker', - name='picture_large', - field=models.ImageField(blank=True, null=True, upload_to=program.models.get_speaker_picture_upload_path), + model_name="speaker", + name="picture_large", + field=models.ImageField( + blank=True, + null=True, + upload_to=program.models.get_speaker_picture_upload_path, + ), ), migrations.AlterField( - model_name='speaker', - name='picture_small', - field=models.ImageField(blank=True, null=True, upload_to=program.models.get_speaker_picture_upload_path), + model_name="speaker", + name="picture_small", + field=models.ImageField( + blank=True, + null=True, + upload_to=program.models.get_speaker_picture_upload_path, + ), ), ] diff --git a/src/program/migrations/0024_auto_20170222_1629.py b/src/program/migrations/0024_auto_20170222_1629.py index cf412a37..dd360126 100644 --- a/src/program/migrations/0024_auto_20170222_1629.py +++ b/src/program/migrations/0024_auto_20170222_1629.py @@ -7,19 +7,24 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ - ('program', '0023_auto_20170218_1243'), - ] + dependencies = [("program", "0023_auto_20170218_1243")] operations = [ migrations.AddField( - model_name='event', - name='video_recording', - field=models.BooleanField(default=True, help_text='Whether the event will be video recorded.'), + model_name="event", + name="video_recording", + field=models.BooleanField( + default=True, help_text="Whether the event will be video recorded." + ), ), migrations.AddField( - model_name='event', - name='video_url', - field=models.URLField(blank=True, help_text='URL to the recording.', max_length=1000, null=True), + model_name="event", + name="video_url", + field=models.URLField( + blank=True, + help_text="URL to the recording.", + max_length=1000, + null=True, + ), ), ] diff --git a/src/program/migrations/0025_auto_20170306_1938.py b/src/program/migrations/0025_auto_20170306_1938.py index 084787b3..00bd41bc 100644 --- a/src/program/migrations/0025_auto_20170306_1938.py +++ b/src/program/migrations/0025_auto_20170306_1938.py @@ -7,14 +7,15 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ - ('program', '0024_auto_20170222_1629'), - ] + dependencies = [("program", "0024_auto_20170222_1629")] operations = [ migrations.AlterField( - model_name='event', - name='video_recording', - field=models.BooleanField(default=True, help_text='Whether the event will be video recorded or not.'), - ), + model_name="event", + name="video_recording", + field=models.BooleanField( + default=True, + help_text="Whether the event will be video recorded or not.", + ), + ) ] diff --git a/src/program/migrations/0026_speaker_user.py b/src/program/migrations/0026_speaker_user.py index 9f19a273..ac6c1466 100644 --- a/src/program/migrations/0026_speaker_user.py +++ b/src/program/migrations/0026_speaker_user.py @@ -11,13 +11,18 @@ class Migration(migrations.Migration): dependencies = [ migrations.swappable_dependency(settings.AUTH_USER_MODEL), - ('program', '0025_auto_20170306_1938'), + ("program", "0025_auto_20170306_1938"), ] operations = [ migrations.AddField( - model_name='speaker', - name='user', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, to=settings.AUTH_USER_MODEL), - ), + model_name="speaker", + name="user", + field=models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.PROTECT, + to=settings.AUTH_USER_MODEL, + ), + ) ] diff --git a/src/program/migrations/0027_auto_20170307_1701.py b/src/program/migrations/0027_auto_20170307_1701.py index ca07c0c4..e4589066 100644 --- a/src/program/migrations/0027_auto_20170307_1701.py +++ b/src/program/migrations/0027_auto_20170307_1701.py @@ -9,14 +9,14 @@ from django.db import migrations class Migration(migrations.Migration): dependencies = [ - ('camps', '0019_auto_20170131_1849'), + ("camps", "0019_auto_20170131_1849"), migrations.swappable_dependency(settings.AUTH_USER_MODEL), - ('program', '0026_speaker_user'), + ("program", "0026_speaker_user"), ] operations = [ migrations.AlterUniqueTogether( - name='speaker', - unique_together=set([('camp', 'user'), ('camp', 'slug'), ('camp', 'name')]), - ), + name="speaker", + unique_together=set([("camp", "user"), ("camp", "slug"), ("camp", "name")]), + ) ] diff --git a/src/program/migrations/0028_auto_20170307_2014.py b/src/program/migrations/0028_auto_20170307_2014.py index bbda54c7..0d56a50c 100644 --- a/src/program/migrations/0028_auto_20170307_2014.py +++ b/src/program/migrations/0028_auto_20170307_2014.py @@ -7,19 +7,33 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ - ('program', '0027_auto_20170307_1701'), - ] + dependencies = [("program", "0027_auto_20170307_1701")] operations = [ migrations.AddField( - model_name='event', - name='submission_status', - field=models.CharField(choices=[('pending', 'Pending approval'), ('approved', 'Approved'), ('rejected', 'Rejected')], default='pending', max_length=50), + model_name="event", + name="submission_status", + field=models.CharField( + choices=[ + ("pending", "Pending approval"), + ("approved", "Approved"), + ("rejected", "Rejected"), + ], + default="pending", + max_length=50, + ), ), migrations.AddField( - model_name='speaker', - name='submission_status', - field=models.CharField(choices=[('pending', 'Pending approval'), ('approved', 'Approved'), ('rejected', 'Rejected')], default='pending', max_length=50), + model_name="speaker", + name="submission_status", + field=models.CharField( + choices=[ + ("pending", "Pending approval"), + ("approved", "Approved"), + ("rejected", "Rejected"), + ], + default="pending", + max_length=50, + ), ), ] diff --git a/src/program/migrations/0029_auto_20170307_2042.py b/src/program/migrations/0029_auto_20170307_2042.py index eb5dd861..e9348eed 100644 --- a/src/program/migrations/0029_auto_20170307_2042.py +++ b/src/program/migrations/0029_auto_20170307_2042.py @@ -7,19 +7,35 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ - ('program', '0028_auto_20170307_2014'), - ] + dependencies = [("program", "0028_auto_20170307_2014")] operations = [ migrations.AlterField( - model_name='event', - name='submission_status', - field=models.CharField(choices=[('draft', 'Draft'), ('pending', 'Pending approval'), ('approved', 'Approved'), ('rejected', 'Rejected')], default='draft', max_length=50), + model_name="event", + name="submission_status", + field=models.CharField( + choices=[ + ("draft", "Draft"), + ("pending", "Pending approval"), + ("approved", "Approved"), + ("rejected", "Rejected"), + ], + default="draft", + max_length=50, + ), ), migrations.AlterField( - model_name='speaker', - name='submission_status', - field=models.CharField(choices=[('draft', 'Draft'), ('pending', 'Pending approval'), ('approved', 'Approved'), ('rejected', 'Rejected')], default='draft', max_length=50), + model_name="speaker", + name="submission_status", + field=models.CharField( + choices=[ + ("draft", "Draft"), + ("pending", "Pending approval"), + ("approved", "Approved"), + ("rejected", "Rejected"), + ], + default="draft", + max_length=50, + ), ), ] diff --git a/src/program/migrations/0030_auto_20170312_1230.py b/src/program/migrations/0030_auto_20170312_1230.py index 27126658..863f6cb6 100644 --- a/src/program/migrations/0030_auto_20170312_1230.py +++ b/src/program/migrations/0030_auto_20170312_1230.py @@ -12,137 +12,278 @@ import uuid class Migration(migrations.Migration): dependencies = [ - ('camps', '0020_camp_read_only'), + ("camps", "0020_camp_read_only"), migrations.swappable_dependency(settings.AUTH_USER_MODEL), - ('program', '0029_auto_20170307_2042'), + ("program", "0029_auto_20170307_2042"), ] operations = [ migrations.CreateModel( - name='EventSubmission', + name="EventSubmission", fields=[ - ('created', models.DateTimeField(auto_now_add=True)), - ('updated', models.DateTimeField(auto_now=True)), - ('uuid', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)), - ('submission_status', models.CharField(choices=[('draft', 'Draft'), ('pending', 'Pending approval'), ('approved', 'Approved'), ('rejected', 'Rejected')], default='draft', max_length=50)), - ('title', models.CharField(help_text='The title of this event', max_length=255)), - ('abstract', models.TextField(help_text='The abstract for this event')), - ('camp', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='eventsubmissions', to='camps.Camp')), - ('event_type', models.ForeignKey(help_text='The type of event', on_delete=django.db.models.deletion.CASCADE, to='program.EventType')), - ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), + ("created", models.DateTimeField(auto_now_add=True)), + ("updated", models.DateTimeField(auto_now=True)), + ( + "uuid", + models.UUIDField( + default=uuid.uuid4, + editable=False, + primary_key=True, + serialize=False, + ), + ), + ( + "submission_status", + models.CharField( + choices=[ + ("draft", "Draft"), + ("pending", "Pending approval"), + ("approved", "Approved"), + ("rejected", "Rejected"), + ], + default="draft", + max_length=50, + ), + ), + ( + "title", + models.CharField( + help_text="The title of this event", max_length=255 + ), + ), + ("abstract", models.TextField(help_text="The abstract for this event")), + ( + "camp", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="eventsubmissions", + to="camps.Camp", + ), + ), + ( + "event_type", + models.ForeignKey( + help_text="The type of event", + on_delete=django.db.models.deletion.CASCADE, + to="program.EventType", + ), + ), + ( + "user", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + to=settings.AUTH_USER_MODEL, + ), + ), ], - options={ - 'abstract': False, - }, + options={"abstract": False}, ), migrations.CreateModel( - name='SpeakerSubmission', + name="SpeakerSubmission", fields=[ - ('created', models.DateTimeField(auto_now_add=True)), - ('updated', models.DateTimeField(auto_now=True)), - ('uuid', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)), - ('submission_status', models.CharField(choices=[('draft', 'Draft'), ('pending', 'Pending approval'), ('approved', 'Approved'), ('rejected', 'Rejected')], default='draft', max_length=50)), - ('name', models.CharField(help_text='Name or alias of the speaker', max_length=150)), - ('biography', models.TextField(help_text='Markdown is supported.')), - ('picture_large', models.ImageField(blank=True, help_text='A picture of the speaker', null=True, upload_to=program.models.get_speakersubmission_picture_upload_path)), - ('picture_small', models.ImageField(blank=True, help_text='A thumbnail of the speaker picture', null=True, upload_to=program.models.get_speakersubmission_picture_upload_path)), - ('camp', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='speakersubmissions', to='camps.Camp')), - ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), + ("created", models.DateTimeField(auto_now_add=True)), + ("updated", models.DateTimeField(auto_now=True)), + ( + "uuid", + models.UUIDField( + default=uuid.uuid4, + editable=False, + primary_key=True, + serialize=False, + ), + ), + ( + "submission_status", + models.CharField( + choices=[ + ("draft", "Draft"), + ("pending", "Pending approval"), + ("approved", "Approved"), + ("rejected", "Rejected"), + ], + default="draft", + max_length=50, + ), + ), + ( + "name", + models.CharField( + help_text="Name or alias of the speaker", max_length=150 + ), + ), + ("biography", models.TextField(help_text="Markdown is supported.")), + ( + "picture_large", + models.ImageField( + blank=True, + help_text="A picture of the speaker", + null=True, + upload_to=program.models.get_speakersubmission_picture_upload_path, + ), + ), + ( + "picture_small", + models.ImageField( + blank=True, + help_text="A thumbnail of the speaker picture", + null=True, + upload_to=program.models.get_speakersubmission_picture_upload_path, + ), + ), + ( + "camp", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="speakersubmissions", + to="camps.Camp", + ), + ), + ( + "user", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + to=settings.AUTH_USER_MODEL, + ), + ), ], - options={ - 'abstract': False, - }, + options={"abstract": False}, ), - migrations.RemoveField( - model_name='event', - name='submission_status', + migrations.RemoveField(model_name="event", name="submission_status"), + migrations.AlterField( + model_name="event", + name="abstract", + field=models.TextField(help_text="The abstract for this event"), ), migrations.AlterField( - model_name='event', - name='abstract', - field=models.TextField(help_text='The abstract for this event'), + model_name="event", + name="camp", + field=models.ForeignKey( + help_text="The camp this event belongs to", + on_delete=django.db.models.deletion.CASCADE, + related_name="events", + to="camps.Camp", + ), ), migrations.AlterField( - model_name='event', - name='camp', - field=models.ForeignKey(help_text='The camp this event belongs to', on_delete=django.db.models.deletion.CASCADE, related_name='events', to='camps.Camp'), + model_name="event", + name="event_type", + field=models.ForeignKey( + help_text="The type of this event", + on_delete=django.db.models.deletion.CASCADE, + to="program.EventType", + ), ), migrations.AlterField( - model_name='event', - name='event_type', - field=models.ForeignKey(help_text='The type of this event', on_delete=django.db.models.deletion.CASCADE, to='program.EventType'), + model_name="event", + name="slug", + field=models.SlugField( + blank=True, + help_text="The slug for this event, created automatically", + max_length=255, + ), ), migrations.AlterField( - model_name='event', - name='slug', - field=models.SlugField(blank=True, help_text='The slug for this event, created automatically', max_length=255), + model_name="event", + name="title", + field=models.CharField(help_text="The title of this event", max_length=255), ), migrations.AlterField( - model_name='event', - name='title', - field=models.CharField(help_text='The title of this event', max_length=255), + model_name="event", + name="video_recording", + field=models.BooleanField( + default=True, help_text="Do we intend to record video of this event?" + ), ), migrations.AlterField( - model_name='event', - name='video_recording', - field=models.BooleanField(default=True, help_text='Do we intend to record video of this event?'), + model_name="event", + name="video_url", + field=models.URLField( + blank=True, help_text="URL to the recording", max_length=1000, null=True + ), ), migrations.AlterField( - model_name='event', - name='video_url', - field=models.URLField(blank=True, help_text='URL to the recording', max_length=1000, null=True), + model_name="eventlocation", + name="camp", + field=models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="eventlocations", + to="camps.Camp", + ), ), migrations.AlterField( - model_name='eventlocation', - name='camp', - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='eventlocations', to='camps.Camp'), + model_name="speaker", + name="biography", + field=models.TextField(help_text="Markdown is supported."), ), migrations.AlterField( - model_name='speaker', - name='biography', - field=models.TextField(help_text='Markdown is supported.'), + model_name="speaker", + name="camp", + field=models.ForeignKey( + help_text="The camp this speaker belongs to", + null=True, + on_delete=django.db.models.deletion.CASCADE, + related_name="speakers", + to="camps.Camp", + ), ), migrations.AlterField( - model_name='speaker', - name='camp', - field=models.ForeignKey(help_text='The camp this speaker belongs to', null=True, on_delete=django.db.models.deletion.CASCADE, related_name='speakers', to='camps.Camp'), + model_name="speaker", + name="events", + field=models.ManyToManyField( + blank=True, + help_text="The event(s) this speaker is anchoring", + to="program.Event", + ), ), migrations.AlterField( - model_name='speaker', - name='events', - field=models.ManyToManyField(blank=True, help_text='The event(s) this speaker is anchoring', to='program.Event'), + model_name="speaker", + name="name", + field=models.CharField( + help_text="Name or alias of the speaker", max_length=150 + ), ), migrations.AlterField( - model_name='speaker', - name='name', - field=models.CharField(help_text='Name or alias of the speaker', max_length=150), + model_name="speaker", + name="picture_large", + field=models.ImageField( + blank=True, + help_text="A picture of the speaker", + null=True, + upload_to=program.models.get_speaker_picture_upload_path, + ), ), migrations.AlterField( - model_name='speaker', - name='picture_large', - field=models.ImageField(blank=True, help_text='A picture of the speaker', null=True, upload_to=program.models.get_speaker_picture_upload_path), + model_name="speaker", + name="picture_small", + field=models.ImageField( + blank=True, + help_text="A thumbnail of the speaker picture", + null=True, + upload_to=program.models.get_speaker_picture_upload_path, + ), ), migrations.AlterField( - model_name='speaker', - name='picture_small', - field=models.ImageField(blank=True, help_text='A thumbnail of the speaker picture', null=True, upload_to=program.models.get_speaker_picture_upload_path), - ), - migrations.AlterField( - model_name='speaker', - name='slug', - field=models.SlugField(blank=True, help_text='The slug for this speaker, will be autocreated', max_length=255), - ), - migrations.RemoveField( - model_name='speaker', - name='submission_status', + model_name="speaker", + name="slug", + field=models.SlugField( + blank=True, + help_text="The slug for this speaker, will be autocreated", + max_length=255, + ), ), + migrations.RemoveField(model_name="speaker", name="submission_status"), migrations.AddField( - model_name='speaker', - name='submission', - field=models.OneToOneField(blank=True, help_text='The speaker submission object this speaker was created from', null=True, on_delete=django.db.models.deletion.CASCADE, to='program.SpeakerSubmission'), + model_name="speaker", + name="submission", + field=models.OneToOneField( + blank=True, + help_text="The speaker submission object this speaker was created from", + null=True, + on_delete=django.db.models.deletion.CASCADE, + to="program.SpeakerSubmission", + ), ), migrations.AlterUniqueTogether( - name='speaker', - unique_together=set([('camp', 'slug'), ('camp', 'name')]), + name="speaker", unique_together=set([("camp", "slug"), ("camp", "name")]) ), ] diff --git a/src/program/migrations/0031_auto_20170312_1529.py b/src/program/migrations/0031_auto_20170312_1529.py index 1fe6552a..edd8a013 100644 --- a/src/program/migrations/0031_auto_20170312_1529.py +++ b/src/program/migrations/0031_auto_20170312_1529.py @@ -7,18 +7,17 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ - ('program', '0030_auto_20170312_1230'), - ] + dependencies = [("program", "0030_auto_20170312_1230")] operations = [ - migrations.RemoveField( - model_name='speaker', - name='user', - ), + migrations.RemoveField(model_name="speaker", name="user"), migrations.AddField( - model_name='eventsubmission', - name='speakers', - field=models.ManyToManyField(blank=True, help_text='The speaker(s) for this event', to='program.SpeakerSubmission'), + model_name="eventsubmission", + name="speakers", + field=models.ManyToManyField( + blank=True, + help_text="The speaker(s) for this event", + to="program.SpeakerSubmission", + ), ), ] diff --git a/src/program/migrations/0032_auto_20170312_1556.py b/src/program/migrations/0032_auto_20170312_1556.py index e0dbbf28..05e699b3 100644 --- a/src/program/migrations/0032_auto_20170312_1556.py +++ b/src/program/migrations/0032_auto_20170312_1556.py @@ -7,39 +7,54 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ - ('program', '0031_auto_20170312_1529'), - ] + dependencies = [("program", "0031_auto_20170312_1529")] operations = [ migrations.AddField( - model_name='eventtype', - name='public', - field=models.BooleanField(default=False, help_text='Check to permit users to submit events of this type'), + model_name="eventtype", + name="public", + field=models.BooleanField( + default=False, + help_text="Check to permit users to submit events of this type", + ), ), migrations.AlterField( - model_name='eventsubmission', - name='speakers', - field=models.ManyToManyField(blank=True, help_text='Pick the speaker(s) for this event', to='program.SpeakerSubmission'), + model_name="eventsubmission", + name="speakers", + field=models.ManyToManyField( + blank=True, + help_text="Pick the speaker(s) for this event", + to="program.SpeakerSubmission", + ), ), migrations.AlterField( - model_name='eventtype', - name='color', - field=models.CharField(help_text='The background color of this event type', max_length=50), + model_name="eventtype", + name="color", + field=models.CharField( + help_text="The background color of this event type", max_length=50 + ), ), migrations.AlterField( - model_name='eventtype', - name='light_text', - field=models.BooleanField(default=False, help_text='Check if this event type should use white text color'), + model_name="eventtype", + name="light_text", + field=models.BooleanField( + default=False, + help_text="Check if this event type should use white text color", + ), ), migrations.AlterField( - model_name='eventtype', - name='name', - field=models.CharField(help_text='The name of this event type', max_length=100, unique=True), + model_name="eventtype", + name="name", + field=models.CharField( + help_text="The name of this event type", max_length=100, unique=True + ), ), migrations.AlterField( - model_name='eventtype', - name='notifications', - field=models.BooleanField(default=False, help_text='Check to send notifications for this event type'), + model_name="eventtype", + name="notifications", + field=models.BooleanField( + default=False, + help_text="Check to send notifications for this event type", + ), ), ] diff --git a/src/program/migrations/0033_auto_20170312_1857.py b/src/program/migrations/0033_auto_20170312_1857.py index 5f6391be..93f722bb 100644 --- a/src/program/migrations/0033_auto_20170312_1857.py +++ b/src/program/migrations/0033_auto_20170312_1857.py @@ -12,93 +12,169 @@ import uuid class Migration(migrations.Migration): dependencies = [ - ('camps', '0020_camp_read_only'), + ("camps", "0020_camp_read_only"), migrations.swappable_dependency(settings.AUTH_USER_MODEL), - ('program', '0032_auto_20170312_1556'), + ("program", "0032_auto_20170312_1556"), ] operations = [ migrations.CreateModel( - name='EventProposal', + name="EventProposal", fields=[ - ('created', models.DateTimeField(auto_now_add=True)), - ('updated', models.DateTimeField(auto_now=True)), - ('uuid', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)), - ('proposal_status', models.CharField(choices=[('draft', 'Draft'), ('pending', 'Pending approval'), ('approved', 'Approved'), ('rejected', 'Rejected')], default='draft', max_length=50)), - ('title', models.CharField(help_text='The title of this event', max_length=255)), - ('abstract', models.TextField(help_text='The abstract for this event')), - ('camp', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='eventproposals', to='camps.Camp')), - ('event_type', models.ForeignKey(help_text='The type of event', on_delete=django.db.models.deletion.CASCADE, to='program.EventType')), + ("created", models.DateTimeField(auto_now_add=True)), + ("updated", models.DateTimeField(auto_now=True)), + ( + "uuid", + models.UUIDField( + default=uuid.uuid4, + editable=False, + primary_key=True, + serialize=False, + ), + ), + ( + "proposal_status", + models.CharField( + choices=[ + ("draft", "Draft"), + ("pending", "Pending approval"), + ("approved", "Approved"), + ("rejected", "Rejected"), + ], + default="draft", + max_length=50, + ), + ), + ( + "title", + models.CharField( + help_text="The title of this event", max_length=255 + ), + ), + ("abstract", models.TextField(help_text="The abstract for this event")), + ( + "camp", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="eventproposals", + to="camps.Camp", + ), + ), + ( + "event_type", + models.ForeignKey( + help_text="The type of event", + on_delete=django.db.models.deletion.CASCADE, + to="program.EventType", + ), + ), ], - options={ - 'abstract': False, - }, + options={"abstract": False}, ), migrations.CreateModel( - name='SpeakerProposal', + name="SpeakerProposal", fields=[ - ('created', models.DateTimeField(auto_now_add=True)), - ('updated', models.DateTimeField(auto_now=True)), - ('uuid', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)), - ('proposal_status', models.CharField(choices=[('draft', 'Draft'), ('pending', 'Pending approval'), ('approved', 'Approved'), ('rejected', 'Rejected')], default='draft', max_length=50)), - ('name', models.CharField(help_text='Name or alias of the speaker', max_length=150)), - ('biography', models.TextField(help_text='Markdown is supported.')), - ('picture_large', models.ImageField(blank=True, help_text='A picture of the speaker', null=True, upload_to=program.models.get_speakerproposal_picture_upload_path)), - ('picture_small', models.ImageField(blank=True, help_text='A thumbnail of the speaker picture', null=True, upload_to=program.models.get_speakerproposal_picture_upload_path)), - ('camp', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='speakerproposals', to='camps.Camp')), - ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), + ("created", models.DateTimeField(auto_now_add=True)), + ("updated", models.DateTimeField(auto_now=True)), + ( + "uuid", + models.UUIDField( + default=uuid.uuid4, + editable=False, + primary_key=True, + serialize=False, + ), + ), + ( + "proposal_status", + models.CharField( + choices=[ + ("draft", "Draft"), + ("pending", "Pending approval"), + ("approved", "Approved"), + ("rejected", "Rejected"), + ], + default="draft", + max_length=50, + ), + ), + ( + "name", + models.CharField( + help_text="Name or alias of the speaker", max_length=150 + ), + ), + ("biography", models.TextField(help_text="Markdown is supported.")), + ( + "picture_large", + models.ImageField( + blank=True, + help_text="A picture of the speaker", + null=True, + upload_to=program.models.get_speakerproposal_picture_upload_path, + ), + ), + ( + "picture_small", + models.ImageField( + blank=True, + help_text="A thumbnail of the speaker picture", + null=True, + upload_to=program.models.get_speakerproposal_picture_upload_path, + ), + ), + ( + "camp", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="speakerproposals", + to="camps.Camp", + ), + ), + ( + "user", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + to=settings.AUTH_USER_MODEL, + ), + ), ], - options={ - 'abstract': False, - }, + options={"abstract": False}, ), - migrations.RemoveField( - model_name='eventsubmission', - name='camp', - ), - migrations.RemoveField( - model_name='eventsubmission', - name='event_type', - ), - migrations.RemoveField( - model_name='eventsubmission', - name='speakers', - ), - migrations.RemoveField( - model_name='eventsubmission', - name='user', - ), - migrations.RemoveField( - model_name='speakersubmission', - name='camp', - ), - migrations.RemoveField( - model_name='speakersubmission', - name='user', - ), - migrations.RemoveField( - model_name='speaker', - name='submission', - ), - migrations.DeleteModel( - name='EventSubmission', - ), - migrations.DeleteModel( - name='SpeakerSubmission', + migrations.RemoveField(model_name="eventsubmission", name="camp"), + migrations.RemoveField(model_name="eventsubmission", name="event_type"), + migrations.RemoveField(model_name="eventsubmission", name="speakers"), + migrations.RemoveField(model_name="eventsubmission", name="user"), + migrations.RemoveField(model_name="speakersubmission", name="camp"), + migrations.RemoveField(model_name="speakersubmission", name="user"), + migrations.RemoveField(model_name="speaker", name="submission"), + migrations.DeleteModel(name="EventSubmission"), + migrations.DeleteModel(name="SpeakerSubmission"), + migrations.AddField( + model_name="eventproposal", + name="speakers", + field=models.ManyToManyField( + blank=True, + help_text="Pick the speaker(s) for this event", + to="program.SpeakerProposal", + ), ), migrations.AddField( - model_name='eventproposal', - name='speakers', - field=models.ManyToManyField(blank=True, help_text='Pick the speaker(s) for this event', to='program.SpeakerProposal'), + model_name="eventproposal", + name="user", + field=models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL + ), ), migrations.AddField( - model_name='eventproposal', - name='user', - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL), - ), - migrations.AddField( - model_name='speaker', - name='proposal', - field=models.OneToOneField(blank=True, help_text='The speaker proposal object this speaker was created from', null=True, on_delete=django.db.models.deletion.CASCADE, to='program.SpeakerProposal'), + model_name="speaker", + name="proposal", + field=models.OneToOneField( + blank=True, + help_text="The speaker proposal object this speaker was created from", + null=True, + on_delete=django.db.models.deletion.CASCADE, + to="program.SpeakerProposal", + ), ), ] diff --git a/src/program/migrations/0034_auto_20170314_2012.py b/src/program/migrations/0034_auto_20170314_2012.py index 71c8c956..8a674835 100644 --- a/src/program/migrations/0034_auto_20170314_2012.py +++ b/src/program/migrations/0034_auto_20170314_2012.py @@ -8,19 +8,29 @@ import program.models class Migration(migrations.Migration): - dependencies = [ - ('program', '0033_auto_20170312_1857'), - ] + dependencies = [("program", "0033_auto_20170312_1857")] operations = [ migrations.AlterField( - model_name='speakerproposal', - name='picture_large', - field=models.ImageField(blank=True, help_text='A picture of the speaker', null=True, storage=program.models.CustomUrlStorage(), upload_to=program.models.get_speakerproposal_picture_upload_path), + model_name="speakerproposal", + name="picture_large", + field=models.ImageField( + blank=True, + help_text="A picture of the speaker", + null=True, + storage=program.models.CustomUrlStorage(), + upload_to=program.models.get_speakerproposal_picture_upload_path, + ), ), migrations.AlterField( - model_name='speakerproposal', - name='picture_small', - field=models.ImageField(blank=True, help_text='A thumbnail of the speaker picture', null=True, storage=program.models.CustomUrlStorage(), upload_to=program.models.get_speakerproposal_picture_upload_path), + model_name="speakerproposal", + name="picture_small", + field=models.ImageField( + blank=True, + help_text="A thumbnail of the speaker picture", + null=True, + storage=program.models.CustomUrlStorage(), + upload_to=program.models.get_speakerproposal_picture_upload_path, + ), ), ] diff --git a/src/program/migrations/0035_auto_20170314_2325.py b/src/program/migrations/0035_auto_20170314_2325.py index 46163b8c..d3283869 100644 --- a/src/program/migrations/0035_auto_20170314_2325.py +++ b/src/program/migrations/0035_auto_20170314_2325.py @@ -7,14 +7,15 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ - ('program', '0034_auto_20170314_2012'), - ] + dependencies = [("program", "0034_auto_20170314_2012")] operations = [ migrations.AlterField( - model_name='eventlocation', - name='icon', - field=models.CharField(help_text="hex for the unicode character in the fontawesome icon set to use, like 'f000' for 'fa-glass'", max_length=100), - ), + model_name="eventlocation", + name="icon", + field=models.CharField( + help_text="hex for the unicode character in the fontawesome icon set to use, like 'f000' for 'fa-glass'", + max_length=100, + ), + ) ] diff --git a/src/program/migrations/0036_auto_20170316_0004.py b/src/program/migrations/0036_auto_20170316_0004.py index e2168fdc..b8931394 100644 --- a/src/program/migrations/0036_auto_20170316_0004.py +++ b/src/program/migrations/0036_auto_20170316_0004.py @@ -8,19 +8,31 @@ import program.models class Migration(migrations.Migration): - dependencies = [ - ('program', '0035_auto_20170314_2325'), - ] + dependencies = [("program", "0035_auto_20170314_2325")] operations = [ migrations.AlterField( - model_name='speakerproposal', - name='picture_large', - field=models.ImageField(blank=True, help_text='A picture of the speaker', max_length=255, null=True, storage=program.models.CustomUrlStorage(), upload_to=program.models.get_speakerproposal_picture_upload_path), + model_name="speakerproposal", + name="picture_large", + field=models.ImageField( + blank=True, + help_text="A picture of the speaker", + max_length=255, + null=True, + storage=program.models.CustomUrlStorage(), + upload_to=program.models.get_speakerproposal_picture_upload_path, + ), ), migrations.AlterField( - model_name='speakerproposal', - name='picture_small', - field=models.ImageField(blank=True, help_text='A thumbnail of the speaker picture', max_length=255, null=True, storage=program.models.CustomUrlStorage(), upload_to=program.models.get_speakerproposal_picture_upload_path), + model_name="speakerproposal", + name="picture_small", + field=models.ImageField( + blank=True, + help_text="A thumbnail of the speaker picture", + max_length=255, + null=True, + storage=program.models.CustomUrlStorage(), + upload_to=program.models.get_speakerproposal_picture_upload_path, + ), ), ] diff --git a/src/program/migrations/0037_eventtype_include_in_event_list.py b/src/program/migrations/0037_eventtype_include_in_event_list.py index 19ec8e86..3d867f3a 100644 --- a/src/program/migrations/0037_eventtype_include_in_event_list.py +++ b/src/program/migrations/0037_eventtype_include_in_event_list.py @@ -7,14 +7,14 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ - ('program', '0036_auto_20170316_0004'), - ] + dependencies = [("program", "0036_auto_20170316_0004")] operations = [ migrations.AddField( - model_name='eventtype', - name='include_in_event_list', - field=models.BooleanField(default=True, help_text='Include events of this type in the event list?'), - ), + model_name="eventtype", + name="include_in_event_list", + field=models.BooleanField( + default=True, help_text="Include events of this type in the event list?" + ), + ) ] diff --git a/src/program/migrations/0038_favorite.py b/src/program/migrations/0038_favorite.py index 0b9b8334..f3f5e2bf 100644 --- a/src/program/migrations/0038_favorite.py +++ b/src/program/migrations/0038_favorite.py @@ -11,16 +11,37 @@ class Migration(migrations.Migration): dependencies = [ migrations.swappable_dependency(settings.AUTH_USER_MODEL), - ('program', '0037_eventtype_include_in_event_list'), + ("program", "0037_eventtype_include_in_event_list"), ] operations = [ migrations.CreateModel( - name='Favorite', + name="Favorite", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('event_instance', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='program.EventInstance')), - ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='favorites', to=settings.AUTH_USER_MODEL)), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "event_instance", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + to="program.EventInstance", + ), + ), + ( + "user", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="favorites", + to=settings.AUTH_USER_MODEL, + ), + ), ], - ), + ) ] diff --git a/src/program/migrations/0039_auto_20170430_1408.py b/src/program/migrations/0039_auto_20170430_1408.py index 7fae4c90..a85a7534 100644 --- a/src/program/migrations/0039_auto_20170430_1408.py +++ b/src/program/migrations/0039_auto_20170430_1408.py @@ -10,17 +10,21 @@ class Migration(migrations.Migration): dependencies = [ migrations.swappable_dependency(settings.AUTH_USER_MODEL), - ('program', '0038_favorite'), + ("program", "0038_favorite"), ] operations = [ migrations.AlterField( - model_name='speaker', - name='events', - field=models.ManyToManyField(blank=True, help_text='The event(s) this speaker is anchoring', related_name='speakers', to='program.Event'), + model_name="speaker", + name="events", + field=models.ManyToManyField( + blank=True, + help_text="The event(s) this speaker is anchoring", + related_name="speakers", + to="program.Event", + ), ), migrations.AlterUniqueTogether( - name='favorite', - unique_together=set([('user', 'event_instance')]), + name="favorite", unique_together=set([("user", "event_instance")]) ), ] diff --git a/src/program/migrations/0040_eventproposal_allow_video_recording.py b/src/program/migrations/0040_eventproposal_allow_video_recording.py index 805f65f8..0a22b856 100644 --- a/src/program/migrations/0040_eventproposal_allow_video_recording.py +++ b/src/program/migrations/0040_eventproposal_allow_video_recording.py @@ -7,14 +7,14 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ - ('program', '0039_auto_20170430_1408'), - ] + dependencies = [("program", "0039_auto_20170430_1408")] operations = [ migrations.AddField( - model_name='eventproposal', - name='allow_video_recording', - field=models.BooleanField(default=False, help_text='If we can video record the event or not'), - ), + model_name="eventproposal", + name="allow_video_recording", + field=models.BooleanField( + default=False, help_text="If we can video record the event or not" + ), + ) ] diff --git a/src/program/migrations/0041_auto_20170711_2248.py b/src/program/migrations/0041_auto_20170711_2248.py index 3aa64a68..1e0690ee 100644 --- a/src/program/migrations/0041_auto_20170711_2248.py +++ b/src/program/migrations/0041_auto_20170711_2248.py @@ -7,19 +7,37 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ - ('program', '0040_eventproposal_allow_video_recording'), - ] + dependencies = [("program", "0040_eventproposal_allow_video_recording")] operations = [ migrations.AlterField( - model_name='eventproposal', - name='proposal_status', - field=models.CharField(choices=[('draft', 'Draft'), ('pending', 'Pending approval'), ('approved', 'Approved'), ('rejected', 'Rejected'), ('modified after approval', 'Modified after approval')], default='draft', max_length=50), + model_name="eventproposal", + name="proposal_status", + field=models.CharField( + choices=[ + ("draft", "Draft"), + ("pending", "Pending approval"), + ("approved", "Approved"), + ("rejected", "Rejected"), + ("modified after approval", "Modified after approval"), + ], + default="draft", + max_length=50, + ), ), migrations.AlterField( - model_name='speakerproposal', - name='proposal_status', - field=models.CharField(choices=[('draft', 'Draft'), ('pending', 'Pending approval'), ('approved', 'Approved'), ('rejected', 'Rejected'), ('modified after approval', 'Modified after approval')], default='draft', max_length=50), + model_name="speakerproposal", + name="proposal_status", + field=models.CharField( + choices=[ + ("draft", "Draft"), + ("pending", "Pending approval"), + ("approved", "Approved"), + ("rejected", "Rejected"), + ("modified after approval", "Modified after approval"), + ], + default="draft", + max_length=50, + ), ), ] diff --git a/src/program/migrations/0042_auto_20170715_1547.py b/src/program/migrations/0042_auto_20170715_1547.py index 006413d0..4a0bcdd2 100644 --- a/src/program/migrations/0042_auto_20170715_1547.py +++ b/src/program/migrations/0042_auto_20170715_1547.py @@ -7,19 +7,23 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ - ('program', '0041_auto_20170711_2248'), - ] + dependencies = [("program", "0041_auto_20170711_2248")] operations = [ migrations.AddField( - model_name='eventproposal', - name='submission_notes', - field=models.TextField(blank=True, help_text='Private notes for the event. Only visible to the submitting user and the BornHack organisers.'), + model_name="eventproposal", + name="submission_notes", + field=models.TextField( + blank=True, + help_text="Private notes for the event. Only visible to the submitting user and the BornHack organisers.", + ), ), migrations.AddField( - model_name='speakerproposal', - name='submission_notes', - field=models.TextField(blank=True, help_text='Private notes for the event. Only visible to the submitting user and the BornHack organisers.'), + model_name="speakerproposal", + name="submission_notes", + field=models.TextField( + blank=True, + help_text="Private notes for the event. Only visible to the submitting user and the BornHack organisers.", + ), ), ] diff --git a/src/program/migrations/0043_auto_20170801_1526.py b/src/program/migrations/0043_auto_20170801_1526.py index 84d8139c..21b499bb 100644 --- a/src/program/migrations/0043_auto_20170801_1526.py +++ b/src/program/migrations/0043_auto_20170801_1526.py @@ -7,19 +7,23 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ - ('program', '0042_auto_20170715_1547'), - ] + dependencies = [("program", "0042_auto_20170715_1547")] operations = [ migrations.AlterField( - model_name='eventproposal', - name='submission_notes', - field=models.TextField(blank=True, help_text='Private notes for this event. Only visible to the submitting user and the BornHack organisers.'), + model_name="eventproposal", + name="submission_notes", + field=models.TextField( + blank=True, + help_text="Private notes for this event. Only visible to the submitting user and the BornHack organisers.", + ), ), migrations.AlterField( - model_name='speakerproposal', - name='submission_notes', - field=models.TextField(blank=True, help_text='Private notes for this speaker. Only visible to the submitting user and the BornHack organisers.'), + model_name="speakerproposal", + name="submission_notes", + field=models.TextField( + blank=True, + help_text="Private notes for this speaker. Only visible to the submitting user and the BornHack organisers.", + ), ), ] diff --git a/src/program/migrations/0044_auto_20170801_1527.py b/src/program/migrations/0044_auto_20170801_1527.py index dbc9cd32..3ea0c67f 100644 --- a/src/program/migrations/0044_auto_20170801_1527.py +++ b/src/program/migrations/0044_auto_20170801_1527.py @@ -7,14 +7,16 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ - ('program', '0043_auto_20170801_1526'), - ] + dependencies = [("program", "0043_auto_20170801_1526")] operations = [ migrations.AlterField( - model_name='eventproposal', - name='speakers', - field=models.ManyToManyField(blank=True, help_text='Pick the speaker(s) for this event. If you cannot see anything here you need to go back and create Speaker Proposal(s) first.', to='program.SpeakerProposal'), - ), + model_name="eventproposal", + name="speakers", + field=models.ManyToManyField( + blank=True, + help_text="Pick the speaker(s) for this event. If you cannot see anything here you need to go back and create Speaker Proposal(s) first.", + to="program.SpeakerProposal", + ), + ) ] diff --git a/src/program/migrations/0045_event_proposal.py b/src/program/migrations/0045_event_proposal.py index 5bf27900..54053167 100644 --- a/src/program/migrations/0045_event_proposal.py +++ b/src/program/migrations/0045_event_proposal.py @@ -8,14 +8,18 @@ import django.db.models.deletion class Migration(migrations.Migration): - dependencies = [ - ('program', '0044_auto_20170801_1527'), - ] + dependencies = [("program", "0044_auto_20170801_1527")] operations = [ migrations.AddField( - model_name='event', - name='proposal', - field=models.OneToOneField(blank=True, help_text='The event proposal object this event was created from', null=True, on_delete=django.db.models.deletion.CASCADE, to='program.EventProposal'), - ), + model_name="event", + name="proposal", + field=models.OneToOneField( + blank=True, + help_text="The event proposal object this event was created from", + null=True, + on_delete=django.db.models.deletion.CASCADE, + to="program.EventProposal", + ), + ) ] diff --git a/src/program/migrations/0046_auto_20180318_0906.py b/src/program/migrations/0046_auto_20180318_0906.py index a9b5b961..486612cf 100644 --- a/src/program/migrations/0046_auto_20180318_0906.py +++ b/src/program/migrations/0046_auto_20180318_0906.py @@ -9,14 +9,16 @@ import django.db.models.deletion class Migration(migrations.Migration): - dependencies = [ - ('program', '0045_event_proposal'), - ] + dependencies = [("program", "0045_event_proposal")] operations = [ migrations.AlterField( - model_name='favorite', - name='user', - field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='favorites', to=settings.AUTH_USER_MODEL), - ), + model_name="favorite", + name="user", + field=models.ForeignKey( + on_delete=django.db.models.deletion.PROTECT, + related_name="favorites", + to=settings.AUTH_USER_MODEL, + ), + ) ] diff --git a/src/program/migrations/0047_auto_20180415_1159.py b/src/program/migrations/0047_auto_20180415_1159.py index e0b6ada7..d847e274 100644 --- a/src/program/migrations/0047_auto_20180415_1159.py +++ b/src/program/migrations/0047_auto_20180415_1159.py @@ -7,79 +7,134 @@ import django.db.models.deletion class Migration(migrations.Migration): - dependencies = [ - ('program', '0046_auto_20180318_0906'), - ] + dependencies = [("program", "0046_auto_20180318_0906")] operations = [ migrations.AlterField( - model_name='event', - name='camp', - field=models.ForeignKey(help_text='The camp this event belongs to', on_delete=django.db.models.deletion.PROTECT, related_name='events', to='camps.Camp'), + model_name="event", + name="camp", + field=models.ForeignKey( + help_text="The camp this event belongs to", + on_delete=django.db.models.deletion.PROTECT, + related_name="events", + to="camps.Camp", + ), ), migrations.AlterField( - model_name='event', - name='event_type', - field=models.ForeignKey(help_text='The type of this event', on_delete=django.db.models.deletion.PROTECT, to='program.EventType'), + model_name="event", + name="event_type", + field=models.ForeignKey( + help_text="The type of this event", + on_delete=django.db.models.deletion.PROTECT, + to="program.EventType", + ), ), migrations.AlterField( - model_name='event', - name='proposal', - field=models.OneToOneField(blank=True, help_text='The event proposal object this event was created from', null=True, on_delete=django.db.models.deletion.PROTECT, to='program.EventProposal'), + model_name="event", + name="proposal", + field=models.OneToOneField( + blank=True, + help_text="The event proposal object this event was created from", + null=True, + on_delete=django.db.models.deletion.PROTECT, + to="program.EventProposal", + ), ), migrations.AlterField( - model_name='eventinstance', - name='event', - field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='instances', to='program.Event'), + model_name="eventinstance", + name="event", + field=models.ForeignKey( + on_delete=django.db.models.deletion.PROTECT, + related_name="instances", + to="program.Event", + ), ), migrations.AlterField( - model_name='eventinstance', - name='location', - field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='eventinstances', to='program.EventLocation'), + model_name="eventinstance", + name="location", + field=models.ForeignKey( + on_delete=django.db.models.deletion.PROTECT, + related_name="eventinstances", + to="program.EventLocation", + ), ), migrations.AlterField( - model_name='eventlocation', - name='camp', - field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='eventlocations', to='camps.Camp'), + model_name="eventlocation", + name="camp", + field=models.ForeignKey( + on_delete=django.db.models.deletion.PROTECT, + related_name="eventlocations", + to="camps.Camp", + ), ), migrations.AlterField( - model_name='eventproposal', - name='camp', - field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='eventproposals', to='camps.Camp'), + model_name="eventproposal", + name="camp", + field=models.ForeignKey( + on_delete=django.db.models.deletion.PROTECT, + related_name="eventproposals", + to="camps.Camp", + ), ), migrations.AlterField( - model_name='eventproposal', - name='event_type', - field=models.ForeignKey(help_text='The type of event', on_delete=django.db.models.deletion.PROTECT, to='program.EventType'), + model_name="eventproposal", + name="event_type", + field=models.ForeignKey( + help_text="The type of event", + on_delete=django.db.models.deletion.PROTECT, + to="program.EventType", + ), ), migrations.AlterField( - model_name='eventproposal', - name='user', - field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to=settings.AUTH_USER_MODEL), + model_name="eventproposal", + name="user", + field=models.ForeignKey( + on_delete=django.db.models.deletion.PROTECT, to=settings.AUTH_USER_MODEL + ), ), migrations.AlterField( - model_name='favorite', - name='event_instance', - field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='program.EventInstance'), + model_name="favorite", + name="event_instance", + field=models.ForeignKey( + on_delete=django.db.models.deletion.PROTECT, to="program.EventInstance" + ), ), migrations.AlterField( - model_name='speaker', - name='camp', - field=models.ForeignKey(help_text='The camp this speaker belongs to', null=True, on_delete=django.db.models.deletion.PROTECT, related_name='speakers', to='camps.Camp'), + model_name="speaker", + name="camp", + field=models.ForeignKey( + help_text="The camp this speaker belongs to", + null=True, + on_delete=django.db.models.deletion.PROTECT, + related_name="speakers", + to="camps.Camp", + ), ), migrations.AlterField( - model_name='speaker', - name='proposal', - field=models.OneToOneField(blank=True, help_text='The speaker proposal object this speaker was created from', null=True, on_delete=django.db.models.deletion.PROTECT, to='program.SpeakerProposal'), + model_name="speaker", + name="proposal", + field=models.OneToOneField( + blank=True, + help_text="The speaker proposal object this speaker was created from", + null=True, + on_delete=django.db.models.deletion.PROTECT, + to="program.SpeakerProposal", + ), ), migrations.AlterField( - model_name='speakerproposal', - name='camp', - field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='speakerproposals', to='camps.Camp'), + model_name="speakerproposal", + name="camp", + field=models.ForeignKey( + on_delete=django.db.models.deletion.PROTECT, + related_name="speakerproposals", + to="camps.Camp", + ), ), migrations.AlterField( - model_name='speakerproposal', - name='user', - field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to=settings.AUTH_USER_MODEL), + model_name="speakerproposal", + name="user", + field=models.ForeignKey( + on_delete=django.db.models.deletion.PROTECT, to=settings.AUTH_USER_MODEL + ), ), ] diff --git a/src/program/migrations/0048_auto_20180512_1625.py b/src/program/migrations/0048_auto_20180512_1625.py index a081dc08..f4ac22ad 100644 --- a/src/program/migrations/0048_auto_20180512_1625.py +++ b/src/program/migrations/0048_auto_20180512_1625.py @@ -8,127 +8,207 @@ import django.db.models.deletion class Migration(migrations.Migration): dependencies = [ - ('camps', '0026_auto_20180506_1633'), + ("camps", "0026_auto_20180506_1633"), migrations.swappable_dependency(settings.AUTH_USER_MODEL), - ('program', '0047_auto_20180415_1159'), + ("program", "0047_auto_20180415_1159"), ] operations = [ migrations.CreateModel( - name='EventTrack', + name="EventTrack", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('created', models.DateTimeField(auto_now_add=True)), - ('updated', models.DateTimeField(auto_now=True)), - ('name', models.CharField(max_length=100)), - ('slug', models.SlugField()), - ('camp', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='eventtracks', to='camps.Camp')), - ('managers', models.ManyToManyField(related_name='managed_tracks', to=settings.AUTH_USER_MODEL)), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("created", models.DateTimeField(auto_now_add=True)), + ("updated", models.DateTimeField(auto_now=True)), + ("name", models.CharField(max_length=100)), + ("slug", models.SlugField()), + ( + "camp", + models.ForeignKey( + on_delete=django.db.models.deletion.PROTECT, + related_name="eventtracks", + to="camps.Camp", + ), + ), + ( + "managers", + models.ManyToManyField( + related_name="managed_tracks", to=settings.AUTH_USER_MODEL + ), + ), ], ), - migrations.RemoveField( - model_name='speaker', - name='picture_large', - ), - migrations.RemoveField( - model_name='speaker', - name='picture_small', - ), - migrations.RemoveField( - model_name='speakerproposal', - name='picture_large', - ), - migrations.RemoveField( - model_name='speakerproposal', - name='picture_small', + migrations.RemoveField(model_name="speaker", name="picture_large"), + migrations.RemoveField(model_name="speaker", name="picture_small"), + migrations.RemoveField(model_name="speakerproposal", name="picture_large"), + migrations.RemoveField(model_name="speakerproposal", name="picture_small"), + migrations.AddField( + model_name="eventproposal", + name="duration", + field=models.IntegerField( + blank=True, + default=None, + help_text="How much time (in minutes) should we set aside for this act? Please keep it between 60 and 180 minutes (1-3 hours).", + null=True, + ), ), migrations.AddField( - model_name='eventproposal', - name='duration', - field=models.IntegerField(blank=True, default=None, help_text='How much time (in minutes) should we set aside for this act? Please keep it between 60 and 180 minutes (1-3 hours).', null=True), + model_name="eventtype", + name="description", + field=models.TextField( + blank=True, + default="", + help_text="The description of this type of event. Used in content submission flow.", + ), ), migrations.AddField( - model_name='eventtype', - name='description', - field=models.TextField(blank=True, default='', help_text='The description of this type of event. Used in content submission flow.'), + model_name="eventtype", + name="icon", + field=models.CharField( + default="wrench", + help_text="Name of the fontawesome icon to use, without the 'fa-' part", + max_length=25, + ), ), migrations.AddField( - model_name='eventtype', - name='icon', - field=models.CharField(default='wrench', help_text="Name of the fontawesome icon to use, without the 'fa-' part", max_length=25), + model_name="eventtype", + name="oneday_ticket_possible", + field=models.BooleanField( + default=False, + help_text="Check if hosting an event of this type qualifies someone for a free oneday ticket", + ), ), migrations.AddField( - model_name='eventtype', - name='oneday_ticket_possible', - field=models.BooleanField(default=False, help_text='Check if hosting an event of this type qualifies someone for a free oneday ticket'), + model_name="speaker", + name="needs_oneday_ticket", + field=models.BooleanField( + default=False, + help_text="Check if BornHack needs to provide a free one-day ticket for this speaker", + ), ), migrations.AddField( - model_name='speaker', - name='needs_oneday_ticket', - field=models.BooleanField(default=False, help_text='Check if BornHack needs to provide a free one-day ticket for this speaker'), + model_name="speakerproposal", + name="needs_oneday_ticket", + field=models.BooleanField( + default=False, + help_text="Check if BornHack needs to provide a free one-day ticket for this speaker", + ), + ), + migrations.AlterField( + model_name="eventlocation", + name="icon", + field=models.CharField( + help_text="Name of the fontawesome icon to use without the 'fa-' part", + max_length=100, + ), + ), + migrations.AlterField( + model_name="eventproposal", + name="abstract", + field=models.TextField( + blank=True, + help_text="The abstract for this event. Describe what the audience can expect to see/hear.", + ), + ), + migrations.AlterField( + model_name="eventproposal", + name="proposal_status", + field=models.CharField( + choices=[ + ("pending", "Pending approval"), + ("approved", "Approved"), + ("rejected", "Rejected"), + ], + default="pending", + max_length=50, + ), + ), + migrations.AlterField( + model_name="eventproposal", + name="speakers", + field=models.ManyToManyField( + blank=True, + help_text="Pick the speaker(s) for this event. If you cannot see anything here you need to go back and create Speaker Proposal(s) first.", + related_name="eventproposals", + to="program.SpeakerProposal", + ), + ), + migrations.AlterField( + model_name="eventproposal", + name="title", + field=models.CharField( + help_text="The title of this event. Keep it short and memorable.", + max_length=255, + ), + ), + migrations.AlterField( + model_name="speakerproposal", + name="biography", + field=models.TextField( + help_text="Biography of the speaker/artist/host. Markdown is supported." + ), + ), + migrations.AlterField( + model_name="speakerproposal", + name="name", + field=models.CharField( + help_text="Name or alias of the speaker/artist/host", max_length=150 + ), + ), + migrations.AlterField( + model_name="speakerproposal", + name="proposal_status", + field=models.CharField( + choices=[ + ("pending", "Pending approval"), + ("approved", "Approved"), + ("rejected", "Rejected"), + ], + default="pending", + max_length=50, + ), + ), + migrations.AlterField( + model_name="speakerproposal", + name="submission_notes", + field=models.TextField( + blank=True, + help_text="Private notes for this speaker/artist/host. Only visible to the submitting user and the BornHack organisers.", + ), ), migrations.AddField( - model_name='speakerproposal', - name='needs_oneday_ticket', - field=models.BooleanField(default=False, help_text='Check if BornHack needs to provide a free one-day ticket for this speaker'), - ), - migrations.AlterField( - model_name='eventlocation', - name='icon', - field=models.CharField(help_text="Name of the fontawesome icon to use without the 'fa-' part", max_length=100), - ), - migrations.AlterField( - model_name='eventproposal', - name='abstract', - field=models.TextField(blank=True, help_text='The abstract for this event. Describe what the audience can expect to see/hear.'), - ), - migrations.AlterField( - model_name='eventproposal', - name='proposal_status', - field=models.CharField(choices=[('pending', 'Pending approval'), ('approved', 'Approved'), ('rejected', 'Rejected')], default='pending', max_length=50), - ), - migrations.AlterField( - model_name='eventproposal', - name='speakers', - field=models.ManyToManyField(blank=True, help_text='Pick the speaker(s) for this event. If you cannot see anything here you need to go back and create Speaker Proposal(s) first.', related_name='eventproposals', to='program.SpeakerProposal'), - ), - migrations.AlterField( - model_name='eventproposal', - name='title', - field=models.CharField(help_text='The title of this event. Keep it short and memorable.', max_length=255), - ), - migrations.AlterField( - model_name='speakerproposal', - name='biography', - field=models.TextField(help_text='Biography of the speaker/artist/host. Markdown is supported.'), - ), - migrations.AlterField( - model_name='speakerproposal', - name='name', - field=models.CharField(help_text='Name or alias of the speaker/artist/host', max_length=150), - ), - migrations.AlterField( - model_name='speakerproposal', - name='proposal_status', - field=models.CharField(choices=[('pending', 'Pending approval'), ('approved', 'Approved'), ('rejected', 'Rejected')], default='pending', max_length=50), - ), - migrations.AlterField( - model_name='speakerproposal', - name='submission_notes', - field=models.TextField(blank=True, help_text='Private notes for this speaker/artist/host. Only visible to the submitting user and the BornHack organisers.'), + model_name="event", + name="track", + field=models.ForeignKey( + blank=True, + help_text="The track this event belongs to", + null=True, + on_delete=django.db.models.deletion.PROTECT, + related_name="events", + to="program.EventTrack", + ), ), migrations.AddField( - model_name='event', - name='track', - field=models.ForeignKey(blank=True, help_text='The track this event belongs to', null=True, on_delete=django.db.models.deletion.PROTECT, related_name='events', to='program.EventTrack'), - ), - migrations.AddField( - model_name='eventproposal', - name='track', - field=models.ForeignKey(blank=True, help_text='The track this event belongs to', null=True, on_delete=django.db.models.deletion.PROTECT, related_name='eventproposals', to='program.EventTrack'), + model_name="eventproposal", + name="track", + field=models.ForeignKey( + blank=True, + help_text="The track this event belongs to", + null=True, + on_delete=django.db.models.deletion.PROTECT, + related_name="eventproposals", + to="program.EventTrack", + ), ), migrations.AlterUniqueTogether( - name='eventtrack', - unique_together={('camp', 'slug'), ('camp', 'name')}, + name="eventtrack", unique_together={("camp", "slug"), ("camp", "name")} ), ] diff --git a/src/program/migrations/0049_add_event_tracks.py b/src/program/migrations/0049_add_event_tracks.py index d19c68ca..db5ea890 100644 --- a/src/program/migrations/0049_add_event_tracks.py +++ b/src/program/migrations/0049_add_event_tracks.py @@ -2,29 +2,21 @@ from django.db import migrations + def add_event_tracks(apps, schema_editor): - Camp = apps.get_model('camps', 'Camp') - EventTrack = apps.get_model('program', 'EventTrack') - EventProposal = apps.get_model('program', 'EventProposal') - Event = apps.get_model('program', 'Event') + Camp = apps.get_model("camps", "Camp") + EventTrack = apps.get_model("program", "EventTrack") + EventProposal = apps.get_model("program", "EventProposal") + Event = apps.get_model("program", "Event") for camp in Camp.objects.all(): # create the default track for this camp - track = EventTrack.objects.create( - name="BornHack", - slug="bornhack", - camp=camp - ) + track = EventTrack.objects.create(name="BornHack", slug="bornhack", camp=camp) Event.objects.filter(camp=camp).update(track=track) EventProposal.objects.filter(camp=camp).update(track=track) class Migration(migrations.Migration): - dependencies = [ - ('program', '0048_auto_20180512_1625'), - ] - - operations = [ - migrations.RunPython(add_event_tracks), - ] + dependencies = [("program", "0048_auto_20180512_1625")] + operations = [migrations.RunPython(add_event_tracks)] diff --git a/src/program/migrations/0050_auto_20180512_1650.py b/src/program/migrations/0050_auto_20180512_1650.py index 492e8e09..92b37b1a 100644 --- a/src/program/migrations/0050_auto_20180512_1650.py +++ b/src/program/migrations/0050_auto_20180512_1650.py @@ -5,21 +5,12 @@ from django.db import migrations class Migration(migrations.Migration): - dependencies = [ - ('program', '0049_add_event_tracks'), - ] + dependencies = [("program", "0049_add_event_tracks")] operations = [ migrations.AlterUniqueTogether( - name='event', - unique_together={('track', 'title'), ('track', 'slug')}, - ), - migrations.RemoveField( - model_name='eventproposal', - name='camp', - ), - migrations.RemoveField( - model_name='event', - name='camp', + name="event", unique_together={("track", "title"), ("track", "slug")} ), + migrations.RemoveField(model_name="eventproposal", name="camp"), + migrations.RemoveField(model_name="event", name="camp"), ] diff --git a/src/program/migrations/0051_auto_20180512_1801.py b/src/program/migrations/0051_auto_20180512_1801.py index c07569ad..70908f20 100644 --- a/src/program/migrations/0051_auto_20180512_1801.py +++ b/src/program/migrations/0051_auto_20180512_1801.py @@ -6,19 +6,27 @@ import django.db.models.deletion class Migration(migrations.Migration): - dependencies = [ - ('program', '0050_auto_20180512_1650'), - ] + dependencies = [("program", "0050_auto_20180512_1650")] operations = [ migrations.AlterField( - model_name='event', - name='track', - field=models.ForeignKey(help_text='The track this event belongs to', on_delete=django.db.models.deletion.PROTECT, related_name='events', to='program.EventTrack'), + model_name="event", + name="track", + field=models.ForeignKey( + help_text="The track this event belongs to", + on_delete=django.db.models.deletion.PROTECT, + related_name="events", + to="program.EventTrack", + ), ), migrations.AlterField( - model_name='eventproposal', - name='track', - field=models.ForeignKey(help_text='The track this event belongs to', on_delete=django.db.models.deletion.PROTECT, related_name='eventproposals', to='program.EventTrack'), + model_name="eventproposal", + name="track", + field=models.ForeignKey( + help_text="The track this event belongs to", + on_delete=django.db.models.deletion.PROTECT, + related_name="eventproposals", + to="program.EventTrack", + ), ), ] diff --git a/src/program/migrations/0052_auto_20180519_2324.py b/src/program/migrations/0052_auto_20180519_2324.py index 3a1dedcb..f0234719 100644 --- a/src/program/migrations/0052_auto_20180519_2324.py +++ b/src/program/migrations/0052_auto_20180519_2324.py @@ -5,14 +5,15 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ - ('program', '0051_auto_20180512_1801'), - ] + dependencies = [("program", "0051_auto_20180512_1801")] operations = [ migrations.AlterField( - model_name='eventproposal', - name='allow_video_recording', - field=models.BooleanField(default=False, help_text='Check if we can video record the event. Leave unchecked to avoid video recording.'), - ), + model_name="eventproposal", + name="allow_video_recording", + field=models.BooleanField( + default=False, + help_text="Check if we can video record the event. Leave unchecked to avoid video recording.", + ), + ) ] diff --git a/src/program/migrations/0053_auto_20180519_2325.py b/src/program/migrations/0053_auto_20180519_2325.py index 7d70c248..c6306e13 100644 --- a/src/program/migrations/0053_auto_20180519_2325.py +++ b/src/program/migrations/0053_auto_20180519_2325.py @@ -5,14 +5,15 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ - ('program', '0052_auto_20180519_2324'), - ] + dependencies = [("program", "0052_auto_20180519_2324")] operations = [ migrations.AlterField( - model_name='eventproposal', - name='allow_video_recording', - field=models.BooleanField(default=False, help_text='Check to allow video recording of the event. Leave unchecked to avoid video recording.'), - ), + model_name="eventproposal", + name="allow_video_recording", + field=models.BooleanField( + default=False, + help_text="Check to allow video recording of the event. Leave unchecked to avoid video recording.", + ), + ) ] diff --git a/src/program/migrations/0054_auto_20180520_1509.py b/src/program/migrations/0054_auto_20180520_1509.py index e859b9ab..ee1800d5 100644 --- a/src/program/migrations/0054_auto_20180520_1509.py +++ b/src/program/migrations/0054_auto_20180520_1509.py @@ -5,18 +5,17 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ - ('program', '0053_auto_20180519_2325'), - ] + dependencies = [("program", "0053_auto_20180519_2325")] operations = [ - migrations.RemoveField( - model_name='eventtype', - name='oneday_ticket_possible', - ), + migrations.RemoveField(model_name="eventtype", name="oneday_ticket_possible"), migrations.AddField( - model_name='eventtype', - name='host_title', - field=models.CharField(default='Person', help_text='What to call someone hosting this type of event. Like "Artist" for Music or "Speaker" for talks.', max_length=30), + model_name="eventtype", + name="host_title", + field=models.CharField( + default="Person", + help_text='What to call someone hosting this type of event. Like "Artist" for Music or "Speaker" for talks.', + max_length=30, + ), ), ] diff --git a/src/program/migrations/0055_auto_20180521_2354.py b/src/program/migrations/0055_auto_20180521_2354.py index 67f2b933..5b3178dc 100644 --- a/src/program/migrations/0055_auto_20180521_2354.py +++ b/src/program/migrations/0055_auto_20180521_2354.py @@ -6,43 +6,106 @@ import django.db.models.deletion class Migration(migrations.Migration): - dependencies = [ - ('program', '0054_auto_20180520_1509'), - ] + dependencies = [("program", "0054_auto_20180520_1509")] operations = [ migrations.CreateModel( - name='Url', + name="Url", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('created', models.DateTimeField(auto_now_add=True)), - ('updated', models.DateTimeField(auto_now=True)), - ('url', models.URLField(help_text='The actual URL')), - ('event', models.ForeignKey(blank=True, help_text='The event proposal object this URL belongs to', null=True, on_delete=django.db.models.deletion.PROTECT, related_name='urls', to='program.Event')), - ('eventproposal', models.ForeignKey(blank=True, help_text='The event proposal object this URL belongs to', null=True, on_delete=django.db.models.deletion.PROTECT, related_name='urls', to='program.EventProposal')), - ('speaker', models.ForeignKey(blank=True, help_text='The speaker proposal object this URL belongs to', null=True, on_delete=django.db.models.deletion.PROTECT, related_name='urls', to='program.Speaker')), - ('speakerproposal', models.ForeignKey(blank=True, help_text='The speaker proposal object this URL belongs to', null=True, on_delete=django.db.models.deletion.PROTECT, related_name='urls', to='program.SpeakerProposal')), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("created", models.DateTimeField(auto_now_add=True)), + ("updated", models.DateTimeField(auto_now=True)), + ("url", models.URLField(help_text="The actual URL")), + ( + "event", + models.ForeignKey( + blank=True, + help_text="The event proposal object this URL belongs to", + null=True, + on_delete=django.db.models.deletion.PROTECT, + related_name="urls", + to="program.Event", + ), + ), + ( + "eventproposal", + models.ForeignKey( + blank=True, + help_text="The event proposal object this URL belongs to", + null=True, + on_delete=django.db.models.deletion.PROTECT, + related_name="urls", + to="program.EventProposal", + ), + ), + ( + "speaker", + models.ForeignKey( + blank=True, + help_text="The speaker proposal object this URL belongs to", + null=True, + on_delete=django.db.models.deletion.PROTECT, + related_name="urls", + to="program.Speaker", + ), + ), + ( + "speakerproposal", + models.ForeignKey( + blank=True, + help_text="The speaker proposal object this URL belongs to", + null=True, + on_delete=django.db.models.deletion.PROTECT, + related_name="urls", + to="program.SpeakerProposal", + ), + ), ], - options={ - 'abstract': False, - }, + options={"abstract": False}, ), migrations.CreateModel( - name='UrlType', + name="UrlType", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('created', models.DateTimeField(auto_now_add=True)), - ('updated', models.DateTimeField(auto_now=True)), - ('name', models.CharField(help_text='The name of this type', max_length=25)), - ('icon', models.CharField(help_text="Name of the fontawesome icon to use without the 'fa-' part", max_length=100)), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("created", models.DateTimeField(auto_now_add=True)), + ("updated", models.DateTimeField(auto_now=True)), + ( + "name", + models.CharField(help_text="The name of this type", max_length=25), + ), + ( + "icon", + models.CharField( + help_text="Name of the fontawesome icon to use without the 'fa-' part", + max_length=100, + ), + ), ], - options={ - 'abstract': False, - }, + options={"abstract": False}, ), migrations.AddField( - model_name='url', - name='urltype', - field=models.ForeignKey(help_text='The type of this URL', on_delete=django.db.models.deletion.PROTECT, to='program.UrlType'), + model_name="url", + name="urltype", + field=models.ForeignKey( + help_text="The type of this URL", + on_delete=django.db.models.deletion.PROTECT, + to="program.UrlType", + ), ), ] diff --git a/src/program/migrations/0056_add_urltypes.py b/src/program/migrations/0056_add_urltypes.py index 1ffea07e..feac5050 100644 --- a/src/program/migrations/0056_add_urltypes.py +++ b/src/program/migrations/0056_add_urltypes.py @@ -2,57 +2,29 @@ from django.db import migrations + def add_urltypes(apps, schema_editor): - UrlType = apps.get_model('program', 'UrlType') + UrlType = apps.get_model("program", "UrlType") - UrlType.objects.create( - name='Other', - icon='link', - ) + UrlType.objects.create(name="Other", icon="link") - UrlType.objects.create( - name='Homepage', - icon='link', - ) + UrlType.objects.create(name="Homepage", icon="link") - UrlType.objects.create( - name='Slides', - icon='link', - ) + UrlType.objects.create(name="Slides", icon="link") - UrlType.objects.create( - name='Twitter', - icon='link', - ) + UrlType.objects.create(name="Twitter", icon="link") - UrlType.objects.create( - name='Mastodon', - icon='link', - ) + UrlType.objects.create(name="Mastodon", icon="link") - UrlType.objects.create( - name='Facebook', - icon='link', - ) + UrlType.objects.create(name="Facebook", icon="link") - UrlType.objects.create( - name='Project', - icon='link', - ) + UrlType.objects.create(name="Project", icon="link") - UrlType.objects.create( - name='Blog', - icon='link', - ) + UrlType.objects.create(name="Blog", icon="link") class Migration(migrations.Migration): - dependencies = [ - ('program', '0055_auto_20180521_2354'), - ] - - operations = [ - migrations.RunPython(add_urltypes), - ] + dependencies = [("program", "0055_auto_20180521_2354")] + operations = [migrations.RunPython(add_urltypes)] diff --git a/src/program/migrations/0057_auto_20180522_0659.py b/src/program/migrations/0057_auto_20180522_0659.py index 910a7f6f..e317c40e 100644 --- a/src/program/migrations/0057_auto_20180522_0659.py +++ b/src/program/migrations/0057_auto_20180522_0659.py @@ -5,14 +5,16 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ - ('program', '0056_add_urltypes'), - ] + dependencies = [("program", "0056_add_urltypes")] operations = [ migrations.AlterField( - model_name='urltype', - name='icon', - field=models.CharField(default='link', help_text="Name of the fontawesome icon to use without the 'fa-' part", max_length=100), - ), + model_name="urltype", + name="icon", + field=models.CharField( + default="link", + help_text="Name of the fontawesome icon to use without the 'fa-' part", + max_length=100, + ), + ) ] diff --git a/src/program/migrations/0058_auto_20180523_0844.py b/src/program/migrations/0058_auto_20180523_0844.py index c6e39171..31394382 100644 --- a/src/program/migrations/0058_auto_20180523_0844.py +++ b/src/program/migrations/0058_auto_20180523_0844.py @@ -5,18 +5,15 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ - ('program', '0057_auto_20180522_0659'), - ] + dependencies = [("program", "0057_auto_20180522_0659")] operations = [ - migrations.AlterModelOptions( - name='urltype', - options={'ordering': ['name']}, - ), + migrations.AlterModelOptions(name="urltype", options={"ordering": ["name"]}), migrations.AlterField( - model_name='urltype', - name='name', - field=models.CharField(help_text='The name of this type', max_length=25, unique=True), + model_name="urltype", + name="name", + field=models.CharField( + help_text="The name of this type", max_length=25, unique=True + ), ), ] diff --git a/src/program/migrations/0059_auto_20180523_2241.py b/src/program/migrations/0059_auto_20180523_2241.py index a32ae010..93bbace5 100644 --- a/src/program/migrations/0059_auto_20180523_2241.py +++ b/src/program/migrations/0059_auto_20180523_2241.py @@ -6,18 +6,15 @@ import uuid class Migration(migrations.Migration): - dependencies = [ - ('program', '0058_auto_20180523_0844'), - ] + dependencies = [("program", "0058_auto_20180523_0844")] operations = [ - migrations.RemoveField( - model_name='url', - name='id', - ), + migrations.RemoveField(model_name="url", name="id"), migrations.AddField( - model_name='url', - name='uuid', - field=models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False), + model_name="url", + name="uuid", + field=models.UUIDField( + default=uuid.uuid4, editable=False, primary_key=True, serialize=False + ), ), ] diff --git a/src/program/migrations/0060_auto_20180603_1455.py b/src/program/migrations/0060_auto_20180603_1455.py index 717dc01b..eee2860a 100644 --- a/src/program/migrations/0060_auto_20180603_1455.py +++ b/src/program/migrations/0060_auto_20180603_1455.py @@ -7,34 +7,47 @@ import django.db.models.deletion class Migration(migrations.Migration): - dependencies = [ - ('program', '0059_auto_20180523_2241'), - ] + dependencies = [("program", "0059_auto_20180523_2241")] operations = [ migrations.AlterField( - model_name='eventtrack', - name='camp', - field=models.ForeignKey(help_text='The Camp this Track belongs to', on_delete=django.db.models.deletion.PROTECT, related_name='eventtracks', to='camps.Camp'), + model_name="eventtrack", + name="camp", + field=models.ForeignKey( + help_text="The Camp this Track belongs to", + on_delete=django.db.models.deletion.PROTECT, + related_name="eventtracks", + to="camps.Camp", + ), ), migrations.AlterField( - model_name='eventtrack', - name='managers', - field=models.ManyToManyField(blank=True, help_text='If this track is managed by someone other than the Content team pick the users here.', related_name='managed_tracks', to=settings.AUTH_USER_MODEL), + model_name="eventtrack", + name="managers", + field=models.ManyToManyField( + blank=True, + help_text="If this track is managed by someone other than the Content team pick the users here.", + related_name="managed_tracks", + to=settings.AUTH_USER_MODEL, + ), ), migrations.AlterField( - model_name='eventtrack', - name='name', - field=models.CharField(help_text='The name of this Track', max_length=100), + model_name="eventtrack", + name="name", + field=models.CharField(help_text="The name of this Track", max_length=100), ), migrations.AlterField( - model_name='eventtrack', - name='slug', - field=models.SlugField(help_text='The url slug for this Track'), + model_name="eventtrack", + name="slug", + field=models.SlugField(help_text="The url slug for this Track"), ), migrations.AlterField( - model_name='speakerproposal', - name='camp', - field=models.ForeignKey(editable=False, on_delete=django.db.models.deletion.PROTECT, related_name='speakerproposals', to='camps.Camp'), + model_name="speakerproposal", + name="camp", + field=models.ForeignKey( + editable=False, + on_delete=django.db.models.deletion.PROTECT, + related_name="speakerproposals", + to="camps.Camp", + ), ), ] diff --git a/src/program/migrations/0061_auto_20180603_1525.py b/src/program/migrations/0061_auto_20180603_1525.py index 0c88b474..9ad33ddf 100644 --- a/src/program/migrations/0061_auto_20180603_1525.py +++ b/src/program/migrations/0061_auto_20180603_1525.py @@ -6,19 +6,31 @@ import django.db.models.deletion class Migration(migrations.Migration): - dependencies = [ - ('program', '0060_auto_20180603_1455'), - ] + dependencies = [("program", "0060_auto_20180603_1455")] operations = [ migrations.AlterField( - model_name='event', - name='proposal', - field=models.OneToOneField(blank=True, editable=False, help_text='The event proposal object this event was created from', null=True, on_delete=django.db.models.deletion.PROTECT, to='program.EventProposal'), + model_name="event", + name="proposal", + field=models.OneToOneField( + blank=True, + editable=False, + help_text="The event proposal object this event was created from", + null=True, + on_delete=django.db.models.deletion.PROTECT, + to="program.EventProposal", + ), ), migrations.AlterField( - model_name='speaker', - name='proposal', - field=models.OneToOneField(blank=True, editable=False, help_text='The speaker proposal object this speaker was created from', null=True, on_delete=django.db.models.deletion.PROTECT, to='program.SpeakerProposal'), + model_name="speaker", + name="proposal", + field=models.OneToOneField( + blank=True, + editable=False, + help_text="The speaker proposal object this speaker was created from", + null=True, + on_delete=django.db.models.deletion.PROTECT, + to="program.SpeakerProposal", + ), ), ] diff --git a/src/program/migrations/0062_auto_20180717_1720.py b/src/program/migrations/0062_auto_20180717_1720.py index 1f369760..2726a485 100644 --- a/src/program/migrations/0062_auto_20180717_1720.py +++ b/src/program/migrations/0062_auto_20180717_1720.py @@ -5,14 +5,16 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ - ('program', '0061_auto_20180603_1525'), - ] + dependencies = [("program", "0061_auto_20180603_1525")] operations = [ migrations.AlterField( - model_name='urltype', - name='icon', - field=models.CharField(default='fas fa-link', help_text="Name of the fontawesome icon to use, including the 'fab fa-' or 'fas fa-' part.", max_length=100), - ), + model_name="urltype", + name="icon", + field=models.CharField( + default="fas fa-link", + help_text="Name of the fontawesome icon to use, including the 'fab fa-' or 'fas fa-' part.", + max_length=100, + ), + ) ] diff --git a/src/program/migrations/0063_auto_20180809_1525.py b/src/program/migrations/0063_auto_20180809_1525.py index d089fe94..d3fb780b 100644 --- a/src/program/migrations/0063_auto_20180809_1525.py +++ b/src/program/migrations/0063_auto_20180809_1525.py @@ -5,14 +5,14 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ - ('program', '0062_auto_20180717_1720'), - ] + dependencies = [("program", "0062_auto_20180717_1720")] operations = [ migrations.AlterField( - model_name='eventproposal', - name='allow_video_recording', - field=models.BooleanField(default=True, help_text='Uncheck this to avoid video recording.'), - ), + model_name="eventproposal", + name="allow_video_recording", + field=models.BooleanField( + default=True, help_text="Uncheck this to avoid video recording." + ), + ) ] diff --git a/src/program/migrations/0064_auto_20180810_1748.py b/src/program/migrations/0064_auto_20180810_1748.py index a9312697..45131411 100644 --- a/src/program/migrations/0064_auto_20180810_1748.py +++ b/src/program/migrations/0064_auto_20180810_1748.py @@ -5,14 +5,14 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ - ('program', '0063_auto_20180809_1525'), - ] + dependencies = [("program", "0063_auto_20180809_1525")] operations = [ migrations.AlterField( - model_name='eventproposal', - name='allow_video_recording', - field=models.BooleanField(default=False, help_text='Uncheck to avoid video recording.'), - ), + model_name="eventproposal", + name="allow_video_recording", + field=models.BooleanField( + default=False, help_text="Uncheck to avoid video recording." + ), + ) ] diff --git a/src/program/migrations/0065_speakerproposal_email.py b/src/program/migrations/0065_speakerproposal_email.py index 31c9ae2e..ef9cdf6a 100644 --- a/src/program/migrations/0065_speakerproposal_email.py +++ b/src/program/migrations/0065_speakerproposal_email.py @@ -5,14 +5,17 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ - ('program', '0064_auto_20180810_1748'), - ] + dependencies = [("program", "0064_auto_20180810_1748")] operations = [ migrations.AddField( - model_name='speakerproposal', - name='email', - field=models.EmailField(blank=True, help_text='The email of the speaker (defaults to the logged in user if empty.', max_length=150, null=True), - ), + model_name="speakerproposal", + name="email", + field=models.EmailField( + blank=True, + help_text="The email of the speaker (defaults to the logged in user if empty.", + max_length=150, + null=True, + ), + ) ] diff --git a/src/program/migrations/0066_speaker_email.py b/src/program/migrations/0066_speaker_email.py index 9cc36b5d..e4834361 100644 --- a/src/program/migrations/0066_speaker_email.py +++ b/src/program/migrations/0066_speaker_email.py @@ -5,14 +5,17 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ - ('program', '0065_speakerproposal_email'), - ] + dependencies = [("program", "0065_speakerproposal_email")] operations = [ migrations.AddField( - model_name='speaker', - name='email', - field=models.EmailField(blank=True, help_text='The email of the speaker.', max_length=150, null=True), - ), + model_name="speaker", + name="email", + field=models.EmailField( + blank=True, + help_text="The email of the speaker.", + max_length=150, + null=True, + ), + ) ] diff --git a/src/program/migrations/0067_auto_20180818_1634.py b/src/program/migrations/0067_auto_20180818_1634.py index a03bed99..1b9b1335 100644 --- a/src/program/migrations/0067_auto_20180818_1634.py +++ b/src/program/migrations/0067_auto_20180818_1634.py @@ -5,13 +5,13 @@ from django.db import migrations class Migration(migrations.Migration): - dependencies = [ - ('program', '0066_speaker_email'), - ] + dependencies = [("program", "0066_speaker_email")] operations = [ migrations.AlterModelOptions( - name='eventproposal', - options={'permissions': (('can_approve_proposals', 'Can approve proposals'),)}, - ), + name="eventproposal", + options={ + "permissions": (("can_approve_proposals", "Can approve proposals"),) + }, + ) ] diff --git a/src/program/migrations/0068_add_email_to_speaker_and_speaker_proposal.py b/src/program/migrations/0068_add_email_to_speaker_and_speaker_proposal.py index 3c9c67c1..1f863777 100644 --- a/src/program/migrations/0068_add_email_to_speaker_and_speaker_proposal.py +++ b/src/program/migrations/0068_add_email_to_speaker_and_speaker_proposal.py @@ -4,8 +4,8 @@ from django.db import migrations def add_email(apps, schema_editor): - Speaker = apps.get_model('program', 'Speaker') - SpeakerProposal = apps.get_model('program', 'SpeakerProposal') + Speaker = apps.get_model("program", "Speaker") + SpeakerProposal = apps.get_model("program", "SpeakerProposal") for speaker in Speaker.objects.all(): if speaker.proposal and not speaker.email: @@ -20,10 +20,6 @@ def add_email(apps, schema_editor): class Migration(migrations.Migration): - dependencies = [ - ('program', '0067_auto_20180818_1634'), - ] + dependencies = [("program", "0067_auto_20180818_1634")] - operations = [ - migrations.RunPython(add_email) - ] + operations = [migrations.RunPython(add_email)] diff --git a/src/program/migrations/0069_add_bogus_email_to_old_speakers.py b/src/program/migrations/0069_add_bogus_email_to_old_speakers.py index 94974a75..eb3176ab 100644 --- a/src/program/migrations/0069_add_bogus_email_to_old_speakers.py +++ b/src/program/migrations/0069_add_bogus_email_to_old_speakers.py @@ -4,7 +4,7 @@ from django.db import migrations def add_bogus_email(apps, schema_editor): - Speaker = apps.get_model('program', 'Speaker') + Speaker = apps.get_model("program", "Speaker") for speaker in Speaker.objects.all(): if not speaker.email: @@ -14,10 +14,6 @@ def add_bogus_email(apps, schema_editor): class Migration(migrations.Migration): - dependencies = [ - ('program', '0068_add_email_to_speaker_and_speaker_proposal'), - ] + dependencies = [("program", "0068_add_email_to_speaker_and_speaker_proposal")] - operations = [ - migrations.RunPython(add_bogus_email) - ] + operations = [migrations.RunPython(add_bogus_email)] diff --git a/src/program/migrations/0070_auto_20180819_1729.py b/src/program/migrations/0070_auto_20180819_1729.py index 3b01d175..5fbe71ec 100644 --- a/src/program/migrations/0070_auto_20180819_1729.py +++ b/src/program/migrations/0070_auto_20180819_1729.py @@ -5,19 +5,22 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ - ('program', '0069_add_bogus_email_to_old_speakers'), - ] + dependencies = [("program", "0069_add_bogus_email_to_old_speakers")] operations = [ migrations.AlterField( - model_name='speaker', - name='email', - field=models.EmailField(help_text='The email of the speaker.', max_length=150), + model_name="speaker", + name="email", + field=models.EmailField( + help_text="The email of the speaker.", max_length=150 + ), ), migrations.AlterField( - model_name='speakerproposal', - name='email', - field=models.EmailField(help_text='The email of the speaker (defaults to the logged in user if empty.', max_length=150), + model_name="speakerproposal", + name="email", + field=models.EmailField( + help_text="The email of the speaker (defaults to the logged in user if empty.", + max_length=150, + ), ), ] diff --git a/src/program/migrations/0071_auto_20180827_1958.py b/src/program/migrations/0071_auto_20180827_1958.py index 00e7ce51..d617ca8e 100644 --- a/src/program/migrations/0071_auto_20180827_1958.py +++ b/src/program/migrations/0071_auto_20180827_1958.py @@ -5,13 +5,6 @@ from django.db import migrations class Migration(migrations.Migration): - dependencies = [ - ('program', '0070_auto_20180819_1729'), - ] + dependencies = [("program", "0070_auto_20180819_1729")] - operations = [ - migrations.AlterModelOptions( - name='eventproposal', - options={}, - ), - ] + operations = [migrations.AlterModelOptions(name="eventproposal", options={})] diff --git a/src/program/mixins.py b/src/program/mixins.py index 2fa7407d..1de73fd3 100644 --- a/src/program/mixins.py +++ b/src/program/mixins.py @@ -12,7 +12,7 @@ class EnsureCFPOpenMixin(object): if not self.camp.call_for_participation_open: messages.error(request, "The Call for Participation is not open.") return redirect( - reverse('program:proposal_list', kwargs={'camp_slug': self.camp.slug}) + reverse("program:proposal_list", kwargs={"camp_slug": self.camp.slug}) ) # alright, continue with the request @@ -22,9 +22,17 @@ class EnsureCFPOpenMixin(object): class EnsureUnapprovedProposalMixin(SingleObjectMixin): def dispatch(self, request, *args, **kwargs): # do not permit editing if the proposal is already approved - if self.get_object().proposal_status == models.UserSubmittedModel.PROPOSAL_APPROVED: - messages.error(request, "This proposal has already been approved. Please contact the organisers if you need to modify something.") - return redirect(reverse('program:proposal_list', kwargs={'camp_slug': self.camp.slug})) + if ( + self.get_object().proposal_status + == models.UserSubmittedModel.PROPOSAL_APPROVED + ): + messages.error( + request, + "This proposal has already been approved. Please contact the organisers if you need to modify something.", + ) + return redirect( + reverse("program:proposal_list", kwargs={"camp_slug": self.camp.slug}) + ) # alright, continue with the request return super().dispatch(request, *args, **kwargs) @@ -35,7 +43,9 @@ class EnsureWritableCampMixin(object): # do not permit view if camp is in readonly mode if self.camp.read_only: messages.error(request, "No thanks") - return redirect(reverse('program:proposal_list', kwargs={'camp_slug': self.camp.slug})) + return redirect( + reverse("program:proposal_list", kwargs={"camp_slug": self.camp.slug}) + ) # alright, continue with the request return super().dispatch(request, *args, **kwargs) @@ -47,7 +57,7 @@ class EnsureUserOwnsProposalMixin(SingleObjectMixin): if self.get_object().user.username != request.user.username: messages.error(request, "No thanks") return redirect( - reverse('program:proposal_list', kwargs={'camp_slug': self.camp.slug}) + reverse("program:proposal_list", kwargs={"camp_slug": self.camp.slug}) ) # alright, continue with the request @@ -58,15 +68,22 @@ class UrlViewMixin(object): """ Mixin with code shared between all the Url views """ + def dispatch(self, request, *args, **kwargs): """ Check that we have a valid SpeakerProposal or EventProposal and that it belongs to the current user """ # get the proposal - if 'event_uuid' in self.kwargs: - self.eventproposal = get_object_or_404(models.EventProposal, uuid=self.kwargs['event_uuid'], user=request.user) - elif 'speaker_uuid' in self.kwargs: - self.speakerproposal = get_object_or_404(models.SpeakerProposal, uuid=self.kwargs['speaker_uuid'], user=request.user) + if "event_uuid" in self.kwargs: + self.eventproposal = get_object_or_404( + models.EventProposal, uuid=self.kwargs["event_uuid"], user=request.user + ) + elif "speaker_uuid" in self.kwargs: + self.speakerproposal = get_object_or_404( + models.SpeakerProposal, + uuid=self.kwargs["speaker_uuid"], + user=request.user, + ) else: # fuckery afoot raise Http404 @@ -77,18 +94,17 @@ class UrlViewMixin(object): Include the proposal in the template context """ context = super().get_context_data(**kwargs) - if hasattr(self, 'eventproposal') and self.eventproposal: - context['eventproposal'] = self.eventproposal + if hasattr(self, "eventproposal") and self.eventproposal: + context["eventproposal"] = self.eventproposal else: - context['speakerproposal'] = self.speakerproposal + context["speakerproposal"] = self.speakerproposal return context def get_success_url(self): """ Return to the detail view of the proposal """ - if hasattr(self, 'eventproposal'): + if hasattr(self, "eventproposal"): return self.eventproposal.get_absolute_url() else: return self.speakerproposal.get_absolute_url() - diff --git a/src/program/models.py b/src/program/models.py index 348127c7..eace0260 100644 --- a/src/program/models.py +++ b/src/program/models.py @@ -28,20 +28,19 @@ class UrlType(CreatedUpdatedModel): """ Each Url object has a type. """ + name = models.CharField( - max_length=25, - help_text='The name of this type', - unique=True, + max_length=25, help_text="The name of this type", unique=True ) icon = models.CharField( max_length=100, - default='fas fa-link', - help_text="Name of the fontawesome icon to use, including the 'fab fa-' or 'fas fa-' part." + default="fas fa-link", + help_text="Name of the fontawesome icon to use, including the 'fab fa-' or 'fas fa-' part.", ) class Meta: - ordering = ['name'] + ordering = ["name"] def __str__(self): return self.name @@ -57,63 +56,56 @@ class Url(CampRelatedModel): Each URL has a UrlType and a GenericForeignKey to the model to which it belongs. When a SpeakerProposal or EventProposal is approved the related URLs will be copied with FK to the new Speaker/Event objects. """ - uuid = models.UUIDField( - primary_key=True, - default=uuid.uuid4, - editable=False, - ) - url = models.URLField( - help_text='The actual URL' - ) + uuid = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False) + + url = models.URLField(help_text="The actual URL") urltype = models.ForeignKey( - 'program.UrlType', - help_text='The type of this URL', - on_delete=models.PROTECT, + "program.UrlType", help_text="The type of this URL", on_delete=models.PROTECT ) speakerproposal = models.ForeignKey( - 'program.SpeakerProposal', + "program.SpeakerProposal", null=True, blank=True, - help_text='The speaker proposal object this URL belongs to', + help_text="The speaker proposal object this URL belongs to", on_delete=models.PROTECT, - related_name='urls', + related_name="urls", ) eventproposal = models.ForeignKey( - 'program.EventProposal', + "program.EventProposal", null=True, blank=True, - help_text='The event proposal object this URL belongs to', + help_text="The event proposal object this URL belongs to", on_delete=models.PROTECT, - related_name='urls', + related_name="urls", ) speaker = models.ForeignKey( - 'program.Speaker', + "program.Speaker", null=True, blank=True, - help_text='The speaker proposal object this URL belongs to', + help_text="The speaker proposal object this URL belongs to", on_delete=models.PROTECT, - related_name='urls', + related_name="urls", ) event = models.ForeignKey( - 'program.Event', + "program.Event", null=True, blank=True, - help_text='The event proposal object this URL belongs to', + help_text="The event proposal object this URL belongs to", on_delete=models.PROTECT, - related_name='urls', + related_name="urls", ) def __str__(self): return self.url def clean(self): - ''' Make sure we have exactly one FK ''' + """ Make sure we have exactly one FK """ fks = 0 if self.speakerproposal: fks += 1 @@ -124,7 +116,11 @@ class Url(CampRelatedModel): if self.event: fks += 1 if fks > 1: - raise(ValidationError("Url objects must have maximum one FK, this has %s" % fks)) + raise ( + ValidationError( + "Url objects must have maximum one FK, this has %s" % fks + ) + ) @property def owner(self): @@ -147,10 +143,10 @@ class Url(CampRelatedModel): return self.owner.camp camp_filter = [ - 'speakerproposal__camp', - 'eventproposal__track__camp', - 'speaker__camp', - 'event__track__camp', + "speakerproposal__camp", + "eventproposal__track__camp", + "speaker__camp", + "event__track__camp", ] @@ -166,54 +162,45 @@ class UserSubmittedModel(CampRelatedModel): class Meta: abstract = True - uuid = models.UUIDField( - primary_key=True, - default=uuid.uuid4, - editable=False, - ) + uuid = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False) - user = models.ForeignKey( - 'auth.User', - on_delete=models.PROTECT - ) + user = models.ForeignKey("auth.User", on_delete=models.PROTECT) - PROPOSAL_PENDING = 'pending' - PROPOSAL_APPROVED = 'approved' - PROPOSAL_REJECTED = 'rejected' + PROPOSAL_PENDING = "pending" + PROPOSAL_APPROVED = "approved" + PROPOSAL_REJECTED = "rejected" - PROPOSAL_STATUSES = [ - PROPOSAL_PENDING, - PROPOSAL_APPROVED, - PROPOSAL_REJECTED, - ] + PROPOSAL_STATUSES = [PROPOSAL_PENDING, PROPOSAL_APPROVED, PROPOSAL_REJECTED] PROPOSAL_STATUS_CHOICES = [ - (PROPOSAL_PENDING, 'Pending approval'), - (PROPOSAL_APPROVED, 'Approved'), - (PROPOSAL_REJECTED, 'Rejected'), + (PROPOSAL_PENDING, "Pending approval"), + (PROPOSAL_APPROVED, "Approved"), + (PROPOSAL_REJECTED, "Rejected"), ] proposal_status = models.CharField( - max_length=50, - choices=PROPOSAL_STATUS_CHOICES, - default=PROPOSAL_PENDING, + max_length=50, choices=PROPOSAL_STATUS_CHOICES, default=PROPOSAL_PENDING ) def __str__(self): - return '%s (submitted by: %s, status: %s)' % (self.headline, self.user, self.proposal_status) + return "%s (submitted by: %s, status: %s)" % ( + self.headline, + self.user, + self.proposal_status, + ) def save(self, **kwargs): if not self.camp.call_for_participation_open: - message = 'Call for participation is not open' - if hasattr(self, 'request'): + message = "Call for participation is not open" + if hasattr(self, "request"): messages.error(self.request, message) raise ValidationError(message) super().save(**kwargs) def delete(self, **kwargs): if not self.camp.call_for_participation_open: - message = 'Call for participation is not open' - if hasattr(self, 'request'): + message = "Call for participation is not open" + if hasattr(self, "request"): messages.error(self.request, message) raise ValidationError(message) super().delete(**kwargs) @@ -223,34 +210,33 @@ class SpeakerProposal(UserSubmittedModel): """ A speaker proposal """ camp = models.ForeignKey( - 'camps.Camp', - related_name='speakerproposals', + "camps.Camp", + related_name="speakerproposals", on_delete=models.PROTECT, editable=False, ) name = models.CharField( - max_length=150, - help_text='Name or alias of the speaker/artist/host', + max_length=150, help_text="Name or alias of the speaker/artist/host" ) email = models.EmailField( max_length=150, - help_text="The email of the speaker (defaults to the logged in user if empty.", + help_text="The email of the speaker (defaults to the logged in user if empty).", ) biography = models.TextField( - help_text='Biography of the speaker/artist/host. Markdown is supported.' + help_text="Biography of the speaker/artist/host. Markdown is supported." ) submission_notes = models.TextField( - help_text='Private notes for this speaker/artist/host. Only visible to the submitting user and the BornHack organisers.', - blank=True + help_text="Private notes for this speaker/artist/host. Only visible to the submitting user and the BornHack organisers.", + blank=True, ) needs_oneday_ticket = models.BooleanField( default=False, - help_text='Check if BornHack needs to provide a free one-day ticket for this speaker', + help_text="Check if BornHack needs to provide a free one-day ticket for this speaker", ) @property @@ -258,14 +244,17 @@ class SpeakerProposal(UserSubmittedModel): return self.name def get_absolute_url(self): - return reverse_lazy('program:speakerproposal_detail', kwargs={'camp_slug': self.camp.slug, 'pk': self.uuid}) + return reverse_lazy( + "program:speakerproposal_detail", + kwargs={"camp_slug": self.camp.slug, "pk": self.uuid}, + ) def mark_as_approved(self, request): """ Marks a SpeakerProposal as approved, including creating/updating the related Speaker object """ - speakerproposalmodel = apps.get_model('program', 'speakerproposal') + speakerproposalmodel = apps.get_model("program", "speakerproposal") # create a Speaker if we don't have one - if not hasattr(self, 'speaker'): - speakermodel = apps.get_model('program', 'speaker') + if not hasattr(self, "speaker"): + speakermodel = apps.get_model("program", "speaker") speaker = speakermodel() speaker.proposal = self else: @@ -290,17 +279,15 @@ class SpeakerProposal(UserSubmittedModel): # copy all the URLs to the speaker object speaker.urls.clear() for url in self.urls.all(): - Url.objects.create( - url=url.url, - urltype=url.urltype, - speaker=speaker - ) + Url.objects.create(url=url.url, urltype=url.urltype, speaker=speaker) # a message to the admin - messages.success(request, "Speaker object %s has been created/updated" % speaker) + messages.success( + request, "Speaker object %s has been created/updated" % speaker + ) def mark_as_rejected(self, request): - speakerproposalmodel = apps.get_model('program', 'speakerproposal') + speakerproposalmodel = apps.get_model("program", "speakerproposal") self.proposal_status = speakerproposalmodel.PROPOSAL_REJECTED self.save() messages.success(request, "SpeakerProposal %s has been rejected" % self.name) @@ -308,58 +295,56 @@ class SpeakerProposal(UserSubmittedModel): class EventProposal(UserSubmittedModel): """ An event proposal """ + track = models.ForeignKey( - 'program.EventTrack', - related_name='eventproposals', - help_text='The track this event belongs to', - on_delete=models.PROTECT + "program.EventTrack", + related_name="eventproposals", + help_text="The track this event belongs to", + on_delete=models.PROTECT, ) title = models.CharField( max_length=255, - help_text='The title of this event. Keep it short and memorable.', + help_text="The title of this event. Keep it short and memorable.", ) abstract = models.TextField( - help_text='The abstract for this event. Describe what the audience can expect to see/hear.', + help_text="The abstract for this event. Describe what the audience can expect to see/hear.", blank=True, ) event_type = models.ForeignKey( - 'program.EventType', - help_text='The type of event', - on_delete=models.PROTECT + "program.EventType", help_text="The type of event", on_delete=models.PROTECT ) speakers = models.ManyToManyField( - 'program.SpeakerProposal', + "program.SpeakerProposal", blank=True, - help_text='Pick the speaker(s) for this event. If you cannot see anything here you need to go back and create Speaker Proposal(s) first.', - related_name='eventproposals', + help_text="Pick the speaker(s) for this event. If you cannot see anything here you need to go back and create Speaker Proposal(s) first.", + related_name="eventproposals", ) allow_video_recording = models.BooleanField( - default=False, - help_text='Uncheck to avoid video recording.' + default=False, help_text="Uncheck to avoid video recording." ) duration = models.IntegerField( default=None, null=True, blank=True, - help_text='How much time (in minutes) should we set aside for this act? Please keep it between 60 and 180 minutes (1-3 hours).' + help_text="How much time (in minutes) should we set aside for this act? Please keep it between 60 and 180 minutes (1-3 hours).", ) submission_notes = models.TextField( - help_text='Private notes for this event. Only visible to the submitting user and the BornHack organisers.', - blank=True + help_text="Private notes for this event. Only visible to the submitting user and the BornHack organisers.", + blank=True, ) @property def camp(self): return self.track.camp - camp_filter = 'track__camp' + camp_filter = "track__camp" @property def headline(self): @@ -367,8 +352,8 @@ class EventProposal(UserSubmittedModel): def get_absolute_url(self): return reverse_lazy( - 'program:eventproposal_detail', - kwargs={'camp_slug': self.camp.slug, 'pk': self.uuid} + "program:eventproposal_detail", + kwargs={"camp_slug": self.camp.slug, "pk": self.uuid}, ) def get_available_speakerproposals(self): @@ -377,15 +362,14 @@ class EventProposal(UserSubmittedModel): which are not already added to this EventProposal """ return SpeakerProposal.objects.filter( - camp=self.track.camp, - user=self.user - ).exclude(uuid__in=self.speakers.all().values_list('uuid')) + camp=self.track.camp, user=self.user + ).exclude(uuid__in=self.speakers.all().values_list("uuid")) def mark_as_approved(self, request): - eventmodel = apps.get_model('program', 'event') - eventproposalmodel = apps.get_model('program', 'eventproposal') + eventmodel = apps.get_model("program", "event") + eventproposalmodel = apps.get_model("program", "eventproposal") # use existing event if we have one - if not hasattr(self, 'event'): + if not hasattr(self, "event"): event = eventmodel() else: event = self.event @@ -404,7 +388,7 @@ class EventProposal(UserSubmittedModel): # clean up event.urls.clear() event.delete() - raise ValidationError('Not all speakers are approved or created yet.') + raise ValidationError("Not all speakers are approved or created yet.") self.proposal_status = eventproposalmodel.PROPOSAL_APPROVED self.save() @@ -412,16 +396,12 @@ class EventProposal(UserSubmittedModel): # clear any old urls from the event object and copy all the URLs from the proposal event.urls.clear() for url in self.urls.all(): - Url.objects.create( - url=url.url, - urltype=url.urltype, - event=event - ) + Url.objects.create(url=url.url, urltype=url.urltype, event=event) messages.success(request, "Event object %s has been created/updated" % event) def mark_as_rejected(self, request): - eventproposalmodel = apps.get_model('program', 'eventproposal') + eventproposalmodel = apps.get_model("program", "eventproposal") self.proposal_status = eventproposalmodel.PROPOSAL_REJECTED self.save() messages.success(request, "EventProposal %s has been rejected" % self.title) @@ -433,127 +413,105 @@ class EventProposal(UserSubmittedModel): class EventTrack(CampRelatedModel): """ All events belong to a track. Administration of a track can be delegated to one or more users. """ - name = models.CharField( - max_length=100, - help_text='The name of this Track', - ) + name = models.CharField(max_length=100, help_text="The name of this Track") - slug = models.SlugField( - help_text='The url slug for this Track' - ) + slug = models.SlugField(help_text="The url slug for this Track") camp = models.ForeignKey( - 'camps.Camp', - related_name='eventtracks', + "camps.Camp", + related_name="eventtracks", on_delete=models.PROTECT, - help_text='The Camp this Track belongs to', + help_text="The Camp this Track belongs to", ) managers = models.ManyToManyField( - 'auth.User', - related_name='managed_tracks', + "auth.User", + related_name="managed_tracks", blank=True, - help_text='If this track is managed by someone other than the Content team pick the users here.' + help_text="If this track is managed by someone other than the Content team pick the users here.", ) def __str__(self): return self.name class Meta: - unique_together = (('camp', 'slug'), ('camp', 'name')) + unique_together = (("camp", "slug"), ("camp", "name")) def serialize(self): - return { - "name": self.name, - "slug": self.slug, - } + return {"name": self.name, "slug": self.slug} class EventLocation(CampRelatedModel): """ The places where stuff happens """ - name = models.CharField( - max_length=100 - ) + name = models.CharField(max_length=100) slug = models.SlugField() icon = models.CharField( max_length=100, - help_text="Name of the fontawesome icon to use without the 'fa-' part" + help_text="Name of the fontawesome icon to use without the 'fa-' part", ) camp = models.ForeignKey( - 'camps.Camp', - related_name='eventlocations', - on_delete=models.PROTECT + "camps.Camp", related_name="eventlocations", on_delete=models.PROTECT ) def __str__(self): - return '{} ({})'.format(self.name, self.camp) + return "{} ({})".format(self.name, self.camp) class Meta: - unique_together = (('camp', 'slug'), ('camp', 'name')) + unique_together = (("camp", "slug"), ("camp", "name")) def serialize(self): - return { - "name": self.name, - "slug": self.slug, - "icon": self.icon, - } + return {"name": self.name, "slug": self.slug, "icon": self.icon} class EventType(CreatedUpdatedModel): """ Every event needs to have a type. """ + name = models.CharField( - max_length=100, - unique=True, - help_text='The name of this event type', + max_length=100, unique=True, help_text="The name of this event type" ) slug = models.SlugField() description = models.TextField( - default='', - help_text='The description of this type of event. Used in content submission flow.', + default="", + help_text="The description of this type of event. Used in content submission flow.", blank=True, ) color = models.CharField( - max_length=50, - help_text='The background color of this event type', + max_length=50, help_text="The background color of this event type" ) light_text = models.BooleanField( - default=False, - help_text='Check if this event type should use white text color', + default=False, help_text="Check if this event type should use white text color" ) icon = models.CharField( max_length=25, help_text="Name of the fontawesome icon to use, without the 'fa-' part", - default='wrench', + default="wrench", ) notifications = models.BooleanField( - default=False, - help_text='Check to send notifications for this event type', + default=False, help_text="Check to send notifications for this event type" ) public = models.BooleanField( - default=False, - help_text='Check to permit users to submit events of this type', + default=False, help_text="Check to permit users to submit events of this type" ) include_in_event_list = models.BooleanField( - default=True, - help_text='Include events of this type in the event list?', + default=True, help_text="Include events of this type in the event list?" ) host_title = models.CharField( max_length=30, help_text='What to call someone hosting this type of event. Like "Artist" for Music or "Speaker" for talks.', - default='Person', + default="Person", ) def __str__(self): @@ -571,61 +529,52 @@ class EventType(CreatedUpdatedModel): class Event(CampRelatedModel): """ Something that is on the program one or more times. """ - title = models.CharField( - max_length=255, - help_text='The title of this event', - ) + title = models.CharField(max_length=255, help_text="The title of this event") - abstract = models.TextField( - help_text='The abstract for this event' - ) + abstract = models.TextField(help_text="The abstract for this event") event_type = models.ForeignKey( - 'program.EventType', - help_text='The type of this event', - on_delete=models.PROTECT + "program.EventType", + help_text="The type of this event", + on_delete=models.PROTECT, ) slug = models.SlugField( blank=True, max_length=255, - help_text='The slug for this event, created automatically', + help_text="The slug for this event, created automatically", ) track = models.ForeignKey( - 'program.EventTrack', - related_name='events', - help_text='The track this event belongs to', - on_delete=models.PROTECT + "program.EventTrack", + related_name="events", + help_text="The track this event belongs to", + on_delete=models.PROTECT, ) video_url = models.URLField( - max_length=1000, - null=True, - blank=True, - help_text='URL to the recording' + max_length=1000, null=True, blank=True, help_text="URL to the recording" ) video_recording = models.BooleanField( - default=True, - help_text='Do we intend to record video of this event?' + default=True, help_text="Do we intend to record video of this event?" ) proposal = models.OneToOneField( - 'program.EventProposal', + "program.EventProposal", null=True, blank=True, - help_text='The event proposal object this event was created from', + help_text="The event proposal object this event was created from", on_delete=models.PROTECT, editable=False, ) class Meta: - ordering = ['title'] - unique_together = (('track', 'slug'), ('track', 'title')) + ordering = ["title"] + unique_together = (("track", "slug"), ("track", "title")) def __str__(self): - return '%s (%s)' % (self.title, self.camp.title) + return "%s (%s)" % (self.title, self.camp.title) def save(self, **kwargs): if not self.slug: @@ -636,38 +585,38 @@ class Event(CampRelatedModel): def camp(self): return self.track.camp - camp_filter = 'track__camp' + camp_filter = "track__camp" @property def speakers_list(self): if self.speakers.exists(): - return ", ".join(self.speakers.all().values_list('name', flat=True)) + return ", ".join(self.speakers.all().values_list("name", flat=True)) return False def get_absolute_url(self): - return reverse_lazy('program:event_detail', kwargs={'camp_slug': self.camp.slug, 'slug': self.slug}) + return reverse_lazy( + "program:event_detail", + kwargs={"camp_slug": self.camp.slug, "slug": self.slug}, + ) def serialize(self): data = { - 'title': self.title, - 'slug': self.slug, - 'abstract': self.abstract, - 'speaker_slugs': [ - speaker.slug - for speaker in self.speakers.all() - ], - 'event_type': self.event_type.name, + "title": self.title, + "slug": self.slug, + "abstract": self.abstract, + "speaker_slugs": [speaker.slug for speaker in self.speakers.all()], + "event_type": self.event_type.name, } if self.video_url: - video_state = 'has-recording' - data['video_url'] = self.video_url + video_state = "has-recording" + data["video_url"] = self.video_url elif self.video_recording: - video_state = 'to-be-recorded' + video_state = "to-be-recorded" elif not self.video_recording: - video_state = 'not-to-be-recorded' + video_state = "not-to-be-recorded" - data['video_state'] = video_state + data["video_state"] = video_state return data @@ -676,38 +625,34 @@ class EventInstance(CampRelatedModel): """ An instance of an event """ event = models.ForeignKey( - 'program.event', - related_name='instances', - on_delete=models.PROTECT + "program.event", related_name="instances", on_delete=models.PROTECT ) when = DateTimeRangeField() - notifications_sent = models.BooleanField( - default=False - ) + notifications_sent = models.BooleanField(default=False) location = models.ForeignKey( - 'program.EventLocation', - related_name='eventinstances', - on_delete=models.PROTECT + "program.EventLocation", related_name="eventinstances", on_delete=models.PROTECT ) class Meta: - ordering = ['when'] + ordering = ["when"] def __str__(self): - return '%s (%s)' % (self.event, self.when) + return "%s (%s)" % (self.event, self.when) def clean(self): if self.location.camp != self.event.camp: - raise ValidationError({'location': 'Error: This location belongs to a different camp'}) + raise ValidationError( + {"location": "Error: This location belongs to a different camp"} + ) @property def camp(self): return self.event.camp - camp_filter = 'event__track__camp' + camp_filter = "event__track__camp" @property def schedule_date(self): @@ -718,55 +663,57 @@ class EventInstance(CampRelatedModel): after substracting 5 hours would be wednesdays date, not thursdays (given settings.SCHEDULE_MIDNIGHT_OFFSET_HOURS=5) """ - return (self.when.lower-timedelta(hours=settings.SCHEDULE_MIDNIGHT_OFFSET_HOURS)).date() + return ( + self.when.lower - timedelta(hours=settings.SCHEDULE_MIDNIGHT_OFFSET_HOURS) + ).date() @property def timeslots(self): """ Find the number of timeslots this eventinstance takes up """ - seconds = (self.when.upper-self.when.lower).seconds + seconds = (self.when.upper - self.when.lower).seconds minutes = seconds / 60 return minutes / settings.SCHEDULE_TIMESLOT_LENGTH_MINUTES def get_ics_event(self): ievent = icalendar.Event() - ievent['summary'] = self.event.title - ievent['description'] = self.event.abstract - ievent['dtstart'] = icalendar.vDatetime(self.when.lower).to_ical() - ievent['dtend'] = icalendar.vDatetime(self.when.upper).to_ical() - ievent['location'] = icalendar.vText(self.location.name) + ievent["summary"] = self.event.title + ievent["description"] = self.event.abstract + ievent["dtstart"] = icalendar.vDatetime(self.when.lower).to_ical() + ievent["dtend"] = icalendar.vDatetime(self.when.upper).to_ical() + ievent["location"] = icalendar.vText(self.location.name) return ievent def serialize(self, user=None): data = { - 'title': self.event.title, - 'slug': self.event.slug + '-' + str(self.id), - 'event_slug': self.event.slug, - 'from': self.when.lower.isoformat(), - 'to': self.when.upper.isoformat(), - 'url': str(self.event.get_absolute_url()), - 'id': self.id, - 'bg-color': self.event.event_type.color, - 'fg-color': '#fff' if self.event.event_type.light_text else '#000', - 'event_type': self.event.event_type.slug, - 'event_track': self.event.track.slug, - 'location': self.location.slug, - 'location_icon': self.location.icon, - 'timeslots': self.timeslots, + "title": self.event.title, + "slug": self.event.slug + "-" + str(self.id), + "event_slug": self.event.slug, + "from": self.when.lower.isoformat(), + "to": self.when.upper.isoformat(), + "url": str(self.event.get_absolute_url()), + "id": self.id, + "bg-color": self.event.event_type.color, + "fg-color": "#fff" if self.event.event_type.light_text else "#000", + "event_type": self.event.event_type.slug, + "event_track": self.event.track.slug, + "location": self.location.slug, + "location_icon": self.location.icon, + "timeslots": self.timeslots, } if self.event.video_url: - video_state = 'has-recording' - data['video_url'] = self.event.video_url + video_state = "has-recording" + data["video_url"] = self.event.video_url elif self.event.video_recording: - video_state = 'to-be-recorded' + video_state = "to-be-recorded" elif not self.event.video_recording: - video_state = 'not-to-be-recorded' + video_state = "not-to-be-recorded" - data['video_state'] = video_state + data["video_state"] = video_state if user and user.is_authenticated: is_favorited = user.favorites.filter(event_instance=self).exists() - data['is_favorited'] = is_favorited + data["is_favorited"] = is_favorited return data @@ -774,61 +721,53 @@ class EventInstance(CampRelatedModel): class Speaker(CampRelatedModel): """ A Person (co)anchoring one or more events on a camp. """ - name = models.CharField( - max_length=150, - help_text='Name or alias of the speaker', - ) + name = models.CharField(max_length=150, help_text="Name or alias of the speaker") - email = models.EmailField( - max_length=150, - help_text="The email of the speaker.", - ) + email = models.EmailField(max_length=150, help_text="The email of the speaker.") - biography = models.TextField( - help_text='Markdown is supported.' - ) + biography = models.TextField(help_text="Markdown is supported.") slug = models.SlugField( blank=True, max_length=255, - help_text='The slug for this speaker, will be autocreated', + help_text="The slug for this speaker, will be autocreated", ) camp = models.ForeignKey( - 'camps.Camp', + "camps.Camp", null=True, - related_name='speakers', - help_text='The camp this speaker belongs to', - on_delete=models.PROTECT + related_name="speakers", + help_text="The camp this speaker belongs to", + on_delete=models.PROTECT, ) events = models.ManyToManyField( Event, blank=True, - help_text='The event(s) this speaker is anchoring', - related_name='speakers' + help_text="The event(s) this speaker is anchoring", + related_name="speakers", ) proposal = models.OneToOneField( - 'program.SpeakerProposal', + "program.SpeakerProposal", null=True, blank=True, - help_text='The speaker proposal object this speaker was created from', + help_text="The speaker proposal object this speaker was created from", on_delete=models.PROTECT, editable=False, ) needs_oneday_ticket = models.BooleanField( default=False, - help_text='Check if BornHack needs to provide a free one-day ticket for this speaker', + help_text="Check if BornHack needs to provide a free one-day ticket for this speaker", ) class Meta: - ordering = ['name'] - unique_together = (('camp', 'name'), ('camp', 'slug')) + ordering = ["name"] + unique_together = (("camp", "name"), ("camp", "slug")) def __str__(self): - return '%s (%s)' % (self.name, self.camp) + return "%s (%s)" % (self.name, self.camp) def save(self, **kwargs): if not self.slug: @@ -836,40 +775,40 @@ class Speaker(CampRelatedModel): super(Speaker, self).save(**kwargs) def get_absolute_url(self): - return reverse_lazy('program:speaker_detail', kwargs={'camp_slug': self.camp.slug, 'slug': self.slug}) + return reverse_lazy( + "program:speaker_detail", + kwargs={"camp_slug": self.camp.slug, "slug": self.slug}, + ) def serialize(self): - data = { - 'name': self.name, - 'slug': self.slug, - 'biography': self.biography, - } + data = {"name": self.name, "slug": self.slug, "biography": self.biography} return data class Favorite(models.Model): user = models.ForeignKey( - 'auth.User', - related_name='favorites', - on_delete=models.PROTECT + "auth.User", related_name="favorites", on_delete=models.PROTECT ) event_instance = models.ForeignKey( - 'program.EventInstance', - on_delete=models.PROTECT + "program.EventInstance", on_delete=models.PROTECT ) class Meta: - unique_together = ['user', 'event_instance'] + unique_together = ["user", "event_instance"] + # classes and functions below here was used by picture handling for speakers before it was removed in May 2018 by tyk + class CustomUrlStorage(FileSystemStorage): """ Must exist because it is mentioned in old migrations. Can be removed when we clean up old migrations at some point """ + pass + def get_speaker_picture_upload_path(): """ Must exist because it is mentioned in old migrations. @@ -877,6 +816,7 @@ def get_speaker_picture_upload_path(): """ pass + def get_speakerproposal_picture_upload_path(): """ Must exist because it is mentioned in old migrations. @@ -884,10 +824,10 @@ def get_speakerproposal_picture_upload_path(): """ pass + def get_speakersubmission_picture_upload_path(): """ Must exist because it is mentioned in old migrations. Can be removed when we clean up old migrations at some point """ pass - diff --git a/src/program/signal_handlers.py b/src/program/signal_handlers.py index 55434053..f6f3dff8 100644 --- a/src/program/signal_handlers.py +++ b/src/program/signal_handlers.py @@ -8,31 +8,46 @@ from django.conf import settings from .email import add_new_speakerproposal_email, add_new_eventproposal_email from .models import EventProposal, SpeakerProposal + logger = logging.getLogger("bornhack.%s" % __name__) def check_speaker_event_camp_consistency(sender, instance, **kwargs): - if kwargs['action'] == 'pre_add': + if kwargs["action"] == "pre_add": from program.models import Speaker, Event + if isinstance(instance, Event): # loop over speakers being added to this event - for pk in kwargs['pk_set']: + for pk in kwargs["pk_set"]: # check if this speaker belongs to a different Camp than the event does speaker = Speaker.objects.get(id=pk) if speaker.camp != instance.camp: - raise ValidationError({'speakers': 'The speaker (%s) belongs to a different camp (%s) than the event does (%s)' % (speaker, speaker.camp, instance.camp)}) + raise ValidationError( + { + "speakers": "The speaker (%s) belongs to a different camp (%s) than the event does (%s)" + % (speaker, speaker.camp, instance.camp) + } + ) elif isinstance(instance, Speaker): # loop over events being added to this speaker - for pk in kwargs['pk_set']: + for pk in kwargs["pk_set"]: # check if this event belongs to a different Camp than the speaker does event = Event.objects.get(id=pk) if event.camp != instance.camp: - raise ValidationError({'events': 'The event (%s) belongs to a different camp (%s) than the event does (%s)' % (event, event.camp, instance.camp)}) + raise ValidationError( + { + "events": "The event (%s) belongs to a different camp (%s) than the event does (%s)" + % (event, event.camp, instance.camp) + } + ) def check_speaker_camp_change(sender, instance, **kwargs): if instance.pk: for event in instance.events.all(): if event.camp != instance.camp: - raise ValidationError({'camp': 'You cannot change the camp a speaker belongs to if the speaker is associated with one or more events.'}) - + raise ValidationError( + { + "camp": "You cannot change the camp a speaker belongs to if the speaker is associated with one or more events." + } + ) diff --git a/src/program/urls.py b/src/program/urls.py index ff5cdc6d..ee6b7e8e 100644 --- a/src/program/urls.py +++ b/src/program/urls.py @@ -1,191 +1,171 @@ from django.urls import path, include from .views import * -app_name = 'program' +app_name = "program" urlpatterns = [ + path("", ScheduleView.as_view(), name="schedule_index"), + path("noscript/", NoScriptScheduleView.as_view(), name="noscript_schedule_index"), + path("ics/", ICSView.as_view(), name="ics_view"), + path("control/", ProgramControlCenter.as_view(), name="program_control_center"), path( - '', - ScheduleView.as_view(), - name='schedule_index' + "proposals/", + include( + [ + path("", ProposalListView.as_view(), name="proposal_list"), + path( + "submit/", + include( + [ + path( + "", + CombinedProposalTypeSelectView.as_view(), + name="proposal_combined_type_select", + ), + path( + "/", + CombinedProposalSubmitView.as_view(), + name="proposal_combined_submit", + ), + path( + "/select_person/", + CombinedProposalPersonSelectView.as_view(), + name="proposal_combined_person_select", + ), + ] + ), + ), + path( + "people/", + include( + [ + path( + "/", + SpeakerProposalDetailView.as_view(), + name="speakerproposal_detail", + ), + path( + "/update/", + SpeakerProposalUpdateView.as_view(), + name="speakerproposal_update", + ), + path( + "/delete/", + SpeakerProposalDeleteView.as_view(), + name="speakerproposal_delete", + ), + path( + "/add_event/", + EventProposalTypeSelectView.as_view(), + name="eventproposal_typeselect", + ), + path( + "/add_event//", + EventProposalCreateView.as_view(), + name="eventproposal_create", + ), + path( + "/add_url/", + UrlCreateView.as_view(), + name="speakerproposalurl_create", + ), + path( + "/urls//update/", + UrlUpdateView.as_view(), + name="speakerproposalurl_update", + ), + path( + "/urls//delete/", + UrlDeleteView.as_view(), + name="speakerproposalurl_delete", + ), + ] + ), + ), + path( + "events/", + include( + [ + path( + "/", + EventProposalDetailView.as_view(), + name="eventproposal_detail", + ), + path( + "/update/", + EventProposalUpdateView.as_view(), + name="eventproposal_update", + ), + path( + "/delete/", + EventProposalDeleteView.as_view(), + name="eventproposal_delete", + ), + path( + "/add_person/", + EventProposalSelectPersonView.as_view(), + name="eventproposal_selectperson", + ), + path( + "/add_person/new/", + SpeakerProposalCreateView.as_view(), + name="speakerproposal_create", + ), + path( + "/add_person//", + EventProposalAddPersonView.as_view(), + name="eventproposal_addperson", + ), + path( + "/remove_person//", + EventProposalRemovePersonView.as_view(), + name="eventproposal_removeperson", + ), + path( + "/add_url/", + UrlCreateView.as_view(), + name="eventproposalurl_create", + ), + path( + "/urls//update/", + UrlUpdateView.as_view(), + name="eventproposalurl_update", + ), + path( + "/urls//delete/", + UrlDeleteView.as_view(), + name="eventproposalurl_delete", + ), + ] + ), + ), + ] + ), ), path( - 'noscript/', - NoScriptScheduleView.as_view(), - name='noscript_schedule_index' - ), - path( - 'ics/', ICSView.as_view(), name="ics_view" - ), - path( - 'control/', ProgramControlCenter.as_view(), name="program_control_center" - ), - path( - 'proposals/', include([ - path( - '', - ProposalListView.as_view(), - name='proposal_list', - ), - path( - 'submit/', include([ - path( - '', - CombinedProposalTypeSelectView.as_view(), - name='proposal_combined_type_select', - ), - path( - '/', - CombinedProposalSubmitView.as_view(), - name='proposal_combined_submit', - ), - path( - '/select_person/', - CombinedProposalPersonSelectView.as_view(), - name='proposal_combined_person_select', - ), - ]), - ), - path( - 'people/', include([ - path( - '/', - SpeakerProposalDetailView.as_view(), - name='speakerproposal_detail' - ), - path( - '/update/', - SpeakerProposalUpdateView.as_view(), - name='speakerproposal_update' - ), - path( - '/delete/', - SpeakerProposalDeleteView.as_view(), - name='speakerproposal_delete' - ), - path( - '/add_event/', - EventProposalTypeSelectView.as_view(), - name='eventproposal_typeselect' - ), - path( - '/add_event//', - EventProposalCreateView.as_view(), - name='eventproposal_create' - ), - path( - '/add_url/', - UrlCreateView.as_view(), - name='speakerproposalurl_create' - ), - path( - '/urls//update/', - UrlUpdateView.as_view(), - name='speakerproposalurl_update' - ), - path( - '/urls//delete/', - UrlDeleteView.as_view(), - name='speakerproposalurl_delete' - ), - ]) - ), - path( - 'events/', include([ - path( - '/', - EventProposalDetailView.as_view(), - name='eventproposal_detail' - ), - path( - '/update/', - EventProposalUpdateView.as_view(), - name='eventproposal_update' - ), - path( - '/delete/', - EventProposalDeleteView.as_view(), - name='eventproposal_delete' - ), - path( - '/add_person/', - EventProposalSelectPersonView.as_view(), - name='eventproposal_selectperson' - ), - path( - '/add_person/new/', - SpeakerProposalCreateView.as_view(), - name='speakerproposal_create' - ), - path( - '/add_person//', - EventProposalAddPersonView.as_view(), - name='eventproposal_addperson' - ), - path( - '/remove_person//', - EventProposalRemovePersonView.as_view(), - name='eventproposal_removeperson' - ), - path( - '/add_url/', - UrlCreateView.as_view(), - name='eventproposalurl_create' - ), - path( - '/urls//update/', - UrlUpdateView.as_view(), - name='eventproposalurl_update' - ), - path( - '/urls//delete/', - UrlDeleteView.as_view(), - name='eventproposalurl_delete' - ), - ]) - ), - ]) - ), - path( - 'speakers/', include([ - path( - '', - SpeakerListView.as_view(), - name='speaker_index' - ), - path( - '/', - SpeakerDetailView.as_view(), - name='speaker_detail' - ), - ]), - ), - path( - 'events/', - EventListView.as_view(), - name='event_index' + "speakers/", + include( + [ + path("", SpeakerListView.as_view(), name="speaker_index"), + path( + "/", SpeakerDetailView.as_view(), name="speaker_detail" + ), + ] + ), ), + path("events/", EventListView.as_view(), name="event_index"), # legacy CFS url kept on purpose to keep old links functional path( - 'call-for-speakers/', + "call-for-speakers/", CallForParticipationView.as_view(), - name='call_for_speakers' + name="call_for_speakers", ), path( - 'call-for-participation/', + "call-for-participation/", CallForParticipationView.as_view(), - name='call_for_participation' - ), - path( - 'calendar', - ICSView.as_view(), - name='ics_calendar' + name="call_for_participation", ), + path("calendar", ICSView.as_view(), name="ics_calendar"), # this must be the last URL here or the regex will overrule the others - path( - '/', - EventDetailView.as_view(), - name='event_detail' - ), + path("/", EventDetailView.as_view(), name="event_detail"), ] - diff --git a/src/program/views.py b/src/program/views.py index af900b29..ef11ef9a 100644 --- a/src/program/views.py +++ b/src/program/views.py @@ -28,7 +28,7 @@ from .email import ( add_new_eventproposal_email, add_new_speakerproposal_email, add_speakerproposal_updated_email, - add_eventproposal_updated_email + add_eventproposal_updated_email, ) from . import models from .forms import SpeakerProposalForm, EventProposalForm @@ -48,41 +48,38 @@ class ICSView(CampViewMixin, View): ) # Type query - type_query = request.GET.get('type', None) + type_query = request.GET.get("type", None) if type_query: - type_slugs = type_query.split(',') - types = models.EventType.objects.filter( - slug__in=type_slugs - ) + type_slugs = type_query.split(",") + types = models.EventType.objects.filter(slug__in=type_slugs) eventinstances = eventinstances.filter(event__event_type__in=types) # Location query - location_query = request.GET.get('location', None) + location_query = request.GET.get("location", None) if location_query: - location_slugs = location_query.split(',') + location_slugs = location_query.split(",") locations = models.EventLocation.objects.filter( - slug__in=location_slugs, - camp=self.camp, + slug__in=location_slugs, camp=self.camp ) eventinstances = eventinstances.filter(location__in=locations) # Video recording query - video_query = request.GET.get('video', None) + video_query = request.GET.get("video", None) if video_query: - video_states = video_query.split(',') + video_states = video_query.split(",") query_kwargs = {} - if 'has-recording' in video_states: - query_kwargs['event__video_url__isnull'] = False + if "has-recording" in video_states: + query_kwargs["event__video_url__isnull"] = False - if 'to-be-recorded' in video_states: - query_kwargs['event__video_recording'] = True + if "to-be-recorded" in video_states: + query_kwargs["event__video_recording"] = True - if 'not-to-be-recorded' in video_states: - if 'event__video_recording' in query_kwargs: - del query_kwargs['event__video_recording'] + if "not-to-be-recorded" in video_states: + if "event__video_recording" in query_kwargs: + del query_kwargs["event__video_recording"] else: - query_kwargs['event__video_recording'] = False + query_kwargs["event__video_recording"] = False eventinstances = eventinstances.filter(**query_kwargs) @@ -91,8 +88,10 @@ class ICSView(CampViewMixin, View): cal.add_component(event_instance.get_ics_event()) response = HttpResponse(cal.to_ical()) - response['Content-Type'] = 'text/calendar' - response['Content-Disposition'] = 'inline; filename={}.ics'.format(self.camp.slug) + response["Content-Type"] = "text/calendar" + response["Content-Disposition"] = "inline; filename={}.ics".format( + self.camp.slug + ) return response @@ -102,8 +101,8 @@ class ICSView(CampViewMixin, View): class ProposalListView(LoginRequiredMixin, CampViewMixin, ListView): model = models.SpeakerProposal - template_name = 'proposal_list.html' - context_object_name = 'speakerproposal_list' + template_name = "proposal_list.html" + context_object_name = "speakerproposal_list" def get_queryset(self, **kwargs): # only show speaker proposals for the current user @@ -112,8 +111,10 @@ class ProposalListView(LoginRequiredMixin, CampViewMixin, ListView): def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) # also add eventproposals to the context - context['eventproposal_list'] = models.EventProposal.objects.filter(track__camp=self.camp, user=self.request.user) - context['eventtype_list'] = models.EventType.objects.filter(public=True) + context["eventproposal_list"] = models.EventProposal.objects.filter( + track__camp=self.camp, user=self.request.user + ) + context["eventtype_list"] = models.EventType.objects.filter(public=True) return context @@ -121,34 +122,40 @@ class ProposalListView(LoginRequiredMixin, CampViewMixin, ListView): # speakerproposal views -class SpeakerProposalCreateView(LoginRequiredMixin, CampViewMixin, EnsureWritableCampMixin, EnsureCFPOpenMixin, CreateView): +class SpeakerProposalCreateView( + LoginRequiredMixin, + CampViewMixin, + EnsureWritableCampMixin, + EnsureCFPOpenMixin, + CreateView, +): """ This view allows a user to create a new SpeakerProposal linked to an existing EventProposal """ + model = models.SpeakerProposal - template_name = 'speakerproposal_form.html' + template_name = "speakerproposal_form.html" form_class = SpeakerProposalForm def dispatch(self, request, *args, **kwargs): """ Get the eventproposal object """ - self.eventproposal = get_object_or_404(models.EventProposal, pk=kwargs['event_uuid']) + self.eventproposal = get_object_or_404( + models.EventProposal, pk=kwargs["event_uuid"] + ) return super().dispatch(request, *args, **kwargs) def get_success_url(self): - return reverse('program:proposal_list', kwargs={'camp_slug': self.camp.slug}) + return reverse("program:proposal_list", kwargs={"camp_slug": self.camp.slug}) def get_form_kwargs(self): """ Set camp and eventtype for the form """ kwargs = super().get_form_kwargs() - kwargs.update({ - 'camp': self.camp, - 'eventtype': self.eventproposal.event_type - }) + kwargs.update({"camp": self.camp, "eventtype": self.eventproposal.event_type}) return kwargs def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) - context['eventproposal'] = self.eventproposal + context["eventproposal"] = self.eventproposal return context def form_valid(self, form): @@ -166,19 +173,29 @@ class SpeakerProposalCreateView(LoginRequiredMixin, CampViewMixin, EnsureWritabl # send mail to content team if not add_new_speakerproposal_email(speakerproposal): - logger.error("Unable to send email to content team after new speakerproposal") + logger.error( + "Unable to send email to content team after new speakerproposal" + ) return redirect( - reverse('program:proposal_list', kwargs={'camp_slug': self.camp.slug}) + reverse("program:proposal_list", kwargs={"camp_slug": self.camp.slug}) ) -class SpeakerProposalUpdateView(LoginRequiredMixin, CampViewMixin, EnsureWritableCampMixin, EnsureUserOwnsProposalMixin, EnsureCFPOpenMixin, UpdateView): +class SpeakerProposalUpdateView( + LoginRequiredMixin, + CampViewMixin, + EnsureWritableCampMixin, + EnsureUserOwnsProposalMixin, + EnsureCFPOpenMixin, + UpdateView, +): """ This view allows a user to update an existing SpeakerProposal. """ + model = models.SpeakerProposal - template_name = 'speakerproposal_form.html' + template_name = "speakerproposal_form.html" form_class = SpeakerProposalForm def get_form_kwargs(self): @@ -201,10 +218,7 @@ class SpeakerProposalUpdateView(LoginRequiredMixin, CampViewMixin, EnsureWritabl eventtype = None # add camp and eventtype to form kwargs - kwargs.update({ - 'camp': self.camp, - 'eventtype': eventtype - }) + kwargs.update({"camp": self.camp, "eventtype": eventtype}) return kwargs @@ -218,54 +232,85 @@ class SpeakerProposalUpdateView(LoginRequiredMixin, CampViewMixin, EnsureWritabl # send mail to content team if not add_speakerproposal_updated_email(speakerproposal): - logger.error("Unable to send email to content team after speakerproposal update") + logger.error( + "Unable to send email to content team after speakerproposal update" + ) # message user and redirect - messages.info(self.request, "Your proposal is now pending approval by the content team.") - return redirect(reverse('program:proposal_list', kwargs={'camp_slug': self.camp.slug})) + messages.info( + self.request, "Your proposal is now pending approval by the content team." + ) + return redirect( + reverse("program:proposal_list", kwargs={"camp_slug": self.camp.slug}) + ) -class SpeakerProposalDeleteView(LoginRequiredMixin, CampViewMixin, EnsureWritableCampMixin, EnsureUserOwnsProposalMixin, EnsureCFPOpenMixin, DeleteView): +class SpeakerProposalDeleteView( + LoginRequiredMixin, + CampViewMixin, + EnsureWritableCampMixin, + EnsureUserOwnsProposalMixin, + EnsureCFPOpenMixin, + DeleteView, +): """ This view allows a user to delete an existing SpeakerProposal object, as long as it is not linked to any EventProposals """ + model = models.SpeakerProposal - template_name = 'proposal_delete.html' + template_name = "proposal_delete.html" def get(self, request, *args, **kwargs): # do not permit deleting if this speakerproposal is linked to any eventproposals if self.get_object().eventproposals.exists(): - messages.error(request, "Cannot delete a person while it is associated with one or more eventproposals. Delete those first.") - return redirect(reverse('program:proposal_list', kwargs={'camp_slug': self.camp.slug})) + messages.error( + request, + "Cannot delete a person while it is associated with one or more eventproposals. Delete those first.", + ) + return redirect( + reverse("program:proposal_list", kwargs={"camp_slug": self.camp.slug}) + ) # continue with the request return super().get(request, *args, **kwargs) def get_success_url(self): - messages.success(self.request, "Proposal '%s' has been deleted." % self.object.name) - return reverse('program:proposal_list', kwargs={'camp_slug': self.camp.slug}) + messages.success( + self.request, "Proposal '%s' has been deleted." % self.object.name + ) + return reverse("program:proposal_list", kwargs={"camp_slug": self.camp.slug}) - -class SpeakerProposalDetailView(LoginRequiredMixin, CampViewMixin, EnsureUserOwnsProposalMixin, DetailView): +class SpeakerProposalDetailView( + LoginRequiredMixin, CampViewMixin, EnsureUserOwnsProposalMixin, DetailView +): model = models.SpeakerProposal - template_name = 'speakerproposal_detail.html' + template_name = "speakerproposal_detail.html" ################################################################################################### # eventproposal views -class EventProposalTypeSelectView(LoginRequiredMixin, CampViewMixin, EnsureWritableCampMixin, EnsureCFPOpenMixin, ListView): +class EventProposalTypeSelectView( + LoginRequiredMixin, + CampViewMixin, + EnsureWritableCampMixin, + EnsureCFPOpenMixin, + ListView, +): """ This view is for selecting the type of event to submit (when adding a new eventproposal to an existing speakerproposal) """ + model = models.EventType - template_name = 'event_type_select.html' + template_name = "event_type_select.html" def dispatch(self, request, *args, **kwargs): """ Get the speakerproposal object """ - self.speaker = get_object_or_404(models.SpeakerProposal, pk=kwargs['speaker_uuid']) + self.speaker = get_object_or_404( + models.SpeakerProposal, pk=kwargs["speaker_uuid"] + ) return super().dispatch(request, *args, **kwargs) def get_queryset(self, **kwargs): @@ -275,20 +320,29 @@ class EventProposalTypeSelectView(LoginRequiredMixin, CampViewMixin, EnsureWrita def get_context_data(self, *args, **kwargs): """ Make speakerproposal object available in template """ context = super().get_context_data(**kwargs) - context['speaker'] = self.speaker + context["speaker"] = self.speaker return context -class EventProposalSelectPersonView(LoginRequiredMixin, CampViewMixin, EnsureWritableCampMixin, EnsureCFPOpenMixin, ListView): +class EventProposalSelectPersonView( + LoginRequiredMixin, + CampViewMixin, + EnsureWritableCampMixin, + EnsureCFPOpenMixin, + ListView, +): """ This view is for selecting an existing speakerproposal to add to an existing eventproposal """ + model = models.SpeakerProposal - template_name = 'event_proposal_select_person.html' + template_name = "event_proposal_select_person.html" def dispatch(self, request, *args, **kwargs): """ Get EventProposal from url kwargs """ - self.eventproposal = get_object_or_404(models.EventProposal, pk=kwargs['event_uuid'], user=request.user) + self.eventproposal = get_object_or_404( + models.EventProposal, pk=kwargs["event_uuid"], user=request.user + ) return super().dispatch(request, *args, **kwargs) def get_queryset(self, **kwargs): @@ -298,60 +352,81 @@ class EventProposalSelectPersonView(LoginRequiredMixin, CampViewMixin, EnsureWri def get_context_data(self, *args, **kwargs): """ Make eventproposal object available in template """ context = super().get_context_data(**kwargs) - context['eventproposal'] = self.eventproposal + context["eventproposal"] = self.eventproposal return context -class EventProposalAddPersonView(LoginRequiredMixin, CampViewMixin, EnsureWritableCampMixin, EnsureCFPOpenMixin, UpdateView): +class EventProposalAddPersonView( + LoginRequiredMixin, + CampViewMixin, + EnsureWritableCampMixin, + EnsureCFPOpenMixin, + UpdateView, +): """ This view is for adding an existing speakerproposal to an existing eventproposal """ + model = models.EventProposal - template_name = 'event_proposal_add_person.html' + template_name = "event_proposal_add_person.html" fields = [] - pk_url_kwarg = 'event_uuid' + pk_url_kwarg = "event_uuid" def dispatch(self, request, *args, **kwargs): """ Get the speakerproposal object """ - self.speakerproposal = get_object_or_404(models.SpeakerProposal, pk=kwargs['speaker_uuid'], user=request.user) + self.speakerproposal = get_object_or_404( + models.SpeakerProposal, pk=kwargs["speaker_uuid"], user=request.user + ) return super().dispatch(request, *args, **kwargs) def get_context_data(self, *args, **kwargs): """ Make speakerproposal object available in template """ context = super().get_context_data(**kwargs) - context['speakerproposal'] = self.speakerproposal + context["speakerproposal"] = self.speakerproposal return context def form_valid(self, form): form.instance.speakers.add(self.speakerproposal) - messages.success(self.request, "%s has been added as %s for %s" % ( - self.speakerproposal.name, - form.instance.event_type.host_title, - form.instance.title - )) + messages.success( + self.request, + "%s has been added as %s for %s" + % ( + self.speakerproposal.name, + form.instance.event_type.host_title, + form.instance.title, + ), + ) return redirect(self.get_success_url()) -class EventProposalRemovePersonView(LoginRequiredMixin, CampViewMixin, EnsureWritableCampMixin, EnsureCFPOpenMixin, UpdateView): +class EventProposalRemovePersonView( + LoginRequiredMixin, + CampViewMixin, + EnsureWritableCampMixin, + EnsureCFPOpenMixin, + UpdateView, +): """ This view is for removing a speakerproposal from an existing eventproposal """ + model = models.EventProposal - template_name = 'event_proposal_remove_person.html' + template_name = "event_proposal_remove_person.html" fields = [] - pk_url_kwarg = 'event_uuid' + pk_url_kwarg = "event_uuid" def dispatch(self, request, *args, **kwargs): """ Get the speakerproposal object and check a few things """ # get the speakerproposal object from URL kwargs - self.speakerproposal = get_object_or_404(models.SpeakerProposal, pk=kwargs['speaker_uuid'], user=request.user) + self.speakerproposal = get_object_or_404( + models.SpeakerProposal, pk=kwargs["speaker_uuid"], user=request.user + ) return super().dispatch(request, *args, **kwargs) - def get_context_data(self, *args, **kwargs): """ Make speakerproposal object available in template """ context = super().get_context_data(**kwargs) - context['speakerproposal'] = self.speakerproposal + context["speakerproposal"] = self.speakerproposal return context def form_valid(self, form): @@ -361,44 +436,57 @@ class EventProposalRemovePersonView(LoginRequiredMixin, CampViewMixin, EnsureWri raise Http404 if self.get_object().speakers.count() == 1: - messages.error(self.request, "Cannot delete the last person associalted with event!") + messages.error( + self.request, "Cannot delete the last person associalted with event!" + ) return redirect(self.get_success_url()) # remove speakerproposal from eventproposal form.instance.speakers.remove(self.speakerproposal) - messages.success(self.request, "%s has been removed from %s" % ( - self.speakerproposal.name, - self.get_object().title - )) + messages.success( + self.request, + "%s has been removed from %s" + % (self.speakerproposal.name, self.get_object().title), + ) return redirect(self.get_success_url()) def get_success_url(self): return reverse( - 'program:eventproposal_detail', kwargs={ - 'camp_slug': self.camp.slug, - 'pk': self.get_object().uuid - }) + "program:eventproposal_detail", + kwargs={"camp_slug": self.camp.slug, "pk": self.get_object().uuid}, + ) -class EventProposalCreateView(LoginRequiredMixin, CampViewMixin, EnsureWritableCampMixin, EnsureCFPOpenMixin, CreateView): +class EventProposalCreateView( + LoginRequiredMixin, + CampViewMixin, + EnsureWritableCampMixin, + EnsureCFPOpenMixin, + CreateView, +): """ This view allows a user to create a new eventproposal linked to an existing speakerproposal """ + model = models.EventProposal - template_name = 'eventproposal_form.html' + template_name = "eventproposal_form.html" form_class = EventProposalForm def dispatch(self, request, *args, **kwargs): """ Get the speakerproposal object """ - self.speakerproposal = get_object_or_404(models.SpeakerProposal, pk=self.kwargs['speaker_uuid']) - self.event_type = get_object_or_404(models.EventType, slug=self.kwargs['event_type_slug']) + self.speakerproposal = get_object_or_404( + models.SpeakerProposal, pk=self.kwargs["speaker_uuid"] + ) + self.event_type = get_object_or_404( + models.EventType, slug=self.kwargs["event_type_slug"] + ) return super().dispatch(request, *args, **kwargs) def get_context_data(self, *args, **kwargs): """ Make speakerproposal object available in template """ context = super().get_context_data(**kwargs) - context['speaker'] = self.speakerproposal - context['event_type'] = self.event_type + context["speaker"] = self.speakerproposal + context["event_type"] = self.event_type return context def get_form_kwargs(self): @@ -406,10 +494,7 @@ class EventProposalCreateView(LoginRequiredMixin, CampViewMixin, EnsureWritableC Set camp and eventtype for the form """ kwargs = super().get_form_kwargs() - kwargs.update({ - 'camp': self.camp, - 'eventtype': self.event_type - }) + kwargs.update({"camp": self.camp, "eventtype": self.event_type}) return kwargs def form_valid(self, form): @@ -427,12 +512,19 @@ class EventProposalCreateView(LoginRequiredMixin, CampViewMixin, EnsureWritableC return redirect(self.get_success_url()) def get_success_url(self): - return reverse('program:proposal_list', kwargs={'camp_slug': self.camp.slug}) + return reverse("program:proposal_list", kwargs={"camp_slug": self.camp.slug}) -class EventProposalUpdateView(LoginRequiredMixin, CampViewMixin, EnsureWritableCampMixin, EnsureUserOwnsProposalMixin, EnsureCFPOpenMixin, UpdateView): +class EventProposalUpdateView( + LoginRequiredMixin, + CampViewMixin, + EnsureWritableCampMixin, + EnsureUserOwnsProposalMixin, + EnsureCFPOpenMixin, + UpdateView, +): model = models.EventProposal - template_name = 'eventproposal_form.html' + template_name = "eventproposal_form.html" form_class = EventProposalForm def get_form_kwargs(self): @@ -440,16 +532,13 @@ class EventProposalUpdateView(LoginRequiredMixin, CampViewMixin, EnsureWritableC Set camp and eventtype for the form """ kwargs = super().get_form_kwargs() - kwargs.update({ - 'camp': self.camp, - 'eventtype': self.get_object().event_type - }) + kwargs.update({"camp": self.camp, "eventtype": self.get_object().event_type}) return kwargs def get_context_data(self, *args, **kwargs): """ Make speakerproposal and eventtype objects available in the template """ context = super().get_context_data(**kwargs) - context['event_type'] = self.get_object().event_type + context["event_type"] = self.get_object().event_type return context def form_valid(self, form): @@ -459,25 +548,43 @@ class EventProposalUpdateView(LoginRequiredMixin, CampViewMixin, EnsureWritableC # send email to content team if not add_eventproposal_updated_email(eventproposal): - logger.error("Unable to send email to content team after eventproposal update") + logger.error( + "Unable to send email to content team after eventproposal update" + ) # message for the user and redirect - messages.info(self.request, "Your proposal is now pending approval by the content team.") - return redirect(reverse('program:proposal_list', kwargs={'camp_slug': self.camp.slug})) + messages.info( + self.request, "Your proposal is now pending approval by the content team." + ) + return redirect( + reverse("program:proposal_list", kwargs={"camp_slug": self.camp.slug}) + ) -class EventProposalDeleteView(LoginRequiredMixin, CampViewMixin, EnsureWritableCampMixin, EnsureUserOwnsProposalMixin, EnsureCFPOpenMixin, DeleteView): +class EventProposalDeleteView( + LoginRequiredMixin, + CampViewMixin, + EnsureWritableCampMixin, + EnsureUserOwnsProposalMixin, + EnsureCFPOpenMixin, + DeleteView, +): model = models.EventProposal - template_name = 'proposal_delete.html' + template_name = "proposal_delete.html" def get_success_url(self): - messages.success(self.request, "Proposal '%s' has been deleted." % self.object.title) - return reverse('program:proposal_list', kwargs={'camp_slug': self.camp.slug}) + messages.success( + self.request, "Proposal '%s' has been deleted." % self.object.title + ) + return reverse("program:proposal_list", kwargs={"camp_slug": self.camp.slug}) -class EventProposalDetailView(LoginRequiredMixin, CampViewMixin, EnsureUserOwnsProposalMixin, DetailView): +class EventProposalDetailView( + LoginRequiredMixin, CampViewMixin, EnsureUserOwnsProposalMixin, DetailView +): model = models.EventProposal - template_name = 'eventproposal_detail.html' + template_name = "eventproposal_detail.html" + ################################################################################################### # combined proposal views @@ -487,8 +594,9 @@ class CombinedProposalTypeSelectView(LoginRequiredMixin, CampViewMixin, ListView """ A view which allows the user to select event type without anything else on the page """ + model = models.EventType - template_name = 'event_type_select.html' + template_name = "event_type_select.html" def get_queryset(self, **kwargs): """ We only allow submissions of events with EventTypes where public=True """ @@ -501,15 +609,18 @@ class CombinedProposalPersonSelectView(LoginRequiredMixin, CampViewMixin, ListVi 2) pressing a button to create a new SpeakerProposal. Redirect straight to 2) if no existing SpeakerProposals exist. """ + model = models.SpeakerProposal - template_name = 'combined_proposal_select_person.html' + template_name = "combined_proposal_select_person.html" def dispatch(self, request, *args, **kwargs): """ Check that we have a valid EventType """ # get EventType from url kwargs - self.eventtype = get_object_or_404(models.EventType, slug=self.kwargs['event_type_slug']) + self.eventtype = get_object_or_404( + models.EventType, slug=self.kwargs["event_type_slug"] + ) return super().dispatch(request, *args, **kwargs) @@ -522,13 +633,21 @@ class CombinedProposalPersonSelectView(LoginRequiredMixin, CampViewMixin, ListVi Add EventType to template context """ context = super().get_context_data(**kwargs) - context['eventtype'] = self.eventtype + context["eventtype"] = self.eventtype return context def get(self, request, *args, **kwargs): """ If we don't have any existing SpeakerProposals just redirect directly to the combined submit view """ if not self.get_queryset().exists(): - return redirect(reverse_lazy('program:proposal_combined_submit', kwargs={'camp_slug': self.camp.slug, 'event_type_slug': self.eventtype.slug})) + return redirect( + reverse_lazy( + "program:proposal_combined_submit", + kwargs={ + "camp_slug": self.camp.slug, + "event_type_slug": self.eventtype.slug, + }, + ) + ) return super().get(request, *args, **kwargs) @@ -538,14 +657,17 @@ class CombinedProposalSubmitView(LoginRequiredMixin, CampViewMixin, CreateView): It allows the user to submit an EventProposal and a SpeakerProposal together. It can also be used with a preselected SpeakerProposal uuid in url kwargs """ - template_name = 'combined_proposal_submit.html' + + template_name = "combined_proposal_submit.html" def dispatch(self, request, *args, **kwargs): """ Check that we have a valid EventType """ # get EventType from url kwargs - self.eventtype = get_object_or_404(models.EventType, slug=self.kwargs['event_type_slug']) + self.eventtype = get_object_or_404( + models.EventType, slug=self.kwargs["event_type_slug"] + ) return super().dispatch(request, *args, **kwargs) @@ -554,19 +676,19 @@ class CombinedProposalSubmitView(LoginRequiredMixin, CampViewMixin, CreateView): Add EventType to template context """ context = super().get_context_data(**kwargs) - context['eventtype'] = self.eventtype + context["eventtype"] = self.eventtype return context def form_valid(self, form): """ Save the object(s) here before redirecting """ - if hasattr(self, 'speakerproposal'): + if hasattr(self, "speakerproposal"): eventproposal = form.save(user=self.request.user, event_type=self.eventtype) eventproposal.speakers.add(self.speakerproposal) else: # first save the SpeakerProposal - speakerproposal = form['speakerproposal'].save(commit=False) + speakerproposal = form["speakerproposal"].save(commit=False) speakerproposal.camp = self.camp speakerproposal.user = self.request.user if not speakerproposal.email: @@ -574,7 +696,9 @@ class CombinedProposalSubmitView(LoginRequiredMixin, CampViewMixin, CreateView): speakerproposal.save() # then save the eventproposal - eventproposal = form['eventproposal'].save(user=self.request.user, event_type=self.eventtype) + eventproposal = form["eventproposal"].save( + user=self.request.user, event_type=self.eventtype + ) eventproposal.user = self.request.user eventproposal.event_type = self.eventtype eventproposal.save() @@ -585,28 +709,34 @@ class CombinedProposalSubmitView(LoginRequiredMixin, CampViewMixin, CreateView): # send mail(s) to content team if not add_new_eventproposal_email(eventproposal): logger.error("Unable to send email to content team after new eventproposal") - if not hasattr(self, 'speakerproposal'): + if not hasattr(self, "speakerproposal"): if not add_new_speakerproposal_email(speakerproposal): - logger.error("Unable to send email to content team after new speakerproposal") + logger.error( + "Unable to send email to content team after new speakerproposal" + ) # all good - return redirect(reverse_lazy('program:proposal_list', kwargs={'camp_slug': self.camp.slug})) + return redirect( + reverse_lazy("program:proposal_list", kwargs={"camp_slug": self.camp.slug}) + ) def get_form_class(self): """ Unless we have an existing SpeakerProposal we must show two forms on the page. We use betterforms.MultiModelForm to combine two forms on the page """ - if hasattr(self, 'speakerproposal'): + if hasattr(self, "speakerproposal"): # we already have a speakerproposal, just show an eventproposal form return EventProposalForm # build our MultiModelForm class CombinedProposalSubmitForm(MultiModelForm): - form_classes = OrderedDict(( - ('speakerproposal', SpeakerProposalForm), - ('eventproposal', EventProposalForm), - )) + form_classes = OrderedDict( + ( + ("speakerproposal", SpeakerProposalForm), + ("eventproposal", EventProposalForm), + ) + ) # return the form class return CombinedProposalSubmitForm @@ -616,10 +746,7 @@ class CombinedProposalSubmitView(LoginRequiredMixin, CampViewMixin, CreateView): Set camp and eventtype for the form """ kwargs = super().get_form_kwargs() - kwargs.update({ - 'camp': self.camp, - 'eventtype': self.eventtype - }) + kwargs.update({"camp": self.camp, "eventtype": self.eventtype}) return kwargs @@ -629,12 +756,12 @@ class CombinedProposalSubmitView(LoginRequiredMixin, CampViewMixin, CreateView): class SpeakerDetailView(CampViewMixin, DetailView): model = models.Speaker - template_name = 'speaker_detail.html' + template_name = "speaker_detail.html" class SpeakerListView(CampViewMixin, ListView): model = models.Speaker - template_name = 'speaker_list.html' + template_name = "speaker_list.html" ################################################################################################### @@ -643,12 +770,12 @@ class SpeakerListView(CampViewMixin, ListView): class EventListView(CampViewMixin, ListView): model = models.Event - template_name = 'event_list.html' + template_name = "event_list.html" class EventDetailView(CampViewMixin, DetailView): model = models.Event - template_name = 'schedule_event_detail.html' + template_name = "schedule_event_detail.html" ################################################################################################### @@ -660,32 +787,38 @@ class NoScriptScheduleView(CampViewMixin, TemplateView): def get_context_data(self, *args, **kwargs): context = super().get_context_data(**kwargs) - context['eventinstances'] = models.EventInstance.objects.filter( + context["eventinstances"] = models.EventInstance.objects.filter( event__track__camp=self.camp - ).order_by('when') + ).order_by("when") return context class ScheduleView(CampViewMixin, TemplateView): - template_name = 'schedule_overview.html' + template_name = "schedule_overview.html" def dispatch(self, request, *args, **kwargs): """ If no events are scheduled redirect to the event page """ response = super().dispatch(request, *args, **kwargs) - if not models.EventInstance.objects.filter(event__track__camp=self.camp).exists(): - return(redirect(reverse('program:event_index', kwargs={'camp_slug': self.camp.slug}))) + if not models.EventInstance.objects.filter( + event__track__camp=self.camp + ).exists(): + return redirect( + reverse("program:event_index", kwargs={"camp_slug": self.camp.slug}) + ) return response def get_context_data(self, *args, **kwargs): context = super(ScheduleView, self).get_context_data(**kwargs) - context['schedule_midnight_offset_hours'] = settings.SCHEDULE_MIDNIGHT_OFFSET_HOURS + context[ + "schedule_midnight_offset_hours" + ] = settings.SCHEDULE_MIDNIGHT_OFFSET_HOURS return context class CallForParticipationView(CampViewMixin, TemplateView): - template_name = 'call_for_participation.html' + template_name = "call_for_participation.html" ################################################################################################### @@ -701,111 +834,193 @@ class ProgramControlCenter(CampViewMixin, TemplateView): def get_context_data(self, *args, **kwargs): context = super().get_context_data(**kwargs) - proposals = models.EventProposal.objects.filter( - camp=self.camp - ).select_related('user', 'event') - context['proposals'] = proposals + proposals = models.EventProposal.objects.filter(camp=self.camp).select_related( + "user", "event" + ) + context["proposals"] = proposals engine = Engine.get_default() - template = engine.get_template('control/proposal_overview.csv') + template = engine.get_template("control/proposal_overview.csv") csv = template.render(Context(context)) - context['csv'] = csv + context["csv"] = csv return context + ################################################################################################### # URL views -class UrlCreateView(LoginRequiredMixin, CampViewMixin, EnsureWritableCampMixin, EnsureCFPOpenMixin, UrlViewMixin, CreateView): + +class UrlCreateView( + LoginRequiredMixin, + CampViewMixin, + EnsureWritableCampMixin, + EnsureCFPOpenMixin, + UrlViewMixin, + CreateView, +): model = models.Url - template_name = 'url_form.html' - fields = ['urltype', 'url'] + template_name = "url_form.html" + fields = ["urltype", "url"] def form_valid(self, form): """ Set the proposal FK before saving Set proposal as pending if it isn't already """ - if hasattr(self, 'eventproposal') and self.eventproposal: + if hasattr(self, "eventproposal") and self.eventproposal: # this URL belongs to an eventproposal form.instance.eventproposal = self.eventproposal url = form.save() - if self.eventproposal.proposal_status != models.SpeakerProposal.PROPOSAL_PENDING: - self.eventproposal.proposal_status = models.SpeakerProposal.PROPOSAL_PENDING + if ( + self.eventproposal.proposal_status + != models.SpeakerProposal.PROPOSAL_PENDING + ): + self.eventproposal.proposal_status = ( + models.SpeakerProposal.PROPOSAL_PENDING + ) self.eventproposal.save() - messages.success(self.request, "%s is now pending review by the Content Team." % self.eventproposal.title) + messages.success( + self.request, + "%s is now pending review by the Content Team." + % self.eventproposal.title, + ) else: # this URL belongs to a speakerproposal form.instance.speakerproposal = self.speakerproposal url = form.save() - if self.speakerproposal.proposal_status != models.SpeakerProposal.PROPOSAL_PENDING: - self.speakerproposal.proposal_status = models.SpeakerProposal.PROPOSAL_PENDING + if ( + self.speakerproposal.proposal_status + != models.SpeakerProposal.PROPOSAL_PENDING + ): + self.speakerproposal.proposal_status = ( + models.SpeakerProposal.PROPOSAL_PENDING + ) self.speakerproposal.save() - messages.success(self.request, "%s is now pending review by the Content Team." % self.speakerproposal.name) + messages.success( + self.request, + "%s is now pending review by the Content Team." + % self.speakerproposal.name, + ) messages.success(self.request, "URL saved.") # all good - return redirect(reverse_lazy('program:proposal_list', kwargs={'camp_slug': self.camp.slug})) + return redirect( + reverse_lazy("program:proposal_list", kwargs={"camp_slug": self.camp.slug}) + ) -class UrlUpdateView(LoginRequiredMixin, CampViewMixin, EnsureWritableCampMixin, EnsureCFPOpenMixin, UrlViewMixin, UpdateView): +class UrlUpdateView( + LoginRequiredMixin, + CampViewMixin, + EnsureWritableCampMixin, + EnsureCFPOpenMixin, + UrlViewMixin, + UpdateView, +): model = models.Url - template_name = 'url_form.html' - fields = ['urltype', 'url'] - pk_url_kwarg = 'url_uuid' + template_name = "url_form.html" + fields = ["urltype", "url"] + pk_url_kwarg = "url_uuid" def form_valid(self, form): """ Set proposal as pending if it isn't already """ - if hasattr(self, 'eventproposal') and self.eventproposal: + if hasattr(self, "eventproposal") and self.eventproposal: # this URL belongs to a speakerproposal url = form.save() - if self.eventproposal.proposal_status != models.SpeakerProposal.PROPOSAL_PENDING: - self.eventproposal.proposal_status = models.SpeakerProposal.PROPOSAL_PENDING + if ( + self.eventproposal.proposal_status + != models.SpeakerProposal.PROPOSAL_PENDING + ): + self.eventproposal.proposal_status = ( + models.SpeakerProposal.PROPOSAL_PENDING + ) self.eventproposal.save() - messages.success(self.request, "%s is now pending review by the Content Team." % self.eventproposal.title) + messages.success( + self.request, + "%s is now pending review by the Content Team." + % self.eventproposal.title, + ) else: # this URL belongs to a speakerproposal url = form.save() - if self.speakerproposal.proposal_status != models.SpeakerProposal.PROPOSAL_PENDING: - self.speakerproposal.proposal_status = models.SpeakerProposal.PROPOSAL_PENDING + if ( + self.speakerproposal.proposal_status + != models.SpeakerProposal.PROPOSAL_PENDING + ): + self.speakerproposal.proposal_status = ( + models.SpeakerProposal.PROPOSAL_PENDING + ) self.speakerproposal.save() - messages.success(self.request, "%s is now pending review by the Content Team." % self.speakerproposal.name) + messages.success( + self.request, + "%s is now pending review by the Content Team." + % self.speakerproposal.name, + ) messages.success(self.request, "URL saved.") # all good - return redirect(reverse_lazy('program:proposal_list', kwargs={'camp_slug': self.camp.slug})) + return redirect( + reverse_lazy("program:proposal_list", kwargs={"camp_slug": self.camp.slug}) + ) -class UrlDeleteView(LoginRequiredMixin, CampViewMixin, EnsureWritableCampMixin, EnsureCFPOpenMixin, UrlViewMixin, DeleteView): +class UrlDeleteView( + LoginRequiredMixin, + CampViewMixin, + EnsureWritableCampMixin, + EnsureCFPOpenMixin, + UrlViewMixin, + DeleteView, +): model = models.Url - template_name = 'url_delete.html' - pk_url_kwarg = 'url_uuid' + template_name = "url_delete.html" + pk_url_kwarg = "url_uuid" def delete(self, request, *args, **kwargs): """ Set proposal as pending if it isn't already """ - if hasattr(self, 'eventproposal') and self.eventproposal: + if hasattr(self, "eventproposal") and self.eventproposal: # this URL belongs to a speakerproposal - if self.eventproposal.proposal_status != models.SpeakerProposal.PROPOSAL_PENDING: - self.eventproposal.proposal_status = models.SpeakerProposal.PROPOSAL_PENDING + if ( + self.eventproposal.proposal_status + != models.SpeakerProposal.PROPOSAL_PENDING + ): + self.eventproposal.proposal_status = ( + models.SpeakerProposal.PROPOSAL_PENDING + ) self.eventproposal.save() - messages.success(self.request, "%s is now pending review by the Content Team." % self.eventproposal.title) + messages.success( + self.request, + "%s is now pending review by the Content Team." + % self.eventproposal.title, + ) else: # this URL belongs to a speakerproposal - if self.speakerproposal.proposal_status != models.SpeakerProposal.PROPOSAL_PENDING: - self.speakerproposal.proposal_status = models.SpeakerProposal.PROPOSAL_PENDING + if ( + self.speakerproposal.proposal_status + != models.SpeakerProposal.PROPOSAL_PENDING + ): + self.speakerproposal.proposal_status = ( + models.SpeakerProposal.PROPOSAL_PENDING + ) self.speakerproposal.save() - messages.success(self.request, "%s is now pending review by the Content Team." % self.speakerproposal.name) + messages.success( + self.request, + "%s is now pending review by the Content Team." + % self.speakerproposal.name, + ) self.object = self.get_object() self.object.delete() messages.success(self.request, "URL deleted.") # all good - return redirect(reverse_lazy('program:proposal_list', kwargs={'camp_slug': self.camp.slug})) - + return redirect( + reverse_lazy("program:proposal_list", kwargs={"camp_slug": self.camp.slug}) + ) diff --git a/src/rideshare/admin.py b/src/rideshare/admin.py index 6a674531..4ced6bf9 100644 --- a/src/rideshare/admin.py +++ b/src/rideshare/admin.py @@ -5,5 +5,5 @@ from .models import Ride @admin.register(Ride) class RideModelAdmin(admin.ModelAdmin): - list_display = ('location', 'when', 'seats', 'user') - list_filter = ('camp', 'user') + list_display = ("location", "when", "seats", "user") + list_filter = ("camp", "user") diff --git a/src/rideshare/apps.py b/src/rideshare/apps.py index 9a8b366f..12d6c9c9 100644 --- a/src/rideshare/apps.py +++ b/src/rideshare/apps.py @@ -2,4 +2,4 @@ from django.apps import AppConfig class RideshareConfig(AppConfig): - name = 'rideshare' + name = "rideshare" diff --git a/src/rideshare/migrations/0001_initial.py b/src/rideshare/migrations/0001_initial.py index b1a843f3..a4527655 100644 --- a/src/rideshare/migrations/0001_initial.py +++ b/src/rideshare/migrations/0001_initial.py @@ -11,26 +11,43 @@ class Migration(migrations.Migration): initial = True dependencies = [ - ('camps', '0028_auto_20180525_1025'), + ("camps", "0028_auto_20180525_1025"), migrations.swappable_dependency(settings.AUTH_USER_MODEL), ] operations = [ migrations.CreateModel( - name='Ride', + name="Ride", fields=[ - ('uuid', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)), - ('created', models.DateTimeField(auto_now_add=True)), - ('updated', models.DateTimeField(auto_now=True)), - ('seats', models.PositiveIntegerField()), - ('location', models.CharField(max_length=100)), - ('when', models.DateTimeField()), - ('description', models.TextField()), - ('camp', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='camps.Camp')), - ('user', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to=settings.AUTH_USER_MODEL)), + ( + "uuid", + models.UUIDField( + default=uuid.uuid4, + editable=False, + primary_key=True, + serialize=False, + ), + ), + ("created", models.DateTimeField(auto_now_add=True)), + ("updated", models.DateTimeField(auto_now=True)), + ("seats", models.PositiveIntegerField()), + ("location", models.CharField(max_length=100)), + ("when", models.DateTimeField()), + ("description", models.TextField()), + ( + "camp", + models.ForeignKey( + on_delete=django.db.models.deletion.PROTECT, to="camps.Camp" + ), + ), + ( + "user", + models.ForeignKey( + on_delete=django.db.models.deletion.PROTECT, + to=settings.AUTH_USER_MODEL, + ), + ), ], - options={ - 'abstract': False, - }, - ), + options={"abstract": False}, + ) ] diff --git a/src/rideshare/migrations/0002_auto_20180814_1942.py b/src/rideshare/migrations/0002_auto_20180814_1942.py index ffcbeff5..fc68d4d6 100644 --- a/src/rideshare/migrations/0002_auto_20180814_1942.py +++ b/src/rideshare/migrations/0002_auto_20180814_1942.py @@ -5,14 +5,12 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ - ('rideshare', '0001_initial'), - ] + dependencies = [("rideshare", "0001_initial")] operations = [ migrations.AlterField( - model_name='ride', - name='when', - field=models.DateTimeField(help_text='Format is YYYY-MM-DD HH:mm'), - ), + model_name="ride", + name="when", + field=models.DateTimeField(help_text="Format is YYYY-MM-DD HH:mm"), + ) ] diff --git a/src/rideshare/models.py b/src/rideshare/models.py index 97ce643a..5379f21f 100644 --- a/src/rideshare/models.py +++ b/src/rideshare/models.py @@ -5,8 +5,8 @@ from utils.models import UUIDModel, CampRelatedModel class Ride(UUIDModel, CampRelatedModel): - camp = models.ForeignKey('camps.Camp', on_delete=models.PROTECT) - user = models.ForeignKey('auth.User', on_delete=models.PROTECT) + camp = models.ForeignKey("camps.Camp", on_delete=models.PROTECT) + user = models.ForeignKey("auth.User", on_delete=models.PROTECT) seats = models.PositiveIntegerField() location = models.CharField(max_length=100) when = models.DateTimeField(help_text="Format is YYYY-MM-DD HH:mm") @@ -14,17 +14,10 @@ class Ride(UUIDModel, CampRelatedModel): def get_absolute_url(self): return reverse( - 'rideshare:detail', - kwargs={ - 'pk': self.pk, - 'camp_slug': self.camp.slug - } + "rideshare:detail", kwargs={"pk": self.pk, "camp_slug": self.camp.slug} ) def __str__(self): return "{} seats from {} at {} by {}".format( - self.seats, - self.location, - self.when, - self.user + self.seats, self.location, self.when, self.user ) diff --git a/src/rideshare/urls.py b/src/rideshare/urls.py index e528e248..c2ca8636 100644 --- a/src/rideshare/urls.py +++ b/src/rideshare/urls.py @@ -1,43 +1,20 @@ from django.urls import path, include -from .views import ( - RideList, - RideCreate, - RideDetail, - RideUpdate, - RideDelete, -) +from .views import RideList, RideCreate, RideDetail, RideUpdate, RideDelete -app_name = 'rideshare' +app_name = "rideshare" urlpatterns = [ + path("", RideList.as_view(), name="list"), + path("create/", RideCreate.as_view(), name="create"), path( - '', - RideList.as_view(), - name='list' + "/", + include( + [ + path("", RideDetail.as_view(), name="detail"), + path("update/", RideUpdate.as_view(), name="update"), + path("delete/", RideDelete.as_view(), name="delete"), + ] + ), ), - path( - 'create/', - RideCreate.as_view(), - name='create' - ), - path( - '/', include([ - path( - '', - RideDetail.as_view(), - name='detail' - ), - path( - 'update/', - RideUpdate.as_view(), - name='update' - ), - path( - 'delete/', - RideDelete.as_view(), - name='delete' - ), - ]) - ) ] diff --git a/src/rideshare/views.py b/src/rideshare/views.py index 3f5ab9fe..563e96aa 100644 --- a/src/rideshare/views.py +++ b/src/rideshare/views.py @@ -19,7 +19,9 @@ from .models import Ride class ContactRideForm(forms.Form): message = forms.CharField( - widget=forms.Textarea(attrs={"placeholder": "Remember to include your contact information!"}), + widget=forms.Textarea( + attrs={"placeholder": "Remember to include your contact information!"} + ), label="Write a message to this rideshare", help_text="ATTENTION!: Pressing send will send an email with the above text. It is up to you to include your contact information so the person receiving the email can contact you.", ) @@ -34,7 +36,7 @@ class RideDetail(LoginRequiredMixin, CampViewMixin, DetailView): def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) - context['form'] = ContactRideForm() + context["form"] = ContactRideForm() return context def post(self, request, **kwargs): @@ -42,16 +44,16 @@ class RideDetail(LoginRequiredMixin, CampViewMixin, DetailView): if form.is_valid(): ride = self.get_object() add_outgoing_email( - text_template='rideshare/emails/contact_mail.txt', + text_template="rideshare/emails/contact_mail.txt", to_recipients=[ride.user.emailaddress_set.get(primary=True).email], formatdict=dict( rideshare_url="https://bornhack.dk{}".format( reverse( - 'rideshare:detail', - kwargs={"camp_slug": self.camp.slug, "pk": ride.pk} + "rideshare:detail", + kwargs={"camp_slug": self.camp.slug, "pk": ride.pk}, ) ), - message=form.cleaned_data['message'], + message=form.cleaned_data["message"], ), subject="BornHack rideshare message!", ) @@ -61,7 +63,7 @@ class RideDetail(LoginRequiredMixin, CampViewMixin, DetailView): class RideCreate(LoginRequiredMixin, CampViewMixin, CreateView): model = Ride - fields = ['location', 'when', 'seats', 'description'] + fields = ["location", "when", "seats", "description"] def form_valid(self, form, **kwargs): ride = form.save(commit=False) @@ -79,11 +81,11 @@ class IsRideOwnerMixin(UserPassesTestMixin): class RideUpdate(LoginRequiredMixin, CampViewMixin, IsRideOwnerMixin, UpdateView): model = Ride - fields = ['location', 'when', 'seats', 'description'] + fields = ["location", "when", "seats", "description"] class RideDelete(LoginRequiredMixin, CampViewMixin, IsRideOwnerMixin, DeleteView): model = Ride def get_success_url(self): - return reverse('rideshare:list', kwargs={'camp_slug': self.camp.slug}) + return reverse("rideshare:list", kwargs={"camp_slug": self.camp.slug}) diff --git a/src/shop/__init__.py b/src/shop/__init__.py index 2da9e616..69ed65e7 100644 --- a/src/shop/__init__.py +++ b/src/shop/__init__.py @@ -1,2 +1 @@ -default_app_config = 'shop.apps.ShopConfig' - +default_app_config = "shop.apps.ShopConfig" diff --git a/src/shop/admin.py b/src/shop/admin.py index 0a226834..c996a98c 100644 --- a/src/shop/admin.py +++ b/src/shop/admin.py @@ -25,99 +25,85 @@ admin.site.register(CoinifyAPIRequest) @admin.register(Invoice) class InvoiceAdmin(admin.ModelAdmin): - list_display = [ - 'id', - 'order', - 'customorder', - 'created', - 'updated', - ] + list_display = ["id", "order", "customorder", "created", "updated"] @admin.register(CreditNote) class CreditNoteAdmin(admin.ModelAdmin): list_display = [ - 'id', - 'user', - 'customer', - 'amount', - 'vat', - 'paid', - 'created', - 'updated', + "id", + "user", + "customer", + "amount", + "vat", + "paid", + "created", + "updated", ] - list_filter = [ - 'paid' - ] + list_filter = ["paid"] @admin.register(CustomOrder) class CustomOrderAdmin(admin.ModelAdmin): list_display = [ - 'id', - 'customer', - 'text', - 'amount', - 'vat', - 'paid', - 'created', - 'updated', + "id", + "customer", + "text", + "amount", + "vat", + "paid", + "created", + "updated", ] - list_filter = [ - 'paid', - ] + list_filter = ["paid"] @admin.register(ProductCategory) class ProductCategoryAdmin(admin.ModelAdmin): - list_display = [ - 'name', - ] + list_display = ["name"] def available_from(product): if product.available_in.lower: return product.available_in.lower.strftime("%c") return "None" -available_from.short_description = 'Available from' + + +available_from.short_description = "Available from" def available_to(product): if product.available_in.upper: return product.available_in.upper.strftime("%c") return "None" -available_to.short_description = 'Available to' + + +available_to.short_description = "Available to" def stock_info(product): if product.stock_amount: - return "{} / {}".format( - product.left_in_stock, - product.stock_amount - ) + return "{} / {}".format(product.left_in_stock, product.stock_amount) return "N/A" @admin.register(Product) class ProductAdmin(admin.ModelAdmin): list_display = [ - 'name', - 'category', - 'ticket_type', - 'price', + "name", + "category", + "ticket_type", + "price", stock_info, available_from, - available_to + available_to, ] - list_filter = [ - 'category', - 'ticket_type', - ] + list_filter = ["category", "ticket_type"] - search_fields = ['name'] + search_fields = ["name"] class ProductInline(admin.TabularInline): @@ -126,59 +112,55 @@ class ProductInline(admin.TabularInline): @admin.register(Order) class OrderAdmin(admin.ModelAdmin): - change_form_template = 'admin/change_order_form.html' - readonly_fields = ( - 'paid', - 'created', - 'updated', - ) + change_form_template = "admin/change_order_form.html" + readonly_fields = ("paid", "created", "updated") def get_email(self, obj): return obj.user.email list_display = [ - 'id', - 'created', - 'updated', - 'user', - 'get_email', - 'total', - 'payment_method', - 'open', - 'paid', - 'cancelled', - 'refunded', + "id", + "created", + "updated", + "user", + "get_email", + "total", + "payment_method", + "open", + "paid", + "cancelled", + "refunded", ] - list_filter = [ - 'payment_method', - 'open', - 'paid', - 'cancelled', - 'refunded', - 'user', - ] + list_filter = ["payment_method", "open", "paid", "cancelled", "refunded", "user"] - exclude = ['products'] + exclude = ["products"] inlines = [ProductInline, ShopTicketInline] - actions = ['mark_order_as_paid', 'mark_order_as_refunded', 'mark_order_as_cancelled'] + actions = [ + "mark_order_as_paid", + "mark_order_as_refunded", + "mark_order_as_cancelled", + ] def mark_order_as_paid(self, request, queryset): for order in queryset.filter(paid=False): order.mark_as_paid(request) - mark_order_as_paid.description = 'Mark order(s) as paid' + + mark_order_as_paid.description = "Mark order(s) as paid" def mark_order_as_refunded(self, request, queryset): for order in queryset.filter(refunded=False): order.mark_as_refunded(request) - mark_order_as_refunded.description = 'Mark order(s) as refunded' + + mark_order_as_refunded.description = "Mark order(s) as refunded" def mark_order_as_cancelled(self, request, queryset): for order in queryset.filter(cancelled=False): order.mark_as_cancelled(request) - mark_order_as_cancelled.description = 'Mark order(s) as cancelled' + + mark_order_as_cancelled.description = "Mark order(s) as cancelled" def get_user_email(obj): diff --git a/src/shop/apps.py b/src/shop/apps.py index 8e6d60e7..ba662fe9 100644 --- a/src/shop/apps.py +++ b/src/shop/apps.py @@ -1,8 +1,8 @@ from django.apps import AppConfig import logging + logger = logging.getLogger("bornhack.%s" % __name__) class ShopConfig(AppConfig): - name = 'shop' - + name = "shop" diff --git a/src/shop/coinify.py b/src/shop/coinify.py index c5a9e43b..86549071 100644 --- a/src/shop/coinify.py +++ b/src/shop/coinify.py @@ -11,15 +11,11 @@ logger = logging.getLogger("bornhack.%s" % __name__) def process_coinify_invoice_json(invoicejson, order, request): # create or update the invoice object in our database coinifyinvoice, created = CoinifyAPIInvoice.objects.update_or_create( - coinify_id=invoicejson['id'], - order=order, - defaults={ - 'invoicejson': invoicejson - }, + coinify_id=invoicejson["id"], order=order, defaults={"invoicejson": invoicejson} ) # if the order is paid in full call the mark as paid method now - if invoicejson['state'] == 'complete' and not coinifyinvoice.order.paid: + if invoicejson["state"] == "complete" and not coinifyinvoice.order.paid: coinifyinvoice.order.mark_as_paid(request=request) return coinifyinvoice @@ -29,21 +25,18 @@ def save_coinify_callback(request, order): # first make a dict with all HTTP_ headers headerdict = {} for key, value in list(request.META.items()): - if key[:5] == 'HTTP_': + if key[:5] == "HTTP_": headerdict[key[5:]] = value # now attempt to parse json try: - parsed = json.loads(request.body.decode('utf-8')) + parsed = json.loads(request.body.decode("utf-8")) except Exception: - parsed = '' + parsed = "" # save this callback to db callbackobject = CoinifyAPICallback.objects.create( - headers=headerdict, - body=request.body, - payload=parsed, - order=order, + headers=headerdict, body=request.body, payload=parsed, order=order ) return callbackobject @@ -51,10 +44,7 @@ def save_coinify_callback(request, order): def coinify_api_request(api_method, order, **kwargs): # Initiate coinify API - coinifyapi = CoinifyAPI( - settings.COINIFY_API_KEY, - settings.COINIFY_API_SECRET - ) + coinifyapi = CoinifyAPI(settings.COINIFY_API_KEY, settings.COINIFY_API_SECRET) # is this a supported method? if not hasattr(coinifyapi, api_method): @@ -74,10 +64,7 @@ def coinify_api_request(api_method, order, **kwargs): # save this API request to the database req = CoinifyAPIRequest.objects.create( - order=order, - method=api_method, - payload=kwargs, - response=response, + order=order, method=api_method, payload=kwargs, response=response ) logger.debug("saved coinify api request %s in db" % req.id) @@ -85,22 +72,19 @@ def coinify_api_request(api_method, order, **kwargs): def handle_coinify_api_response(apireq, order, request): - if apireq.method == 'invoice_create' or apireq.method == 'invoice_get': + if apireq.method == "invoice_create" or apireq.method == "invoice_get": # Parse api response - if apireq.response['success']: + if apireq.response["success"]: # save this new coinify invoice to the DB coinifyinvoice = process_coinify_invoice_json( - invoicejson=apireq.response['data'], - order=order, - request=request, + invoicejson=apireq.response["data"], order=order, request=request ) return coinifyinvoice else: - api_error = apireq.response['error'] - logger.error("coinify API error: %s (%s)" % ( - api_error['message'], - api_error['code'] - )) + api_error = apireq.response["error"] + logger.error( + "coinify API error: %s (%s)" % (api_error["message"], api_error["code"]) + ) return False else: logger.error("coinify api method not supported" % apireq.method) @@ -112,16 +96,10 @@ def handle_coinify_api_response(apireq, order, request): def get_coinify_invoice(coinify_invoiceid, order, request): # put args for API request together - invoicedict = { - 'invoice_id': coinify_invoiceid - } + invoicedict = {"invoice_id": coinify_invoiceid} # perform the api request - apireq = coinify_api_request( - api_method='invoice_get', - order=order, - **invoicedict - ) + apireq = coinify_api_request(api_method="invoice_get", order=order, **invoicedict) coinifyinvoice = handle_coinify_api_response(apireq, order, request) return coinifyinvoice @@ -130,23 +108,20 @@ def get_coinify_invoice(coinify_invoiceid, order, request): def create_coinify_invoice(order, request): # put args for API request together invoicedict = { - 'amount': float(order.total), - 'currency': 'DKK', - 'plugin_name': 'BornHack webshop', - 'plugin_version': '1.0', - 'description': 'BornHack order id #%s' % order.id, - 'callback_url': order.get_coinify_callback_url(request), - 'return_url': order.get_coinify_thanks_url(request), - 'cancel_url': order.get_cancel_url(request), + "amount": float(order.total), + "currency": "DKK", + "plugin_name": "BornHack webshop", + "plugin_version": "1.0", + "description": "BornHack order id #%s" % order.id, + "callback_url": order.get_coinify_callback_url(request), + "return_url": order.get_coinify_thanks_url(request), + "cancel_url": order.get_cancel_url(request), } # perform the API request apireq = coinify_api_request( - api_method='invoice_create', - order=order, - **invoicedict + api_method="invoice_create", order=order, **invoicedict ) coinifyinvoice = handle_coinify_api_response(apireq, order, request) return coinifyinvoice - diff --git a/src/shop/context_processors.py b/src/shop/context_processors.py index ec572d80..3a36f960 100644 --- a/src/shop/context_processors.py +++ b/src/shop/context_processors.py @@ -6,5 +6,5 @@ def current_order(request): if orders: order = orders[0] - return {'current_order': order} + return {"current_order": order} return {} diff --git a/src/shop/email.py b/src/shop/email.py index ba1edef5..c7bcfc9d 100644 --- a/src/shop/email.py +++ b/src/shop/email.py @@ -1,53 +1,52 @@ from utils.email import add_outgoing_email import logging + logger = logging.getLogger("bornhack.%s" % __name__) def add_creditnote_email(creditnote): # put formatdict together - formatdict = { - 'creditnote': creditnote, - } + formatdict = {"creditnote": creditnote} - subject = 'BornHack creditnote %s' % creditnote.pk + subject = "BornHack creditnote %s" % creditnote.pk # add email to outgoing email queue return add_outgoing_email( - text_template='emails/creditnote_email.txt', - html_template='emails/creditnote_email.html', + text_template="emails/creditnote_email.txt", + html_template="emails/creditnote_email.html", to_recipients=creditnote.user.email, formatdict=formatdict, subject=subject, attachment=creditnote.pdf.read(), - attachment_filename=creditnote.filename + attachment_filename=creditnote.filename, ) def add_invoice_email(invoice): # put formatdict together formatdict = { - 'ordernumber': invoice.order.pk, - 'invoicenumber': invoice.pk, - 'filename': invoice.filename, + "ordernumber": invoice.order.pk, + "invoicenumber": invoice.pk, + "filename": invoice.filename, } - subject = 'BornHack invoice %s' % invoice.pk + subject = "BornHack invoice %s" % invoice.pk # add email to outgoing email queue return add_outgoing_email( - text_template='emails/invoice_email.txt', - html_template='emails/invoice_email.html', + text_template="emails/invoice_email.txt", + html_template="emails/invoice_email.html", to_recipients=invoice.order.user.email, formatdict=formatdict, subject=subject, attachment=invoice.pdf.read(), - attachment_filename=invoice.filename + attachment_filename=invoice.filename, ) def add_test_email(recipient): return add_outgoing_email( - text_template='emails/testmail.txt', + text_template="emails/testmail.txt", to_recipients=recipient, - subject='testmail from bornhack website' + subject="testmail from bornhack website", ) diff --git a/src/shop/epay.py b/src/shop/epay.py index 764cec28..efca5af6 100644 --- a/src/shop/epay.py +++ b/src/shop/epay.py @@ -4,28 +4,28 @@ from django.conf import settings def calculate_epay_hash(order, request): hashstring = ( - '{merchant_number}{description}11{amount}DKK' - '{order_id}{accept_url}{cancel_url}{callback_url}{md5_secret}' + "{merchant_number}{description}11{amount}DKK" + "{order_id}{accept_url}{cancel_url}{callback_url}{md5_secret}" ).format( merchant_number=settings.EPAY_MERCHANT_NUMBER, description=order.description, - amount=order.total*100, + amount=order.total * 100, order_id=order.pk, accept_url=order.get_epay_accept_url(request), cancel_url=order.get_cancel_url(request), callback_url=order.get_epay_callback_url(request), md5_secret=settings.EPAY_MD5_SECRET, ) - epay_hash = hashlib.md5(hashstring.encode('utf-8')).hexdigest() + epay_hash = hashlib.md5(hashstring.encode("utf-8")).hexdigest() return epay_hash def validate_epay_callback(query): - hashstring = '' + hashstring = "" for key, value in query.items(): - if key != 'hash': + if key != "hash": hashstring += value hash = hashlib.md5( - (hashstring + settings.EPAY_MD5_SECRET).encode('utf-8') + (hashstring + settings.EPAY_MD5_SECRET).encode("utf-8") ).hexdigest() - return hash == query['hash'] + return hash == query["hash"] diff --git a/src/shop/invoiceworker.py b/src/shop/invoiceworker.py index e3d210bb..bbc9df07 100644 --- a/src/shop/invoiceworker.py +++ b/src/shop/invoiceworker.py @@ -4,8 +4,9 @@ from utils.pdf import generate_pdf_letter from shop.email import add_invoice_email, add_creditnote_email from shop.models import Order, CustomOrder, Invoice, CreditNote import logging + logging.basicConfig(level=logging.INFO) -logger = logging.getLogger('bornhack.%s' % __name__) +logger = logging.getLogger("bornhack.%s" % __name__) def do_work(): @@ -19,37 +20,40 @@ def do_work(): for order in Order.objects.filter(paid=True, invoice__isnull=True): # generate invoice for this Order Invoice.objects.create(order=order) - logger.info('Generated Invoice object for %s' % order) + logger.info("Generated Invoice object for %s" % order) # check if we need to generate any invoices for custom orders for customorder in CustomOrder.objects.filter(invoice__isnull=True): # generate invoice for this CustomOrder Invoice.objects.create(customorder=customorder) - logger.info('Generated Invoice object for %s' % customorder) + logger.info("Generated Invoice object for %s" % customorder) # check if we need to generate any pdf invoices - for invoice in Invoice.objects.filter(pdf=''): + for invoice in Invoice.objects.filter(pdf=""): # generate the pdf try: if invoice.customorder: - template = 'pdf/custominvoice.html' + template = "pdf/custominvoice.html" else: - template = 'pdf/invoice.html' + template = "pdf/invoice.html" pdffile = generate_pdf_letter( filename=invoice.filename, template=template, formatdict={ - 'invoice': invoice, - 'bank': settings.BANKACCOUNT_BANK, - 'bank_iban': settings.BANKACCOUNT_IBAN, - 'bank_bic': settings.BANKACCOUNT_SWIFTBIC, - 'bank_dk_reg': settings.BANKACCOUNT_REG, - 'bank_dk_accno': settings.BANKACCOUNT_ACCOUNT, + "invoice": invoice, + "bank": settings.BANKACCOUNT_BANK, + "bank_iban": settings.BANKACCOUNT_IBAN, + "bank_bic": settings.BANKACCOUNT_SWIFTBIC, + "bank_dk_reg": settings.BANKACCOUNT_REG, + "bank_dk_accno": settings.BANKACCOUNT_ACCOUNT, }, ) - logger.info('Generated pdf for invoice %s' % invoice) + logger.info("Generated pdf for invoice %s" % invoice) except Exception as E: - logger.exception('Unable to generate PDF file for invoice #%s. Error: %s' % (invoice.pk, E)) + logger.exception( + "Unable to generate PDF file for invoice #%s. Error: %s" + % (invoice.pk, E) + ) continue # update invoice object with the file @@ -57,36 +61,41 @@ def do_work(): invoice.save() # check if we need to send out any invoices (only for shop orders, and only where pdf has been generated) - for invoice in Invoice.objects.filter(order__isnull=False, sent_to_customer=False).exclude(pdf=''): + for invoice in Invoice.objects.filter( + order__isnull=False, sent_to_customer=False + ).exclude(pdf=""): logger.info("found unmailed Invoice object: %s" % invoice) # add email to the outgoing email queue if add_invoice_email(invoice=invoice): invoice.sent_to_customer = True invoice.save() - logger.info('OK: Invoice email to {} added to queue.'.format( - invoice.order.user.email) + logger.info( + "OK: Invoice email to {} added to queue.".format( + invoice.order.user.email + ) ) else: - logger.error('Unable to add email for invoice {} to {}'.format( - invoice.pk, - invoice.order.user.email + logger.error( + "Unable to add email for invoice {} to {}".format( + invoice.pk, invoice.order.user.email ) ) # check if we need to generate any pdf creditnotes? - for creditnote in CreditNote.objects.filter(pdf=''): + for creditnote in CreditNote.objects.filter(pdf=""): # generate the pdf try: pdffile = generate_pdf_letter( filename=creditnote.filename, - template='pdf/creditnote.html', - formatdict={ - 'creditnote': creditnote, - }, + template="pdf/creditnote.html", + formatdict={"creditnote": creditnote}, ) - logger.info('Generated pdf for creditnote %s' % creditnote) + logger.info("Generated pdf for creditnote %s" % creditnote) except Exception as E: - logger.exception('Unable to generate PDF file for creditnote #%s. Error: %s' % (creditnote.pk, E)) + logger.exception( + "Unable to generate PDF file for creditnote #%s. Error: %s" + % (creditnote.pk, E) + ) continue # update creditnote object with the file @@ -94,12 +103,18 @@ def do_work(): creditnote.save() # check if we need to send out any creditnotes (only where pdf has been generated and only for creditnotes linked to a user) - for creditnote in CreditNote.objects.filter(sent_to_customer=False).exclude(pdf='').exclude(user=None): + for creditnote in ( + CreditNote.objects.filter(sent_to_customer=False) + .exclude(pdf="") + .exclude(user=None) + ): # send the email if add_creditnote_email(creditnote=creditnote): - logger.info('OK: Creditnote email to %s added' % creditnote.user.email) + logger.info("OK: Creditnote email to %s added" % creditnote.user.email) creditnote.sent_to_customer = True creditnote.save() else: - logger.error('Unable to add creditnote email for creditnote %s to %s' % (creditnote.pk, creditnote.user.email)) - + logger.error( + "Unable to add creditnote email for creditnote %s to %s" + % (creditnote.pk, creditnote.user.email) + ) diff --git a/src/shop/managers.py b/src/shop/managers.py index db8e3920..278eb068 100644 --- a/src/shop/managers.py +++ b/src/shop/managers.py @@ -3,16 +3,11 @@ from django.utils import timezone class ProductQuerySet(QuerySet): - def available(self): - return self.filter( - available_in__contains=timezone.now(), - category__public=True - ) + return self.filter(available_in__contains=timezone.now(), category__public=True) class OrderQuerySet(QuerySet): - def not_cancelled(self): return self.filter(cancelled=False) diff --git a/src/shop/migrations/0001_initial.py b/src/shop/migrations/0001_initial.py index 1166c608..4fc77a41 100644 --- a/src/shop/migrations/0001_initial.py +++ b/src/shop/migrations/0001_initial.py @@ -15,113 +15,218 @@ class Migration(migrations.Migration): initial = True dependencies = [ - ('camps', '0004_camp_ticket_sale_open'), + ("camps", "0004_camp_ticket_sale_open"), migrations.swappable_dependency(settings.AUTH_USER_MODEL), ] operations = [ migrations.CreateModel( - name='EpayCallback', + name="EpayCallback", fields=[ - ('created', models.DateTimeField(auto_now_add=True)), - ('updated', models.DateTimeField(auto_now=True)), - ('uuid', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)), - ('payload', django.contrib.postgres.fields.jsonb.JSONField()), + ("created", models.DateTimeField(auto_now_add=True)), + ("updated", models.DateTimeField(auto_now=True)), + ( + "uuid", + models.UUIDField( + default=uuid.uuid4, + editable=False, + primary_key=True, + serialize=False, + ), + ), + ("payload", django.contrib.postgres.fields.jsonb.JSONField()), ], options={ - 'verbose_name': 'Epay Callback', - 'verbose_name_plural': 'Epay Callbacks', + "verbose_name": "Epay Callback", + "verbose_name_plural": "Epay Callbacks", }, ), migrations.CreateModel( - name='EpayPayment', + name="EpayPayment", fields=[ - ('created', models.DateTimeField(auto_now_add=True)), - ('updated', models.DateTimeField(auto_now=True)), - ('uuid', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)), - ('txnid', models.IntegerField()), - ('callback', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='shop.EpayCallback')), + ("created", models.DateTimeField(auto_now_add=True)), + ("updated", models.DateTimeField(auto_now=True)), + ( + "uuid", + models.UUIDField( + default=uuid.uuid4, + editable=False, + primary_key=True, + serialize=False, + ), + ), + ("txnid", models.IntegerField()), + ( + "callback", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + to="shop.EpayCallback", + ), + ), ], options={ - 'verbose_name': 'Epay Payment', - 'verbose_name_plural': 'Epay Payments', + "verbose_name": "Epay Payment", + "verbose_name_plural": "Epay Payments", }, ), migrations.CreateModel( - name='Order', + name="Order", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('created', models.DateTimeField(auto_now_add=True)), - ('updated', models.DateTimeField(auto_now=True)), - ('paid', models.BooleanField(default=False, help_text='Whether this order has been paid.', verbose_name='Paid?')), - ('payment_method', models.CharField(choices=[(b'credit_card', b'Credit card'), (b'altcoin', b'Altcoin'), (b'bank_transfer', b'Bank transfer')], default=b'credit_card', max_length=50)), - ('camp', models.ForeignKey(help_text='The camp this order is for.', on_delete=django.db.models.deletion.CASCADE, to='camps.Camp', verbose_name='Camp')), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("created", models.DateTimeField(auto_now_add=True)), + ("updated", models.DateTimeField(auto_now=True)), + ( + "paid", + models.BooleanField( + default=False, + help_text="Whether this order has been paid.", + verbose_name="Paid?", + ), + ), + ( + "payment_method", + models.CharField( + choices=[ + (b"credit_card", b"Credit card"), + (b"altcoin", b"Altcoin"), + (b"bank_transfer", b"Bank transfer"), + ], + default=b"credit_card", + max_length=50, + ), + ), + ( + "camp", + models.ForeignKey( + help_text="The camp this order is for.", + on_delete=django.db.models.deletion.CASCADE, + to="camps.Camp", + verbose_name="Camp", + ), + ), ], - options={ - 'abstract': False, - }, + options={"abstract": False}, ), migrations.CreateModel( - name='OrderProductRelation', + name="OrderProductRelation", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('quantity', models.PositiveIntegerField()), - ('order', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='shop.Order')), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("quantity", models.PositiveIntegerField()), + ( + "order", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, to="shop.Order" + ), + ), ], ), migrations.CreateModel( - name='Product', + name="Product", fields=[ - ('created', models.DateTimeField(auto_now_add=True)), - ('updated', models.DateTimeField(auto_now=True)), - ('uuid', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)), - ('name', models.CharField(max_length=150)), - ('price', models.IntegerField(help_text='Price of the ticket (in DKK).')), - ('description', models.TextField()), - ('available_in', django.contrib.postgres.fields.ranges.DateTimeRangeField(help_text='Which period is this ticket available for purchase? | (Format: YYYY-MM-DD HH:MM) | Only one of start/end is required')), + ("created", models.DateTimeField(auto_now_add=True)), + ("updated", models.DateTimeField(auto_now=True)), + ( + "uuid", + models.UUIDField( + default=uuid.uuid4, + editable=False, + primary_key=True, + serialize=False, + ), + ), + ("name", models.CharField(max_length=150)), + ( + "price", + models.IntegerField(help_text="Price of the ticket (in DKK)."), + ), + ("description", models.TextField()), + ( + "available_in", + django.contrib.postgres.fields.ranges.DateTimeRangeField( + help_text="Which period is this ticket available for purchase? | (Format: YYYY-MM-DD HH:MM) | Only one of start/end is required" + ), + ), ], options={ - 'ordering': ['available_in'], - 'verbose_name': 'Product', - 'verbose_name_plural': 'Products', + "ordering": ["available_in"], + "verbose_name": "Product", + "verbose_name_plural": "Products", }, ), migrations.CreateModel( - name='ProductCategory', + name="ProductCategory", fields=[ - ('created', models.DateTimeField(auto_now_add=True)), - ('updated', models.DateTimeField(auto_now=True)), - ('uuid', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)), - ('name', models.CharField(max_length=150)), + ("created", models.DateTimeField(auto_now_add=True)), + ("updated", models.DateTimeField(auto_now=True)), + ( + "uuid", + models.UUIDField( + default=uuid.uuid4, + editable=False, + primary_key=True, + serialize=False, + ), + ), + ("name", models.CharField(max_length=150)), ], options={ - 'verbose_name': 'Product category', - 'verbose_name_plural': 'Product categories', + "verbose_name": "Product category", + "verbose_name_plural": "Product categories", }, ), migrations.AddField( - model_name='product', - name='category', - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='shop.ProductCategory'), + model_name="product", + name="category", + field=models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, to="shop.ProductCategory" + ), ), migrations.AddField( - model_name='orderproductrelation', - name='product', - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='shop.Product'), + model_name="orderproductrelation", + name="product", + field=models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, to="shop.Product" + ), ), migrations.AddField( - model_name='order', - name='products', - field=models.ManyToManyField(through='shop.OrderProductRelation', to='shop.Product'), + model_name="order", + name="products", + field=models.ManyToManyField( + through="shop.OrderProductRelation", to="shop.Product" + ), ), migrations.AddField( - model_name='order', - name='user', - field=models.ForeignKey(help_text='The user this order belongs to.', on_delete=django.db.models.deletion.CASCADE, related_name='orders', to=settings.AUTH_USER_MODEL, verbose_name='User'), + model_name="order", + name="user", + field=models.ForeignKey( + help_text="The user this order belongs to.", + on_delete=django.db.models.deletion.CASCADE, + related_name="orders", + to=settings.AUTH_USER_MODEL, + verbose_name="User", + ), ), migrations.AddField( - model_name='epaypayment', - name='order', - field=models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to='shop.Order'), + model_name="epaypayment", + name="order", + field=models.OneToOneField( + on_delete=django.db.models.deletion.CASCADE, to="shop.Order" + ), ), ] diff --git a/src/shop/migrations/0002_orderproductrelation_handed_out.py b/src/shop/migrations/0002_orderproductrelation_handed_out.py index 457ddf97..732fb13d 100644 --- a/src/shop/migrations/0002_orderproductrelation_handed_out.py +++ b/src/shop/migrations/0002_orderproductrelation_handed_out.py @@ -7,14 +7,12 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ - ('shop', '0001_initial'), - ] + dependencies = [("shop", "0001_initial")] operations = [ migrations.AddField( - model_name='orderproductrelation', - name='handed_out', + model_name="orderproductrelation", + name="handed_out", field=models.BooleanField(default=False), - ), + ) ] diff --git a/src/shop/migrations/0003_auto_20160513_0646.py b/src/shop/migrations/0003_auto_20160513_0646.py index 8af642bd..02408d36 100644 --- a/src/shop/migrations/0003_auto_20160513_0646.py +++ b/src/shop/migrations/0003_auto_20160513_0646.py @@ -8,29 +8,41 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ - ('shop', '0002_orderproductrelation_handed_out'), - ] + dependencies = [("shop", "0002_orderproductrelation_handed_out")] operations = [ migrations.AddField( - model_name='order', - name='finalized', - field=models.BooleanField(default=False, help_text='Whether this order has been finalized.', verbose_name='Finalized?'), + model_name="order", + name="finalized", + field=models.BooleanField( + default=False, + help_text="Whether this order has been finalized.", + verbose_name="Finalized?", + ), ), migrations.AlterField( - model_name='order', - name='payment_method', - field=models.CharField(choices=[(b'credit_card', b'Credit card'), (b'blockchain', b'Blockchain'), (b'bank_transfer', b'Bank transfer')], default=b'blockchain', max_length=50), + model_name="order", + name="payment_method", + field=models.CharField( + choices=[ + (b"credit_card", b"Credit card"), + (b"blockchain", b"Blockchain"), + (b"bank_transfer", b"Bank transfer"), + ], + default=b"blockchain", + max_length=50, + ), ), migrations.AlterField( - model_name='product', - name='available_in', - field=django.contrib.postgres.fields.ranges.DateTimeRangeField(help_text='Which period is this product available for purchase? | (Format: YYYY-MM-DD HH:MM) | Only one of start/end is required'), + model_name="product", + name="available_in", + field=django.contrib.postgres.fields.ranges.DateTimeRangeField( + help_text="Which period is this product available for purchase? | (Format: YYYY-MM-DD HH:MM) | Only one of start/end is required" + ), ), migrations.AlterField( - model_name='product', - name='price', - field=models.IntegerField(help_text='Price of the product (in DKK).'), + model_name="product", + name="price", + field=models.IntegerField(help_text="Price of the product (in DKK)."), ), ] diff --git a/src/shop/migrations/0004_auto_20160515_1604.py b/src/shop/migrations/0004_auto_20160515_1604.py index b897d043..e078dbfb 100644 --- a/src/shop/migrations/0004_auto_20160515_1604.py +++ b/src/shop/migrations/0004_auto_20160515_1604.py @@ -8,20 +8,22 @@ import django.db.models.deletion class Migration(migrations.Migration): - dependencies = [ - ('shop', '0003_auto_20160513_0646'), - ] + dependencies = [("shop", "0003_auto_20160513_0646")] operations = [ migrations.AddField( - model_name='productcategory', - name='slug', - field=models.SlugField(default=''), + model_name="productcategory", + name="slug", + field=models.SlugField(default=""), preserve_default=False, ), migrations.AlterField( - model_name='product', - name='category', - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='products', to='shop.ProductCategory'), + model_name="product", + name="category", + field=models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="products", + to="shop.ProductCategory", + ), ), ] diff --git a/src/shop/migrations/0005_product_slug.py b/src/shop/migrations/0005_product_slug.py index 60045e50..be218090 100644 --- a/src/shop/migrations/0005_product_slug.py +++ b/src/shop/migrations/0005_product_slug.py @@ -7,15 +7,13 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ - ('shop', '0004_auto_20160515_1604'), - ] + dependencies = [("shop", "0004_auto_20160515_1604")] operations = [ migrations.AddField( - model_name='product', - name='slug', - field=models.SlugField(default=''), + model_name="product", + name="slug", + field=models.SlugField(default=""), preserve_default=False, - ), + ) ] diff --git a/src/shop/migrations/0006_ensure_slugs.py b/src/shop/migrations/0006_ensure_slugs.py index d287a273..3e890d00 100644 --- a/src/shop/migrations/0006_ensure_slugs.py +++ b/src/shop/migrations/0006_ensure_slugs.py @@ -6,8 +6,8 @@ from django.db import migrations def ensure_slugs(apps, schema_editor): - ProductCategory = apps.get_model('shop', 'ProductCategory') - Product = apps.get_model('shop', 'Product') + ProductCategory = apps.get_model("shop", "ProductCategory") + Product = apps.get_model("shop", "Product") for category in ProductCategory.objects.all(): category.save() @@ -18,10 +18,6 @@ def ensure_slugs(apps, schema_editor): class Migration(migrations.Migration): - dependencies = [ - ('shop', '0005_product_slug'), - ] + dependencies = [("shop", "0005_product_slug")] - operations = [ - migrations.RunPython(ensure_slugs, migrations.RunPython.noop) - ] + operations = [migrations.RunPython(ensure_slugs, migrations.RunPython.noop)] diff --git a/src/shop/migrations/0007_auto_20160515_2157.py b/src/shop/migrations/0007_auto_20160515_2157.py index a4f42bf4..7fcf1354 100644 --- a/src/shop/migrations/0007_auto_20160515_2157.py +++ b/src/shop/migrations/0007_auto_20160515_2157.py @@ -7,22 +7,20 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ - ('shop', '0006_ensure_slugs'), - ] + dependencies = [("shop", "0006_ensure_slugs")] operations = [ migrations.AddField( - model_name='order', - name='open', - field=models.NullBooleanField(default=True, help_text='Whether this order is open or not. "None" means closed.', verbose_name='Open?'), - ), - migrations.RemoveField( - model_name='order', - name='finalized', + model_name="order", + name="open", + field=models.NullBooleanField( + default=True, + help_text='Whether this order is open or not. "None" means closed.', + verbose_name="Open?", + ), ), + migrations.RemoveField(model_name="order", name="finalized"), migrations.AlterUniqueTogether( - name='order', - unique_together=set([('user', 'open')]), + name="order", unique_together=set([("user", "open")]) ), ] diff --git a/src/shop/migrations/0008_auto_20160516_0954.py b/src/shop/migrations/0008_auto_20160516_0954.py index 574a6e2d..47e81a5c 100644 --- a/src/shop/migrations/0008_auto_20160516_0954.py +++ b/src/shop/migrations/0008_auto_20160516_0954.py @@ -9,21 +9,25 @@ from django.utils.timezone import utc class Migration(migrations.Migration): - dependencies = [ - ('shop', '0007_auto_20160515_2157'), - ] + dependencies = [("shop", "0007_auto_20160515_2157")] operations = [ migrations.AddField( - model_name='orderproductrelation', - name='created', - field=models.DateTimeField(auto_now_add=True, default=datetime.datetime(2016, 5, 16, 9, 53, 59, 584701, tzinfo=utc)), + model_name="orderproductrelation", + name="created", + field=models.DateTimeField( + auto_now_add=True, + default=datetime.datetime(2016, 5, 16, 9, 53, 59, 584701, tzinfo=utc), + ), preserve_default=False, ), migrations.AddField( - model_name='orderproductrelation', - name='updated', - field=models.DateTimeField(auto_now=True, default=datetime.datetime(2016, 5, 16, 9, 54, 3, 23885, tzinfo=utc)), + model_name="orderproductrelation", + name="updated", + field=models.DateTimeField( + auto_now=True, + default=datetime.datetime(2016, 5, 16, 9, 54, 3, 23885, tzinfo=utc), + ), preserve_default=False, ), ] diff --git a/src/shop/migrations/0009_epaycallback_md5valid.py b/src/shop/migrations/0009_epaycallback_md5valid.py index a27b8e48..3e573827 100644 --- a/src/shop/migrations/0009_epaycallback_md5valid.py +++ b/src/shop/migrations/0009_epaycallback_md5valid.py @@ -7,14 +7,12 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ - ('shop', '0008_auto_20160516_0954'), - ] + dependencies = [("shop", "0008_auto_20160516_0954")] operations = [ migrations.AddField( - model_name='epaycallback', - name='md5valid', + model_name="epaycallback", + name="md5valid", field=models.BooleanField(default=False), - ), + ) ] diff --git a/src/shop/migrations/0010_auto_20160517_1313.py b/src/shop/migrations/0010_auto_20160517_1313.py index 1bb9d585..79d32ac5 100644 --- a/src/shop/migrations/0010_auto_20160517_1313.py +++ b/src/shop/migrations/0010_auto_20160517_1313.py @@ -8,31 +8,47 @@ import django.db.models.deletion class Migration(migrations.Migration): - dependencies = [ - ('shop', '0009_epaycallback_md5valid'), - ] + dependencies = [("shop", "0009_epaycallback_md5valid")] operations = [ migrations.CreateModel( - name='Invoice', + name="Invoice", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('created', models.DateTimeField(auto_now_add=True)), - ('updated', models.DateTimeField(auto_now=True)), - ('sent_to_customer', models.BooleanField(default=False)), - ('order', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to='shop.Order')), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("created", models.DateTimeField(auto_now_add=True)), + ("updated", models.DateTimeField(auto_now=True)), + ("sent_to_customer", models.BooleanField(default=False)), + ( + "order", + models.OneToOneField( + on_delete=django.db.models.deletion.CASCADE, to="shop.Order" + ), + ), ], - options={ - 'abstract': False, - }, + options={"abstract": False}, ), migrations.AlterModelOptions( - name='epaycallback', - options={'ordering': ['-created'], 'verbose_name': 'Epay Callback', 'verbose_name_plural': 'Epay Callbacks'}, + name="epaycallback", + options={ + "ordering": ["-created"], + "verbose_name": "Epay Callback", + "verbose_name_plural": "Epay Callbacks", + }, ), migrations.AddField( - model_name='product', - name='public', - field=models.BooleanField(default=True, help_text=b'Is this product publicly available in the webshop?'), + model_name="product", + name="public", + field=models.BooleanField( + default=True, + help_text=b"Is this product publicly available in the webshop?", + ), ), ] diff --git a/src/shop/migrations/0011_auto_20160517_1902.py b/src/shop/migrations/0011_auto_20160517_1902.py index aa3aa215..4112786f 100644 --- a/src/shop/migrations/0011_auto_20160517_1902.py +++ b/src/shop/migrations/0011_auto_20160517_1902.py @@ -7,18 +7,13 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ - ('shop', '0010_auto_20160517_1313'), - ] + dependencies = [("shop", "0010_auto_20160517_1313")] operations = [ - migrations.RemoveField( - model_name='product', - name='public', - ), + migrations.RemoveField(model_name="product", name="public"), migrations.AddField( - model_name='productcategory', - name='public', + model_name="productcategory", + name="public", field=models.BooleanField(default=True), ), ] diff --git a/src/shop/migrations/0012_ticket.py b/src/shop/migrations/0012_ticket.py index 77edc681..e2c711a1 100644 --- a/src/shop/migrations/0012_ticket.py +++ b/src/shop/migrations/0012_ticket.py @@ -9,22 +9,36 @@ import uuid class Migration(migrations.Migration): - dependencies = [ - ('shop', '0011_auto_20160517_1902'), - ] + dependencies = [("shop", "0011_auto_20160517_1902")] operations = [ migrations.CreateModel( - name='Ticket', + name="Ticket", fields=[ - ('created', models.DateTimeField(auto_now_add=True)), - ('updated', models.DateTimeField(auto_now=True)), - ('uuid', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)), - ('order', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='shop.Order')), - ('product', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='shop.Product')), + ("created", models.DateTimeField(auto_now_add=True)), + ("updated", models.DateTimeField(auto_now=True)), + ( + "uuid", + models.UUIDField( + default=uuid.uuid4, + editable=False, + primary_key=True, + serialize=False, + ), + ), + ( + "order", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, to="shop.Order" + ), + ), + ( + "product", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, to="shop.Product" + ), + ), ], - options={ - 'abstract': False, - }, - ), + options={"abstract": False}, + ) ] diff --git a/src/shop/migrations/0013_ticket_qrcode_base64.py b/src/shop/migrations/0013_ticket_qrcode_base64.py index 50b1ee3b..2c053741 100644 --- a/src/shop/migrations/0013_ticket_qrcode_base64.py +++ b/src/shop/migrations/0013_ticket_qrcode_base64.py @@ -7,14 +7,12 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ - ('shop', '0012_ticket'), - ] + dependencies = [("shop", "0012_ticket")] operations = [ migrations.AddField( - model_name='ticket', - name='qrcode_base64', + model_name="ticket", + name="qrcode_base64", field=models.TextField(blank=True, null=True), - ), + ) ] diff --git a/src/shop/migrations/0014_ticket_name.py b/src/shop/migrations/0014_ticket_name.py index eca8266e..970597de 100644 --- a/src/shop/migrations/0014_ticket_name.py +++ b/src/shop/migrations/0014_ticket_name.py @@ -7,15 +7,17 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ - ('shop', '0013_ticket_qrcode_base64'), - ] + dependencies = [("shop", "0013_ticket_qrcode_base64")] operations = [ migrations.AddField( - model_name='ticket', - name='name', - field=models.CharField(default='', help_text=b'Name of the person this ticket belongs to. This can be different from the buying user.', max_length=100), + model_name="ticket", + name="name", + field=models.CharField( + default="", + help_text=b"Name of the person this ticket belongs to. This can be different from the buying user.", + max_length=100, + ), preserve_default=False, - ), + ) ] diff --git a/src/shop/migrations/0015_coinifyapiinvoice_coinifycallback.py b/src/shop/migrations/0015_coinifyapiinvoice_coinifycallback.py index 7c43860a..f5f9a11e 100644 --- a/src/shop/migrations/0015_coinifyapiinvoice_coinifycallback.py +++ b/src/shop/migrations/0015_coinifyapiinvoice_coinifycallback.py @@ -9,35 +9,55 @@ import django.db.models.deletion class Migration(migrations.Migration): - dependencies = [ - ('shop', '0014_ticket_name'), - ] + dependencies = [("shop", "0014_ticket_name")] operations = [ migrations.CreateModel( - name='CoinifyAPIInvoice', + name="CoinifyAPIInvoice", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('created', models.DateTimeField(auto_now_add=True)), - ('updated', models.DateTimeField(auto_now=True)), - ('invoicejson', django.contrib.postgres.fields.jsonb.JSONField()), - ('order', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to='shop.Order')), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("created", models.DateTimeField(auto_now_add=True)), + ("updated", models.DateTimeField(auto_now=True)), + ("invoicejson", django.contrib.postgres.fields.jsonb.JSONField()), + ( + "order", + models.OneToOneField( + on_delete=django.db.models.deletion.CASCADE, to="shop.Order" + ), + ), ], - options={ - 'abstract': False, - }, + options={"abstract": False}, ), migrations.CreateModel( - name='CoinifyCallback', + name="CoinifyCallback", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('created', models.DateTimeField(auto_now_add=True)), - ('updated', models.DateTimeField(auto_now=True)), - ('payload', django.contrib.postgres.fields.jsonb.JSONField()), - ('order', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='shop.Order')), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("created", models.DateTimeField(auto_now_add=True)), + ("updated", models.DateTimeField(auto_now=True)), + ("payload", django.contrib.postgres.fields.jsonb.JSONField()), + ( + "order", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, to="shop.Order" + ), + ), ], - options={ - 'abstract': False, - }, + options={"abstract": False}, ), ] diff --git a/src/shop/migrations/0016_auto_20160529_1122.py b/src/shop/migrations/0016_auto_20160529_1122.py index 3cafe063..11ba2595 100644 --- a/src/shop/migrations/0016_auto_20160529_1122.py +++ b/src/shop/migrations/0016_auto_20160529_1122.py @@ -8,20 +8,18 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ - ('shop', '0015_coinifyapiinvoice_coinifycallback'), - ] + dependencies = [("shop", "0015_coinifyapiinvoice_coinifycallback")] operations = [ migrations.AddField( - model_name='coinifycallback', - name='headers', + model_name="coinifycallback", + name="headers", field=django.contrib.postgres.fields.jsonb.JSONField(default=None), preserve_default=False, ), migrations.AddField( - model_name='coinifycallback', - name='valid', + model_name="coinifycallback", + name="valid", field=models.BooleanField(default=False), ), ] diff --git a/src/shop/migrations/0017_auto_20160529_1626.py b/src/shop/migrations/0017_auto_20160529_1626.py index c20b0376..760b3095 100644 --- a/src/shop/migrations/0017_auto_20160529_1626.py +++ b/src/shop/migrations/0017_auto_20160529_1626.py @@ -7,13 +7,8 @@ from django.db import migrations class Migration(migrations.Migration): - dependencies = [ - ('shop', '0016_auto_20160529_1122'), - ] + dependencies = [("shop", "0016_auto_20160529_1122")] operations = [ - migrations.AlterModelOptions( - name='order', - options={'ordering': ['-created']}, - ), + migrations.AlterModelOptions(name="order", options={"ordering": ["-created"]}) ] diff --git a/src/shop/migrations/0018_auto_20160529_1736.py b/src/shop/migrations/0018_auto_20160529_1736.py index 141ccb87..ccfb3590 100644 --- a/src/shop/migrations/0018_auto_20160529_1736.py +++ b/src/shop/migrations/0018_auto_20160529_1736.py @@ -7,13 +7,10 @@ from django.db import migrations class Migration(migrations.Migration): - dependencies = [ - ('shop', '0017_auto_20160529_1626'), - ] + dependencies = [("shop", "0017_auto_20160529_1626")] operations = [ migrations.RenameModel( - old_name='CoinifyCallback', - new_name='CoinifyAPICallback', - ), + old_name="CoinifyCallback", new_name="CoinifyAPICallback" + ) ] diff --git a/src/shop/migrations/0019_invoice_pdf_generated.py b/src/shop/migrations/0019_invoice_pdf_generated.py index d1fa0564..f9edfaa8 100644 --- a/src/shop/migrations/0019_invoice_pdf_generated.py +++ b/src/shop/migrations/0019_invoice_pdf_generated.py @@ -7,14 +7,12 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ - ('shop', '0018_auto_20160529_1736'), - ] + dependencies = [("shop", "0018_auto_20160529_1736")] operations = [ migrations.AddField( - model_name='invoice', - name='pdf_generated', + model_name="invoice", + name="pdf_generated", field=models.BooleanField(default=False), - ), + ) ] diff --git a/src/shop/migrations/0020_auto_20160530_1824.py b/src/shop/migrations/0020_auto_20160530_1824.py index 436d6306..8a1b1645 100644 --- a/src/shop/migrations/0020_auto_20160530_1824.py +++ b/src/shop/migrations/0020_auto_20160530_1824.py @@ -7,18 +7,13 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ - ('shop', '0019_invoice_pdf_generated'), - ] + dependencies = [("shop", "0019_invoice_pdf_generated")] operations = [ - migrations.RemoveField( - model_name='invoice', - name='pdf_generated', - ), + migrations.RemoveField(model_name="invoice", name="pdf_generated"), migrations.AddField( - model_name='invoice', - name='pdf', - field=models.FileField(blank=True, null=True, upload_to=b'invoices/'), + model_name="invoice", + name="pdf", + field=models.FileField(blank=True, null=True, upload_to=b"invoices/"), ), ] diff --git a/src/shop/migrations/0021_ticket_email.py b/src/shop/migrations/0021_ticket_email.py index d49ca6da..5f7b79e9 100644 --- a/src/shop/migrations/0021_ticket_email.py +++ b/src/shop/migrations/0021_ticket_email.py @@ -7,14 +7,12 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ - ('shop', '0020_auto_20160530_1824'), - ] + dependencies = [("shop", "0020_auto_20160530_1824")] operations = [ migrations.AddField( - model_name='ticket', - name='email', + model_name="ticket", + name="email", field=models.EmailField(blank=True, max_length=254, null=True), - ), + ) ] diff --git a/src/shop/migrations/0022_auto_20160530_2301.py b/src/shop/migrations/0022_auto_20160530_2301.py index e8a6b834..60418a7e 100644 --- a/src/shop/migrations/0022_auto_20160530_2301.py +++ b/src/shop/migrations/0022_auto_20160530_2301.py @@ -8,24 +8,35 @@ import django.db.models.deletion class Migration(migrations.Migration): - dependencies = [ - ('shop', '0021_ticket_email'), - ] + dependencies = [("shop", "0021_ticket_email")] operations = [ migrations.AlterField( - model_name='ticket', - name='name', - field=models.CharField(blank=True, help_text=b'Name of the person this ticket belongs to. This can be different from the buying user.', max_length=100, null=True), + model_name="ticket", + name="name", + field=models.CharField( + blank=True, + help_text=b"Name of the person this ticket belongs to. This can be different from the buying user.", + max_length=100, + null=True, + ), ), migrations.AlterField( - model_name='ticket', - name='order', - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='tickets', to='shop.Order'), + model_name="ticket", + name="order", + field=models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="tickets", + to="shop.Order", + ), ), migrations.AlterField( - model_name='ticket', - name='product', - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='tickets', to='shop.Product'), + model_name="ticket", + name="product", + field=models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="tickets", + to="shop.Product", + ), ), ] diff --git a/src/shop/migrations/0023_order_cancelled.py b/src/shop/migrations/0023_order_cancelled.py index 012a62ba..1210e060 100644 --- a/src/shop/migrations/0023_order_cancelled.py +++ b/src/shop/migrations/0023_order_cancelled.py @@ -7,14 +7,12 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ - ('shop', '0022_auto_20160530_2301'), - ] + dependencies = [("shop", "0022_auto_20160530_2301")] operations = [ migrations.AddField( - model_name='order', - name='cancelled', + model_name="order", + name="cancelled", field=models.BooleanField(default=False), - ), + ) ] diff --git a/src/shop/migrations/0024_auto_20160605_2126.py b/src/shop/migrations/0024_auto_20160605_2126.py index f081627a..9764b42a 100644 --- a/src/shop/migrations/0024_auto_20160605_2126.py +++ b/src/shop/migrations/0024_auto_20160605_2126.py @@ -7,18 +7,28 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ - ('shop', '0023_order_cancelled'), - ] + dependencies = [("shop", "0023_order_cancelled")] operations = [ migrations.AlterModelOptions( - name='product', - options={'ordering': ['available_in', 'price'], 'verbose_name': 'Product', 'verbose_name_plural': 'Products'}, + name="product", + options={ + "ordering": ["available_in", "price"], + "verbose_name": "Product", + "verbose_name_plural": "Products", + }, ), migrations.AlterField( - model_name='order', - name='payment_method', - field=models.CharField(choices=[(b'credit_card', b'Credit card'), (b'blockchain', b'Blockchain'), (b'bank_transfer', b'Bank transfer')], default=b'', max_length=50), + model_name="order", + name="payment_method", + field=models.CharField( + choices=[ + (b"credit_card", b"Credit card"), + (b"blockchain", b"Blockchain"), + (b"bank_transfer", b"Bank transfer"), + ], + default=b"", + max_length=50, + ), ), ] diff --git a/src/shop/migrations/0025_creditnote.py b/src/shop/migrations/0025_creditnote.py index 76c7ccee..0da4f0a6 100644 --- a/src/shop/migrations/0025_creditnote.py +++ b/src/shop/migrations/0025_creditnote.py @@ -11,25 +11,50 @@ class Migration(migrations.Migration): dependencies = [ migrations.swappable_dependency(settings.AUTH_USER_MODEL), - ('shop', '0024_auto_20160605_2126'), + ("shop", "0024_auto_20160605_2126"), ] operations = [ migrations.CreateModel( - name='CreditNote', + name="CreditNote", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('created', models.DateTimeField(auto_now_add=True)), - ('updated', models.DateTimeField(auto_now=True)), - ('amount', models.DecimalField(decimal_places=2, max_digits=10)), - ('text', models.TextField()), - ('pdf', models.FileField(blank=True, null=True, upload_to=b'creditnotes/')), - ('paid', models.BooleanField(default=False, help_text='Whether this creditnote has been paid.', verbose_name='Paid?')), - ('sent_to_customer', models.BooleanField(default=False)), - ('user', models.ForeignKey(help_text='The user this credit note belongs to.', on_delete=django.db.models.deletion.CASCADE, related_name='creditnotes', to=settings.AUTH_USER_MODEL, verbose_name='User')), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("created", models.DateTimeField(auto_now_add=True)), + ("updated", models.DateTimeField(auto_now=True)), + ("amount", models.DecimalField(decimal_places=2, max_digits=10)), + ("text", models.TextField()), + ( + "pdf", + models.FileField(blank=True, null=True, upload_to=b"creditnotes/"), + ), + ( + "paid", + models.BooleanField( + default=False, + help_text="Whether this creditnote has been paid.", + verbose_name="Paid?", + ), + ), + ("sent_to_customer", models.BooleanField(default=False)), + ( + "user", + models.ForeignKey( + help_text="The user this credit note belongs to.", + on_delete=django.db.models.deletion.CASCADE, + related_name="creditnotes", + to=settings.AUTH_USER_MODEL, + verbose_name="User", + ), + ), ], - options={ - 'abstract': False, - }, - ), + options={"abstract": False}, + ) ] diff --git a/src/shop/migrations/0026_order_refunded.py b/src/shop/migrations/0026_order_refunded.py index 5cbd9599..31798b55 100644 --- a/src/shop/migrations/0026_order_refunded.py +++ b/src/shop/migrations/0026_order_refunded.py @@ -7,14 +7,16 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ - ('shop', '0025_creditnote'), - ] + dependencies = [("shop", "0025_creditnote")] operations = [ migrations.AddField( - model_name='order', - name='refunded', - field=models.BooleanField(default=False, help_text='Whether this order has been refunded.', verbose_name='Refunded?'), - ), + model_name="order", + name="refunded", + field=models.BooleanField( + default=False, + help_text="Whether this order has been refunded.", + verbose_name="Refunded?", + ), + ) ] diff --git a/src/shop/migrations/0027_auto_20160712_2036.py b/src/shop/migrations/0027_auto_20160712_2036.py index 99633251..f4ae3f30 100644 --- a/src/shop/migrations/0027_auto_20160712_2036.py +++ b/src/shop/migrations/0027_auto_20160712_2036.py @@ -10,68 +10,128 @@ import django.db.models.deletion class Migration(migrations.Migration): dependencies = [ - ('camps', '0005_auto_20160510_2011'), - ('shop', '0026_order_refunded'), + ("camps", "0005_auto_20160510_2011"), + ("shop", "0026_order_refunded"), ] operations = [ migrations.CreateModel( - name='CustomOrder', + name="CustomOrder", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('created', models.DateTimeField(auto_now_add=True)), - ('updated', models.DateTimeField(auto_now=True)), - ('text', models.TextField()), - ('amount', models.IntegerField(help_text='Amount of this custom order (in DKK, including VAT).')), - ('paid', models.BooleanField(default=False, help_text='Whether this custom order has been paid.', verbose_name='Paid?')), - ('camp', models.ForeignKey(help_text='The camp this custom order is for.', on_delete=django.db.models.deletion.CASCADE, to='camps.Camp', verbose_name='Camp')), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("created", models.DateTimeField(auto_now_add=True)), + ("updated", models.DateTimeField(auto_now=True)), + ("text", models.TextField()), + ( + "amount", + models.IntegerField( + help_text="Amount of this custom order (in DKK, including VAT)." + ), + ), + ( + "paid", + models.BooleanField( + default=False, + help_text="Whether this custom order has been paid.", + verbose_name="Paid?", + ), + ), + ( + "camp", + models.ForeignKey( + help_text="The camp this custom order is for.", + on_delete=django.db.models.deletion.CASCADE, + to="camps.Camp", + verbose_name="Camp", + ), + ), ], - options={ - 'abstract': False, - }, + options={"abstract": False}, ), migrations.AlterModelOptions( - name='creditnote', - options={'ordering': ['-created']}, + name="creditnote", options={"ordering": ["-created"]} ), migrations.AlterField( - model_name='creditnote', - name='paid', - field=models.BooleanField(default=False, help_text='Whether the amount in this creditnote has been paid back to the customer.', verbose_name='Paid?'), + model_name="creditnote", + name="paid", + field=models.BooleanField( + default=False, + help_text="Whether the amount in this creditnote has been paid back to the customer.", + verbose_name="Paid?", + ), ), migrations.AlterField( - model_name='invoice', - name='order', - field=models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='shop.Order'), + model_name="invoice", + name="order", + field=models.OneToOneField( + blank=True, + null=True, + on_delete=django.db.models.deletion.CASCADE, + to="shop.Order", + ), ), migrations.AlterField( - model_name='order', - name='camp', - field=models.ForeignKey(help_text='The camp this shop order is for.', on_delete=django.db.models.deletion.CASCADE, to='camps.Camp', verbose_name='Camp'), + model_name="order", + name="camp", + field=models.ForeignKey( + help_text="The camp this shop order is for.", + on_delete=django.db.models.deletion.CASCADE, + to="camps.Camp", + verbose_name="Camp", + ), ), migrations.AlterField( - model_name='order', - name='open', - field=models.NullBooleanField(default=True, help_text='Whether this shop order is open or not. "None" means closed.', verbose_name='Open?'), + model_name="order", + name="open", + field=models.NullBooleanField( + default=True, + help_text='Whether this shop order is open or not. "None" means closed.', + verbose_name="Open?", + ), ), migrations.AlterField( - model_name='order', - name='paid', - field=models.BooleanField(default=False, help_text='Whether this shop order has been paid.', verbose_name='Paid?'), + model_name="order", + name="paid", + field=models.BooleanField( + default=False, + help_text="Whether this shop order has been paid.", + verbose_name="Paid?", + ), ), migrations.AlterField( - model_name='order', - name='user', - field=models.ForeignKey(help_text='The user this shop order belongs to.', on_delete=django.db.models.deletion.CASCADE, related_name='orders', to=settings.AUTH_USER_MODEL, verbose_name='User'), + model_name="order", + name="user", + field=models.ForeignKey( + help_text="The user this shop order belongs to.", + on_delete=django.db.models.deletion.CASCADE, + related_name="orders", + to=settings.AUTH_USER_MODEL, + verbose_name="User", + ), ), migrations.AlterField( - model_name='product', - name='price', - field=models.IntegerField(help_text='Price of the product (in DKK, including VAT).'), + model_name="product", + name="price", + field=models.IntegerField( + help_text="Price of the product (in DKK, including VAT)." + ), ), migrations.AddField( - model_name='invoice', - name='customorder', - field=models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='shop.CustomOrder'), + model_name="invoice", + name="customorder", + field=models.OneToOneField( + blank=True, + null=True, + on_delete=django.db.models.deletion.CASCADE, + to="shop.CustomOrder", + ), ), ] diff --git a/src/shop/migrations/0028_auto_20160712_2119.py b/src/shop/migrations/0028_auto_20160712_2119.py index ee6223bd..722e9cc8 100644 --- a/src/shop/migrations/0028_auto_20160712_2119.py +++ b/src/shop/migrations/0028_auto_20160712_2119.py @@ -7,20 +7,21 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ - ('shop', '0027_auto_20160712_2036'), - ] + dependencies = [("shop", "0027_auto_20160712_2036")] operations = [ migrations.AddField( - model_name='customorder', - name='customer', - field=models.TextField(default='', help_text='The customer info for this order, use
for newlines'), + model_name="customorder", + name="customer", + field=models.TextField( + default="", + help_text="The customer info for this order, use
for newlines", + ), preserve_default=False, ), migrations.AlterField( - model_name='customorder', - name='text', - field=models.TextField(help_text='The invoice text'), + model_name="customorder", + name="text", + field=models.TextField(help_text="The invoice text"), ), ] diff --git a/src/shop/migrations/0029_auto_20160712_2133.py b/src/shop/migrations/0029_auto_20160712_2133.py index d09693c3..4fbcb646 100644 --- a/src/shop/migrations/0029_auto_20160712_2133.py +++ b/src/shop/migrations/0029_auto_20160712_2133.py @@ -7,14 +7,12 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ - ('shop', '0028_auto_20160712_2119'), - ] + dependencies = [("shop", "0028_auto_20160712_2119")] operations = [ migrations.AlterField( - model_name='customorder', - name='customer', - field=models.TextField(help_text='The customer info for this order'), - ), + model_name="customorder", + name="customer", + field=models.TextField(help_text="The customer info for this order"), + ) ] diff --git a/src/shop/migrations/0030_auto_20160827_0752.py b/src/shop/migrations/0030_auto_20160827_0752.py index 0d62a79a..bca69d09 100644 --- a/src/shop/migrations/0030_auto_20160827_0752.py +++ b/src/shop/migrations/0030_auto_20160827_0752.py @@ -7,18 +7,20 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ - ('shop', '0029_auto_20160712_2133'), - ] + dependencies = [("shop", "0029_auto_20160712_2133")] operations = [ migrations.AlterModelOptions( - name='product', - options={'ordering': ['available_in', 'price', 'name'], 'verbose_name': 'Product', 'verbose_name_plural': 'Products'}, + name="product", + options={ + "ordering": ["available_in", "price", "name"], + "verbose_name": "Product", + "verbose_name_plural": "Products", + }, ), migrations.AddField( - model_name='ticket', - name='checked_in', + model_name="ticket", + name="checked_in", field=models.BooleanField(default=False), ), ] diff --git a/src/shop/migrations/0031_auto_20161109_1000.py b/src/shop/migrations/0031_auto_20161109_1000.py index 387db206..594b436b 100644 --- a/src/shop/migrations/0031_auto_20161109_1000.py +++ b/src/shop/migrations/0031_auto_20161109_1000.py @@ -7,14 +7,21 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ - ('shop', '0030_auto_20160827_0752'), - ] + dependencies = [("shop", "0030_auto_20160827_0752")] operations = [ migrations.AlterField( - model_name='order', - name='payment_method', - field=models.CharField(choices=[(b'credit_card', b'Credit card'), (b'blockchain', b'Blockchain'), (b'bank_transfer', b'Bank transfer'), (b'cash', b'Cash')], default=b'', max_length=50), - ), + model_name="order", + name="payment_method", + field=models.CharField( + choices=[ + (b"credit_card", b"Credit card"), + (b"blockchain", b"Blockchain"), + (b"bank_transfer", b"Bank transfer"), + (b"cash", b"Cash"), + ], + default=b"", + max_length=50, + ), + ) ] diff --git a/src/shop/migrations/0032_order_customer_comment.py b/src/shop/migrations/0032_order_customer_comment.py index 96b45fb3..4f2ab0bc 100644 --- a/src/shop/migrations/0032_order_customer_comment.py +++ b/src/shop/migrations/0032_order_customer_comment.py @@ -7,14 +7,16 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ - ('shop', '0031_auto_20161109_1000'), - ] + dependencies = [("shop", "0031_auto_20161109_1000")] operations = [ migrations.AddField( - model_name='order', - name='customer_comment', - field=models.TextField(default=b'', help_text='If you have any comments about the order please enter them here.', verbose_name='Customer comment'), - ), + model_name="order", + name="customer_comment", + field=models.TextField( + default=b"", + help_text="If you have any comments about the order please enter them here.", + verbose_name="Customer comment", + ), + ) ] diff --git a/src/shop/migrations/0033_auto_20161212_1756.py b/src/shop/migrations/0033_auto_20161212_1756.py index 74ff236d..2d94e2dd 100644 --- a/src/shop/migrations/0033_auto_20161212_1756.py +++ b/src/shop/migrations/0033_auto_20161212_1756.py @@ -7,17 +7,9 @@ from django.db import migrations class Migration(migrations.Migration): - dependencies = [ - ('shop', '0032_order_customer_comment'), - ] + dependencies = [("shop", "0032_order_customer_comment")] operations = [ - migrations.RemoveField( - model_name='customorder', - name='camp', - ), - migrations.RemoveField( - model_name='order', - name='camp', - ), + migrations.RemoveField(model_name="customorder", name="camp"), + migrations.RemoveField(model_name="order", name="camp"), ] diff --git a/src/shop/migrations/0034_auto_20170131_1849.py b/src/shop/migrations/0034_auto_20170131_1849.py index f345d341..de1e1388 100644 --- a/src/shop/migrations/0034_auto_20170131_1849.py +++ b/src/shop/migrations/0034_auto_20170131_1849.py @@ -7,34 +7,50 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ - ('shop', '0033_auto_20161212_1756'), - ] + dependencies = [("shop", "0033_auto_20161212_1756")] operations = [ migrations.AlterField( - model_name='creditnote', - name='pdf', - field=models.FileField(blank=True, null=True, upload_to='creditnotes/'), + model_name="creditnote", + name="pdf", + field=models.FileField(blank=True, null=True, upload_to="creditnotes/"), ), migrations.AlterField( - model_name='invoice', - name='pdf', - field=models.FileField(blank=True, null=True, upload_to='invoices/'), + model_name="invoice", + name="pdf", + field=models.FileField(blank=True, null=True, upload_to="invoices/"), ), migrations.AlterField( - model_name='order', - name='customer_comment', - field=models.TextField(default='', help_text='If you have any comments about the order please enter them here.', verbose_name='Customer comment'), + model_name="order", + name="customer_comment", + field=models.TextField( + default="", + help_text="If you have any comments about the order please enter them here.", + verbose_name="Customer comment", + ), ), migrations.AlterField( - model_name='order', - name='payment_method', - field=models.CharField(choices=[('credit_card', 'Credit card'), ('blockchain', 'Blockchain'), ('bank_transfer', 'Bank transfer'), ('cash', 'Cash')], default='', max_length=50), + model_name="order", + name="payment_method", + field=models.CharField( + choices=[ + ("credit_card", "Credit card"), + ("blockchain", "Blockchain"), + ("bank_transfer", "Bank transfer"), + ("cash", "Cash"), + ], + default="", + max_length=50, + ), ), migrations.AlterField( - model_name='ticket', - name='name', - field=models.CharField(blank=True, help_text='Name of the person this ticket belongs to. This can be different from the buying user.', max_length=100, null=True), + model_name="ticket", + name="name", + field=models.CharField( + blank=True, + help_text="Name of the person this ticket belongs to. This can be different from the buying user.", + max_length=100, + null=True, + ), ), ] diff --git a/src/shop/migrations/0035_auto_20170222_1629.py b/src/shop/migrations/0035_auto_20170222_1629.py index 8e28746a..08d72f3e 100644 --- a/src/shop/migrations/0035_auto_20170222_1629.py +++ b/src/shop/migrations/0035_auto_20170222_1629.py @@ -7,14 +7,17 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ - ('shop', '0034_auto_20170131_1849'), - ] + dependencies = [("shop", "0034_auto_20170131_1849")] operations = [ migrations.AlterField( - model_name='order', - name='customer_comment', - field=models.TextField(blank=True, default='', help_text='If you have any comments about the order please enter them here.', verbose_name='Customer comment'), - ), + model_name="order", + name="customer_comment", + field=models.TextField( + blank=True, + default="", + help_text="If you have any comments about the order please enter them here.", + verbose_name="Customer comment", + ), + ) ] diff --git a/src/shop/migrations/0036_auto_20170319_2155.py b/src/shop/migrations/0036_auto_20170319_2155.py index 42c69b7c..6d47d76b 100644 --- a/src/shop/migrations/0036_auto_20170319_2155.py +++ b/src/shop/migrations/0036_auto_20170319_2155.py @@ -7,14 +7,10 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ - ('shop', '0035_auto_20170222_1629'), - ] + dependencies = [("shop", "0035_auto_20170222_1629")] operations = [ migrations.AlterField( - model_name='product', - name='slug', - field=models.SlugField(unique=True), - ), + model_name="product", name="slug", field=models.SlugField(unique=True) + ) ] diff --git a/src/shop/migrations/0037_auto_20170319_2204.py b/src/shop/migrations/0037_auto_20170319_2204.py index 394f0c13..a764d9f6 100644 --- a/src/shop/migrations/0037_auto_20170319_2204.py +++ b/src/shop/migrations/0037_auto_20170319_2204.py @@ -7,14 +7,12 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ - ('shop', '0036_auto_20170319_2155'), - ] + dependencies = [("shop", "0036_auto_20170319_2155")] operations = [ migrations.AlterField( - model_name='product', - name='slug', + model_name="product", + name="slug", field=models.SlugField(max_length=100, unique=True), - ), + ) ] diff --git a/src/shop/migrations/0038_auto_20170323_2021.py b/src/shop/migrations/0038_auto_20170323_2021.py index bb761986..f7262d78 100644 --- a/src/shop/migrations/0038_auto_20170323_2021.py +++ b/src/shop/migrations/0038_auto_20170323_2021.py @@ -7,14 +7,22 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ - ('shop', '0037_auto_20170319_2204'), - ] + dependencies = [("shop", "0037_auto_20170319_2204")] operations = [ migrations.AlterField( - model_name='order', - name='payment_method', - field=models.CharField(blank=True, choices=[('credit_card', 'Credit card'), ('blockchain', 'Blockchain'), ('bank_transfer', 'Bank transfer'), ('cash', 'Cash')], default='', max_length=50), - ), + model_name="order", + name="payment_method", + field=models.CharField( + blank=True, + choices=[ + ("credit_card", "Credit card"), + ("blockchain", "Blockchain"), + ("bank_transfer", "Bank transfer"), + ("cash", "Cash"), + ], + default="", + max_length=50, + ), + ) ] diff --git a/src/shop/migrations/0039_auto_20170403_1752.py b/src/shop/migrations/0039_auto_20170403_1752.py index 9be91371..b64e34f5 100644 --- a/src/shop/migrations/0039_auto_20170403_1752.py +++ b/src/shop/migrations/0039_auto_20170403_1752.py @@ -8,19 +8,17 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ - ('shop', '0038_auto_20170323_2021'), - ] + dependencies = [("shop", "0038_auto_20170323_2021")] operations = [ migrations.AddField( - model_name='coinifyapicallback', - name='body', - field=models.TextField(default=''), + model_name="coinifyapicallback", + name="body", + field=models.TextField(default=""), ), migrations.AlterField( - model_name='coinifyapicallback', - name='payload', + model_name="coinifyapicallback", + name="payload", field=django.contrib.postgres.fields.jsonb.JSONField(null=True), ), ] diff --git a/src/shop/migrations/0040_auto_20170408_1055.py b/src/shop/migrations/0040_auto_20170408_1055.py index e258b4a9..348ff5c7 100644 --- a/src/shop/migrations/0040_auto_20170408_1055.py +++ b/src/shop/migrations/0040_auto_20170408_1055.py @@ -8,14 +8,12 @@ from django.db import migrations class Migration(migrations.Migration): - dependencies = [ - ('shop', '0039_auto_20170403_1752'), - ] + dependencies = [("shop", "0039_auto_20170403_1752")] operations = [ migrations.AlterField( - model_name='epaycallback', - name='payload', + model_name="epaycallback", + name="payload", field=django.contrib.postgres.fields.jsonb.JSONField(blank=True), - ), + ) ] diff --git a/src/shop/migrations/0041_auto_20170408_1104.py b/src/shop/migrations/0041_auto_20170408_1104.py index e455b252..da269add 100644 --- a/src/shop/migrations/0041_auto_20170408_1104.py +++ b/src/shop/migrations/0041_auto_20170408_1104.py @@ -8,20 +8,20 @@ from django.db import migrations class Migration(migrations.Migration): - dependencies = [ - ('shop', '0040_auto_20170408_1055'), - ] + dependencies = [("shop", "0040_auto_20170408_1055")] operations = [ migrations.AlterField( - model_name='coinifyapicallback', - name='payload', - field=django.contrib.postgres.fields.jsonb.JSONField(blank=True, default=''), + model_name="coinifyapicallback", + name="payload", + field=django.contrib.postgres.fields.jsonb.JSONField( + blank=True, default="" + ), preserve_default=False, ), migrations.AlterField( - model_name='epaycallback', - name='payload', + model_name="epaycallback", + name="payload", field=django.contrib.postgres.fields.jsonb.JSONField(), ), ] diff --git a/src/shop/migrations/0042_auto_20170507_1000.py b/src/shop/migrations/0042_auto_20170507_1000.py index 3bb8fe2b..b22acf73 100644 --- a/src/shop/migrations/0042_auto_20170507_1000.py +++ b/src/shop/migrations/0042_auto_20170507_1000.py @@ -8,14 +8,16 @@ import django.db.models.deletion class Migration(migrations.Migration): - dependencies = [ - ('shop', '0041_auto_20170408_1104'), - ] + dependencies = [("shop", "0041_auto_20170408_1104")] operations = [ migrations.AlterField( - model_name='coinifyapiinvoice', - name='order', - field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='coinify_api_invoices', to='shop.Order'), - ), + model_name="coinifyapiinvoice", + name="order", + field=models.ForeignKey( + on_delete=django.db.models.deletion.PROTECT, + related_name="coinify_api_invoices", + to="shop.Order", + ), + ) ] diff --git a/src/shop/migrations/0043_auto_20170507_1309.py b/src/shop/migrations/0043_auto_20170507_1309.py index 414d8af7..a7b2db45 100644 --- a/src/shop/migrations/0043_auto_20170507_1309.py +++ b/src/shop/migrations/0043_auto_20170507_1309.py @@ -9,28 +9,43 @@ import django.db.models.deletion class Migration(migrations.Migration): - dependencies = [ - ('shop', '0042_auto_20170507_1000'), - ] + dependencies = [("shop", "0042_auto_20170507_1000")] operations = [ migrations.CreateModel( - name='CoinifyAPIRequest', + name="CoinifyAPIRequest", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('created', models.DateTimeField(auto_now_add=True)), - ('updated', models.DateTimeField(auto_now=True)), - ('payload', django.contrib.postgres.fields.jsonb.JSONField()), - ('response', models.TextField()), - ('order', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='coinify_api_requests', to='shop.Order')), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("created", models.DateTimeField(auto_now_add=True)), + ("updated", models.DateTimeField(auto_now=True)), + ("payload", django.contrib.postgres.fields.jsonb.JSONField()), + ("response", models.TextField()), + ( + "order", + models.ForeignKey( + on_delete=django.db.models.deletion.PROTECT, + related_name="coinify_api_requests", + to="shop.Order", + ), + ), ], - options={ - 'abstract': False, - }, + options={"abstract": False}, ), migrations.AlterField( - model_name='coinifyapicallback', - name='order', - field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='coinify_api_callbacks', to='shop.Order'), + model_name="coinifyapicallback", + name="order", + field=models.ForeignKey( + on_delete=django.db.models.deletion.PROTECT, + related_name="coinify_api_callbacks", + to="shop.Order", + ), ), ] diff --git a/src/shop/migrations/0044_coinifyapiinvoice_coinify_id.py b/src/shop/migrations/0044_coinifyapiinvoice_coinify_id.py index 54c8a18d..083987f1 100644 --- a/src/shop/migrations/0044_coinifyapiinvoice_coinify_id.py +++ b/src/shop/migrations/0044_coinifyapiinvoice_coinify_id.py @@ -7,14 +7,12 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ - ('shop', '0043_auto_20170507_1309'), - ] + dependencies = [("shop", "0043_auto_20170507_1309")] operations = [ migrations.AddField( - model_name='coinifyapiinvoice', - name='coinify_id', + model_name="coinifyapiinvoice", + name="coinify_id", field=models.IntegerField(null=True), - ), + ) ] diff --git a/src/shop/migrations/0045_auto_20170507_1648.py b/src/shop/migrations/0045_auto_20170507_1648.py index 695e3ba4..b708040d 100644 --- a/src/shop/migrations/0045_auto_20170507_1648.py +++ b/src/shop/migrations/0045_auto_20170507_1648.py @@ -7,14 +7,10 @@ from django.db import migrations class Migration(migrations.Migration): - dependencies = [ - ('shop', '0044_coinifyapiinvoice_coinify_id'), - ] + dependencies = [("shop", "0044_coinifyapiinvoice_coinify_id")] operations = [ migrations.RenameField( - model_name='coinifyapicallback', - old_name='valid', - new_name='authenticated', - ), + model_name="coinifyapicallback", old_name="valid", new_name="authenticated" + ) ] diff --git a/src/shop/migrations/0046_coinifyapirequest_method.py b/src/shop/migrations/0046_coinifyapirequest_method.py index 2710bf59..8fb4706a 100644 --- a/src/shop/migrations/0046_coinifyapirequest_method.py +++ b/src/shop/migrations/0046_coinifyapirequest_method.py @@ -7,15 +7,13 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ - ('shop', '0045_auto_20170507_1648'), - ] + dependencies = [("shop", "0045_auto_20170507_1648")] operations = [ migrations.AddField( - model_name='coinifyapirequest', - name='method', - field=models.CharField(default='', max_length=100), + model_name="coinifyapirequest", + name="method", + field=models.CharField(default="", max_length=100), preserve_default=False, - ), + ) ] diff --git a/src/shop/migrations/0047_auto_20170522_1942.py b/src/shop/migrations/0047_auto_20170522_1942.py index ed1edaaf..d826942b 100644 --- a/src/shop/migrations/0047_auto_20170522_1942.py +++ b/src/shop/migrations/0047_auto_20170522_1942.py @@ -8,14 +8,12 @@ from django.db import migrations class Migration(migrations.Migration): - dependencies = [ - ('shop', '0046_coinifyapirequest_method'), - ] + dependencies = [("shop", "0046_coinifyapirequest_method")] operations = [ migrations.AlterField( - model_name='coinifyapirequest', - name='response', + model_name="coinifyapirequest", + name="response", field=django.contrib.postgres.fields.jsonb.JSONField(), - ), + ) ] diff --git a/src/shop/migrations/0048_product_ticket_type.py b/src/shop/migrations/0048_product_ticket_type.py index f473f593..55f2f072 100644 --- a/src/shop/migrations/0048_product_ticket_type.py +++ b/src/shop/migrations/0048_product_ticket_type.py @@ -8,15 +8,17 @@ import django.db.models.deletion class Migration(migrations.Migration): - dependencies = [ - ('tickets', '0001_initial'), - ('shop', '0047_auto_20170522_1942'), - ] + dependencies = [("tickets", "0001_initial"), ("shop", "0047_auto_20170522_1942")] operations = [ migrations.AddField( - model_name='product', - name='ticket_type', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='tickets.TicketType'), - ), + model_name="product", + name="ticket_type", + field=models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.CASCADE, + to="tickets.TicketType", + ), + ) ] diff --git a/src/shop/migrations/0049_auto_20170914_2034.py b/src/shop/migrations/0049_auto_20170914_2034.py index fb244fbf..ca1f13d4 100644 --- a/src/shop/migrations/0049_auto_20170914_2034.py +++ b/src/shop/migrations/0049_auto_20170914_2034.py @@ -7,19 +7,21 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ - ('shop', '0048_product_ticket_type'), - ] + dependencies = [("shop", "0048_product_ticket_type")] operations = [ migrations.AddField( - model_name='customorder', - name='danish_vat', - field=models.BooleanField(default=True, help_text='Danish VAT?'), + model_name="customorder", + name="danish_vat", + field=models.BooleanField(default=True, help_text="Danish VAT?"), ), migrations.AlterField( - model_name='customorder', - name='paid', - field=models.BooleanField(default=False, help_text='Check when this custom order has been paid (or if it gets cancelled out by a Credit Note)', verbose_name='Paid?'), + model_name="customorder", + name="paid", + field=models.BooleanField( + default=False, + help_text="Check when this custom order has been paid (or if it gets cancelled out by a Credit Note)", + verbose_name="Paid?", + ), ), ] diff --git a/src/shop/migrations/0050_auto_20170916_1336.py b/src/shop/migrations/0050_auto_20170916_1336.py index 2959d9ef..8856bf57 100644 --- a/src/shop/migrations/0050_auto_20170916_1336.py +++ b/src/shop/migrations/0050_auto_20170916_1336.py @@ -9,24 +9,34 @@ import django.db.models.deletion class Migration(migrations.Migration): - dependencies = [ - ('shop', '0049_auto_20170914_2034'), - ] + dependencies = [("shop", "0049_auto_20170914_2034")] operations = [ migrations.AddField( - model_name='creditnote', - name='customer', - field=models.TextField(blank=True, default='', help_text='Customer info if no user is selected'), + model_name="creditnote", + name="customer", + field=models.TextField( + blank=True, default="", help_text="Customer info if no user is selected" + ), ), migrations.AlterField( - model_name='creditnote', - name='text', - field=models.TextField(help_text='Description of what this credit note covers'), + model_name="creditnote", + name="text", + field=models.TextField( + help_text="Description of what this credit note covers" + ), ), migrations.AlterField( - model_name='creditnote', - name='user', - field=models.ForeignKey(blank=True, help_text='The user this credit note belongs to, if any.', null=True, on_delete=django.db.models.deletion.CASCADE, related_name='creditnotes', to=settings.AUTH_USER_MODEL, verbose_name='User'), + model_name="creditnote", + name="user", + field=models.ForeignKey( + blank=True, + help_text="The user this credit note belongs to, if any.", + null=True, + on_delete=django.db.models.deletion.CASCADE, + related_name="creditnotes", + to=settings.AUTH_USER_MODEL, + verbose_name="User", + ), ), ] diff --git a/src/shop/migrations/0051_creditnote_danish_vat.py b/src/shop/migrations/0051_creditnote_danish_vat.py index c2ad3508..9b7a2efe 100644 --- a/src/shop/migrations/0051_creditnote_danish_vat.py +++ b/src/shop/migrations/0051_creditnote_danish_vat.py @@ -7,14 +7,12 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ - ('shop', '0050_auto_20170916_1336'), - ] + dependencies = [("shop", "0050_auto_20170916_1336")] operations = [ migrations.AddField( - model_name='creditnote', - name='danish_vat', - field=models.BooleanField(default=True, help_text='Danish VAT?'), - ), + model_name="creditnote", + name="danish_vat", + field=models.BooleanField(default=True, help_text="Danish VAT?"), + ) ] diff --git a/src/shop/migrations/0052_auto_20171004_0005.py b/src/shop/migrations/0052_auto_20171004_0005.py index 92f85171..fcd772aa 100644 --- a/src/shop/migrations/0052_auto_20171004_0005.py +++ b/src/shop/migrations/0052_auto_20171004_0005.py @@ -7,20 +7,10 @@ from django.db import migrations class Migration(migrations.Migration): - dependencies = [ - ('shop', '0051_creditnote_danish_vat'), - ] + dependencies = [("shop", "0051_creditnote_danish_vat")] operations = [ - migrations.RemoveField( - model_name='ticket', - name='order', - ), - migrations.RemoveField( - model_name='ticket', - name='product', - ), - migrations.DeleteModel( - name='Ticket', - ), + migrations.RemoveField(model_name="ticket", name="order"), + migrations.RemoveField(model_name="ticket", name="product"), + migrations.DeleteModel(name="Ticket"), ] diff --git a/src/shop/migrations/0053_auto_20180318_0906.py b/src/shop/migrations/0053_auto_20180318_0906.py index 0acbc182..6270bab7 100644 --- a/src/shop/migrations/0053_auto_20180318_0906.py +++ b/src/shop/migrations/0053_auto_20180318_0906.py @@ -9,44 +9,71 @@ import django.db.models.deletion class Migration(migrations.Migration): - dependencies = [ - ('shop', '0052_auto_20171004_0005'), - ] + dependencies = [("shop", "0052_auto_20171004_0005")] operations = [ migrations.AlterField( - model_name='creditnote', - name='user', - field=models.ForeignKey(blank=True, help_text='The user this credit note belongs to, if any.', null=True, on_delete=django.db.models.deletion.PROTECT, related_name='creditnotes', to=settings.AUTH_USER_MODEL, verbose_name='User'), + model_name="creditnote", + name="user", + field=models.ForeignKey( + blank=True, + help_text="The user this credit note belongs to, if any.", + null=True, + on_delete=django.db.models.deletion.PROTECT, + related_name="creditnotes", + to=settings.AUTH_USER_MODEL, + verbose_name="User", + ), ), migrations.AlterField( - model_name='epaypayment', - name='callback', - field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='shop.EpayCallback'), + model_name="epaypayment", + name="callback", + field=models.ForeignKey( + on_delete=django.db.models.deletion.PROTECT, to="shop.EpayCallback" + ), ), migrations.AlterField( - model_name='order', - name='user', - field=models.ForeignKey(help_text='The user this shop order belongs to.', on_delete=django.db.models.deletion.PROTECT, related_name='orders', to=settings.AUTH_USER_MODEL, verbose_name='User'), + model_name="order", + name="user", + field=models.ForeignKey( + help_text="The user this shop order belongs to.", + on_delete=django.db.models.deletion.PROTECT, + related_name="orders", + to=settings.AUTH_USER_MODEL, + verbose_name="User", + ), ), migrations.AlterField( - model_name='orderproductrelation', - name='order', - field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='shop.Order'), + model_name="orderproductrelation", + name="order", + field=models.ForeignKey( + on_delete=django.db.models.deletion.PROTECT, to="shop.Order" + ), ), migrations.AlterField( - model_name='orderproductrelation', - name='product', - field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='shop.Product'), + model_name="orderproductrelation", + name="product", + field=models.ForeignKey( + on_delete=django.db.models.deletion.PROTECT, to="shop.Product" + ), ), migrations.AlterField( - model_name='product', - name='category', - field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='products', to='shop.ProductCategory'), + model_name="product", + name="category", + field=models.ForeignKey( + on_delete=django.db.models.deletion.PROTECT, + related_name="products", + to="shop.ProductCategory", + ), ), migrations.AlterField( - model_name='product', - name='ticket_type', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, to='tickets.TicketType'), + model_name="product", + name="ticket_type", + field=models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.PROTECT, + to="tickets.TicketType", + ), ), ] diff --git a/src/shop/migrations/0054_auto_20180415_1159.py b/src/shop/migrations/0054_auto_20180415_1159.py index 51f19464..43e8b6dc 100644 --- a/src/shop/migrations/0054_auto_20180415_1159.py +++ b/src/shop/migrations/0054_auto_20180415_1159.py @@ -6,29 +6,43 @@ import django.db.models.deletion class Migration(migrations.Migration): - dependencies = [ - ('shop', '0053_auto_20180318_0906'), - ] + dependencies = [("shop", "0053_auto_20180318_0906")] operations = [ migrations.AddField( - model_name='product', - name='stock_amount', - field=models.IntegerField(blank=True, help_text='Initial amount available in stock if there is a limited supply, e.g. fridge space', null=True), + model_name="product", + name="stock_amount", + field=models.IntegerField( + blank=True, + help_text="Initial amount available in stock if there is a limited supply, e.g. fridge space", + null=True, + ), ), migrations.AlterField( - model_name='epaypayment', - name='order', - field=models.OneToOneField(on_delete=django.db.models.deletion.PROTECT, to='shop.Order'), + model_name="epaypayment", + name="order", + field=models.OneToOneField( + on_delete=django.db.models.deletion.PROTECT, to="shop.Order" + ), ), migrations.AlterField( - model_name='invoice', - name='customorder', - field=models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, to='shop.CustomOrder'), + model_name="invoice", + name="customorder", + field=models.OneToOneField( + blank=True, + null=True, + on_delete=django.db.models.deletion.PROTECT, + to="shop.CustomOrder", + ), ), migrations.AlterField( - model_name='invoice', - name='order', - field=models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, to='shop.Order'), + model_name="invoice", + name="order", + field=models.OneToOneField( + blank=True, + null=True, + on_delete=django.db.models.deletion.PROTECT, + to="shop.Order", + ), ), ] diff --git a/src/shop/migrations/0055_order_customer_address.py b/src/shop/migrations/0055_order_customer_address.py index 2720cf33..9a5b2ba7 100644 --- a/src/shop/migrations/0055_order_customer_address.py +++ b/src/shop/migrations/0055_order_customer_address.py @@ -5,14 +5,14 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ - ('shop', '0054_auto_20180415_1159'), - ] + dependencies = [("shop", "0054_auto_20180415_1159")] operations = [ migrations.AddField( - model_name='order', - name='customer_address', - field=models.TextField(blank=True, help_text='The additional customer address for this order'), - ), + model_name="order", + name="customer_address", + field=models.TextField( + blank=True, help_text="The additional customer address for this order" + ), + ) ] diff --git a/src/shop/migrations/0056_auto_20180827_1020.py b/src/shop/migrations/0056_auto_20180827_1020.py index fa2aa4d0..7fda5586 100644 --- a/src/shop/migrations/0056_auto_20180827_1020.py +++ b/src/shop/migrations/0056_auto_20180827_1020.py @@ -5,18 +5,16 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ - ('shop', '0055_order_customer_address'), - ] + dependencies = [("shop", "0055_order_customer_address")] operations = [ - migrations.RemoveField( - model_name='order', - name='customer_address', - ), + migrations.RemoveField(model_name="order", name="customer_address"), migrations.AddField( - model_name='order', - name='invoice_address', - field=models.TextField(blank=True, help_text='The invoice address for this order. Leave blank to use the email associated with the logged in user.'), + model_name="order", + name="invoice_address", + field=models.TextField( + blank=True, + help_text="The invoice address for this order. Leave blank to use the email associated with the logged in user.", + ), ), ] diff --git a/src/shop/migrations/0057_order_notes.py b/src/shop/migrations/0057_order_notes.py index 2e0aee52..1823f1ec 100644 --- a/src/shop/migrations/0057_order_notes.py +++ b/src/shop/migrations/0057_order_notes.py @@ -5,14 +5,16 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ - ('shop', '0056_auto_20180827_1020'), - ] + dependencies = [("shop", "0056_auto_20180827_1020")] operations = [ migrations.AddField( - model_name='order', - name='notes', - field=models.TextField(blank=True, default='', help_text='Any internal notes about this order can be entered here. They will not be printed on the invoice or shown to the customer in any way.'), - ), + model_name="order", + name="notes", + field=models.TextField( + blank=True, + default="", + help_text="Any internal notes about this order can be entered here. They will not be printed on the invoice or shown to the customer in any way.", + ), + ) ] diff --git a/src/shop/urls.py b/src/shop/urls.py index 061b411c..4078b47f 100644 --- a/src/shop/urls.py +++ b/src/shop/urls.py @@ -1,31 +1,62 @@ from django.urls import path, include from .views import * -app_name = 'shop' +app_name = "shop" urlpatterns = [ - path('', ShopIndexView.as_view(), name='index'), - - path('products//', ProductDetailView.as_view(), name='product_detail'), - - path('orders/', OrderListView.as_view(), name='order_list'), - path('orders//', include([ - path('', OrderDetailView.as_view(), name='order_detail'), - path('invoice/', DownloadInvoiceView.as_view(), name='download_invoice'), - path('mark_as_paid/', OrderMarkAsPaidView.as_view(), name='mark_order_as_paid'), - - path('pay/creditcard/', EpayFormView.as_view(), name='epay_form'), - path('pay/creditcard/callback/',EpayCallbackView.as_view(), name='epay_callback'), - path('pay/creditcard/thanks/', EpayThanksView.as_view(), name='epay_thanks'), - - path('pay/blockchain/', CoinifyRedirectView.as_view(), name='coinify_pay'), - path('pay/blockchain/callback/', CoinifyCallbackView.as_view(), name='coinify_callback'), - path('pay/blockchain/thanks/', CoinifyThanksView.as_view(), name='coinify_thanks'), - - path('pay/banktransfer/', BankTransferView.as_view(), name='bank_transfer'), - - path('pay/cash/', CashView.as_view(), name='cash'), - ])), - path('creditnotes/', CreditNoteListView.as_view(), name='creditnote_list'), - path('creditnotes//pdf/', DownloadCreditNoteView.as_view(), name='download_creditnote'), + path("", ShopIndexView.as_view(), name="index"), + path("products//", ProductDetailView.as_view(), name="product_detail"), + path("orders/", OrderListView.as_view(), name="order_list"), + path( + "orders//", + include( + [ + path("", OrderDetailView.as_view(), name="order_detail"), + path( + "invoice/", DownloadInvoiceView.as_view(), name="download_invoice" + ), + path( + "mark_as_paid/", + OrderMarkAsPaidView.as_view(), + name="mark_order_as_paid", + ), + path("pay/creditcard/", EpayFormView.as_view(), name="epay_form"), + path( + "pay/creditcard/callback/", + EpayCallbackView.as_view(), + name="epay_callback", + ), + path( + "pay/creditcard/thanks/", + EpayThanksView.as_view(), + name="epay_thanks", + ), + path( + "pay/blockchain/", CoinifyRedirectView.as_view(), name="coinify_pay" + ), + path( + "pay/blockchain/callback/", + CoinifyCallbackView.as_view(), + name="coinify_callback", + ), + path( + "pay/blockchain/thanks/", + CoinifyThanksView.as_view(), + name="coinify_thanks", + ), + path( + "pay/banktransfer/", + BankTransferView.as_view(), + name="bank_transfer", + ), + path("pay/cash/", CashView.as_view(), name="cash"), + ] + ), + ), + path("creditnotes/", CreditNoteListView.as_view(), name="creditnote_list"), + path( + "creditnotes//pdf/", + DownloadCreditNoteView.as_view(), + name="download_creditnote", + ), ] diff --git a/src/sponsors/admin.py b/src/sponsors/admin.py index 15e855bd..9f5e4ff5 100644 --- a/src/sponsors/admin.py +++ b/src/sponsors/admin.py @@ -5,13 +5,13 @@ from .models import Sponsor, SponsorTier @admin.register(Sponsor) class SponsorAdmin(admin.ModelAdmin): - list_display = ('name', 'tier') - list_filter = ('tier__camp',) + list_display = ("name", "tier") + list_filter = ("tier__camp",) @admin.register(SponsorTier) class SponsorTierAdmin(admin.ModelAdmin): - list_display = ('name', 'camp', 'weight') - list_editable = ('weight',) - list_filter = ('camp',) - ordering = ('weight', ) + list_display = ("name", "camp", "weight") + list_editable = ("weight",) + list_filter = ("camp",) + ordering = ("weight",) diff --git a/src/sponsors/apps.py b/src/sponsors/apps.py index 4db5584e..bec0db41 100644 --- a/src/sponsors/apps.py +++ b/src/sponsors/apps.py @@ -2,4 +2,4 @@ from django.apps import AppConfig class SponsorsConfig(AppConfig): - name = 'sponsors' + name = "sponsors" diff --git a/src/sponsors/management/commands/generate_sponsor_tickets.py b/src/sponsors/management/commands/generate_sponsor_tickets.py index cecbb601..d2684728 100644 --- a/src/sponsors/management/commands/generate_sponsor_tickets.py +++ b/src/sponsors/management/commands/generate_sponsor_tickets.py @@ -8,22 +8,20 @@ from tickets.models import SponsorTicket, TicketType class Command(BaseCommand): - help = 'Creates sponsor tickets' + help = "Creates sponsor tickets" def add_arguments(self, parser): - parser.add_argument('camp_slug', type=str,) - parser.add_argument('ticket_type_pk', type=str,) + parser.add_argument("camp_slug", type=str) + parser.add_argument("ticket_type_pk", type=str) def output(self, message): - self.stdout.write('{}: {}'.format( - timezone.now().strftime("%Y-%m-%d %H:%M:%S"), - message - ) + self.stdout.write( + "{}: {}".format(timezone.now().strftime("%Y-%m-%d %H:%M:%S"), message) ) def handle(self, *args, **options): - ticket_type = TicketType.objects.get(pk=options['ticket_type_pk']) - camp = Camp.objects.get(slug=options['camp_slug']) + ticket_type = TicketType.objects.get(pk=options["ticket_type_pk"]) + camp = Camp.objects.get(slug=options["camp_slug"]) sponsors = Sponsor.objects.filter(tier__camp=camp, tickets_generated=False) for sponsor in sponsors: @@ -33,9 +31,14 @@ class Command(BaseCommand): ticket = SponsorTicket(sponsor=sponsor, ticket_type=ticket_type) ticket.save() ticket.generate_pdf() - self.output("- {}_ticket_{}.pdf".format(ticket.shortname, ticket.pk)) + self.output( + "- {}_ticket_{}.pdf".format(ticket.shortname, ticket.pk) + ) sponsor.tickets_generated = True sponsor.save() else: - self.output("{} is in tier {}, which has no tickets set.".format(sponsor, sponsor.tier)) - + self.output( + "{} is in tier {}, which has no tickets set.".format( + sponsor, sponsor.tier + ) + ) diff --git a/src/sponsors/migrations/0001_initial.py b/src/sponsors/migrations/0001_initial.py index f4fe970f..9fbfa1d0 100644 --- a/src/sponsors/migrations/0001_initial.py +++ b/src/sponsors/migrations/0001_initial.py @@ -10,23 +10,53 @@ class Migration(migrations.Migration): initial = True - dependencies = [ - ] + dependencies = [] operations = [ migrations.CreateModel( - name='Sponsor', + name="Sponsor", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('created', models.DateTimeField(auto_now_add=True)), - ('updated', models.DateTimeField(auto_now=True)), - ('name', models.CharField(help_text='Name of the sponsor', max_length=150)), - ('tier', models.IntegerField(choices=[(1, 'Gold'), (2, 'Silver'), (3, 'Bronze'), (4, 'Sponsor')], help_text='The tier of the sponsorship')), - ('description', models.TextField(help_text='A short description of the sponsorship')), - ('logo', models.ImageField(help_text='A logo for the sponsor', upload_to=sponsors.models.get_sponsor_upload_path)), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("created", models.DateTimeField(auto_now_add=True)), + ("updated", models.DateTimeField(auto_now=True)), + ( + "name", + models.CharField(help_text="Name of the sponsor", max_length=150), + ), + ( + "tier", + models.IntegerField( + choices=[ + (1, "Gold"), + (2, "Silver"), + (3, "Bronze"), + (4, "Sponsor"), + ], + help_text="The tier of the sponsorship", + ), + ), + ( + "description", + models.TextField( + help_text="A short description of the sponsorship" + ), + ), + ( + "logo", + models.ImageField( + help_text="A logo for the sponsor", + upload_to=sponsors.models.get_sponsor_upload_path, + ), + ), ], - options={ - 'abstract': False, - }, - ), + options={"abstract": False}, + ) ] diff --git a/src/sponsors/migrations/0002_auto_20170711_2341.py b/src/sponsors/migrations/0002_auto_20170711_2341.py index 339d081c..4ffe4fbc 100644 --- a/src/sponsors/migrations/0002_auto_20170711_2341.py +++ b/src/sponsors/migrations/0002_auto_20170711_2341.py @@ -8,27 +8,43 @@ import django.db.models.deletion class Migration(migrations.Migration): - dependencies = [ - ('sponsors', '0001_initial'), - ] + dependencies = [("sponsors", "0001_initial")] operations = [ migrations.CreateModel( - name='SponsorTier', + name="SponsorTier", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('created', models.DateTimeField(auto_now_add=True)), - ('updated', models.DateTimeField(auto_now=True)), - ('name', models.CharField(help_text='Name of the tier (gold, silver, etc.)', max_length=25)), - ('description', models.TextField(help_text='A description of what the tier includes.')), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("created", models.DateTimeField(auto_now_add=True)), + ("updated", models.DateTimeField(auto_now=True)), + ( + "name", + models.CharField( + help_text="Name of the tier (gold, silver, etc.)", max_length=25 + ), + ), + ( + "description", + models.TextField( + help_text="A description of what the tier includes." + ), + ), ], - options={ - 'abstract': False, - }, + options={"abstract": False}, ), migrations.AlterField( - model_name='sponsor', - name='tier', - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='sponsors.SponsorTier'), + model_name="sponsor", + name="tier", + field=models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, to="sponsors.SponsorTier" + ), ), ] diff --git a/src/sponsors/migrations/0003_sponsortier_camp.py b/src/sponsors/migrations/0003_sponsortier_camp.py index 2aef250e..926115f3 100644 --- a/src/sponsors/migrations/0003_sponsortier_camp.py +++ b/src/sponsors/migrations/0003_sponsortier_camp.py @@ -9,14 +9,20 @@ import django.db.models.deletion class Migration(migrations.Migration): dependencies = [ - ('camps', '0021_auto_20170711_2247'), - ('sponsors', '0002_auto_20170711_2341'), + ("camps", "0021_auto_20170711_2247"), + ("sponsors", "0002_auto_20170711_2341"), ] operations = [ migrations.AddField( - model_name='sponsortier', - name='camp', - field=models.ForeignKey(help_text='The camp this sponsor tier belongs to', null=True, on_delete=django.db.models.deletion.CASCADE, related_name='sponsor_tiers', to='camps.Camp'), - ), + model_name="sponsortier", + name="camp", + field=models.ForeignKey( + help_text="The camp this sponsor tier belongs to", + null=True, + on_delete=django.db.models.deletion.CASCADE, + related_name="sponsor_tiers", + to="camps.Camp", + ), + ) ] diff --git a/src/sponsors/migrations/0004_sponsortier_weight.py b/src/sponsors/migrations/0004_sponsortier_weight.py index bf238bd2..c82ba4b1 100644 --- a/src/sponsors/migrations/0004_sponsortier_weight.py +++ b/src/sponsors/migrations/0004_sponsortier_weight.py @@ -7,14 +7,15 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ - ('sponsors', '0003_sponsortier_camp'), - ] + dependencies = [("sponsors", "0003_sponsortier_camp")] operations = [ migrations.AddField( - model_name='sponsortier', - name='weight', - field=models.IntegerField(default=0, help_text='This decides where on the list the tier will be shown. I.e.\n gold should have a lower value than silver.'), - ), + model_name="sponsortier", + name="weight", + field=models.IntegerField( + default=0, + help_text="This decides where on the list the tier will be shown. I.e.\n gold should have a lower value than silver.", + ), + ) ] diff --git a/src/sponsors/migrations/0005_sponsor_url.py b/src/sponsors/migrations/0005_sponsor_url.py index 98a5d60a..29c5bc5f 100644 --- a/src/sponsors/migrations/0005_sponsor_url.py +++ b/src/sponsors/migrations/0005_sponsor_url.py @@ -7,14 +7,14 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ - ('sponsors', '0004_sponsortier_weight'), - ] + dependencies = [("sponsors", "0004_sponsortier_weight")] operations = [ migrations.AddField( - model_name='sponsor', - name='url', - field=models.URLField(blank=True, help_text='A URL to the sponsor.', null=True), - ), + model_name="sponsor", + name="url", + field=models.URLField( + blank=True, help_text="A URL to the sponsor.", null=True + ), + ) ] diff --git a/src/sponsors/migrations/0006_auto_20170715_1110.py b/src/sponsors/migrations/0006_auto_20170715_1110.py index 8cb9df30..2d9571fb 100644 --- a/src/sponsors/migrations/0006_auto_20170715_1110.py +++ b/src/sponsors/migrations/0006_auto_20170715_1110.py @@ -7,19 +7,19 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ - ('sponsors', '0005_sponsor_url'), - ] + dependencies = [("sponsors", "0005_sponsor_url")] operations = [ migrations.AlterField( - model_name='sponsor', - name='logo', - field=models.URLField(help_text='A URL to the logo', max_length=255), + model_name="sponsor", + name="logo", + field=models.URLField(help_text="A URL to the logo", max_length=255), ), migrations.AlterField( - model_name='sponsor', - name='url', - field=models.URLField(blank=True, help_text='An URL to the sponsor.', null=True), + model_name="sponsor", + name="url", + field=models.URLField( + blank=True, help_text="An URL to the sponsor.", null=True + ), ), ] diff --git a/src/sponsors/migrations/0007_auto_20180318_0906.py b/src/sponsors/migrations/0007_auto_20180318_0906.py index b08c2de7..e5ae89a0 100644 --- a/src/sponsors/migrations/0007_auto_20180318_0906.py +++ b/src/sponsors/migrations/0007_auto_20180318_0906.py @@ -8,19 +8,25 @@ import django.db.models.deletion class Migration(migrations.Migration): - dependencies = [ - ('sponsors', '0006_auto_20170715_1110'), - ] + dependencies = [("sponsors", "0006_auto_20170715_1110")] operations = [ migrations.AlterField( - model_name='sponsor', - name='tier', - field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='sponsors.SponsorTier'), + model_name="sponsor", + name="tier", + field=models.ForeignKey( + on_delete=django.db.models.deletion.PROTECT, to="sponsors.SponsorTier" + ), ), migrations.AlterField( - model_name='sponsortier', - name='camp', - field=models.ForeignKey(help_text='The camp this sponsor tier belongs to', null=True, on_delete=django.db.models.deletion.PROTECT, related_name='sponsor_tiers', to='camps.Camp'), + model_name="sponsortier", + name="camp", + field=models.ForeignKey( + help_text="The camp this sponsor tier belongs to", + null=True, + on_delete=django.db.models.deletion.PROTECT, + related_name="sponsor_tiers", + to="camps.Camp", + ), ), ] diff --git a/src/sponsors/migrations/0008_auto_20180815_1119.py b/src/sponsors/migrations/0008_auto_20180815_1119.py index b28de296..55b20e4d 100644 --- a/src/sponsors/migrations/0008_auto_20180815_1119.py +++ b/src/sponsors/migrations/0008_auto_20180815_1119.py @@ -5,19 +5,21 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ - ('sponsors', '0007_auto_20180318_0906'), - ] + dependencies = [("sponsors", "0007_auto_20180318_0906")] operations = [ migrations.AddField( - model_name='sponsor', - name='tickets_generated', + model_name="sponsor", + name="tickets_generated", field=models.BooleanField(default=False), ), migrations.AddField( - model_name='sponsortier', - name='tickets', - field=models.IntegerField(blank=True, help_text='If set this is the number of tickets generated for a sponsor in this tier.', null=True), + model_name="sponsortier", + name="tickets", + field=models.IntegerField( + blank=True, + help_text="If set this is the number of tickets generated for a sponsor in this tier.", + null=True, + ), ), ] diff --git a/src/sponsors/migrations/0009_sponsor_logo_filename.py b/src/sponsors/migrations/0009_sponsor_logo_filename.py index 14be6a38..053ac404 100644 --- a/src/sponsors/migrations/0009_sponsor_logo_filename.py +++ b/src/sponsors/migrations/0009_sponsor_logo_filename.py @@ -5,14 +5,14 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ - ('sponsors', '0008_auto_20180815_1119'), - ] + dependencies = [("sponsors", "0008_auto_20180815_1119")] operations = [ migrations.AddField( - model_name='sponsor', - name='logo_filename', - field=models.CharField(blank=True, help_text='Filename of the logo', max_length=255, null=True), - ), + model_name="sponsor", + name="logo_filename", + field=models.CharField( + blank=True, help_text="Filename of the logo", max_length=255, null=True + ), + ) ] diff --git a/src/sponsors/migrations/0010_populate_logo_filename.py b/src/sponsors/migrations/0010_populate_logo_filename.py index 5d0bedd7..5e3859f8 100644 --- a/src/sponsors/migrations/0010_populate_logo_filename.py +++ b/src/sponsors/migrations/0010_populate_logo_filename.py @@ -2,18 +2,16 @@ from django.db import migrations + def populate_logo_filename(apps, schema_editor): - Sponsor = apps.get_model('sponsors', 'Sponsor') + Sponsor = apps.get_model("sponsors", "Sponsor") for sponsor in Sponsor.objects.all(): sponsor.logo_filename = sponsor.logo.split("/")[-1] sponsor.save() + class Migration(migrations.Migration): - dependencies = [ - ('sponsors', '0009_sponsor_logo_filename'), - ] + dependencies = [("sponsors", "0009_sponsor_logo_filename")] - operations = [ - migrations.RunPython(populate_logo_filename), - ] + operations = [migrations.RunPython(populate_logo_filename)] diff --git a/src/sponsors/migrations/0011_auto_20181118_1513.py b/src/sponsors/migrations/0011_auto_20181118_1513.py index 9cee6d9d..c2621351 100644 --- a/src/sponsors/migrations/0011_auto_20181118_1513.py +++ b/src/sponsors/migrations/0011_auto_20181118_1513.py @@ -5,18 +5,13 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ - ('sponsors', '0010_populate_logo_filename'), - ] + dependencies = [("sponsors", "0010_populate_logo_filename")] operations = [ - migrations.RemoveField( - model_name='sponsor', - name='logo', - ), + migrations.RemoveField(model_name="sponsor", name="logo"), migrations.AlterField( - model_name='sponsor', - name='logo_filename', - field=models.CharField(help_text='Filename of the logo', max_length=255), + model_name="sponsor", + name="logo_filename", + field=models.CharField(help_text="Filename of the logo", max_length=255), ), ] diff --git a/src/sponsors/models.py b/src/sponsors/models.py index d7ab4a45..8ed52c0e 100644 --- a/src/sponsors/models.py +++ b/src/sponsors/models.py @@ -4,79 +4,61 @@ from utils.models import CampRelatedModel def get_sponsor_upload_path(instance, filename): - return 'public/sponsors/{camp_slug}/{filename}'.format( + return "public/sponsors/{camp_slug}/{filename}".format( camp_slug=instance.tier.camp.slug, - filename='{}_logo.{}'.format( - instance.name.lower(), - filename.split('.')[-1] - ) + filename="{}_logo.{}".format(instance.name.lower(), filename.split(".")[-1]), ) class Sponsor(CampRelatedModel): - name = models.CharField( - max_length=150, - help_text='Name of the sponsor' - ) + name = models.CharField(max_length=150, help_text="Name of the sponsor") - tier = models.ForeignKey('sponsors.SponsorTier', on_delete=models.PROTECT) + tier = models.ForeignKey("sponsors.SponsorTier", on_delete=models.PROTECT) - description = models.TextField( - help_text='A short description of the sponsorship' - ) + description = models.TextField(help_text="A short description of the sponsorship") - logo_filename = models.CharField( - max_length=255, - help_text='Filename of the logo' - ) + logo_filename = models.CharField(max_length=255, help_text="Filename of the logo") - url = models.URLField( - null=True, - blank=True, - help_text="An URL to the sponsor." - ) + url = models.URLField(null=True, blank=True, help_text="An URL to the sponsor.") tickets_generated = models.BooleanField(default=False) def __str__(self): - return '{} ({})'.format(self.name, self.tier.camp) + return "{} ({})".format(self.name, self.tier.camp) @property def camp(self): return self.tier.camp - camp_filter = 'tier__camp' + camp_filter = "tier__camp" class SponsorTier(CampRelatedModel): name = models.CharField( - max_length=25, - help_text='Name of the tier (gold, silver, etc.)' + max_length=25, help_text="Name of the tier (gold, silver, etc.)" ) - description = models.TextField( - help_text='A description of what the tier includes.' - ) + description = models.TextField(help_text="A description of what the tier includes.") camp = models.ForeignKey( - 'camps.Camp', + "camps.Camp", null=True, on_delete=models.PROTECT, - related_name='sponsor_tiers', - help_text='The camp this sponsor tier belongs to', + related_name="sponsor_tiers", + help_text="The camp this sponsor tier belongs to", ) weight = models.IntegerField( default=0, help_text="""This decides where on the list the tier will be shown. I.e. - gold should have a lower value than silver.""" + gold should have a lower value than silver.""", ) tickets = models.IntegerField( null=True, blank=True, - help_text="If set this is the number of tickets generated for a sponsor in this tier." + help_text="If set this is the number of tickets generated for a sponsor in this tier.", ) def __str__(self): - return '{} ({})'.format(self.name, self.camp) + return "{} ({})".format(self.name, self.camp) diff --git a/src/sponsors/views.py b/src/sponsors/views.py index 87ecd49e..01b590a8 100644 --- a/src/sponsors/views.py +++ b/src/sponsors/views.py @@ -6,15 +6,9 @@ from .models import Sponsor class SponsorsView(CampViewMixin, ListView): model = Sponsor - template_name = 'sponsors.html' - context_object_name = 'sponsors' + template_name = "sponsors.html" + context_object_name = "sponsors" def get_queryset(self, **kwargs): queryset = super().get_queryset() - return queryset.filter( - tier__camp=self.camp - ).order_by( - 'tier__weight', - 'name', - ) - + return queryset.filter(tier__camp=self.camp).order_by("tier__weight", "name") diff --git a/src/static_src/img/feed-icon-28x28.png b/src/static_src/img/feed-icon-28x28.png new file mode 100755 index 0000000000000000000000000000000000000000..d64c669c7589d3a886682dbd1f3c83b716a420f5 GIT binary patch literal 1737 zcmV;)1~&PLP)sAF&N>2z!Fdr4Imm26om*2a>%jE0(;Kv%yf78|JB{oGfPNxX8x(_?yCCg`;V_$ zXsz+vi(@PROR2wt+9on+`tt9tz79KlSO2H>IyGO>#kRR$cU=`Hmyc#J&lVDyanqor z1tA1LcZEeQ^@U{`(^^*e%-kna7Wft+z>JVkoMv=$6&UWDkQ$<2lKHssGAf!lTvqVr4)B+FQFUkn06c#WX1OxA_5 z;;t4x27iQdkQg)F7+O{!f8h`chd+YqxfC)gbK_tz9fLAfFeIEn@r7e^t8mW`EtHtl zf~sX-Ks>w(zD$JfL<}?-ObbNSqyoSo8EhI@Me*$0_W}BkY=u=l5_at*Bqz>Bs-YQ{ zos4mvG?H^x!JY63{2$(dmAw(OgDBN4r@D?n>1$kSvMo%1n@ne~L*#Ej+@`@-enjuF z&(K|SKhjN0k!f56nXE1WtNKQG3pT>t|2pJAM+hc@!uQ#Vl>I(@D{D3pxKswlb>~tD zb^TOW4Rc`CjDzjiNDWa)=dPf5=zVl-eHJ}`?5*&!96k~1@ekpr?gI+6@IV)I-%YZ1 z=-v+aWGLp%CKUe#s$sz;wpp^;mX)Y(TnOzI;dNa_{>&cebNk>B1K00F_Tam4Z(qQO zd23_Pq2no`*2DW|3GJHdIgFd8T4NJhnrn;yjGBaL&ff6-AOJ$zP&E^gesm2|&uoXB zvj$EwiHzuj`}0P$f4kO{ObL|Si{@9rxo7|l7_S!?%oAqFYC^>-3Q9eduY7-u)FfIoCHc?ZV)@-|{<8PO#m0!q@K`h=j&~-o;Qk3aNwz=j=|n zt*@f@(}n2RJRjZ1wpX$pMoIGICP*h?K<~6}fS2ozSx$Zo7}Z$8j=^Jwto#h>^+V-5 z;CNj~*)B4qf2rJg3h)YcC8lmRCX=+ze4R)W{Rjv-OrYtP6i`tkW#ZBZo zAquzQ)1pNRc%A~zt)gVgBrSNqe~I>8uMwtO7Oxi|M?C$Fs^Ts74UpfJM^h3sV?wMW0WJehh2{~g4ogxB$XB+z3 zj>dqsQ-JDmG0PG|RvIr$F{C4kCg$jP$}HFbr*4{YjY!qNUc40!F-=kycOU+QnB?Mx z8|Kk4n-6^So&Tjm@IeU{f$7jOq0(5vX+iOD$&HEn>6Ln&9A*v|n??7|MdU7@C{vjR z$f_|A5hO^O4ut*#ZxgtJGkT`cL-*i%v!F$w>{{>2ab(X< zB7{67ze4nP(?WE=r;}pbYUptK=i7b_Vo0DObgB4h*)ZMw#4Moef;n1P)m$$SapFyk zgn28|VG$Q8#!==OS!68?6Qk&A<31f;^D`aBP}NOF+u83;43FmqXr@XA^@G5zL#R|Z z-6OEbB$o=0VUJMXVpoM`Q5^X>w^j&dHb$?C`9O1za}2k1oIVYauA>==_^=F>L6=L^ zy)3G=Vq5~I&uoz(IUI+sizYAj3Qn3MPY>NxTc2EAJ9P$1)throw new TypeError("isEnabled expects a single character string parameter");switch(a){case"y":return i.indexOf("Y")!==-1;case"M":return i.indexOf("M")!==-1;case"d":return i.toLowerCase().indexOf("d")!==-1;case"h":case"H":return i.toLowerCase().indexOf("h")!==-1;case"m":return i.indexOf("m")!==-1;case"s":return i.indexOf("s")!==-1;default:return!1}},A=function(){return z("h")||z("m")||z("s")},B=function(){return z("y")||z("M")||z("d")},C=function(){var b=a("").append(a("").append(a("").addClass("prev").attr("data-action","previous").append(a("").addClass(d.icons.previous))).append(a("").addClass("picker-switch").attr("data-action","pickerSwitch").attr("colspan",d.calendarWeeks?"6":"5")).append(a("").addClass("next").attr("data-action","next").append(a("").addClass(d.icons.next)))),c=a("").append(a("").append(a("").attr("colspan",d.calendarWeeks?"8":"7")));return[a("
").addClass("datepicker-days").append(a("").addClass("table-condensed").append(b).append(a(""))),a("
").addClass("datepicker-months").append(a("
").addClass("table-condensed").append(b.clone()).append(c.clone())),a("
").addClass("datepicker-years").append(a("
").addClass("table-condensed").append(b.clone()).append(c.clone())),a("
").addClass("datepicker-decades").append(a("
").addClass("table-condensed").append(b.clone()).append(c.clone()))]},D=function(){var b=a(""),c=a(""),e=a("");return z("h")&&(b.append(a("
").append(a("").attr({href:"#",tabindex:"-1",title:d.tooltips.incrementHour}).addClass("btn").attr("data-action","incrementHours").append(a("").addClass(d.icons.up)))),c.append(a("").append(a("").addClass("timepicker-hour").attr({"data-time-component":"hours",title:d.tooltips.pickHour}).attr("data-action","showHours"))),e.append(a("").append(a("").attr({href:"#",tabindex:"-1",title:d.tooltips.decrementHour}).addClass("btn").attr("data-action","decrementHours").append(a("").addClass(d.icons.down))))),z("m")&&(z("h")&&(b.append(a("").addClass("separator")),c.append(a("").addClass("separator").html(":")),e.append(a("").addClass("separator"))),b.append(a("").append(a("").attr({href:"#",tabindex:"-1",title:d.tooltips.incrementMinute}).addClass("btn").attr("data-action","incrementMinutes").append(a("").addClass(d.icons.up)))),c.append(a("").append(a("").addClass("timepicker-minute").attr({"data-time-component":"minutes",title:d.tooltips.pickMinute}).attr("data-action","showMinutes"))),e.append(a("").append(a("").attr({href:"#",tabindex:"-1",title:d.tooltips.decrementMinute}).addClass("btn").attr("data-action","decrementMinutes").append(a("").addClass(d.icons.down))))),z("s")&&(z("m")&&(b.append(a("").addClass("separator")),c.append(a("").addClass("separator").html(":")),e.append(a("").addClass("separator"))),b.append(a("").append(a("").attr({href:"#",tabindex:"-1",title:d.tooltips.incrementSecond}).addClass("btn").attr("data-action","incrementSeconds").append(a("").addClass(d.icons.up)))),c.append(a("").append(a("").addClass("timepicker-second").attr({"data-time-component":"seconds",title:d.tooltips.pickSecond}).attr("data-action","showSeconds"))),e.append(a("").append(a("").attr({href:"#",tabindex:"-1",title:d.tooltips.decrementSecond}).addClass("btn").attr("data-action","decrementSeconds").append(a("").addClass(d.icons.down))))),h||(b.append(a("").addClass("separator")),c.append(a("").append(a("").addClass("separator"))),a("
").addClass("timepicker-picker").append(a("").addClass("table-condensed").append([b,c,e]))},E=function(){var b=a("
").addClass("timepicker-hours").append(a("
").addClass("table-condensed")),c=a("
").addClass("timepicker-minutes").append(a("
").addClass("table-condensed")),d=a("
").addClass("timepicker-seconds").append(a("
").addClass("table-condensed")),e=[D()];return z("h")&&e.push(b),z("m")&&e.push(c),z("s")&&e.push(d),e},F=function(){var b=[];return d.showTodayButton&&b.push(a("
").append(a("").attr({"data-action":"today",title:d.tooltips.today}).append(a("").addClass(d.icons.today)))),!d.sideBySide&&B()&&A()&&b.push(a("").append(a("").attr({"data-action":"togglePicker",title:d.tooltips.selectTime}).append(a("").addClass(d.icons.time)))),d.showClear&&b.push(a("").append(a("").attr({"data-action":"clear",title:d.tooltips.clear}).append(a("").addClass(d.icons.clear)))),d.showClose&&b.push(a("").append(a("").attr({"data-action":"close",title:d.tooltips.close}).append(a("").addClass(d.icons.close)))),a("").addClass("table-condensed").append(a("").append(a("").append(b)))},G=function(){var b=a("
").addClass("bootstrap-datetimepicker-widget dropdown-menu"),c=a("
").addClass("datepicker").append(C()),e=a("
").addClass("timepicker").append(E()),f=a("
    ").addClass("list-unstyled"),g=a("
  • ").addClass("picker-switch"+(d.collapse?" accordion-toggle":"")).append(F());return d.inline&&b.removeClass("dropdown-menu"),h&&b.addClass("usetwentyfour"),z("s")&&!h&&b.addClass("wider"),d.sideBySide&&B()&&A()?(b.addClass("timepicker-sbs"),"top"===d.toolbarPlacement&&b.append(g),b.append(a("
    ").addClass("row").append(c.addClass("col-md-6")).append(e.addClass("col-md-6"))),"bottom"===d.toolbarPlacement&&b.append(g),b):("top"===d.toolbarPlacement&&f.append(g),B()&&f.append(a("
  • ").addClass(d.collapse&&A()?"collapse in":"").append(c)),"default"===d.toolbarPlacement&&f.append(g),A()&&f.append(a("
  • ").addClass(d.collapse&&B()?"collapse":"").append(e)),"bottom"===d.toolbarPlacement&&f.append(g),b.append(f))},H=function(){var b,e={};return b=c.is("input")||d.inline?c.data():c.find("input").data(),b.dateOptions&&b.dateOptions instanceof Object&&(e=a.extend(!0,e,b.dateOptions)),a.each(d,function(a){var c="date"+a.charAt(0).toUpperCase()+a.slice(1);void 0!==b[c]&&(e[a]=b[c])}),e},I=function(){var b,e=(n||c).position(),f=(n||c).offset(),g=d.widgetPositioning.vertical,h=d.widgetPositioning.horizontal;if(d.widgetParent)b=d.widgetParent.append(o);else if(c.is("input"))b=c.after(o).parent();else{if(d.inline)return void(b=c.append(o));b=c,c.children().first().after(o)}if("auto"===g&&(g=f.top+1.5*o.height()>=a(window).height()+a(window).scrollTop()&&o.height()+c.outerHeight()a(window).width()?"right":"left"),"top"===g?o.addClass("top").removeClass("bottom"):o.addClass("bottom").removeClass("top"),"right"===h?o.addClass("pull-right"):o.removeClass("pull-right"),"static"===b.css("position")&&(b=b.parents().filter(function(){return"static"!==a(this).css("position")}).first()),0===b.length)throw new Error("datetimepicker component should be placed within a non-static positioned container");o.css({top:"top"===g?"auto":e.top+c.outerHeight(),bottom:"top"===g?b.outerHeight()-(b===c?0:e.top):"auto",left:"left"===h?b===c?0:e.left:"auto",right:"left"===h?"auto":b.outerWidth()-c.outerWidth()-(b===c?0:e.left)})},J=function(a){"dp.change"===a.type&&(a.date&&a.date.isSame(a.oldDate)||!a.date&&!a.oldDate)||c.trigger(a)},K=function(a){"y"===a&&(a="YYYY"),J({type:"dp.update",change:a,viewDate:f.clone()})},L=function(a){o&&(a&&(k=Math.max(p,Math.min(3,k+a))),o.find(".datepicker > div").hide().filter(".datepicker-"+q[k].clsName).show())},M=function(){var b=a("
"),c=f.clone().startOf("w").startOf("d");for(d.calendarWeeks===!0&&b.append(a(""),d.calendarWeeks&&c.append('"),j.push(c)),k=["day"],b.isBefore(f,"M")&&k.push("old"),b.isAfter(f,"M")&&k.push("new"),b.isSame(e,"d")&&!m&&k.push("active"),R(b,"d")||k.push("disabled"),b.isSame(y(),"d")&&k.push("today"),0!==b.day()&&6!==b.day()||k.push("weekend"),J({type:"dp.classify",date:b,classNames:k}),c.append('"),b.add(1,"d");h.find("tbody").empty().append(j),T(),U(),V()}},X=function(){var b=o.find(".timepicker-hours table"),c=f.clone().startOf("d"),d=[],e=a("");for(f.hour()>11&&!h&&c.hour(12);c.isSame(f,"d")&&(h||f.hour()<12&&c.hour()<12||f.hour()>11);)c.hour()%4===0&&(e=a(""),d.push(e)),e.append('"),c.add(1,"h");b.empty().append(d)},Y=function(){for(var b=o.find(".timepicker-minutes table"),c=f.clone().startOf("h"),e=[],g=a(""),h=1===d.stepping?5:d.stepping;f.isSame(c,"h");)c.minute()%(4*h)===0&&(g=a(""),e.push(g)),g.append('"),c.add(h,"m");b.empty().append(e)},Z=function(){for(var b=o.find(".timepicker-seconds table"),c=f.clone().startOf("m"),d=[],e=a("");f.isSame(c,"m");)c.second()%20===0&&(e=a(""),d.push(e)),e.append('"),c.add(5,"s");b.empty().append(d)},$=function(){var a,b,c=o.find(".timepicker span[data-time-component]");h||(a=o.find(".timepicker [data-action=togglePeriod]"),b=e.clone().add(e.hours()>=12?-12:12,"h"),a.text(e.format("A")),R(b,"h")?a.removeClass("disabled"):a.addClass("disabled")),c.filter("[data-time-component=hours]").text(e.format(h?"HH":"hh")),c.filter("[data-time-component=minutes]").text(e.format("mm")),c.filter("[data-time-component=seconds]").text(e.format("ss")),X(),Y(),Z()},_=function(){o&&(W(),$())},aa=function(a){var b=m?null:e;if(!a)return m=!0,g.val(""),c.data("date",""),J({type:"dp.change",date:!1,oldDate:b}),void _();if(a=a.clone().locale(d.locale),x()&&a.tz(d.timeZone),1!==d.stepping)for(a.minutes(Math.round(a.minutes()/d.stepping)*d.stepping).seconds(0);d.minDate&&a.isBefore(d.minDate);)a.add(d.stepping,"minutes");R(a)?(e=a,f=e.clone(),g.val(e.format(i)),c.data("date",e.format(i)),m=!1,_(),J({type:"dp.change",date:e.clone(),oldDate:b})):(d.keepInvalid?J({type:"dp.change",date:a,oldDate:b}):g.val(m?"":e.format(i)),J({type:"dp.error",date:a,oldDate:b}))},ba=function(){var b=!1;return o?(o.find(".collapse").each(function(){var c=a(this).data("collapse");return!c||!c.transitioning||(b=!0,!1)}),b?l:(n&&n.hasClass("btn")&&n.toggleClass("active"),o.hide(),a(window).off("resize",I),o.off("click","[data-action]"),o.off("mousedown",!1),o.remove(),o=!1,J({type:"dp.hide",date:e.clone()}),g.blur(),f=e.clone(),l)):l},ca=function(){aa(null)},da=function(a){return void 0===d.parseInputDate?(!b.isMoment(a)||a instanceof Date)&&(a=y(a)):a=d.parseInputDate(a),a},ea={next:function(){var a=q[k].navFnc;f.add(q[k].navStep,a),W(),K(a)},previous:function(){var a=q[k].navFnc;f.subtract(q[k].navStep,a),W(),K(a)},pickerSwitch:function(){L(1)},selectMonth:function(b){var c=a(b.target).closest("tbody").find("span").index(a(b.target));f.month(c),k===p?(aa(e.clone().year(f.year()).month(f.month())),d.inline||ba()):(L(-1),W()),K("M")},selectYear:function(b){var c=parseInt(a(b.target).text(),10)||0;f.year(c),k===p?(aa(e.clone().year(f.year())),d.inline||ba()):(L(-1),W()),K("YYYY")},selectDecade:function(b){var c=parseInt(a(b.target).data("selection"),10)||0;f.year(c),k===p?(aa(e.clone().year(f.year())),d.inline||ba()):(L(-1),W()),K("YYYY")},selectDay:function(b){var c=f.clone();a(b.target).is(".old")&&c.subtract(1,"M"),a(b.target).is(".new")&&c.add(1,"M"),aa(c.date(parseInt(a(b.target).text(),10))),A()||d.keepOpen||d.inline||ba()},incrementHours:function(){var a=e.clone().add(1,"h");R(a,"h")&&aa(a)},incrementMinutes:function(){var a=e.clone().add(d.stepping,"m");R(a,"m")&&aa(a)},incrementSeconds:function(){var a=e.clone().add(1,"s");R(a,"s")&&aa(a)},decrementHours:function(){var a=e.clone().subtract(1,"h");R(a,"h")&&aa(a)},decrementMinutes:function(){var a=e.clone().subtract(d.stepping,"m");R(a,"m")&&aa(a)},decrementSeconds:function(){var a=e.clone().subtract(1,"s");R(a,"s")&&aa(a)},togglePeriod:function(){aa(e.clone().add(e.hours()>=12?-12:12,"h"))},togglePicker:function(b){var c,e=a(b.target),f=e.closest("ul"),g=f.find(".in"),h=f.find(".collapse:not(.in)");if(g&&g.length){if(c=g.data("collapse"),c&&c.transitioning)return;g.collapse?(g.collapse("hide"),h.collapse("show")):(g.removeClass("in"),h.addClass("in")),e.is("span")?e.toggleClass(d.icons.time+" "+d.icons.date):e.find("span").toggleClass(d.icons.time+" "+d.icons.date)}},showPicker:function(){o.find(".timepicker > div:not(.timepicker-picker)").hide(),o.find(".timepicker .timepicker-picker").show()},showHours:function(){o.find(".timepicker .timepicker-picker").hide(),o.find(".timepicker .timepicker-hours").show()},showMinutes:function(){o.find(".timepicker .timepicker-picker").hide(),o.find(".timepicker .timepicker-minutes").show()},showSeconds:function(){o.find(".timepicker .timepicker-picker").hide(),o.find(".timepicker .timepicker-seconds").show()},selectHour:function(b){var c=parseInt(a(b.target).text(),10);h||(e.hours()>=12?12!==c&&(c+=12):12===c&&(c=0)),aa(e.clone().hours(c)),ea.showPicker.call(l)},selectMinute:function(b){aa(e.clone().minutes(parseInt(a(b.target).text(),10))),ea.showPicker.call(l)},selectSecond:function(b){aa(e.clone().seconds(parseInt(a(b.target).text(),10))),ea.showPicker.call(l)},clear:ca,today:function(){var a=y();R(a,"d")&&aa(a)},close:ba},fa=function(b){return!a(b.currentTarget).is(".disabled")&&(ea[a(b.currentTarget).data("action")].apply(l,arguments),!1)},ga=function(){var b,c={year:function(a){return a.month(0).date(1).hours(0).seconds(0).minutes(0)},month:function(a){return a.date(1).hours(0).seconds(0).minutes(0)},day:function(a){return a.hours(0).seconds(0).minutes(0)},hour:function(a){return a.seconds(0).minutes(0)},minute:function(a){return a.seconds(0)}};return g.prop("disabled")||!d.ignoreReadonly&&g.prop("readonly")||o?l:(void 0!==g.val()&&0!==g.val().trim().length?aa(da(g.val().trim())):m&&d.useCurrent&&(d.inline||g.is("input")&&0===g.val().trim().length)&&(b=y(),"string"==typeof d.useCurrent&&(b=c[d.useCurrent](b)),aa(b)),o=G(),M(),S(),o.find(".timepicker-hours").hide(),o.find(".timepicker-minutes").hide(),o.find(".timepicker-seconds").hide(),_(),L(),a(window).on("resize",I),o.on("click","[data-action]",fa),o.on("mousedown",!1),n&&n.hasClass("btn")&&n.toggleClass("active"),I(),o.show(),d.focusOnShow&&!g.is(":focus")&&g.focus(),J({type:"dp.show"}),l)},ha=function(){return o?ba():ga()},ia=function(a){var b,c,e,f,g=null,h=[],i={},j=a.which,k="p";w[j]=k;for(b in w)w.hasOwnProperty(b)&&w[b]===k&&(h.push(b),parseInt(b,10)!==j&&(i[b]=!0));for(b in d.keyBinds)if(d.keyBinds.hasOwnProperty(b)&&"function"==typeof d.keyBinds[b]&&(e=b.split(" "),e.length===h.length&&v[j]===e[e.length-1])){for(f=!0,c=e.length-2;c>=0;c--)if(!(v[e[c]]in i)){f=!1;break}if(f){g=d.keyBinds[b];break}}g&&(g.call(l,o),a.stopPropagation(),a.preventDefault())},ja=function(a){w[a.which]="r",a.stopPropagation(),a.preventDefault()},ka=function(b){var c=a(b.target).val().trim(),d=c?da(c):null;return aa(d),b.stopImmediatePropagation(),!1},la=function(){g.on({change:ka,blur:d.debug?"":ba,keydown:ia,keyup:ja,focus:d.allowInputToggle?ga:""}),c.is("input")?g.on({focus:ga}):n&&(n.on("click",ha),n.on("mousedown",!1))},ma=function(){g.off({change:ka,blur:blur,keydown:ia,keyup:ja,focus:d.allowInputToggle?ba:""}),c.is("input")?g.off({focus:ga}):n&&(n.off("click",ha),n.off("mousedown",!1))},na=function(b){var c={};return a.each(b,function(){var a=da(this);a.isValid()&&(c[a.format("YYYY-MM-DD")]=!0)}),!!Object.keys(c).length&&c},oa=function(b){var c={};return a.each(b,function(){c[this]=!0}),!!Object.keys(c).length&&c},pa=function(){var a=d.format||"L LT";i=a.replace(/(\[[^\[]*\])|(\\)?(LTS|LT|LL?L?L?|l{1,4})/g,function(a){var b=e.localeData().longDateFormat(a)||a;return b.replace(/(\[[^\[]*\])|(\\)?(LTS|LT|LL?L?L?|l{1,4})/g,function(a){return e.localeData().longDateFormat(a)||a})}),j=d.extraFormats?d.extraFormats.slice():[],j.indexOf(a)<0&&j.indexOf(i)<0&&j.push(i),h=i.toLowerCase().indexOf("a")<1&&i.replace(/\[.*?\]/g,"").indexOf("h")<1,z("y")&&(p=2),z("M")&&(p=1),z("d")&&(p=0),k=Math.max(p,k),m||aa(e)};if(l.destroy=function(){ba(),ma(),c.removeData("DateTimePicker"),c.removeData("date")},l.toggle=ha,l.show=ga,l.hide=ba,l.disable=function(){return ba(),n&&n.hasClass("btn")&&n.addClass("disabled"),g.prop("disabled",!0),l},l.enable=function(){return n&&n.hasClass("btn")&&n.removeClass("disabled"),g.prop("disabled",!1),l},l.ignoreReadonly=function(a){if(0===arguments.length)return d.ignoreReadonly;if("boolean"!=typeof a)throw new TypeError("ignoreReadonly () expects a boolean parameter");return d.ignoreReadonly=a,l},l.options=function(b){if(0===arguments.length)return a.extend(!0,{},d);if(!(b instanceof Object))throw new TypeError("options() options parameter should be an object");return a.extend(!0,d,b),a.each(d,function(a,b){if(void 0===l[a])throw new TypeError("option "+a+" is not recognized!");l[a](b)}),l},l.date=function(a){if(0===arguments.length)return m?null:e.clone();if(!(null===a||"string"==typeof a||b.isMoment(a)||a instanceof Date))throw new TypeError("date() parameter must be one of [null, string, moment or Date]");return aa(null===a?null:da(a)),l},l.format=function(a){if(0===arguments.length)return d.format;if("string"!=typeof a&&("boolean"!=typeof a||a!==!1))throw new TypeError("format() expects a string or boolean:false parameter "+a);return d.format=a,i&&pa(),l},l.timeZone=function(a){if(0===arguments.length)return d.timeZone;if("string"!=typeof a)throw new TypeError("newZone() expects a string parameter");return d.timeZone=a,l},l.dayViewHeaderFormat=function(a){if(0===arguments.length)return d.dayViewHeaderFormat;if("string"!=typeof a)throw new TypeError("dayViewHeaderFormat() expects a string parameter");return d.dayViewHeaderFormat=a,l},l.extraFormats=function(a){if(0===arguments.length)return d.extraFormats;if(a!==!1&&!(a instanceof Array))throw new TypeError("extraFormats() expects an array or false parameter");return d.extraFormats=a,j&&pa(),l},l.disabledDates=function(b){if(0===arguments.length)return d.disabledDates?a.extend({},d.disabledDates):d.disabledDates;if(!b)return d.disabledDates=!1,_(),l;if(!(b instanceof Array))throw new TypeError("disabledDates() expects an array parameter");return d.disabledDates=na(b),d.enabledDates=!1,_(),l},l.enabledDates=function(b){if(0===arguments.length)return d.enabledDates?a.extend({},d.enabledDates):d.enabledDates;if(!b)return d.enabledDates=!1,_(),l;if(!(b instanceof Array))throw new TypeError("enabledDates() expects an array parameter");return d.enabledDates=na(b),d.disabledDates=!1,_(),l},l.daysOfWeekDisabled=function(a){if(0===arguments.length)return d.daysOfWeekDisabled.splice(0);if("boolean"==typeof a&&!a)return d.daysOfWeekDisabled=!1,_(),l;if(!(a instanceof Array))throw new TypeError("daysOfWeekDisabled() expects an array parameter");if(d.daysOfWeekDisabled=a.reduce(function(a,b){return b=parseInt(b,10),b>6||b<0||isNaN(b)?a:(a.indexOf(b)===-1&&a.push(b),a)},[]).sort(),d.useCurrent&&!d.keepInvalid){for(var b=0;!R(e,"d");){if(e.add(1,"d"),31===b)throw"Tried 31 times to find a valid date";b++}aa(e)}return _(),l},l.maxDate=function(a){if(0===arguments.length)return d.maxDate?d.maxDate.clone():d.maxDate;if("boolean"==typeof a&&a===!1)return d.maxDate=!1,_(),l;"string"==typeof a&&("now"!==a&&"moment"!==a||(a=y()));var b=da(a);if(!b.isValid())throw new TypeError("maxDate() Could not parse date parameter: "+a);if(d.minDate&&b.isBefore(d.minDate))throw new TypeError("maxDate() date parameter is before options.minDate: "+b.format(i));return d.maxDate=b,d.useCurrent&&!d.keepInvalid&&e.isAfter(a)&&aa(d.maxDate),f.isAfter(b)&&(f=b.clone().subtract(d.stepping,"m")),_(),l},l.minDate=function(a){if(0===arguments.length)return d.minDate?d.minDate.clone():d.minDate;if("boolean"==typeof a&&a===!1)return d.minDate=!1,_(),l;"string"==typeof a&&("now"!==a&&"moment"!==a||(a=y()));var b=da(a);if(!b.isValid())throw new TypeError("minDate() Could not parse date parameter: "+a);if(d.maxDate&&b.isAfter(d.maxDate))throw new TypeError("minDate() date parameter is after options.maxDate: "+b.format(i));return d.minDate=b,d.useCurrent&&!d.keepInvalid&&e.isBefore(a)&&aa(d.minDate),f.isBefore(b)&&(f=b.clone().add(d.stepping,"m")),_(),l},l.defaultDate=function(a){if(0===arguments.length)return d.defaultDate?d.defaultDate.clone():d.defaultDate;if(!a)return d.defaultDate=!1,l;"string"==typeof a&&(a="now"===a||"moment"===a?y():y(a));var b=da(a);if(!b.isValid())throw new TypeError("defaultDate() Could not parse date parameter: "+a);if(!R(b))throw new TypeError("defaultDate() date passed is invalid according to component setup validations");return d.defaultDate=b,(d.defaultDate&&d.inline||""===g.val().trim())&&aa(d.defaultDate),l},l.locale=function(a){if(0===arguments.length)return d.locale;if(!b.localeData(a))throw new TypeError("locale() locale "+a+" is not loaded from moment locales!");return d.locale=a,e.locale(d.locale),f.locale(d.locale),i&&pa(),o&&(ba(),ga()),l},l.stepping=function(a){return 0===arguments.length?d.stepping:(a=parseInt(a,10),(isNaN(a)||a<1)&&(a=1),d.stepping=a,l)},l.useCurrent=function(a){var b=["year","month","day","hour","minute"];if(0===arguments.length)return d.useCurrent;if("boolean"!=typeof a&&"string"!=typeof a)throw new TypeError("useCurrent() expects a boolean or string parameter");if("string"==typeof a&&b.indexOf(a.toLowerCase())===-1)throw new TypeError("useCurrent() expects a string parameter of "+b.join(", "));return d.useCurrent=a,l},l.collapse=function(a){if(0===arguments.length)return d.collapse;if("boolean"!=typeof a)throw new TypeError("collapse() expects a boolean parameter");return d.collapse===a?l:(d.collapse=a,o&&(ba(),ga()),l)},l.icons=function(b){if(0===arguments.length)return a.extend({},d.icons);if(!(b instanceof Object))throw new TypeError("icons() expects parameter to be an Object");return a.extend(d.icons,b),o&&(ba(),ga()),l},l.tooltips=function(b){if(0===arguments.length)return a.extend({},d.tooltips);if(!(b instanceof Object))throw new TypeError("tooltips() expects parameter to be an Object");return a.extend(d.tooltips,b),o&&(ba(),ga()),l},l.useStrict=function(a){if(0===arguments.length)return d.useStrict;if("boolean"!=typeof a)throw new TypeError("useStrict() expects a boolean parameter");return d.useStrict=a,l},l.sideBySide=function(a){if(0===arguments.length)return d.sideBySide;if("boolean"!=typeof a)throw new TypeError("sideBySide() expects a boolean parameter");return d.sideBySide=a,o&&(ba(),ga()),l},l.viewMode=function(a){if(0===arguments.length)return d.viewMode;if("string"!=typeof a)throw new TypeError("viewMode() expects a string parameter");if(r.indexOf(a)===-1)throw new TypeError("viewMode() parameter must be one of ("+r.join(", ")+") value");return d.viewMode=a,k=Math.max(r.indexOf(a),p),L(),l},l.toolbarPlacement=function(a){if(0===arguments.length)return d.toolbarPlacement;if("string"!=typeof a)throw new TypeError("toolbarPlacement() expects a string parameter");if(u.indexOf(a)===-1)throw new TypeError("toolbarPlacement() parameter must be one of ("+u.join(", ")+") value");return d.toolbarPlacement=a,o&&(ba(),ga()),l},l.widgetPositioning=function(b){if(0===arguments.length)return a.extend({},d.widgetPositioning);if("[object Object]"!=={}.toString.call(b))throw new TypeError("widgetPositioning() expects an object variable");if(b.horizontal){if("string"!=typeof b.horizontal)throw new TypeError("widgetPositioning() horizontal variable must be a string");if(b.horizontal=b.horizontal.toLowerCase(),t.indexOf(b.horizontal)===-1)throw new TypeError("widgetPositioning() expects horizontal parameter to be one of ("+t.join(", ")+")");d.widgetPositioning.horizontal=b.horizontal}if(b.vertical){if("string"!=typeof b.vertical)throw new TypeError("widgetPositioning() vertical variable must be a string");if(b.vertical=b.vertical.toLowerCase(),s.indexOf(b.vertical)===-1)throw new TypeError("widgetPositioning() expects vertical parameter to be one of ("+s.join(", ")+")");d.widgetPositioning.vertical=b.vertical}return _(),l},l.calendarWeeks=function(a){if(0===arguments.length)return d.calendarWeeks;if("boolean"!=typeof a)throw new TypeError("calendarWeeks() expects parameter to be a boolean value");return d.calendarWeeks=a,_(),l},l.showTodayButton=function(a){if(0===arguments.length)return d.showTodayButton;if("boolean"!=typeof a)throw new TypeError("showTodayButton() expects a boolean parameter");return d.showTodayButton=a,o&&(ba(),ga()),l},l.showClear=function(a){if(0===arguments.length)return d.showClear;if("boolean"!=typeof a)throw new TypeError("showClear() expects a boolean parameter");return d.showClear=a,o&&(ba(),ga()),l},l.widgetParent=function(b){if(0===arguments.length)return d.widgetParent;if("string"==typeof b&&(b=a(b)),null!==b&&"string"!=typeof b&&!(b instanceof a))throw new TypeError("widgetParent() expects a string or a jQuery object parameter");return d.widgetParent=b,o&&(ba(),ga()),l},l.keepOpen=function(a){if(0===arguments.length)return d.keepOpen;if("boolean"!=typeof a)throw new TypeError("keepOpen() expects a boolean parameter");return d.keepOpen=a,l},l.focusOnShow=function(a){if(0===arguments.length)return d.focusOnShow;if("boolean"!=typeof a)throw new TypeError("focusOnShow() expects a boolean parameter");return d.focusOnShow=a,l},l.inline=function(a){if(0===arguments.length)return d.inline;if("boolean"!=typeof a)throw new TypeError("inline() expects a boolean parameter");return d.inline=a,l},l.clear=function(){return ca(),l},l.keyBinds=function(a){return 0===arguments.length?d.keyBinds:(d.keyBinds=a,l)},l.getMoment=function(a){return y(a)},l.debug=function(a){if("boolean"!=typeof a)throw new TypeError("debug() expects a boolean parameter");return d.debug=a,l},l.allowInputToggle=function(a){if(0===arguments.length)return d.allowInputToggle;if("boolean"!=typeof a)throw new TypeError("allowInputToggle() expects a boolean parameter");return d.allowInputToggle=a,l},l.showClose=function(a){if(0===arguments.length)return d.showClose;if("boolean"!=typeof a)throw new TypeError("showClose() expects a boolean parameter");return d.showClose=a,l},l.keepInvalid=function(a){if(0===arguments.length)return d.keepInvalid;if("boolean"!=typeof a)throw new TypeError("keepInvalid() expects a boolean parameter"); +return d.keepInvalid=a,l},l.datepickerInput=function(a){if(0===arguments.length)return d.datepickerInput;if("string"!=typeof a)throw new TypeError("datepickerInput() expects a string parameter");return d.datepickerInput=a,l},l.parseInputDate=function(a){if(0===arguments.length)return d.parseInputDate;if("function"!=typeof a)throw new TypeError("parseInputDate() sholud be as function");return d.parseInputDate=a,l},l.disabledTimeIntervals=function(b){if(0===arguments.length)return d.disabledTimeIntervals?a.extend({},d.disabledTimeIntervals):d.disabledTimeIntervals;if(!b)return d.disabledTimeIntervals=!1,_(),l;if(!(b instanceof Array))throw new TypeError("disabledTimeIntervals() expects an array parameter");return d.disabledTimeIntervals=b,_(),l},l.disabledHours=function(b){if(0===arguments.length)return d.disabledHours?a.extend({},d.disabledHours):d.disabledHours;if(!b)return d.disabledHours=!1,_(),l;if(!(b instanceof Array))throw new TypeError("disabledHours() expects an array parameter");if(d.disabledHours=oa(b),d.enabledHours=!1,d.useCurrent&&!d.keepInvalid){for(var c=0;!R(e,"h");){if(e.add(1,"h"),24===c)throw"Tried 24 times to find a valid date";c++}aa(e)}return _(),l},l.enabledHours=function(b){if(0===arguments.length)return d.enabledHours?a.extend({},d.enabledHours):d.enabledHours;if(!b)return d.enabledHours=!1,_(),l;if(!(b instanceof Array))throw new TypeError("enabledHours() expects an array parameter");if(d.enabledHours=oa(b),d.disabledHours=!1,d.useCurrent&&!d.keepInvalid){for(var c=0;!R(e,"h");){if(e.add(1,"h"),24===c)throw"Tried 24 times to find a valid date";c++}aa(e)}return _(),l},l.viewDate=function(a){if(0===arguments.length)return f.clone();if(!a)return f=e.clone(),l;if(!("string"==typeof a||b.isMoment(a)||a instanceof Date))throw new TypeError("viewDate() parameter must be one of [string, moment or Date]");return f=da(a),K(),l},c.is("input"))g=c;else if(g=c.find(d.datepickerInput),0===g.length)g=c.find("input");else if(!g.is("input"))throw new Error('CSS class "'+d.datepickerInput+'" cannot be applied to non input element');if(c.hasClass("input-group")&&(n=0===c.find(".datepickerbutton").length?c.find(".input-group-addon"):c.find(".datepickerbutton")),!d.inline&&!g.is("input"))throw new Error("Could not initialize DateTimePicker without an input element");return e=y(),f=e.clone(),a.extend(!0,d,H()),l.options(d),pa(),la(),g.prop("disabled")&&l.disable(),g.is("input")&&0!==g.val().trim().length?aa(da(g.val().trim())):d.defaultDate&&void 0===g.attr("placeholder")&&aa(d.defaultDate),d.inline&&ga(),l};return a.fn.datetimepicker=function(b){b=b||{};var d,e=Array.prototype.slice.call(arguments,1),f=!0,g=["destroy","hide","show","toggle"];if("object"==typeof b)return this.each(function(){var d,e=a(this);e.data("DateTimePicker")||(d=a.extend(!0,{},a.fn.datetimepicker.defaults,b),e.data("DateTimePicker",c(e,d)))});if("string"==typeof b)return this.each(function(){var c=a(this),g=c.data("DateTimePicker");if(!g)throw new Error('bootstrap-datetimepicker("'+b+'") method was called on an element that is not using DateTimePicker');d=g[b].apply(g,e),f=d===g}),f||a.inArray(b,g)>-1?this:d;throw new TypeError("Invalid arguments for DateTimePicker: "+b)},a.fn.datetimepicker.defaults={timeZone:"",format:!1,dayViewHeaderFormat:"MMMM YYYY",extraFormats:!1,stepping:1,minDate:!1,maxDate:!1,useCurrent:!0,collapse:!0,locale:b.locale(),defaultDate:!1,disabledDates:!1,enabledDates:!1,icons:{time:"glyphicon glyphicon-time",date:"glyphicon glyphicon-calendar",up:"glyphicon glyphicon-chevron-up",down:"glyphicon glyphicon-chevron-down",previous:"glyphicon glyphicon-chevron-left",next:"glyphicon glyphicon-chevron-right",today:"glyphicon glyphicon-screenshot",clear:"glyphicon glyphicon-trash",close:"glyphicon glyphicon-remove"},tooltips:{today:"Go to today",clear:"Clear selection",close:"Close the picker",selectMonth:"Select Month",prevMonth:"Previous Month",nextMonth:"Next Month",selectYear:"Select Year",prevYear:"Previous Year",nextYear:"Next Year",selectDecade:"Select Decade",prevDecade:"Previous Decade",nextDecade:"Next Decade",prevCentury:"Previous Century",nextCentury:"Next Century",pickHour:"Pick Hour",incrementHour:"Increment Hour",decrementHour:"Decrement Hour",pickMinute:"Pick Minute",incrementMinute:"Increment Minute",decrementMinute:"Decrement Minute",pickSecond:"Pick Second",incrementSecond:"Increment Second",decrementSecond:"Decrement Second",togglePeriod:"Toggle Period",selectTime:"Select Time"},useStrict:!1,sideBySide:!1,daysOfWeekDisabled:!1,calendarWeeks:!1,viewMode:"days",toolbarPlacement:"default",showTodayButton:!1,showClear:!1,showClose:!1,widgetPositioning:{horizontal:"auto",vertical:"auto"},widgetParent:null,ignoreReadonly:!1,keepOpen:!1,focusOnShow:!0,inline:!1,keepInvalid:!1,datepickerInput:".datepickerinput",keyBinds:{up:function(a){if(a){var b=this.date()||this.getMoment();a.find(".datepicker").is(":visible")?this.date(b.clone().subtract(7,"d")):this.date(b.clone().add(this.stepping(),"m"))}},down:function(a){if(!a)return void this.show();var b=this.date()||this.getMoment();a.find(".datepicker").is(":visible")?this.date(b.clone().add(7,"d")):this.date(b.clone().subtract(this.stepping(),"m"))},"control up":function(a){if(a){var b=this.date()||this.getMoment();a.find(".datepicker").is(":visible")?this.date(b.clone().subtract(1,"y")):this.date(b.clone().add(1,"h"))}},"control down":function(a){if(a){var b=this.date()||this.getMoment();a.find(".datepicker").is(":visible")?this.date(b.clone().add(1,"y")):this.date(b.clone().subtract(1,"h"))}},left:function(a){if(a){var b=this.date()||this.getMoment();a.find(".datepicker").is(":visible")&&this.date(b.clone().subtract(1,"d"))}},right:function(a){if(a){var b=this.date()||this.getMoment();a.find(".datepicker").is(":visible")&&this.date(b.clone().add(1,"d"))}},pageUp:function(a){if(a){var b=this.date()||this.getMoment();a.find(".datepicker").is(":visible")&&this.date(b.clone().subtract(1,"M"))}},pageDown:function(a){if(a){var b=this.date()||this.getMoment();a.find(".datepicker").is(":visible")&&this.date(b.clone().add(1,"M"))}},enter:function(){this.hide()},escape:function(){this.hide()},"control space":function(a){a&&a.find(".timepicker").is(":visible")&&a.find('.btn[data-action="togglePeriod"]').click()},t:function(){this.date(this.getMoment())},delete:function(){this.clear()}},debug:!1,allowInputToggle:!1,disabledTimeIntervals:!1,disabledHours:!1,enabledHours:!1,viewDate:!1},a.fn.datetimepicker}); \ No newline at end of file diff --git a/src/static_src/js/moment-with-locales.min.js b/src/static_src/js/moment-with-locales.min.js new file mode 100644 index 00000000..f6043488 --- /dev/null +++ b/src/static_src/js/moment-with-locales.min.js @@ -0,0 +1,10 @@ +//! moment.js +//! version : 2.9.0 +//! authors : Tim Wood, Iskren Chernev, Moment.js contributors +//! license : MIT +//! momentjs.com +(function(a){function b(a,b,c){switch(arguments.length){case 2:return null!=a?a:b;case 3:return null!=a?a:null!=b?b:c;default:throw new Error("Implement me")}}function c(a,b){return Bb.call(a,b)}function d(){return{empty:!1,unusedTokens:[],unusedInput:[],overflow:-2,charsLeftOver:0,nullInput:!1,invalidMonth:null,invalidFormat:!1,userInvalidated:!1,iso:!1}}function e(a){vb.suppressDeprecationWarnings===!1&&"undefined"!=typeof console&&console.warn&&console.warn("Deprecation warning: "+a)}function f(a,b){var c=!0;return o(function(){return c&&(e(a),c=!1),b.apply(this,arguments)},b)}function g(a,b){sc[a]||(e(b),sc[a]=!0)}function h(a,b){return function(c){return r(a.call(this,c),b)}}function i(a,b){return function(c){return this.localeData().ordinal(a.call(this,c),b)}}function j(a,b){var c,d,e=12*(b.year()-a.year())+(b.month()-a.month()),f=a.clone().add(e,"months");return 0>b-f?(c=a.clone().add(e-1,"months"),d=(b-f)/(f-c)):(c=a.clone().add(e+1,"months"),d=(b-f)/(c-f)),-(e+d)}function k(a,b,c){var d;return null==c?b:null!=a.meridiemHour?a.meridiemHour(b,c):null!=a.isPM?(d=a.isPM(c),d&&12>b&&(b+=12),d||12!==b||(b=0),b):b}function l(){}function m(a,b){b!==!1&&H(a),p(this,a),this._d=new Date(+a._d),uc===!1&&(uc=!0,vb.updateOffset(this),uc=!1)}function n(a){var b=A(a),c=b.year||0,d=b.quarter||0,e=b.month||0,f=b.week||0,g=b.day||0,h=b.hour||0,i=b.minute||0,j=b.second||0,k=b.millisecond||0;this._milliseconds=+k+1e3*j+6e4*i+36e5*h,this._days=+g+7*f,this._months=+e+3*d+12*c,this._data={},this._locale=vb.localeData(),this._bubble()}function o(a,b){for(var d in b)c(b,d)&&(a[d]=b[d]);return c(b,"toString")&&(a.toString=b.toString),c(b,"valueOf")&&(a.valueOf=b.valueOf),a}function p(a,b){var c,d,e;if("undefined"!=typeof b._isAMomentObject&&(a._isAMomentObject=b._isAMomentObject),"undefined"!=typeof b._i&&(a._i=b._i),"undefined"!=typeof b._f&&(a._f=b._f),"undefined"!=typeof b._l&&(a._l=b._l),"undefined"!=typeof b._strict&&(a._strict=b._strict),"undefined"!=typeof b._tzm&&(a._tzm=b._tzm),"undefined"!=typeof b._isUTC&&(a._isUTC=b._isUTC),"undefined"!=typeof b._offset&&(a._offset=b._offset),"undefined"!=typeof b._pf&&(a._pf=b._pf),"undefined"!=typeof b._locale&&(a._locale=b._locale),Kb.length>0)for(c in Kb)d=Kb[c],e=b[d],"undefined"!=typeof e&&(a[d]=e);return a}function q(a){return 0>a?Math.ceil(a):Math.floor(a)}function r(a,b,c){for(var d=""+Math.abs(a),e=a>=0;d.lengthd;d++)(c&&a[d]!==b[d]||!c&&C(a[d])!==C(b[d]))&&g++;return g+f}function z(a){if(a){var b=a.toLowerCase().replace(/(.)s$/,"$1");a=lc[a]||mc[b]||b}return a}function A(a){var b,d,e={};for(d in a)c(a,d)&&(b=z(d),b&&(e[b]=a[d]));return e}function B(b){var c,d;if(0===b.indexOf("week"))c=7,d="day";else{if(0!==b.indexOf("month"))return;c=12,d="month"}vb[b]=function(e,f){var g,h,i=vb._locale[b],j=[];if("number"==typeof e&&(f=e,e=a),h=function(a){var b=vb().utc().set(d,a);return i.call(vb._locale,b,e||"")},null!=f)return h(f);for(g=0;c>g;g++)j.push(h(g));return j}}function C(a){var b=+a,c=0;return 0!==b&&isFinite(b)&&(c=b>=0?Math.floor(b):Math.ceil(b)),c}function D(a,b){return new Date(Date.UTC(a,b+1,0)).getUTCDate()}function E(a,b,c){return jb(vb([a,11,31+b-c]),b,c).week}function F(a){return G(a)?366:365}function G(a){return a%4===0&&a%100!==0||a%400===0}function H(a){var b;a._a&&-2===a._pf.overflow&&(b=a._a[Db]<0||a._a[Db]>11?Db:a._a[Eb]<1||a._a[Eb]>D(a._a[Cb],a._a[Db])?Eb:a._a[Fb]<0||a._a[Fb]>24||24===a._a[Fb]&&(0!==a._a[Gb]||0!==a._a[Hb]||0!==a._a[Ib])?Fb:a._a[Gb]<0||a._a[Gb]>59?Gb:a._a[Hb]<0||a._a[Hb]>59?Hb:a._a[Ib]<0||a._a[Ib]>999?Ib:-1,a._pf._overflowDayOfYear&&(Cb>b||b>Eb)&&(b=Eb),a._pf.overflow=b)}function I(b){return null==b._isValid&&(b._isValid=!isNaN(b._d.getTime())&&b._pf.overflow<0&&!b._pf.empty&&!b._pf.invalidMonth&&!b._pf.nullInput&&!b._pf.invalidFormat&&!b._pf.userInvalidated,b._strict&&(b._isValid=b._isValid&&0===b._pf.charsLeftOver&&0===b._pf.unusedTokens.length&&b._pf.bigHour===a)),b._isValid}function J(a){return a?a.toLowerCase().replace("_","-"):a}function K(a){for(var b,c,d,e,f=0;f0;){if(d=L(e.slice(0,b).join("-")))return d;if(c&&c.length>=b&&y(e,c,!0)>=b-1)break;b--}f++}return null}function L(a){var b=null;if(!Jb[a]&&Lb)try{b=vb.locale(),require("./locale/"+a),vb.locale(b)}catch(c){}return Jb[a]}function M(a,b){var c,d;return b._isUTC?(c=b.clone(),d=(vb.isMoment(a)||x(a)?+a:+vb(a))-+c,c._d.setTime(+c._d+d),vb.updateOffset(c,!1),c):vb(a).local()}function N(a){return a.match(/\[[\s\S]/)?a.replace(/^\[|\]$/g,""):a.replace(/\\/g,"")}function O(a){var b,c,d=a.match(Pb);for(b=0,c=d.length;c>b;b++)d[b]=rc[d[b]]?rc[d[b]]:N(d[b]);return function(e){var f="";for(b=0;c>b;b++)f+=d[b]instanceof Function?d[b].call(e,a):d[b];return f}}function P(a,b){return a.isValid()?(b=Q(b,a.localeData()),nc[b]||(nc[b]=O(b)),nc[b](a)):a.localeData().invalidDate()}function Q(a,b){function c(a){return b.longDateFormat(a)||a}var d=5;for(Qb.lastIndex=0;d>=0&&Qb.test(a);)a=a.replace(Qb,c),Qb.lastIndex=0,d-=1;return a}function R(a,b){var c,d=b._strict;switch(a){case"Q":return _b;case"DDDD":return bc;case"YYYY":case"GGGG":case"gggg":return d?cc:Tb;case"Y":case"G":case"g":return ec;case"YYYYYY":case"YYYYY":case"GGGGG":case"ggggg":return d?dc:Ub;case"S":if(d)return _b;case"SS":if(d)return ac;case"SSS":if(d)return bc;case"DDD":return Sb;case"MMM":case"MMMM":case"dd":case"ddd":case"dddd":return Wb;case"a":case"A":return b._locale._meridiemParse;case"x":return Zb;case"X":return $b;case"Z":case"ZZ":return Xb;case"T":return Yb;case"SSSS":return Vb;case"MM":case"DD":case"YY":case"GG":case"gg":case"HH":case"hh":case"mm":case"ss":case"ww":case"WW":return d?ac:Rb;case"M":case"D":case"d":case"H":case"h":case"m":case"s":case"w":case"W":case"e":case"E":return Rb;case"Do":return d?b._locale._ordinalParse:b._locale._ordinalParseLenient;default:return c=new RegExp($(Z(a.replace("\\","")),"i"))}}function S(a){a=a||"";var b=a.match(Xb)||[],c=b[b.length-1]||[],d=(c+"").match(jc)||["-",0,0],e=+(60*d[1])+C(d[2]);return"+"===d[0]?e:-e}function T(a,b,c){var d,e=c._a;switch(a){case"Q":null!=b&&(e[Db]=3*(C(b)-1));break;case"M":case"MM":null!=b&&(e[Db]=C(b)-1);break;case"MMM":case"MMMM":d=c._locale.monthsParse(b,a,c._strict),null!=d?e[Db]=d:c._pf.invalidMonth=b;break;case"D":case"DD":null!=b&&(e[Eb]=C(b));break;case"Do":null!=b&&(e[Eb]=C(parseInt(b.match(/\d{1,2}/)[0],10)));break;case"DDD":case"DDDD":null!=b&&(c._dayOfYear=C(b));break;case"YY":e[Cb]=vb.parseTwoDigitYear(b);break;case"YYYY":case"YYYYY":case"YYYYYY":e[Cb]=C(b);break;case"a":case"A":c._meridiem=b;break;case"h":case"hh":c._pf.bigHour=!0;case"H":case"HH":e[Fb]=C(b);break;case"m":case"mm":e[Gb]=C(b);break;case"s":case"ss":e[Hb]=C(b);break;case"S":case"SS":case"SSS":case"SSSS":e[Ib]=C(1e3*("0."+b));break;case"x":c._d=new Date(C(b));break;case"X":c._d=new Date(1e3*parseFloat(b));break;case"Z":case"ZZ":c._useUTC=!0,c._tzm=S(b);break;case"dd":case"ddd":case"dddd":d=c._locale.weekdaysParse(b),null!=d?(c._w=c._w||{},c._w.d=d):c._pf.invalidWeekday=b;break;case"w":case"ww":case"W":case"WW":case"d":case"e":case"E":a=a.substr(0,1);case"gggg":case"GGGG":case"GGGGG":a=a.substr(0,2),b&&(c._w=c._w||{},c._w[a]=C(b));break;case"gg":case"GG":c._w=c._w||{},c._w[a]=vb.parseTwoDigitYear(b)}}function U(a){var c,d,e,f,g,h,i;c=a._w,null!=c.GG||null!=c.W||null!=c.E?(g=1,h=4,d=b(c.GG,a._a[Cb],jb(vb(),1,4).year),e=b(c.W,1),f=b(c.E,1)):(g=a._locale._week.dow,h=a._locale._week.doy,d=b(c.gg,a._a[Cb],jb(vb(),g,h).year),e=b(c.w,1),null!=c.d?(f=c.d,g>f&&++e):f=null!=c.e?c.e+g:g),i=kb(d,e,f,h,g),a._a[Cb]=i.year,a._dayOfYear=i.dayOfYear}function V(a){var c,d,e,f,g=[];if(!a._d){for(e=X(a),a._w&&null==a._a[Eb]&&null==a._a[Db]&&U(a),a._dayOfYear&&(f=b(a._a[Cb],e[Cb]),a._dayOfYear>F(f)&&(a._pf._overflowDayOfYear=!0),d=fb(f,0,a._dayOfYear),a._a[Db]=d.getUTCMonth(),a._a[Eb]=d.getUTCDate()),c=0;3>c&&null==a._a[c];++c)a._a[c]=g[c]=e[c];for(;7>c;c++)a._a[c]=g[c]=null==a._a[c]?2===c?1:0:a._a[c];24===a._a[Fb]&&0===a._a[Gb]&&0===a._a[Hb]&&0===a._a[Ib]&&(a._nextDay=!0,a._a[Fb]=0),a._d=(a._useUTC?fb:eb).apply(null,g),null!=a._tzm&&a._d.setUTCMinutes(a._d.getUTCMinutes()-a._tzm),a._nextDay&&(a._a[Fb]=24)}}function W(a){var b;a._d||(b=A(a._i),a._a=[b.year,b.month,b.day||b.date,b.hour,b.minute,b.second,b.millisecond],V(a))}function X(a){var b=new Date;return a._useUTC?[b.getUTCFullYear(),b.getUTCMonth(),b.getUTCDate()]:[b.getFullYear(),b.getMonth(),b.getDate()]}function Y(b){if(b._f===vb.ISO_8601)return void ab(b);b._a=[],b._pf.empty=!0;var c,d,e,f,g,h=""+b._i,i=h.length,j=0;for(e=Q(b._f,b._locale).match(Pb)||[],c=0;c0&&b._pf.unusedInput.push(g),h=h.slice(h.indexOf(d)+d.length),j+=d.length),rc[f]?(d?b._pf.empty=!1:b._pf.unusedTokens.push(f),T(f,d,b)):b._strict&&!d&&b._pf.unusedTokens.push(f);b._pf.charsLeftOver=i-j,h.length>0&&b._pf.unusedInput.push(h),b._pf.bigHour===!0&&b._a[Fb]<=12&&(b._pf.bigHour=a),b._a[Fb]=k(b._locale,b._a[Fb],b._meridiem),V(b),H(b)}function Z(a){return a.replace(/\\(\[)|\\(\])|\[([^\]\[]*)\]|\\(.)/g,function(a,b,c,d,e){return b||c||d||e})}function $(a){return a.replace(/[-\/\\^$*+?.()|[\]{}]/g,"\\$&")}function _(a){var b,c,e,f,g;if(0===a._f.length)return a._pf.invalidFormat=!0,void(a._d=new Date(0/0));for(f=0;fg)&&(e=g,c=b));o(a,c||b)}function ab(a){var b,c,d=a._i,e=fc.exec(d);if(e){for(a._pf.iso=!0,b=0,c=hc.length;c>b;b++)if(hc[b][1].exec(d)){a._f=hc[b][0]+(e[6]||" ");break}for(b=0,c=ic.length;c>b;b++)if(ic[b][1].exec(d)){a._f+=ic[b][0];break}d.match(Xb)&&(a._f+="Z"),Y(a)}else a._isValid=!1}function bb(a){ab(a),a._isValid===!1&&(delete a._isValid,vb.createFromInputFallback(a))}function cb(a,b){var c,d=[];for(c=0;ca&&h.setFullYear(a),h}function fb(a){var b=new Date(Date.UTC.apply(null,arguments));return 1970>a&&b.setUTCFullYear(a),b}function gb(a,b){if("string"==typeof a)if(isNaN(a)){if(a=b.weekdaysParse(a),"number"!=typeof a)return null}else a=parseInt(a,10);return a}function hb(a,b,c,d,e){return e.relativeTime(b||1,!!c,a,d)}function ib(a,b,c){var d=vb.duration(a).abs(),e=Ab(d.as("s")),f=Ab(d.as("m")),g=Ab(d.as("h")),h=Ab(d.as("d")),i=Ab(d.as("M")),j=Ab(d.as("y")),k=e0,k[4]=c,hb.apply({},k)}function jb(a,b,c){var d,e=c-b,f=c-a.day();return f>e&&(f-=7),e-7>f&&(f+=7),d=vb(a).add(f,"d"),{week:Math.ceil(d.dayOfYear()/7),year:d.year()}}function kb(a,b,c,d,e){var f,g,h=fb(a,0,1).getUTCDay();return h=0===h?7:h,c=null!=c?c:e,f=e-h+(h>d?7:0)-(e>h?7:0),g=7*(b-1)+(c-e)+f+1,{year:g>0?a:a-1,dayOfYear:g>0?g:F(a-1)+g}}function lb(b){var c,d=b._i,e=b._f;return b._locale=b._locale||vb.localeData(b._l),null===d||e===a&&""===d?vb.invalid({nullInput:!0}):("string"==typeof d&&(b._i=d=b._locale.preparse(d)),vb.isMoment(d)?new m(d,!0):(e?w(e)?_(b):Y(b):db(b),c=new m(b),c._nextDay&&(c.add(1,"d"),c._nextDay=a),c))}function mb(a,b){var c,d;if(1===b.length&&w(b[0])&&(b=b[0]),!b.length)return vb();for(c=b[0],d=1;d=0?"+":"-";return b+r(Math.abs(a),6)},gg:function(){return r(this.weekYear()%100,2)},gggg:function(){return r(this.weekYear(),4)},ggggg:function(){return r(this.weekYear(),5)},GG:function(){return r(this.isoWeekYear()%100,2)},GGGG:function(){return r(this.isoWeekYear(),4)},GGGGG:function(){return r(this.isoWeekYear(),5)},e:function(){return this.weekday()},E:function(){return this.isoWeekday()},a:function(){return this.localeData().meridiem(this.hours(),this.minutes(),!0)},A:function(){return this.localeData().meridiem(this.hours(),this.minutes(),!1)},H:function(){return this.hours()},h:function(){return this.hours()%12||12},m:function(){return this.minutes()},s:function(){return this.seconds()},S:function(){return C(this.milliseconds()/100)},SS:function(){return r(C(this.milliseconds()/10),2)},SSS:function(){return r(this.milliseconds(),3)},SSSS:function(){return r(this.milliseconds(),3)},Z:function(){var a=this.utcOffset(),b="+";return 0>a&&(a=-a,b="-"),b+r(C(a/60),2)+":"+r(C(a)%60,2)},ZZ:function(){var a=this.utcOffset(),b="+";return 0>a&&(a=-a,b="-"),b+r(C(a/60),2)+r(C(a)%60,2)},z:function(){return this.zoneAbbr()},zz:function(){return this.zoneName()},x:function(){return this.valueOf()},X:function(){return this.unix()},Q:function(){return this.quarter()}},sc={},tc=["months","monthsShort","weekdays","weekdaysShort","weekdaysMin"],uc=!1;pc.length;)xb=pc.pop(),rc[xb+"o"]=i(rc[xb],xb);for(;qc.length;)xb=qc.pop(),rc[xb+xb]=h(rc[xb],2);rc.DDDD=h(rc.DDD,3),o(l.prototype,{set:function(a){var b,c;for(c in a)b=a[c],"function"==typeof b?this[c]=b:this["_"+c]=b;this._ordinalParseLenient=new RegExp(this._ordinalParse.source+"|"+/\d{1,2}/.source)},_months:"January_February_March_April_May_June_July_August_September_October_November_December".split("_"),months:function(a){return this._months[a.month()]},_monthsShort:"Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec".split("_"),monthsShort:function(a){return this._monthsShort[a.month()]},monthsParse:function(a,b,c){var d,e,f;for(this._monthsParse||(this._monthsParse=[],this._longMonthsParse=[],this._shortMonthsParse=[]),d=0;12>d;d++){if(e=vb.utc([2e3,d]),c&&!this._longMonthsParse[d]&&(this._longMonthsParse[d]=new RegExp("^"+this.months(e,"").replace(".","")+"$","i"),this._shortMonthsParse[d]=new RegExp("^"+this.monthsShort(e,"").replace(".","")+"$","i")),c||this._monthsParse[d]||(f="^"+this.months(e,"")+"|^"+this.monthsShort(e,""),this._monthsParse[d]=new RegExp(f.replace(".",""),"i")),c&&"MMMM"===b&&this._longMonthsParse[d].test(a))return d;if(c&&"MMM"===b&&this._shortMonthsParse[d].test(a))return d;if(!c&&this._monthsParse[d].test(a))return d}},_weekdays:"Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),weekdays:function(a){return this._weekdays[a.day()]},_weekdaysShort:"Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),weekdaysShort:function(a){return this._weekdaysShort[a.day()]},_weekdaysMin:"Su_Mo_Tu_We_Th_Fr_Sa".split("_"),weekdaysMin:function(a){return this._weekdaysMin[a.day()]},weekdaysParse:function(a){var b,c,d;for(this._weekdaysParse||(this._weekdaysParse=[]),b=0;7>b;b++)if(this._weekdaysParse[b]||(c=vb([2e3,1]).day(b),d="^"+this.weekdays(c,"")+"|^"+this.weekdaysShort(c,"")+"|^"+this.weekdaysMin(c,""),this._weekdaysParse[b]=new RegExp(d.replace(".",""),"i")),this._weekdaysParse[b].test(a))return b},_longDateFormat:{LTS:"h:mm:ss A",LT:"h:mm A",L:"MM/DD/YYYY",LL:"MMMM D, YYYY",LLL:"MMMM D, YYYY LT",LLLL:"dddd, MMMM D, YYYY LT"},longDateFormat:function(a){var b=this._longDateFormat[a];return!b&&this._longDateFormat[a.toUpperCase()]&&(b=this._longDateFormat[a.toUpperCase()].replace(/MMMM|MM|DD|dddd/g,function(a){return a.slice(1)}),this._longDateFormat[a]=b),b},isPM:function(a){return"p"===(a+"").toLowerCase().charAt(0)},_meridiemParse:/[ap]\.?m?\.?/i,meridiem:function(a,b,c){return a>11?c?"pm":"PM":c?"am":"AM"},_calendar:{sameDay:"[Today at] LT",nextDay:"[Tomorrow at] LT",nextWeek:"dddd [at] LT",lastDay:"[Yesterday at] LT",lastWeek:"[Last] dddd [at] LT",sameElse:"L"},calendar:function(a,b,c){var d=this._calendar[a];return"function"==typeof d?d.apply(b,[c]):d},_relativeTime:{future:"in %s",past:"%s ago",s:"a few seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",M:"a month",MM:"%d months",y:"a year",yy:"%d years"},relativeTime:function(a,b,c,d){var e=this._relativeTime[c];return"function"==typeof e?e(a,b,c,d):e.replace(/%d/i,a)},pastFuture:function(a,b){var c=this._relativeTime[a>0?"future":"past"];return"function"==typeof c?c(b):c.replace(/%s/i,b)},ordinal:function(a){return this._ordinal.replace("%d",a)},_ordinal:"%d",_ordinalParse:/\d{1,2}/,preparse:function(a){return a},postformat:function(a){return a},week:function(a){return jb(a,this._week.dow,this._week.doy).week},_week:{dow:0,doy:6},firstDayOfWeek:function(){return this._week.dow},firstDayOfYear:function(){return this._week.doy},_invalidDate:"Invalid date",invalidDate:function(){return this._invalidDate}}),vb=function(b,c,e,f){var g;return"boolean"==typeof e&&(f=e,e=a),g={},g._isAMomentObject=!0,g._i=b,g._f=c,g._l=e,g._strict=f,g._isUTC=!1,g._pf=d(),lb(g)},vb.suppressDeprecationWarnings=!1,vb.createFromInputFallback=f("moment construction falls back to js Date. This is discouraged and will be removed in upcoming major release. Please refer to https://github.com/moment/moment/issues/1407 for more info.",function(a){a._d=new Date(a._i+(a._useUTC?" UTC":""))}),vb.min=function(){var a=[].slice.call(arguments,0);return mb("isBefore",a)},vb.max=function(){var a=[].slice.call(arguments,0);return mb("isAfter",a)},vb.utc=function(b,c,e,f){var g;return"boolean"==typeof e&&(f=e,e=a),g={},g._isAMomentObject=!0,g._useUTC=!0,g._isUTC=!0,g._l=e,g._i=b,g._f=c,g._strict=f,g._pf=d(),lb(g).utc()},vb.unix=function(a){return vb(1e3*a)},vb.duration=function(a,b){var d,e,f,g,h=a,i=null;return vb.isDuration(a)?h={ms:a._milliseconds,d:a._days,M:a._months}:"number"==typeof a?(h={},b?h[b]=a:h.milliseconds=a):(i=Nb.exec(a))?(d="-"===i[1]?-1:1,h={y:0,d:C(i[Eb])*d,h:C(i[Fb])*d,m:C(i[Gb])*d,s:C(i[Hb])*d,ms:C(i[Ib])*d}):(i=Ob.exec(a))?(d="-"===i[1]?-1:1,f=function(a){var b=a&&parseFloat(a.replace(",","."));return(isNaN(b)?0:b)*d},h={y:f(i[2]),M:f(i[3]),d:f(i[4]),h:f(i[5]),m:f(i[6]),s:f(i[7]),w:f(i[8])}):null==h?h={}:"object"==typeof h&&("from"in h||"to"in h)&&(g=t(vb(h.from),vb(h.to)),h={},h.ms=g.milliseconds,h.M=g.months),e=new n(h),vb.isDuration(a)&&c(a,"_locale")&&(e._locale=a._locale),e},vb.version=yb,vb.defaultFormat=gc,vb.ISO_8601=function(){},vb.momentProperties=Kb,vb.updateOffset=function(){},vb.relativeTimeThreshold=function(b,c){return oc[b]===a?!1:c===a?oc[b]:(oc[b]=c,!0)},vb.lang=f("moment.lang is deprecated. Use moment.locale instead.",function(a,b){return vb.locale(a,b)}),vb.locale=function(a,b){var c;return a&&(c="undefined"!=typeof b?vb.defineLocale(a,b):vb.localeData(a),c&&(vb.duration._locale=vb._locale=c)),vb._locale._abbr},vb.defineLocale=function(a,b){return null!==b?(b.abbr=a,Jb[a]||(Jb[a]=new l),Jb[a].set(b),vb.locale(a),Jb[a]):(delete Jb[a],null)},vb.langData=f("moment.langData is deprecated. Use moment.localeData instead.",function(a){return vb.localeData(a)}),vb.localeData=function(a){var b;if(a&&a._locale&&a._locale._abbr&&(a=a._locale._abbr),!a)return vb._locale;if(!w(a)){if(b=L(a))return b;a=[a]}return K(a)},vb.isMoment=function(a){return a instanceof m||null!=a&&c(a,"_isAMomentObject")},vb.isDuration=function(a){return a instanceof n};for(xb=tc.length-1;xb>=0;--xb)B(tc[xb]);vb.normalizeUnits=function(a){return z(a)},vb.invalid=function(a){var b=vb.utc(0/0);return null!=a?o(b._pf,a):b._pf.userInvalidated=!0,b},vb.parseZone=function(){return vb.apply(null,arguments).parseZone()},vb.parseTwoDigitYear=function(a){return C(a)+(C(a)>68?1900:2e3)},vb.isDate=x,o(vb.fn=m.prototype,{clone:function(){return vb(this)},valueOf:function(){return+this._d-6e4*(this._offset||0)},unix:function(){return Math.floor(+this/1e3)},toString:function(){return this.clone().locale("en").format("ddd MMM DD YYYY HH:mm:ss [GMT]ZZ")},toDate:function(){return this._offset?new Date(+this):this._d},toISOString:function(){var a=vb(this).utc();return 00:!1},parsingFlags:function(){return o({},this._pf)},invalidAt:function(){return this._pf.overflow},utc:function(a){return this.utcOffset(0,a)},local:function(a){return this._isUTC&&(this.utcOffset(0,a),this._isUTC=!1,a&&this.subtract(this._dateUtcOffset(),"m")),this},format:function(a){var b=P(this,a||vb.defaultFormat);return this.localeData().postformat(b)},add:u(1,"add"),subtract:u(-1,"subtract"),diff:function(a,b,c){var d,e,f=M(a,this),g=6e4*(f.utcOffset()-this.utcOffset());return b=z(b),"year"===b||"month"===b||"quarter"===b?(e=j(this,f),"quarter"===b?e/=3:"year"===b&&(e/=12)):(d=this-f,e="second"===b?d/1e3:"minute"===b?d/6e4:"hour"===b?d/36e5:"day"===b?(d-g)/864e5:"week"===b?(d-g)/6048e5:d),c?e:q(e)},from:function(a,b){return vb.duration({to:this,from:a}).locale(this.locale()).humanize(!b)},fromNow:function(a){return this.from(vb(),a)},calendar:function(a){var b=a||vb(),c=M(b,this).startOf("day"),d=this.diff(c,"days",!0),e=-6>d?"sameElse":-1>d?"lastWeek":0>d?"lastDay":1>d?"sameDay":2>d?"nextDay":7>d?"nextWeek":"sameElse";return this.format(this.localeData().calendar(e,this,vb(b)))},isLeapYear:function(){return G(this.year())},isDST:function(){return this.utcOffset()>this.clone().month(0).utcOffset()||this.utcOffset()>this.clone().month(5).utcOffset()},day:function(a){var b=this._isUTC?this._d.getUTCDay():this._d.getDay();return null!=a?(a=gb(a,this.localeData()),this.add(a-b,"d")):b},month:qb("Month",!0),startOf:function(a){switch(a=z(a)){case"year":this.month(0);case"quarter":case"month":this.date(1);case"week":case"isoWeek":case"day":this.hours(0);case"hour":this.minutes(0);case"minute":this.seconds(0);case"second":this.milliseconds(0)}return"week"===a?this.weekday(0):"isoWeek"===a&&this.isoWeekday(1),"quarter"===a&&this.month(3*Math.floor(this.month()/3)),this},endOf:function(b){return b=z(b),b===a||"millisecond"===b?this:this.startOf(b).add(1,"isoWeek"===b?"week":b).subtract(1,"ms")},isAfter:function(a,b){var c;return b=z("undefined"!=typeof b?b:"millisecond"),"millisecond"===b?(a=vb.isMoment(a)?a:vb(a),+this>+a):(c=vb.isMoment(a)?+a:+vb(a),c<+this.clone().startOf(b))},isBefore:function(a,b){var c;return b=z("undefined"!=typeof b?b:"millisecond"),"millisecond"===b?(a=vb.isMoment(a)?a:vb(a),+a>+this):(c=vb.isMoment(a)?+a:+vb(a),+this.clone().endOf(b)a?this:a}),max:f("moment().max is deprecated, use moment.max instead. https://github.com/moment/moment/issues/1548",function(a){return a=vb.apply(null,arguments),a>this?this:a}),zone:f("moment().zone is deprecated, use moment().utcOffset instead. https://github.com/moment/moment/issues/1779",function(a,b){return null!=a?("string"!=typeof a&&(a=-a),this.utcOffset(a,b),this):-this.utcOffset()}),utcOffset:function(a,b){var c,d=this._offset||0;return null!=a?("string"==typeof a&&(a=S(a)),Math.abs(a)<16&&(a=60*a),!this._isUTC&&b&&(c=this._dateUtcOffset()),this._offset=a,this._isUTC=!0,null!=c&&this.add(c,"m"),d!==a&&(!b||this._changeInProgress?v(this,vb.duration(a-d,"m"),1,!1):this._changeInProgress||(this._changeInProgress=!0,vb.updateOffset(this,!0),this._changeInProgress=null)),this):this._isUTC?d:this._dateUtcOffset()},isLocal:function(){return!this._isUTC},isUtcOffset:function(){return this._isUTC},isUtc:function(){return this._isUTC&&0===this._offset},zoneAbbr:function(){return this._isUTC?"UTC":""},zoneName:function(){return this._isUTC?"Coordinated Universal Time":""},parseZone:function(){return this._tzm?this.utcOffset(this._tzm):"string"==typeof this._i&&this.utcOffset(S(this._i)),this},hasAlignedHourOffset:function(a){return a=a?vb(a).utcOffset():0,(this.utcOffset()-a)%60===0},daysInMonth:function(){return D(this.year(),this.month())},dayOfYear:function(a){var b=Ab((vb(this).startOf("day")-vb(this).startOf("year"))/864e5)+1;return null==a?b:this.add(a-b,"d")},quarter:function(a){return null==a?Math.ceil((this.month()+1)/3):this.month(3*(a-1)+this.month()%3)},weekYear:function(a){var b=jb(this,this.localeData()._week.dow,this.localeData()._week.doy).year;return null==a?b:this.add(a-b,"y")},isoWeekYear:function(a){var b=jb(this,1,4).year;return null==a?b:this.add(a-b,"y")},week:function(a){var b=this.localeData().week(this);return null==a?b:this.add(7*(a-b),"d")},isoWeek:function(a){var b=jb(this,1,4).week;return null==a?b:this.add(7*(a-b),"d")},weekday:function(a){var b=(this.day()+7-this.localeData()._week.dow)%7;return null==a?b:this.add(a-b,"d")},isoWeekday:function(a){return null==a?this.day()||7:this.day(this.day()%7?a:a-7)},isoWeeksInYear:function(){return E(this.year(),1,4)},weeksInYear:function(){var a=this.localeData()._week;return E(this.year(),a.dow,a.doy)},get:function(a){return a=z(a),this[a]()},set:function(a,b){var c;if("object"==typeof a)for(c in a)this.set(c,a[c]);else a=z(a),"function"==typeof this[a]&&this[a](b);return this},locale:function(b){var c;return b===a?this._locale._abbr:(c=vb.localeData(b),null!=c&&(this._locale=c),this)},lang:f("moment().lang() is deprecated. Instead, use moment().localeData() to get the language configuration. Use moment().locale() to change languages.",function(b){return b===a?this.localeData():this.locale(b)}),localeData:function(){return this._locale},_dateUtcOffset:function(){return 15*-Math.round(this._d.getTimezoneOffset()/15)}}),vb.fn.millisecond=vb.fn.milliseconds=qb("Milliseconds",!1),vb.fn.second=vb.fn.seconds=qb("Seconds",!1),vb.fn.minute=vb.fn.minutes=qb("Minutes",!1),vb.fn.hour=vb.fn.hours=qb("Hours",!0),vb.fn.date=qb("Date",!0),vb.fn.dates=f("dates accessor is deprecated. Use date instead.",qb("Date",!0)),vb.fn.year=qb("FullYear",!0),vb.fn.years=f("years accessor is deprecated. Use year instead.",qb("FullYear",!0)),vb.fn.days=vb.fn.day,vb.fn.months=vb.fn.month,vb.fn.weeks=vb.fn.week,vb.fn.isoWeeks=vb.fn.isoWeek,vb.fn.quarters=vb.fn.quarter,vb.fn.toJSON=vb.fn.toISOString,vb.fn.isUTC=vb.fn.isUtc,o(vb.duration.fn=n.prototype,{_bubble:function(){var a,b,c,d=this._milliseconds,e=this._days,f=this._months,g=this._data,h=0;g.milliseconds=d%1e3,a=q(d/1e3),g.seconds=a%60,b=q(a/60),g.minutes=b%60,c=q(b/60),g.hours=c%24,e+=q(c/24),h=q(rb(e)),e-=q(sb(h)),f+=q(e/30),e%=30,h+=q(f/12),f%=12,g.days=e,g.months=f,g.years=h},abs:function(){return this._milliseconds=Math.abs(this._milliseconds),this._days=Math.abs(this._days),this._months=Math.abs(this._months),this._data.milliseconds=Math.abs(this._data.milliseconds),this._data.seconds=Math.abs(this._data.seconds),this._data.minutes=Math.abs(this._data.minutes),this._data.hours=Math.abs(this._data.hours),this._data.months=Math.abs(this._data.months),this._data.years=Math.abs(this._data.years),this},weeks:function(){return q(this.days()/7)},valueOf:function(){return this._milliseconds+864e5*this._days+this._months%12*2592e6+31536e6*C(this._months/12) +},humanize:function(a){var b=ib(this,!a,this.localeData());return a&&(b=this.localeData().pastFuture(+this,b)),this.localeData().postformat(b)},add:function(a,b){var c=vb.duration(a,b);return this._milliseconds+=c._milliseconds,this._days+=c._days,this._months+=c._months,this._bubble(),this},subtract:function(a,b){var c=vb.duration(a,b);return this._milliseconds-=c._milliseconds,this._days-=c._days,this._months-=c._months,this._bubble(),this},get:function(a){return a=z(a),this[a.toLowerCase()+"s"]()},as:function(a){var b,c;if(a=z(a),"month"===a||"year"===a)return b=this._days+this._milliseconds/864e5,c=this._months+12*rb(b),"month"===a?c:c/12;switch(b=this._days+Math.round(sb(this._months/12)),a){case"week":return b/7+this._milliseconds/6048e5;case"day":return b+this._milliseconds/864e5;case"hour":return 24*b+this._milliseconds/36e5;case"minute":return 24*b*60+this._milliseconds/6e4;case"second":return 24*b*60*60+this._milliseconds/1e3;case"millisecond":return Math.floor(24*b*60*60*1e3)+this._milliseconds;default:throw new Error("Unknown unit "+a)}},lang:vb.fn.lang,locale:vb.fn.locale,toIsoString:f("toIsoString() is deprecated. Please use toISOString() instead (notice the capitals)",function(){return this.toISOString()}),toISOString:function(){var a=Math.abs(this.years()),b=Math.abs(this.months()),c=Math.abs(this.days()),d=Math.abs(this.hours()),e=Math.abs(this.minutes()),f=Math.abs(this.seconds()+this.milliseconds()/1e3);return this.asSeconds()?(this.asSeconds()<0?"-":"")+"P"+(a?a+"Y":"")+(b?b+"M":"")+(c?c+"D":"")+(d||e||f?"T":"")+(d?d+"H":"")+(e?e+"M":"")+(f?f+"S":""):"P0D"},localeData:function(){return this._locale},toJSON:function(){return this.toISOString()}}),vb.duration.fn.toString=vb.duration.fn.toISOString;for(xb in kc)c(kc,xb)&&tb(xb.toLowerCase());vb.duration.fn.asMilliseconds=function(){return this.as("ms")},vb.duration.fn.asSeconds=function(){return this.as("s")},vb.duration.fn.asMinutes=function(){return this.as("m")},vb.duration.fn.asHours=function(){return this.as("h")},vb.duration.fn.asDays=function(){return this.as("d")},vb.duration.fn.asWeeks=function(){return this.as("weeks")},vb.duration.fn.asMonths=function(){return this.as("M")},vb.duration.fn.asYears=function(){return this.as("y")},vb.locale("en",{ordinalParse:/\d{1,2}(th|st|nd|rd)/,ordinal:function(a){var b=a%10,c=1===C(a%100/10)?"th":1===b?"st":2===b?"nd":3===b?"rd":"th";return a+c}}),function(a){a(vb)}(function(a){return a.defineLocale("af",{months:"Januarie_Februarie_Maart_April_Mei_Junie_Julie_Augustus_September_Oktober_November_Desember".split("_"),monthsShort:"Jan_Feb_Mar_Apr_Mei_Jun_Jul_Aug_Sep_Okt_Nov_Des".split("_"),weekdays:"Sondag_Maandag_Dinsdag_Woensdag_Donderdag_Vrydag_Saterdag".split("_"),weekdaysShort:"Son_Maa_Din_Woe_Don_Vry_Sat".split("_"),weekdaysMin:"So_Ma_Di_Wo_Do_Vr_Sa".split("_"),meridiemParse:/vm|nm/i,isPM:function(a){return/^nm$/i.test(a)},meridiem:function(a,b,c){return 12>a?c?"vm":"VM":c?"nm":"NM"},longDateFormat:{LT:"HH:mm",LTS:"LT:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY LT",LLLL:"dddd, D MMMM YYYY LT"},calendar:{sameDay:"[Vandag om] LT",nextDay:"[Môre om] LT",nextWeek:"dddd [om] LT",lastDay:"[Gister om] LT",lastWeek:"[Laas] dddd [om] LT",sameElse:"L"},relativeTime:{future:"oor %s",past:"%s gelede",s:"'n paar sekondes",m:"'n minuut",mm:"%d minute",h:"'n uur",hh:"%d ure",d:"'n dag",dd:"%d dae",M:"'n maand",MM:"%d maande",y:"'n jaar",yy:"%d jaar"},ordinalParse:/\d{1,2}(ste|de)/,ordinal:function(a){return a+(1===a||8===a||a>=20?"ste":"de")},week:{dow:1,doy:4}})}),function(a){a(vb)}(function(a){return a.defineLocale("ar-ma",{months:"يناير_فبراير_مارس_أبريل_ماي_يونيو_يوليوز_غشت_شتنبر_أكتوبر_نونبر_دجنبر".split("_"),monthsShort:"يناير_فبراير_مارس_أبريل_ماي_يونيو_يوليوز_غشت_شتنبر_أكتوبر_نونبر_دجنبر".split("_"),weekdays:"الأحد_الإتنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت".split("_"),weekdaysShort:"احد_اتنين_ثلاثاء_اربعاء_خميس_جمعة_سبت".split("_"),weekdaysMin:"ح_ن_ث_ر_خ_ج_س".split("_"),longDateFormat:{LT:"HH:mm",LTS:"LT:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY LT",LLLL:"dddd D MMMM YYYY LT"},calendar:{sameDay:"[اليوم على الساعة] LT",nextDay:"[غدا على الساعة] LT",nextWeek:"dddd [على الساعة] LT",lastDay:"[أمس على الساعة] LT",lastWeek:"dddd [على الساعة] LT",sameElse:"L"},relativeTime:{future:"في %s",past:"منذ %s",s:"ثوان",m:"دقيقة",mm:"%d دقائق",h:"ساعة",hh:"%d ساعات",d:"يوم",dd:"%d أيام",M:"شهر",MM:"%d أشهر",y:"سنة",yy:"%d سنوات"},week:{dow:6,doy:12}})}),function(a){a(vb)}(function(a){var b={1:"١",2:"٢",3:"٣",4:"٤",5:"٥",6:"٦",7:"٧",8:"٨",9:"٩",0:"٠"},c={"١":"1","٢":"2","٣":"3","٤":"4","٥":"5","٦":"6","٧":"7","٨":"8","٩":"9","٠":"0"};return a.defineLocale("ar-sa",{months:"يناير_فبراير_مارس_أبريل_مايو_يونيو_يوليو_أغسطس_سبتمبر_أكتوبر_نوفمبر_ديسمبر".split("_"),monthsShort:"يناير_فبراير_مارس_أبريل_مايو_يونيو_يوليو_أغسطس_سبتمبر_أكتوبر_نوفمبر_ديسمبر".split("_"),weekdays:"الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت".split("_"),weekdaysShort:"أحد_إثنين_ثلاثاء_أربعاء_خميس_جمعة_سبت".split("_"),weekdaysMin:"ح_ن_ث_ر_خ_ج_س".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY LT",LLLL:"dddd D MMMM YYYY LT"},meridiemParse:/ص|م/,isPM:function(a){return"م"===a},meridiem:function(a){return 12>a?"ص":"م"},calendar:{sameDay:"[اليوم على الساعة] LT",nextDay:"[غدا على الساعة] LT",nextWeek:"dddd [على الساعة] LT",lastDay:"[أمس على الساعة] LT",lastWeek:"dddd [على الساعة] LT",sameElse:"L"},relativeTime:{future:"في %s",past:"منذ %s",s:"ثوان",m:"دقيقة",mm:"%d دقائق",h:"ساعة",hh:"%d ساعات",d:"يوم",dd:"%d أيام",M:"شهر",MM:"%d أشهر",y:"سنة",yy:"%d سنوات"},preparse:function(a){return a.replace(/[١٢٣٤٥٦٧٨٩٠]/g,function(a){return c[a]}).replace(/،/g,",")},postformat:function(a){return a.replace(/\d/g,function(a){return b[a]}).replace(/,/g,"،")},week:{dow:6,doy:12}})}),function(a){a(vb)}(function(a){return a.defineLocale("ar-tn",{months:"جانفي_فيفري_مارس_أفريل_ماي_جوان_جويلية_أوت_سبتمبر_أكتوبر_نوفمبر_ديسمبر".split("_"),monthsShort:"جانفي_فيفري_مارس_أفريل_ماي_جوان_جويلية_أوت_سبتمبر_أكتوبر_نوفمبر_ديسمبر".split("_"),weekdays:"الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت".split("_"),weekdaysShort:"أحد_إثنين_ثلاثاء_أربعاء_خميس_جمعة_سبت".split("_"),weekdaysMin:"ح_ن_ث_ر_خ_ج_س".split("_"),longDateFormat:{LT:"HH:mm",LTS:"LT:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY LT",LLLL:"dddd D MMMM YYYY LT"},calendar:{sameDay:"[اليوم على الساعة] LT",nextDay:"[غدا على الساعة] LT",nextWeek:"dddd [على الساعة] LT",lastDay:"[أمس على الساعة] LT",lastWeek:"dddd [على الساعة] LT",sameElse:"L"},relativeTime:{future:"في %s",past:"منذ %s",s:"ثوان",m:"دقيقة",mm:"%d دقائق",h:"ساعة",hh:"%d ساعات",d:"يوم",dd:"%d أيام",M:"شهر",MM:"%d أشهر",y:"سنة",yy:"%d سنوات"},week:{dow:1,doy:4}})}),function(a){a(vb)}(function(a){var b={1:"١",2:"٢",3:"٣",4:"٤",5:"٥",6:"٦",7:"٧",8:"٨",9:"٩",0:"٠"},c={"١":"1","٢":"2","٣":"3","٤":"4","٥":"5","٦":"6","٧":"7","٨":"8","٩":"9","٠":"0"},d=function(a){return 0===a?0:1===a?1:2===a?2:a%100>=3&&10>=a%100?3:a%100>=11?4:5},e={s:["أقل من ثانية","ثانية واحدة",["ثانيتان","ثانيتين"],"%d ثوان","%d ثانية","%d ثانية"],m:["أقل من دقيقة","دقيقة واحدة",["دقيقتان","دقيقتين"],"%d دقائق","%d دقيقة","%d دقيقة"],h:["أقل من ساعة","ساعة واحدة",["ساعتان","ساعتين"],"%d ساعات","%d ساعة","%d ساعة"],d:["أقل من يوم","يوم واحد",["يومان","يومين"],"%d أيام","%d يومًا","%d يوم"],M:["أقل من شهر","شهر واحد",["شهران","شهرين"],"%d أشهر","%d شهرا","%d شهر"],y:["أقل من عام","عام واحد",["عامان","عامين"],"%d أعوام","%d عامًا","%d عام"]},f=function(a){return function(b,c){var f=d(b),g=e[a][d(b)];return 2===f&&(g=g[c?0:1]),g.replace(/%d/i,b)}},g=["كانون الثاني يناير","شباط فبراير","آذار مارس","نيسان أبريل","أيار مايو","حزيران يونيو","تموز يوليو","آب أغسطس","أيلول سبتمبر","تشرين الأول أكتوبر","تشرين الثاني نوفمبر","كانون الأول ديسمبر"];return a.defineLocale("ar",{months:g,monthsShort:g,weekdays:"الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت".split("_"),weekdaysShort:"أحد_إثنين_ثلاثاء_أربعاء_خميس_جمعة_سبت".split("_"),weekdaysMin:"ح_ن_ث_ر_خ_ج_س".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY LT",LLLL:"dddd D MMMM YYYY LT"},meridiemParse:/ص|م/,isPM:function(a){return"م"===a},meridiem:function(a){return 12>a?"ص":"م"},calendar:{sameDay:"[اليوم عند الساعة] LT",nextDay:"[غدًا عند الساعة] LT",nextWeek:"dddd [عند الساعة] LT",lastDay:"[أمس عند الساعة] LT",lastWeek:"dddd [عند الساعة] LT",sameElse:"L"},relativeTime:{future:"بعد %s",past:"منذ %s",s:f("s"),m:f("m"),mm:f("m"),h:f("h"),hh:f("h"),d:f("d"),dd:f("d"),M:f("M"),MM:f("M"),y:f("y"),yy:f("y")},preparse:function(a){return a.replace(/[١٢٣٤٥٦٧٨٩٠]/g,function(a){return c[a]}).replace(/،/g,",")},postformat:function(a){return a.replace(/\d/g,function(a){return b[a]}).replace(/,/g,"،")},week:{dow:6,doy:12}})}),function(a){a(vb)}(function(a){var b={1:"-inci",5:"-inci",8:"-inci",70:"-inci",80:"-inci",2:"-nci",7:"-nci",20:"-nci",50:"-nci",3:"-üncü",4:"-üncü",100:"-üncü",6:"-ncı",9:"-uncu",10:"-uncu",30:"-uncu",60:"-ıncı",90:"-ıncı"};return a.defineLocale("az",{months:"yanvar_fevral_mart_aprel_may_iyun_iyul_avqust_sentyabr_oktyabr_noyabr_dekabr".split("_"),monthsShort:"yan_fev_mar_apr_may_iyn_iyl_avq_sen_okt_noy_dek".split("_"),weekdays:"Bazar_Bazar ertəsi_Çərşənbə axşamı_Çərşənbə_Cümə axşamı_Cümə_Şənbə".split("_"),weekdaysShort:"Baz_BzE_ÇAx_Çər_CAx_Cüm_Şən".split("_"),weekdaysMin:"Bz_BE_ÇA_Çə_CA_Cü_Şə".split("_"),longDateFormat:{LT:"HH:mm",LTS:"LT:ss",L:"DD.MM.YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY LT",LLLL:"dddd, D MMMM YYYY LT"},calendar:{sameDay:"[bugün saat] LT",nextDay:"[sabah saat] LT",nextWeek:"[gələn həftə] dddd [saat] LT",lastDay:"[dünən] LT",lastWeek:"[keçən həftə] dddd [saat] LT",sameElse:"L"},relativeTime:{future:"%s sonra",past:"%s əvvəl",s:"birneçə saniyyə",m:"bir dəqiqə",mm:"%d dəqiqə",h:"bir saat",hh:"%d saat",d:"bir gün",dd:"%d gün",M:"bir ay",MM:"%d ay",y:"bir il",yy:"%d il"},meridiemParse:/gecə|səhər|gündüz|axşam/,isPM:function(a){return/^(gündüz|axşam)$/.test(a)},meridiem:function(a){return 4>a?"gecə":12>a?"səhər":17>a?"gündüz":"axşam"},ordinalParse:/\d{1,2}-(ıncı|inci|nci|üncü|ncı|uncu)/,ordinal:function(a){if(0===a)return a+"-ıncı";var c=a%10,d=a%100-c,e=a>=100?100:null;return a+(b[c]||b[d]||b[e])},week:{dow:1,doy:7}})}),function(a){a(vb)}(function(a){function b(a,b){var c=a.split("_");return b%10===1&&b%100!==11?c[0]:b%10>=2&&4>=b%10&&(10>b%100||b%100>=20)?c[1]:c[2]}function c(a,c,d){var e={mm:c?"хвіліна_хвіліны_хвілін":"хвіліну_хвіліны_хвілін",hh:c?"гадзіна_гадзіны_гадзін":"гадзіну_гадзіны_гадзін",dd:"дзень_дні_дзён",MM:"месяц_месяцы_месяцаў",yy:"год_гады_гадоў"};return"m"===d?c?"хвіліна":"хвіліну":"h"===d?c?"гадзіна":"гадзіну":a+" "+b(e[d],+a)}function d(a,b){var c={nominative:"студзень_люты_сакавік_красавік_травень_чэрвень_ліпень_жнівень_верасень_кастрычнік_лістапад_снежань".split("_"),accusative:"студзеня_лютага_сакавіка_красавіка_траўня_чэрвеня_ліпеня_жніўня_верасня_кастрычніка_лістапада_снежня".split("_")},d=/D[oD]?(\[[^\[\]]*\]|\s+)+MMMM?/.test(b)?"accusative":"nominative";return c[d][a.month()]}function e(a,b){var c={nominative:"нядзеля_панядзелак_аўторак_серада_чацвер_пятніца_субота".split("_"),accusative:"нядзелю_панядзелак_аўторак_сераду_чацвер_пятніцу_суботу".split("_")},d=/\[ ?[Вв] ?(?:мінулую|наступную)? ?\] ?dddd/.test(b)?"accusative":"nominative";return c[d][a.day()]}return a.defineLocale("be",{months:d,monthsShort:"студ_лют_сак_крас_трав_чэрв_ліп_жнів_вер_каст_ліст_снеж".split("_"),weekdays:e,weekdaysShort:"нд_пн_ат_ср_чц_пт_сб".split("_"),weekdaysMin:"нд_пн_ат_ср_чц_пт_сб".split("_"),longDateFormat:{LT:"HH:mm",LTS:"LT:ss",L:"DD.MM.YYYY",LL:"D MMMM YYYY г.",LLL:"D MMMM YYYY г., LT",LLLL:"dddd, D MMMM YYYY г., LT"},calendar:{sameDay:"[Сёння ў] LT",nextDay:"[Заўтра ў] LT",lastDay:"[Учора ў] LT",nextWeek:function(){return"[У] dddd [ў] LT"},lastWeek:function(){switch(this.day()){case 0:case 3:case 5:case 6:return"[У мінулую] dddd [ў] LT";case 1:case 2:case 4:return"[У мінулы] dddd [ў] LT"}},sameElse:"L"},relativeTime:{future:"праз %s",past:"%s таму",s:"некалькі секунд",m:c,mm:c,h:c,hh:c,d:"дзень",dd:c,M:"месяц",MM:c,y:"год",yy:c},meridiemParse:/ночы|раніцы|дня|вечара/,isPM:function(a){return/^(дня|вечара)$/.test(a)},meridiem:function(a){return 4>a?"ночы":12>a?"раніцы":17>a?"дня":"вечара"},ordinalParse:/\d{1,2}-(і|ы|га)/,ordinal:function(a,b){switch(b){case"M":case"d":case"DDD":case"w":case"W":return a%10!==2&&a%10!==3||a%100===12||a%100===13?a+"-ы":a+"-і";case"D":return a+"-га";default:return a}},week:{dow:1,doy:7}})}),function(a){a(vb)}(function(a){return a.defineLocale("bg",{months:"януари_февруари_март_април_май_юни_юли_август_септември_октомври_ноември_декември".split("_"),monthsShort:"янр_фев_мар_апр_май_юни_юли_авг_сеп_окт_ное_дек".split("_"),weekdays:"неделя_понеделник_вторник_сряда_четвъртък_петък_събота".split("_"),weekdaysShort:"нед_пон_вто_сря_чет_пет_съб".split("_"),weekdaysMin:"нд_пн_вт_ср_чт_пт_сб".split("_"),longDateFormat:{LT:"H:mm",LTS:"LT:ss",L:"D.MM.YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY LT",LLLL:"dddd, D MMMM YYYY LT"},calendar:{sameDay:"[Днес в] LT",nextDay:"[Утре в] LT",nextWeek:"dddd [в] LT",lastDay:"[Вчера в] LT",lastWeek:function(){switch(this.day()){case 0:case 3:case 6:return"[В изминалата] dddd [в] LT";case 1:case 2:case 4:case 5:return"[В изминалия] dddd [в] LT"}},sameElse:"L"},relativeTime:{future:"след %s",past:"преди %s",s:"няколко секунди",m:"минута",mm:"%d минути",h:"час",hh:"%d часа",d:"ден",dd:"%d дни",M:"месец",MM:"%d месеца",y:"година",yy:"%d години"},ordinalParse:/\d{1,2}-(ев|ен|ти|ви|ри|ми)/,ordinal:function(a){var b=a%10,c=a%100;return 0===a?a+"-ев":0===c?a+"-ен":c>10&&20>c?a+"-ти":1===b?a+"-ви":2===b?a+"-ри":7===b||8===b?a+"-ми":a+"-ти"},week:{dow:1,doy:7}})}),function(a){a(vb)}(function(a){var b={1:"১",2:"২",3:"৩",4:"৪",5:"৫",6:"৬",7:"৭",8:"৮",9:"৯",0:"০"},c={"১":"1","২":"2","৩":"3","৪":"4","৫":"5","৬":"6","৭":"7","৮":"8","৯":"9","০":"0"};return a.defineLocale("bn",{months:"জানুয়ারী_ফেবুয়ারী_মার্চ_এপ্রিল_মে_জুন_জুলাই_অগাস্ট_সেপ্টেম্বর_অক্টোবর_নভেম্বর_ডিসেম্বর".split("_"),monthsShort:"জানু_ফেব_মার্চ_এপর_মে_জুন_জুল_অগ_সেপ্ট_অক্টো_নভ_ডিসেম্".split("_"),weekdays:"রবিবার_সোমবার_মঙ্গলবার_বুধবার_বৃহস্পত্তিবার_শুক্রুবার_শনিবার".split("_"),weekdaysShort:"রবি_সোম_মঙ্গল_বুধ_বৃহস্পত্তি_শুক্রু_শনি".split("_"),weekdaysMin:"রব_সম_মঙ্গ_বু_ব্রিহ_শু_শনি".split("_"),longDateFormat:{LT:"A h:mm সময়",LTS:"A h:mm:ss সময়",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY, LT",LLLL:"dddd, D MMMM YYYY, LT"},calendar:{sameDay:"[আজ] LT",nextDay:"[আগামীকাল] LT",nextWeek:"dddd, LT",lastDay:"[গতকাল] LT",lastWeek:"[গত] dddd, LT",sameElse:"L"},relativeTime:{future:"%s পরে",past:"%s আগে",s:"কএক সেকেন্ড",m:"এক মিনিট",mm:"%d মিনিট",h:"এক ঘন্টা",hh:"%d ঘন্টা",d:"এক দিন",dd:"%d দিন",M:"এক মাস",MM:"%d মাস",y:"এক বছর",yy:"%d বছর"},preparse:function(a){return a.replace(/[১২৩৪৫৬৭৮৯০]/g,function(a){return c[a]})},postformat:function(a){return a.replace(/\d/g,function(a){return b[a]})},meridiemParse:/রাত|শকাল|দুপুর|বিকেল|রাত/,isPM:function(a){return/^(দুপুর|বিকেল|রাত)$/.test(a)},meridiem:function(a){return 4>a?"রাত":10>a?"শকাল":17>a?"দুপুর":20>a?"বিকেল":"রাত"},week:{dow:0,doy:6}})}),function(a){a(vb)}(function(a){var b={1:"༡",2:"༢",3:"༣",4:"༤",5:"༥",6:"༦",7:"༧",8:"༨",9:"༩",0:"༠"},c={"༡":"1","༢":"2","༣":"3","༤":"4","༥":"5","༦":"6","༧":"7","༨":"8","༩":"9","༠":"0"};return a.defineLocale("bo",{months:"ཟླ་བ་དང་པོ_ཟླ་བ་གཉིས་པ_ཟླ་བ་གསུམ་པ_ཟླ་བ་བཞི་པ_ཟླ་བ་ལྔ་པ_ཟླ་བ་དྲུག་པ_ཟླ་བ་བདུན་པ_ཟླ་བ་བརྒྱད་པ_ཟླ་བ་དགུ་པ_ཟླ་བ་བཅུ་པ_ཟླ་བ་བཅུ་གཅིག་པ_ཟླ་བ་བཅུ་གཉིས་པ".split("_"),monthsShort:"ཟླ་བ་དང་པོ_ཟླ་བ་གཉིས་པ_ཟླ་བ་གསུམ་པ_ཟླ་བ་བཞི་པ_ཟླ་བ་ལྔ་པ_ཟླ་བ་དྲུག་པ_ཟླ་བ་བདུན་པ_ཟླ་བ་བརྒྱད་པ_ཟླ་བ་དགུ་པ_ཟླ་བ་བཅུ་པ_ཟླ་བ་བཅུ་གཅིག་པ_ཟླ་བ་བཅུ་གཉིས་པ".split("_"),weekdays:"གཟའ་ཉི་མ་_གཟའ་ཟླ་བ་_གཟའ་མིག་དམར་_གཟའ་ལྷག་པ་_གཟའ་ཕུར་བུ_གཟའ་པ་སངས་_གཟའ་སྤེན་པ་".split("_"),weekdaysShort:"ཉི་མ་_ཟླ་བ་_མིག་དམར་_ལྷག་པ་_ཕུར་བུ_པ་སངས་_སྤེན་པ་".split("_"),weekdaysMin:"ཉི་མ་_ཟླ་བ་_མིག་དམར་_ལྷག་པ་_ཕུར་བུ_པ་སངས་_སྤེན་པ་".split("_"),longDateFormat:{LT:"A h:mm",LTS:"LT:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY, LT",LLLL:"dddd, D MMMM YYYY, LT"},calendar:{sameDay:"[དི་རིང] LT",nextDay:"[སང་ཉིན] LT",nextWeek:"[བདུན་ཕྲག་རྗེས་མ], LT",lastDay:"[ཁ་སང] LT",lastWeek:"[བདུན་ཕྲག་མཐའ་མ] dddd, LT",sameElse:"L"},relativeTime:{future:"%s ལ་",past:"%s སྔན་ལ",s:"ལམ་སང",m:"སྐར་མ་གཅིག",mm:"%d སྐར་མ",h:"ཆུ་ཚོད་གཅིག",hh:"%d ཆུ་ཚོད",d:"ཉིན་གཅིག",dd:"%d ཉིན་",M:"ཟླ་བ་གཅིག",MM:"%d ཟླ་བ",y:"ལོ་གཅིག",yy:"%d ལོ"},preparse:function(a){return a.replace(/[༡༢༣༤༥༦༧༨༩༠]/g,function(a){return c[a]})},postformat:function(a){return a.replace(/\d/g,function(a){return b[a]})},meridiemParse:/མཚན་མོ|ཞོགས་ཀས|ཉིན་གུང|དགོང་དག|མཚན་མོ/,isPM:function(a){return/^(ཉིན་གུང|དགོང་དག|མཚན་མོ)$/.test(a)},meridiem:function(a){return 4>a?"མཚན་མོ":10>a?"ཞོགས་ཀས":17>a?"ཉིན་གུང":20>a?"དགོང་དག":"མཚན་མོ"},week:{dow:0,doy:6}})}),function(a){a(vb)}(function(b){function c(a,b,c){var d={mm:"munutenn",MM:"miz",dd:"devezh"};return a+" "+f(d[c],a)}function d(a){switch(e(a)){case 1:case 3:case 4:case 5:case 9:return a+" bloaz";default:return a+" vloaz"}}function e(a){return a>9?e(a%10):a}function f(a,b){return 2===b?g(a):a}function g(b){var c={m:"v",b:"v",d:"z"};return c[b.charAt(0)]===a?b:c[b.charAt(0)]+b.substring(1)}return b.defineLocale("br",{months:"Genver_C'hwevrer_Meurzh_Ebrel_Mae_Mezheven_Gouere_Eost_Gwengolo_Here_Du_Kerzu".split("_"),monthsShort:"Gen_C'hwe_Meu_Ebr_Mae_Eve_Gou_Eos_Gwe_Her_Du_Ker".split("_"),weekdays:"Sul_Lun_Meurzh_Merc'her_Yaou_Gwener_Sadorn".split("_"),weekdaysShort:"Sul_Lun_Meu_Mer_Yao_Gwe_Sad".split("_"),weekdaysMin:"Su_Lu_Me_Mer_Ya_Gw_Sa".split("_"),longDateFormat:{LT:"h[e]mm A",LTS:"h[e]mm:ss A",L:"DD/MM/YYYY",LL:"D [a viz] MMMM YYYY",LLL:"D [a viz] MMMM YYYY LT",LLLL:"dddd, D [a viz] MMMM YYYY LT"},calendar:{sameDay:"[Hiziv da] LT",nextDay:"[Warc'hoazh da] LT",nextWeek:"dddd [da] LT",lastDay:"[Dec'h da] LT",lastWeek:"dddd [paset da] LT",sameElse:"L"},relativeTime:{future:"a-benn %s",past:"%s 'zo",s:"un nebeud segondennoù",m:"ur vunutenn",mm:c,h:"un eur",hh:"%d eur",d:"un devezh",dd:c,M:"ur miz",MM:c,y:"ur bloaz",yy:d},ordinalParse:/\d{1,2}(añ|vet)/,ordinal:function(a){var b=1===a?"añ":"vet";return a+b},week:{dow:1,doy:4}})}),function(a){a(vb)}(function(a){function b(a,b,c){var d=a+" ";switch(c){case"m":return b?"jedna minuta":"jedne minute";case"mm":return d+=1===a?"minuta":2===a||3===a||4===a?"minute":"minuta";case"h":return b?"jedan sat":"jednog sata";case"hh":return d+=1===a?"sat":2===a||3===a||4===a?"sata":"sati";case"dd":return d+=1===a?"dan":"dana";case"MM":return d+=1===a?"mjesec":2===a||3===a||4===a?"mjeseca":"mjeseci";case"yy":return d+=1===a?"godina":2===a||3===a||4===a?"godine":"godina"}}return a.defineLocale("bs",{months:"januar_februar_mart_april_maj_juni_juli_august_septembar_oktobar_novembar_decembar".split("_"),monthsShort:"jan._feb._mar._apr._maj._jun._jul._aug._sep._okt._nov._dec.".split("_"),weekdays:"nedjelja_ponedjeljak_utorak_srijeda_četvrtak_petak_subota".split("_"),weekdaysShort:"ned._pon._uto._sri._čet._pet._sub.".split("_"),weekdaysMin:"ne_po_ut_sr_če_pe_su".split("_"),longDateFormat:{LT:"H:mm",LTS:"LT:ss",L:"DD. MM. YYYY",LL:"D. MMMM YYYY",LLL:"D. MMMM YYYY LT",LLLL:"dddd, D. MMMM YYYY LT"},calendar:{sameDay:"[danas u] LT",nextDay:"[sutra u] LT",nextWeek:function(){switch(this.day()){case 0:return"[u] [nedjelju] [u] LT";case 3:return"[u] [srijedu] [u] LT";case 6:return"[u] [subotu] [u] LT";case 1:case 2:case 4:case 5:return"[u] dddd [u] LT"}},lastDay:"[jučer u] LT",lastWeek:function(){switch(this.day()){case 0:case 3:return"[prošlu] dddd [u] LT";case 6:return"[prošle] [subote] [u] LT";case 1:case 2:case 4:case 5:return"[prošli] dddd [u] LT"}},sameElse:"L"},relativeTime:{future:"za %s",past:"prije %s",s:"par sekundi",m:b,mm:b,h:b,hh:b,d:"dan",dd:b,M:"mjesec",MM:b,y:"godinu",yy:b},ordinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:7}})}),function(a){a(vb)}(function(a){return a.defineLocale("ca",{months:"gener_febrer_març_abril_maig_juny_juliol_agost_setembre_octubre_novembre_desembre".split("_"),monthsShort:"gen._febr._mar._abr._mai._jun._jul._ag._set._oct._nov._des.".split("_"),weekdays:"diumenge_dilluns_dimarts_dimecres_dijous_divendres_dissabte".split("_"),weekdaysShort:"dg._dl._dt._dc._dj._dv._ds.".split("_"),weekdaysMin:"Dg_Dl_Dt_Dc_Dj_Dv_Ds".split("_"),longDateFormat:{LT:"H:mm",LTS:"LT:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY LT",LLLL:"dddd D MMMM YYYY LT"},calendar:{sameDay:function(){return"[avui a "+(1!==this.hours()?"les":"la")+"] LT"},nextDay:function(){return"[demà a "+(1!==this.hours()?"les":"la")+"] LT"},nextWeek:function(){return"dddd [a "+(1!==this.hours()?"les":"la")+"] LT"},lastDay:function(){return"[ahir a "+(1!==this.hours()?"les":"la")+"] LT"},lastWeek:function(){return"[el] dddd [passat a "+(1!==this.hours()?"les":"la")+"] LT"},sameElse:"L"},relativeTime:{future:"en %s",past:"fa %s",s:"uns segons",m:"un minut",mm:"%d minuts",h:"una hora",hh:"%d hores",d:"un dia",dd:"%d dies",M:"un mes",MM:"%d mesos",y:"un any",yy:"%d anys"},ordinalParse:/\d{1,2}(r|n|t|è|a)/,ordinal:function(a,b){var c=1===a?"r":2===a?"n":3===a?"r":4===a?"t":"è";return("w"===b||"W"===b)&&(c="a"),a+c},week:{dow:1,doy:4}})}),function(a){a(vb)}(function(a){function b(a){return a>1&&5>a&&1!==~~(a/10)}function c(a,c,d,e){var f=a+" ";switch(d){case"s":return c||e?"pár sekund":"pár sekundami";case"m":return c?"minuta":e?"minutu":"minutou";case"mm":return c||e?f+(b(a)?"minuty":"minut"):f+"minutami";break;case"h":return c?"hodina":e?"hodinu":"hodinou";case"hh":return c||e?f+(b(a)?"hodiny":"hodin"):f+"hodinami";break;case"d":return c||e?"den":"dnem";case"dd":return c||e?f+(b(a)?"dny":"dní"):f+"dny";break;case"M":return c||e?"měsíc":"měsícem";case"MM":return c||e?f+(b(a)?"měsíce":"měsíců"):f+"měsíci";break;case"y":return c||e?"rok":"rokem";case"yy":return c||e?f+(b(a)?"roky":"let"):f+"lety"}}var d="leden_únor_březen_duben_květen_červen_červenec_srpen_září_říjen_listopad_prosinec".split("_"),e="led_úno_bře_dub_kvě_čvn_čvc_srp_zář_říj_lis_pro".split("_");return a.defineLocale("cs",{months:d,monthsShort:e,monthsParse:function(a,b){var c,d=[];for(c=0;12>c;c++)d[c]=new RegExp("^"+a[c]+"$|^"+b[c]+"$","i");return d}(d,e),weekdays:"neděle_pondělí_úterý_středa_čtvrtek_pátek_sobota".split("_"),weekdaysShort:"ne_po_út_st_čt_pá_so".split("_"),weekdaysMin:"ne_po_út_st_čt_pá_so".split("_"),longDateFormat:{LT:"H:mm",LTS:"LT:ss",L:"DD.MM.YYYY",LL:"D. MMMM YYYY",LLL:"D. MMMM YYYY LT",LLLL:"dddd D. MMMM YYYY LT"},calendar:{sameDay:"[dnes v] LT",nextDay:"[zítra v] LT",nextWeek:function(){switch(this.day()){case 0:return"[v neděli v] LT";case 1:case 2:return"[v] dddd [v] LT";case 3:return"[ve středu v] LT";case 4:return"[ve čtvrtek v] LT";case 5:return"[v pátek v] LT";case 6:return"[v sobotu v] LT"}},lastDay:"[včera v] LT",lastWeek:function(){switch(this.day()){case 0:return"[minulou neděli v] LT";case 1:case 2:return"[minulé] dddd [v] LT";case 3:return"[minulou středu v] LT";case 4:case 5:return"[minulý] dddd [v] LT";case 6:return"[minulou sobotu v] LT"}},sameElse:"L"},relativeTime:{future:"za %s",past:"před %s",s:c,m:c,mm:c,h:c,hh:c,d:c,dd:c,M:c,MM:c,y:c,yy:c},ordinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}})}),function(a){a(vb)}(function(a){return a.defineLocale("cv",{months:"кăрлач_нарăс_пуш_ака_май_çĕртме_утă_çурла_авăн_юпа_чӳк_раштав".split("_"),monthsShort:"кăр_нар_пуш_ака_май_çĕр_утă_çур_ав_юпа_чӳк_раш".split("_"),weekdays:"вырсарникун_тунтикун_ытларикун_юнкун_кĕçнерникун_эрнекун_шăматкун".split("_"),weekdaysShort:"выр_тун_ытл_юн_кĕç_эрн_шăм".split("_"),weekdaysMin:"вр_тн_ыт_юн_кç_эр_шм".split("_"),longDateFormat:{LT:"HH:mm",LTS:"LT:ss",L:"DD-MM-YYYY",LL:"YYYY [çулхи] MMMM [уйăхĕн] D[-мĕшĕ]",LLL:"YYYY [çулхи] MMMM [уйăхĕн] D[-мĕшĕ], LT",LLLL:"dddd, YYYY [çулхи] MMMM [уйăхĕн] D[-мĕшĕ], LT"},calendar:{sameDay:"[Паян] LT [сехетре]",nextDay:"[Ыран] LT [сехетре]",lastDay:"[Ĕнер] LT [сехетре]",nextWeek:"[Çитес] dddd LT [сехетре]",lastWeek:"[Иртнĕ] dddd LT [сехетре]",sameElse:"L"},relativeTime:{future:function(a){var b=/сехет$/i.exec(a)?"рен":/çул$/i.exec(a)?"тан":"ран";return a+b},past:"%s каялла",s:"пĕр-ик çеккунт",m:"пĕр минут",mm:"%d минут",h:"пĕр сехет",hh:"%d сехет",d:"пĕр кун",dd:"%d кун",M:"пĕр уйăх",MM:"%d уйăх",y:"пĕр çул",yy:"%d çул"},ordinalParse:/\d{1,2}-мĕш/,ordinal:"%d-мĕш",week:{dow:1,doy:7}})}),function(a){a(vb)}(function(a){return a.defineLocale("cy",{months:"Ionawr_Chwefror_Mawrth_Ebrill_Mai_Mehefin_Gorffennaf_Awst_Medi_Hydref_Tachwedd_Rhagfyr".split("_"),monthsShort:"Ion_Chwe_Maw_Ebr_Mai_Meh_Gor_Aws_Med_Hyd_Tach_Rhag".split("_"),weekdays:"Dydd Sul_Dydd Llun_Dydd Mawrth_Dydd Mercher_Dydd Iau_Dydd Gwener_Dydd Sadwrn".split("_"),weekdaysShort:"Sul_Llun_Maw_Mer_Iau_Gwe_Sad".split("_"),weekdaysMin:"Su_Ll_Ma_Me_Ia_Gw_Sa".split("_"),longDateFormat:{LT:"HH:mm",LTS:"LT:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY LT",LLLL:"dddd, D MMMM YYYY LT"},calendar:{sameDay:"[Heddiw am] LT",nextDay:"[Yfory am] LT",nextWeek:"dddd [am] LT",lastDay:"[Ddoe am] LT",lastWeek:"dddd [diwethaf am] LT",sameElse:"L"},relativeTime:{future:"mewn %s",past:"%s yn ôl",s:"ychydig eiliadau",m:"munud",mm:"%d munud",h:"awr",hh:"%d awr",d:"diwrnod",dd:"%d diwrnod",M:"mis",MM:"%d mis",y:"blwyddyn",yy:"%d flynedd"},ordinalParse:/\d{1,2}(fed|ain|af|il|ydd|ed|eg)/,ordinal:function(a){var b=a,c="",d=["","af","il","ydd","ydd","ed","ed","ed","fed","fed","fed","eg","fed","eg","eg","fed","eg","eg","fed","eg","fed"];return b>20?c=40===b||50===b||60===b||80===b||100===b?"fed":"ain":b>0&&(c=d[b]),a+c},week:{dow:1,doy:4}})}),function(a){a(vb)}(function(a){return a.defineLocale("da",{months:"januar_februar_marts_april_maj_juni_juli_august_september_oktober_november_december".split("_"),monthsShort:"jan_feb_mar_apr_maj_jun_jul_aug_sep_okt_nov_dec".split("_"),weekdays:"søndag_mandag_tirsdag_onsdag_torsdag_fredag_lørdag".split("_"),weekdaysShort:"søn_man_tir_ons_tor_fre_lør".split("_"),weekdaysMin:"sø_ma_ti_on_to_fr_lø".split("_"),longDateFormat:{LT:"HH:mm",LTS:"LT:ss",L:"DD/MM/YYYY",LL:"D. MMMM YYYY",LLL:"D. MMMM YYYY LT",LLLL:"dddd [d.] D. MMMM YYYY LT"},calendar:{sameDay:"[I dag kl.] LT",nextDay:"[I morgen kl.] LT",nextWeek:"dddd [kl.] LT",lastDay:"[I går kl.] LT",lastWeek:"[sidste] dddd [kl] LT",sameElse:"L"},relativeTime:{future:"om %s",past:"%s siden",s:"få sekunder",m:"et minut",mm:"%d minutter",h:"en time",hh:"%d timer",d:"en dag",dd:"%d dage",M:"en måned",MM:"%d måneder",y:"et år",yy:"%d år"},ordinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}})}),function(a){a(vb)}(function(a){function b(a,b,c){var d={m:["eine Minute","einer Minute"],h:["eine Stunde","einer Stunde"],d:["ein Tag","einem Tag"],dd:[a+" Tage",a+" Tagen"],M:["ein Monat","einem Monat"],MM:[a+" Monate",a+" Monaten"],y:["ein Jahr","einem Jahr"],yy:[a+" Jahre",a+" Jahren"]};return b?d[c][0]:d[c][1]}return a.defineLocale("de-at",{months:"Jänner_Februar_März_April_Mai_Juni_Juli_August_September_Oktober_November_Dezember".split("_"),monthsShort:"Jän._Febr._Mrz._Apr._Mai_Jun._Jul._Aug._Sept._Okt._Nov._Dez.".split("_"),weekdays:"Sonntag_Montag_Dienstag_Mittwoch_Donnerstag_Freitag_Samstag".split("_"),weekdaysShort:"So._Mo._Di._Mi._Do._Fr._Sa.".split("_"),weekdaysMin:"So_Mo_Di_Mi_Do_Fr_Sa".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD.MM.YYYY",LL:"D. MMMM YYYY",LLL:"D. MMMM YYYY LT",LLLL:"dddd, D. MMMM YYYY LT"},calendar:{sameDay:"[Heute um] LT [Uhr]",sameElse:"L",nextDay:"[Morgen um] LT [Uhr]",nextWeek:"dddd [um] LT [Uhr]",lastDay:"[Gestern um] LT [Uhr]",lastWeek:"[letzten] dddd [um] LT [Uhr]"},relativeTime:{future:"in %s",past:"vor %s",s:"ein paar Sekunden",m:b,mm:"%d Minuten",h:b,hh:"%d Stunden",d:b,dd:b,M:b,MM:b,y:b,yy:b},ordinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}})}),function(a){a(vb)}(function(a){function b(a,b,c){var d={m:["eine Minute","einer Minute"],h:["eine Stunde","einer Stunde"],d:["ein Tag","einem Tag"],dd:[a+" Tage",a+" Tagen"],M:["ein Monat","einem Monat"],MM:[a+" Monate",a+" Monaten"],y:["ein Jahr","einem Jahr"],yy:[a+" Jahre",a+" Jahren"]};return b?d[c][0]:d[c][1]}return a.defineLocale("de",{months:"Januar_Februar_März_April_Mai_Juni_Juli_August_September_Oktober_November_Dezember".split("_"),monthsShort:"Jan._Febr._Mrz._Apr._Mai_Jun._Jul._Aug._Sept._Okt._Nov._Dez.".split("_"),weekdays:"Sonntag_Montag_Dienstag_Mittwoch_Donnerstag_Freitag_Samstag".split("_"),weekdaysShort:"So._Mo._Di._Mi._Do._Fr._Sa.".split("_"),weekdaysMin:"So_Mo_Di_Mi_Do_Fr_Sa".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD.MM.YYYY",LL:"D. MMMM YYYY",LLL:"D. MMMM YYYY LT",LLLL:"dddd, D. MMMM YYYY LT"},calendar:{sameDay:"[Heute um] LT [Uhr]",sameElse:"L",nextDay:"[Morgen um] LT [Uhr]",nextWeek:"dddd [um] LT [Uhr]",lastDay:"[Gestern um] LT [Uhr]",lastWeek:"[letzten] dddd [um] LT [Uhr]"},relativeTime:{future:"in %s",past:"vor %s",s:"ein paar Sekunden",m:b,mm:"%d Minuten",h:b,hh:"%d Stunden",d:b,dd:b,M:b,MM:b,y:b,yy:b},ordinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}})}),function(a){a(vb)}(function(a){return a.defineLocale("el",{monthsNominativeEl:"Ιανουάριος_Φεβρουάριος_Μάρτιος_Απρίλιος_Μάιος_Ιούνιος_Ιούλιος_Αύγουστος_Σεπτέμβριος_Οκτώβριος_Νοέμβριος_Δεκέμβριος".split("_"),monthsGenitiveEl:"Ιανουαρίου_Φεβρουαρίου_Μαρτίου_Απριλίου_Μαΐου_Ιουνίου_Ιουλίου_Αυγούστου_Σεπτεμβρίου_Οκτωβρίου_Νοεμβρίου_Δεκεμβρίου".split("_"),months:function(a,b){return/D/.test(b.substring(0,b.indexOf("MMMM")))?this._monthsGenitiveEl[a.month()]:this._monthsNominativeEl[a.month()]},monthsShort:"Ιαν_Φεβ_Μαρ_Απρ_Μαϊ_Ιουν_Ιουλ_Αυγ_Σεπ_Οκτ_Νοε_Δεκ".split("_"),weekdays:"Κυριακή_Δευτέρα_Τρίτη_Τετάρτη_Πέμπτη_Παρασκευή_Σάββατο".split("_"),weekdaysShort:"Κυρ_Δευ_Τρι_Τετ_Πεμ_Παρ_Σαβ".split("_"),weekdaysMin:"Κυ_Δε_Τρ_Τε_Πε_Πα_Σα".split("_"),meridiem:function(a,b,c){return a>11?c?"μμ":"ΜΜ":c?"πμ":"ΠΜ"},isPM:function(a){return"μ"===(a+"").toLowerCase()[0]},meridiemParse:/[ΠΜ]\.?Μ?\.?/i,longDateFormat:{LT:"h:mm A",LTS:"h:mm:ss A",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY LT",LLLL:"dddd, D MMMM YYYY LT"},calendarEl:{sameDay:"[Σήμερα {}] LT",nextDay:"[Αύριο {}] LT",nextWeek:"dddd [{}] LT",lastDay:"[Χθες {}] LT",lastWeek:function(){switch(this.day()){case 6:return"[το προηγούμενο] dddd [{}] LT";default:return"[την προηγούμενη] dddd [{}] LT"}},sameElse:"L"},calendar:function(a,b){var c=this._calendarEl[a],d=b&&b.hours();return"function"==typeof c&&(c=c.apply(b)),c.replace("{}",d%12===1?"στη":"στις")},relativeTime:{future:"σε %s",past:"%s πριν",s:"λίγα δευτερόλεπτα",m:"ένα λεπτό",mm:"%d λεπτά",h:"μία ώρα",hh:"%d ώρες",d:"μία μέρα",dd:"%d μέρες",M:"ένας μήνας",MM:"%d μήνες",y:"ένας χρόνος",yy:"%d χρόνια"},ordinalParse:/\d{1,2}η/,ordinal:"%dη",week:{dow:1,doy:4}})}),function(a){a(vb)}(function(a){return a.defineLocale("en-au",{months:"January_February_March_April_May_June_July_August_September_October_November_December".split("_"),monthsShort:"Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec".split("_"),weekdays:"Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),weekdaysShort:"Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),weekdaysMin:"Su_Mo_Tu_We_Th_Fr_Sa".split("_"),longDateFormat:{LT:"h:mm A",LTS:"h:mm:ss A",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY LT",LLLL:"dddd, D MMMM YYYY LT"},calendar:{sameDay:"[Today at] LT",nextDay:"[Tomorrow at] LT",nextWeek:"dddd [at] LT",lastDay:"[Yesterday at] LT",lastWeek:"[Last] dddd [at] LT",sameElse:"L"},relativeTime:{future:"in %s",past:"%s ago",s:"a few seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",M:"a month",MM:"%d months",y:"a year",yy:"%d years"},ordinalParse:/\d{1,2}(st|nd|rd|th)/,ordinal:function(a){var b=a%10,c=1===~~(a%100/10)?"th":1===b?"st":2===b?"nd":3===b?"rd":"th";return a+c},week:{dow:1,doy:4}})}),function(a){a(vb)}(function(a){return a.defineLocale("en-ca",{months:"January_February_March_April_May_June_July_August_September_October_November_December".split("_"),monthsShort:"Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec".split("_"),weekdays:"Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),weekdaysShort:"Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),weekdaysMin:"Su_Mo_Tu_We_Th_Fr_Sa".split("_"),longDateFormat:{LT:"h:mm A",LTS:"h:mm:ss A",L:"YYYY-MM-DD",LL:"D MMMM, YYYY",LLL:"D MMMM, YYYY LT",LLLL:"dddd, D MMMM, YYYY LT"},calendar:{sameDay:"[Today at] LT",nextDay:"[Tomorrow at] LT",nextWeek:"dddd [at] LT",lastDay:"[Yesterday at] LT",lastWeek:"[Last] dddd [at] LT",sameElse:"L"},relativeTime:{future:"in %s",past:"%s ago",s:"a few seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",M:"a month",MM:"%d months",y:"a year",yy:"%d years"},ordinalParse:/\d{1,2}(st|nd|rd|th)/,ordinal:function(a){var b=a%10,c=1===~~(a%100/10)?"th":1===b?"st":2===b?"nd":3===b?"rd":"th"; +return a+c}})}),function(a){a(vb)}(function(a){return a.defineLocale("en-gb",{months:"January_February_March_April_May_June_July_August_September_October_November_December".split("_"),monthsShort:"Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec".split("_"),weekdays:"Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),weekdaysShort:"Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),weekdaysMin:"Su_Mo_Tu_We_Th_Fr_Sa".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY LT",LLLL:"dddd, D MMMM YYYY LT"},calendar:{sameDay:"[Today at] LT",nextDay:"[Tomorrow at] LT",nextWeek:"dddd [at] LT",lastDay:"[Yesterday at] LT",lastWeek:"[Last] dddd [at] LT",sameElse:"L"},relativeTime:{future:"in %s",past:"%s ago",s:"a few seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",M:"a month",MM:"%d months",y:"a year",yy:"%d years"},ordinalParse:/\d{1,2}(st|nd|rd|th)/,ordinal:function(a){var b=a%10,c=1===~~(a%100/10)?"th":1===b?"st":2===b?"nd":3===b?"rd":"th";return a+c},week:{dow:1,doy:4}})}),function(a){a(vb)}(function(a){return a.defineLocale("eo",{months:"januaro_februaro_marto_aprilo_majo_junio_julio_aŭgusto_septembro_oktobro_novembro_decembro".split("_"),monthsShort:"jan_feb_mar_apr_maj_jun_jul_aŭg_sep_okt_nov_dec".split("_"),weekdays:"Dimanĉo_Lundo_Mardo_Merkredo_Ĵaŭdo_Vendredo_Sabato".split("_"),weekdaysShort:"Dim_Lun_Mard_Merk_Ĵaŭ_Ven_Sab".split("_"),weekdaysMin:"Di_Lu_Ma_Me_Ĵa_Ve_Sa".split("_"),longDateFormat:{LT:"HH:mm",LTS:"LT:ss",L:"YYYY-MM-DD",LL:"D[-an de] MMMM, YYYY",LLL:"D[-an de] MMMM, YYYY LT",LLLL:"dddd, [la] D[-an de] MMMM, YYYY LT"},meridiemParse:/[ap]\.t\.m/i,isPM:function(a){return"p"===a.charAt(0).toLowerCase()},meridiem:function(a,b,c){return a>11?c?"p.t.m.":"P.T.M.":c?"a.t.m.":"A.T.M."},calendar:{sameDay:"[Hodiaŭ je] LT",nextDay:"[Morgaŭ je] LT",nextWeek:"dddd [je] LT",lastDay:"[Hieraŭ je] LT",lastWeek:"[pasinta] dddd [je] LT",sameElse:"L"},relativeTime:{future:"je %s",past:"antaŭ %s",s:"sekundoj",m:"minuto",mm:"%d minutoj",h:"horo",hh:"%d horoj",d:"tago",dd:"%d tagoj",M:"monato",MM:"%d monatoj",y:"jaro",yy:"%d jaroj"},ordinalParse:/\d{1,2}a/,ordinal:"%da",week:{dow:1,doy:7}})}),function(a){a(vb)}(function(a){var b="ene._feb._mar._abr._may._jun._jul._ago._sep._oct._nov._dic.".split("_"),c="ene_feb_mar_abr_may_jun_jul_ago_sep_oct_nov_dic".split("_");return a.defineLocale("es",{months:"enero_febrero_marzo_abril_mayo_junio_julio_agosto_septiembre_octubre_noviembre_diciembre".split("_"),monthsShort:function(a,d){return/-MMM-/.test(d)?c[a.month()]:b[a.month()]},weekdays:"domingo_lunes_martes_miércoles_jueves_viernes_sábado".split("_"),weekdaysShort:"dom._lun._mar._mié._jue._vie._sáb.".split("_"),weekdaysMin:"Do_Lu_Ma_Mi_Ju_Vi_Sá".split("_"),longDateFormat:{LT:"H:mm",LTS:"LT:ss",L:"DD/MM/YYYY",LL:"D [de] MMMM [de] YYYY",LLL:"D [de] MMMM [de] YYYY LT",LLLL:"dddd, D [de] MMMM [de] YYYY LT"},calendar:{sameDay:function(){return"[hoy a la"+(1!==this.hours()?"s":"")+"] LT"},nextDay:function(){return"[mañana a la"+(1!==this.hours()?"s":"")+"] LT"},nextWeek:function(){return"dddd [a la"+(1!==this.hours()?"s":"")+"] LT"},lastDay:function(){return"[ayer a la"+(1!==this.hours()?"s":"")+"] LT"},lastWeek:function(){return"[el] dddd [pasado a la"+(1!==this.hours()?"s":"")+"] LT"},sameElse:"L"},relativeTime:{future:"en %s",past:"hace %s",s:"unos segundos",m:"un minuto",mm:"%d minutos",h:"una hora",hh:"%d horas",d:"un día",dd:"%d días",M:"un mes",MM:"%d meses",y:"un año",yy:"%d años"},ordinalParse:/\d{1,2}º/,ordinal:"%dº",week:{dow:1,doy:4}})}),function(a){a(vb)}(function(a){function b(a,b,c,d){var e={s:["mõne sekundi","mõni sekund","paar sekundit"],m:["ühe minuti","üks minut"],mm:[a+" minuti",a+" minutit"],h:["ühe tunni","tund aega","üks tund"],hh:[a+" tunni",a+" tundi"],d:["ühe päeva","üks päev"],M:["kuu aja","kuu aega","üks kuu"],MM:[a+" kuu",a+" kuud"],y:["ühe aasta","aasta","üks aasta"],yy:[a+" aasta",a+" aastat"]};return b?e[c][2]?e[c][2]:e[c][1]:d?e[c][0]:e[c][1]}return a.defineLocale("et",{months:"jaanuar_veebruar_märts_aprill_mai_juuni_juuli_august_september_oktoober_november_detsember".split("_"),monthsShort:"jaan_veebr_märts_apr_mai_juuni_juuli_aug_sept_okt_nov_dets".split("_"),weekdays:"pühapäev_esmaspäev_teisipäev_kolmapäev_neljapäev_reede_laupäev".split("_"),weekdaysShort:"P_E_T_K_N_R_L".split("_"),weekdaysMin:"P_E_T_K_N_R_L".split("_"),longDateFormat:{LT:"H:mm",LTS:"LT:ss",L:"DD.MM.YYYY",LL:"D. MMMM YYYY",LLL:"D. MMMM YYYY LT",LLLL:"dddd, D. MMMM YYYY LT"},calendar:{sameDay:"[Täna,] LT",nextDay:"[Homme,] LT",nextWeek:"[Järgmine] dddd LT",lastDay:"[Eile,] LT",lastWeek:"[Eelmine] dddd LT",sameElse:"L"},relativeTime:{future:"%s pärast",past:"%s tagasi",s:b,m:b,mm:b,h:b,hh:b,d:b,dd:"%d päeva",M:b,MM:b,y:b,yy:b},ordinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}})}),function(a){a(vb)}(function(a){return a.defineLocale("eu",{months:"urtarrila_otsaila_martxoa_apirila_maiatza_ekaina_uztaila_abuztua_iraila_urria_azaroa_abendua".split("_"),monthsShort:"urt._ots._mar._api._mai._eka._uzt._abu._ira._urr._aza._abe.".split("_"),weekdays:"igandea_astelehena_asteartea_asteazkena_osteguna_ostirala_larunbata".split("_"),weekdaysShort:"ig._al._ar._az._og._ol._lr.".split("_"),weekdaysMin:"ig_al_ar_az_og_ol_lr".split("_"),longDateFormat:{LT:"HH:mm",LTS:"LT:ss",L:"YYYY-MM-DD",LL:"YYYY[ko] MMMM[ren] D[a]",LLL:"YYYY[ko] MMMM[ren] D[a] LT",LLLL:"dddd, YYYY[ko] MMMM[ren] D[a] LT",l:"YYYY-M-D",ll:"YYYY[ko] MMM D[a]",lll:"YYYY[ko] MMM D[a] LT",llll:"ddd, YYYY[ko] MMM D[a] LT"},calendar:{sameDay:"[gaur] LT[etan]",nextDay:"[bihar] LT[etan]",nextWeek:"dddd LT[etan]",lastDay:"[atzo] LT[etan]",lastWeek:"[aurreko] dddd LT[etan]",sameElse:"L"},relativeTime:{future:"%s barru",past:"duela %s",s:"segundo batzuk",m:"minutu bat",mm:"%d minutu",h:"ordu bat",hh:"%d ordu",d:"egun bat",dd:"%d egun",M:"hilabete bat",MM:"%d hilabete",y:"urte bat",yy:"%d urte"},ordinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:7}})}),function(a){a(vb)}(function(a){var b={1:"۱",2:"۲",3:"۳",4:"۴",5:"۵",6:"۶",7:"۷",8:"۸",9:"۹",0:"۰"},c={"۱":"1","۲":"2","۳":"3","۴":"4","۵":"5","۶":"6","۷":"7","۸":"8","۹":"9","۰":"0"};return a.defineLocale("fa",{months:"ژانویه_فوریه_مارس_آوریل_مه_ژوئن_ژوئیه_اوت_سپتامبر_اکتبر_نوامبر_دسامبر".split("_"),monthsShort:"ژانویه_فوریه_مارس_آوریل_مه_ژوئن_ژوئیه_اوت_سپتامبر_اکتبر_نوامبر_دسامبر".split("_"),weekdays:"یک‌شنبه_دوشنبه_سه‌شنبه_چهارشنبه_پنج‌شنبه_جمعه_شنبه".split("_"),weekdaysShort:"یک‌شنبه_دوشنبه_سه‌شنبه_چهارشنبه_پنج‌شنبه_جمعه_شنبه".split("_"),weekdaysMin:"ی_د_س_چ_پ_ج_ش".split("_"),longDateFormat:{LT:"HH:mm",LTS:"LT:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY LT",LLLL:"dddd, D MMMM YYYY LT"},meridiemParse:/قبل از ظهر|بعد از ظهر/,isPM:function(a){return/بعد از ظهر/.test(a)},meridiem:function(a){return 12>a?"قبل از ظهر":"بعد از ظهر"},calendar:{sameDay:"[امروز ساعت] LT",nextDay:"[فردا ساعت] LT",nextWeek:"dddd [ساعت] LT",lastDay:"[دیروز ساعت] LT",lastWeek:"dddd [پیش] [ساعت] LT",sameElse:"L"},relativeTime:{future:"در %s",past:"%s پیش",s:"چندین ثانیه",m:"یک دقیقه",mm:"%d دقیقه",h:"یک ساعت",hh:"%d ساعت",d:"یک روز",dd:"%d روز",M:"یک ماه",MM:"%d ماه",y:"یک سال",yy:"%d سال"},preparse:function(a){return a.replace(/[۰-۹]/g,function(a){return c[a]}).replace(/،/g,",")},postformat:function(a){return a.replace(/\d/g,function(a){return b[a]}).replace(/,/g,"،")},ordinalParse:/\d{1,2}م/,ordinal:"%dم",week:{dow:6,doy:12}})}),function(a){a(vb)}(function(a){function b(a,b,d,e){var f="";switch(d){case"s":return e?"muutaman sekunnin":"muutama sekunti";case"m":return e?"minuutin":"minuutti";case"mm":f=e?"minuutin":"minuuttia";break;case"h":return e?"tunnin":"tunti";case"hh":f=e?"tunnin":"tuntia";break;case"d":return e?"päivän":"päivä";case"dd":f=e?"päivän":"päivää";break;case"M":return e?"kuukauden":"kuukausi";case"MM":f=e?"kuukauden":"kuukautta";break;case"y":return e?"vuoden":"vuosi";case"yy":f=e?"vuoden":"vuotta"}return f=c(a,e)+" "+f}function c(a,b){return 10>a?b?e[a]:d[a]:a}var d="nolla yksi kaksi kolme neljä viisi kuusi seitsemän kahdeksan yhdeksän".split(" "),e=["nolla","yhden","kahden","kolmen","neljän","viiden","kuuden",d[7],d[8],d[9]];return a.defineLocale("fi",{months:"tammikuu_helmikuu_maaliskuu_huhtikuu_toukokuu_kesäkuu_heinäkuu_elokuu_syyskuu_lokakuu_marraskuu_joulukuu".split("_"),monthsShort:"tammi_helmi_maalis_huhti_touko_kesä_heinä_elo_syys_loka_marras_joulu".split("_"),weekdays:"sunnuntai_maanantai_tiistai_keskiviikko_torstai_perjantai_lauantai".split("_"),weekdaysShort:"su_ma_ti_ke_to_pe_la".split("_"),weekdaysMin:"su_ma_ti_ke_to_pe_la".split("_"),longDateFormat:{LT:"HH.mm",LTS:"HH.mm.ss",L:"DD.MM.YYYY",LL:"Do MMMM[ta] YYYY",LLL:"Do MMMM[ta] YYYY, [klo] LT",LLLL:"dddd, Do MMMM[ta] YYYY, [klo] LT",l:"D.M.YYYY",ll:"Do MMM YYYY",lll:"Do MMM YYYY, [klo] LT",llll:"ddd, Do MMM YYYY, [klo] LT"},calendar:{sameDay:"[tänään] [klo] LT",nextDay:"[huomenna] [klo] LT",nextWeek:"dddd [klo] LT",lastDay:"[eilen] [klo] LT",lastWeek:"[viime] dddd[na] [klo] LT",sameElse:"L"},relativeTime:{future:"%s päästä",past:"%s sitten",s:b,m:b,mm:b,h:b,hh:b,d:b,dd:b,M:b,MM:b,y:b,yy:b},ordinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}})}),function(a){a(vb)}(function(a){return a.defineLocale("fo",{months:"januar_februar_mars_apríl_mai_juni_juli_august_september_oktober_november_desember".split("_"),monthsShort:"jan_feb_mar_apr_mai_jun_jul_aug_sep_okt_nov_des".split("_"),weekdays:"sunnudagur_mánadagur_týsdagur_mikudagur_hósdagur_fríggjadagur_leygardagur".split("_"),weekdaysShort:"sun_mán_týs_mik_hós_frí_ley".split("_"),weekdaysMin:"su_má_tý_mi_hó_fr_le".split("_"),longDateFormat:{LT:"HH:mm",LTS:"LT:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY LT",LLLL:"dddd D. MMMM, YYYY LT"},calendar:{sameDay:"[Í dag kl.] LT",nextDay:"[Í morgin kl.] LT",nextWeek:"dddd [kl.] LT",lastDay:"[Í gjár kl.] LT",lastWeek:"[síðstu] dddd [kl] LT",sameElse:"L"},relativeTime:{future:"um %s",past:"%s síðani",s:"fá sekund",m:"ein minutt",mm:"%d minuttir",h:"ein tími",hh:"%d tímar",d:"ein dagur",dd:"%d dagar",M:"ein mánaði",MM:"%d mánaðir",y:"eitt ár",yy:"%d ár"},ordinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}})}),function(a){a(vb)}(function(a){return a.defineLocale("fr-ca",{months:"janvier_février_mars_avril_mai_juin_juillet_août_septembre_octobre_novembre_décembre".split("_"),monthsShort:"janv._févr._mars_avr._mai_juin_juil._août_sept._oct._nov._déc.".split("_"),weekdays:"dimanche_lundi_mardi_mercredi_jeudi_vendredi_samedi".split("_"),weekdaysShort:"dim._lun._mar._mer._jeu._ven._sam.".split("_"),weekdaysMin:"Di_Lu_Ma_Me_Je_Ve_Sa".split("_"),longDateFormat:{LT:"HH:mm",LTS:"LT:ss",L:"YYYY-MM-DD",LL:"D MMMM YYYY",LLL:"D MMMM YYYY LT",LLLL:"dddd D MMMM YYYY LT"},calendar:{sameDay:"[Aujourd'hui à] LT",nextDay:"[Demain à] LT",nextWeek:"dddd [à] LT",lastDay:"[Hier à] LT",lastWeek:"dddd [dernier à] LT",sameElse:"L"},relativeTime:{future:"dans %s",past:"il y a %s",s:"quelques secondes",m:"une minute",mm:"%d minutes",h:"une heure",hh:"%d heures",d:"un jour",dd:"%d jours",M:"un mois",MM:"%d mois",y:"un an",yy:"%d ans"},ordinalParse:/\d{1,2}(er|)/,ordinal:function(a){return a+(1===a?"er":"")}})}),function(a){a(vb)}(function(a){return a.defineLocale("fr",{months:"janvier_février_mars_avril_mai_juin_juillet_août_septembre_octobre_novembre_décembre".split("_"),monthsShort:"janv._févr._mars_avr._mai_juin_juil._août_sept._oct._nov._déc.".split("_"),weekdays:"dimanche_lundi_mardi_mercredi_jeudi_vendredi_samedi".split("_"),weekdaysShort:"dim._lun._mar._mer._jeu._ven._sam.".split("_"),weekdaysMin:"Di_Lu_Ma_Me_Je_Ve_Sa".split("_"),longDateFormat:{LT:"HH:mm",LTS:"LT:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY LT",LLLL:"dddd D MMMM YYYY LT"},calendar:{sameDay:"[Aujourd'hui à] LT",nextDay:"[Demain à] LT",nextWeek:"dddd [à] LT",lastDay:"[Hier à] LT",lastWeek:"dddd [dernier à] LT",sameElse:"L"},relativeTime:{future:"dans %s",past:"il y a %s",s:"quelques secondes",m:"une minute",mm:"%d minutes",h:"une heure",hh:"%d heures",d:"un jour",dd:"%d jours",M:"un mois",MM:"%d mois",y:"un an",yy:"%d ans"},ordinalParse:/\d{1,2}(er|)/,ordinal:function(a){return a+(1===a?"er":"")},week:{dow:1,doy:4}})}),function(a){a(vb)}(function(a){var b="jan._feb._mrt._apr._mai_jun._jul._aug._sep._okt._nov._des.".split("_"),c="jan_feb_mrt_apr_mai_jun_jul_aug_sep_okt_nov_des".split("_");return a.defineLocale("fy",{months:"jannewaris_febrewaris_maart_april_maaie_juny_july_augustus_septimber_oktober_novimber_desimber".split("_"),monthsShort:function(a,d){return/-MMM-/.test(d)?c[a.month()]:b[a.month()]},weekdays:"snein_moandei_tiisdei_woansdei_tongersdei_freed_sneon".split("_"),weekdaysShort:"si._mo._ti._wo._to._fr._so.".split("_"),weekdaysMin:"Si_Mo_Ti_Wo_To_Fr_So".split("_"),longDateFormat:{LT:"HH:mm",LTS:"LT:ss",L:"DD-MM-YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY LT",LLLL:"dddd D MMMM YYYY LT"},calendar:{sameDay:"[hjoed om] LT",nextDay:"[moarn om] LT",nextWeek:"dddd [om] LT",lastDay:"[juster om] LT",lastWeek:"[ôfrûne] dddd [om] LT",sameElse:"L"},relativeTime:{future:"oer %s",past:"%s lyn",s:"in pear sekonden",m:"ien minút",mm:"%d minuten",h:"ien oere",hh:"%d oeren",d:"ien dei",dd:"%d dagen",M:"ien moanne",MM:"%d moannen",y:"ien jier",yy:"%d jierren"},ordinalParse:/\d{1,2}(ste|de)/,ordinal:function(a){return a+(1===a||8===a||a>=20?"ste":"de")},week:{dow:1,doy:4}})}),function(a){a(vb)}(function(a){return a.defineLocale("gl",{months:"Xaneiro_Febreiro_Marzo_Abril_Maio_Xuño_Xullo_Agosto_Setembro_Outubro_Novembro_Decembro".split("_"),monthsShort:"Xan._Feb._Mar._Abr._Mai._Xuñ._Xul._Ago._Set._Out._Nov._Dec.".split("_"),weekdays:"Domingo_Luns_Martes_Mércores_Xoves_Venres_Sábado".split("_"),weekdaysShort:"Dom._Lun._Mar._Mér._Xov._Ven._Sáb.".split("_"),weekdaysMin:"Do_Lu_Ma_Mé_Xo_Ve_Sá".split("_"),longDateFormat:{LT:"H:mm",LTS:"LT:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY LT",LLLL:"dddd D MMMM YYYY LT"},calendar:{sameDay:function(){return"[hoxe "+(1!==this.hours()?"ás":"á")+"] LT"},nextDay:function(){return"[mañá "+(1!==this.hours()?"ás":"á")+"] LT"},nextWeek:function(){return"dddd ["+(1!==this.hours()?"ás":"a")+"] LT"},lastDay:function(){return"[onte "+(1!==this.hours()?"á":"a")+"] LT"},lastWeek:function(){return"[o] dddd [pasado "+(1!==this.hours()?"ás":"a")+"] LT"},sameElse:"L"},relativeTime:{future:function(a){return"uns segundos"===a?"nuns segundos":"en "+a},past:"hai %s",s:"uns segundos",m:"un minuto",mm:"%d minutos",h:"unha hora",hh:"%d horas",d:"un día",dd:"%d días",M:"un mes",MM:"%d meses",y:"un ano",yy:"%d anos"},ordinalParse:/\d{1,2}º/,ordinal:"%dº",week:{dow:1,doy:7}})}),function(a){a(vb)}(function(a){return a.defineLocale("he",{months:"ינואר_פברואר_מרץ_אפריל_מאי_יוני_יולי_אוגוסט_ספטמבר_אוקטובר_נובמבר_דצמבר".split("_"),monthsShort:"ינו׳_פבר׳_מרץ_אפר׳_מאי_יוני_יולי_אוג׳_ספט׳_אוק׳_נוב׳_דצמ׳".split("_"),weekdays:"ראשון_שני_שלישי_רביעי_חמישי_שישי_שבת".split("_"),weekdaysShort:"א׳_ב׳_ג׳_ד׳_ה׳_ו׳_ש׳".split("_"),weekdaysMin:"א_ב_ג_ד_ה_ו_ש".split("_"),longDateFormat:{LT:"HH:mm",LTS:"LT:ss",L:"DD/MM/YYYY",LL:"D [ב]MMMM YYYY",LLL:"D [ב]MMMM YYYY LT",LLLL:"dddd, D [ב]MMMM YYYY LT",l:"D/M/YYYY",ll:"D MMM YYYY",lll:"D MMM YYYY LT",llll:"ddd, D MMM YYYY LT"},calendar:{sameDay:"[היום ב־]LT",nextDay:"[מחר ב־]LT",nextWeek:"dddd [בשעה] LT",lastDay:"[אתמול ב־]LT",lastWeek:"[ביום] dddd [האחרון בשעה] LT",sameElse:"L"},relativeTime:{future:"בעוד %s",past:"לפני %s",s:"מספר שניות",m:"דקה",mm:"%d דקות",h:"שעה",hh:function(a){return 2===a?"שעתיים":a+" שעות"},d:"יום",dd:function(a){return 2===a?"יומיים":a+" ימים"},M:"חודש",MM:function(a){return 2===a?"חודשיים":a+" חודשים"},y:"שנה",yy:function(a){return 2===a?"שנתיים":a%10===0&&10!==a?a+" שנה":a+" שנים"}}})}),function(a){a(vb)}(function(a){var b={1:"१",2:"२",3:"३",4:"४",5:"५",6:"६",7:"७",8:"८",9:"९",0:"०"},c={"१":"1","२":"2","३":"3","४":"4","५":"5","६":"6","७":"7","८":"8","९":"9","०":"0"};return a.defineLocale("hi",{months:"जनवरी_फ़रवरी_मार्च_अप्रैल_मई_जून_जुलाई_अगस्त_सितम्बर_अक्टूबर_नवम्बर_दिसम्बर".split("_"),monthsShort:"जन._फ़र._मार्च_अप्रै._मई_जून_जुल._अग._सित._अक्टू._नव._दिस.".split("_"),weekdays:"रविवार_सोमवार_मंगलवार_बुधवार_गुरूवार_शुक्रवार_शनिवार".split("_"),weekdaysShort:"रवि_सोम_मंगल_बुध_गुरू_शुक्र_शनि".split("_"),weekdaysMin:"र_सो_मं_बु_गु_शु_श".split("_"),longDateFormat:{LT:"A h:mm बजे",LTS:"A h:mm:ss बजे",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY, LT",LLLL:"dddd, D MMMM YYYY, LT"},calendar:{sameDay:"[आज] LT",nextDay:"[कल] LT",nextWeek:"dddd, LT",lastDay:"[कल] LT",lastWeek:"[पिछले] dddd, LT",sameElse:"L"},relativeTime:{future:"%s में",past:"%s पहले",s:"कुछ ही क्षण",m:"एक मिनट",mm:"%d मिनट",h:"एक घंटा",hh:"%d घंटे",d:"एक दिन",dd:"%d दिन",M:"एक महीने",MM:"%d महीने",y:"एक वर्ष",yy:"%d वर्ष"},preparse:function(a){return a.replace(/[१२३४५६७८९०]/g,function(a){return c[a]})},postformat:function(a){return a.replace(/\d/g,function(a){return b[a]})},meridiemParse:/रात|सुबह|दोपहर|शाम/,meridiemHour:function(a,b){return 12===a&&(a=0),"रात"===b?4>a?a:a+12:"सुबह"===b?a:"दोपहर"===b?a>=10?a:a+12:"शाम"===b?a+12:void 0},meridiem:function(a){return 4>a?"रात":10>a?"सुबह":17>a?"दोपहर":20>a?"शाम":"रात"},week:{dow:0,doy:6}})}),function(a){a(vb)}(function(a){function b(a,b,c){var d=a+" ";switch(c){case"m":return b?"jedna minuta":"jedne minute";case"mm":return d+=1===a?"minuta":2===a||3===a||4===a?"minute":"minuta";case"h":return b?"jedan sat":"jednog sata";case"hh":return d+=1===a?"sat":2===a||3===a||4===a?"sata":"sati";case"dd":return d+=1===a?"dan":"dana";case"MM":return d+=1===a?"mjesec":2===a||3===a||4===a?"mjeseca":"mjeseci";case"yy":return d+=1===a?"godina":2===a||3===a||4===a?"godine":"godina"}}return a.defineLocale("hr",{months:"sječanj_veljača_ožujak_travanj_svibanj_lipanj_srpanj_kolovoz_rujan_listopad_studeni_prosinac".split("_"),monthsShort:"sje._vel._ožu._tra._svi._lip._srp._kol._ruj._lis._stu._pro.".split("_"),weekdays:"nedjelja_ponedjeljak_utorak_srijeda_četvrtak_petak_subota".split("_"),weekdaysShort:"ned._pon._uto._sri._čet._pet._sub.".split("_"),weekdaysMin:"ne_po_ut_sr_če_pe_su".split("_"),longDateFormat:{LT:"H:mm",LTS:"LT:ss",L:"DD. MM. YYYY",LL:"D. MMMM YYYY",LLL:"D. MMMM YYYY LT",LLLL:"dddd, D. MMMM YYYY LT"},calendar:{sameDay:"[danas u] LT",nextDay:"[sutra u] LT",nextWeek:function(){switch(this.day()){case 0:return"[u] [nedjelju] [u] LT";case 3:return"[u] [srijedu] [u] LT";case 6:return"[u] [subotu] [u] LT";case 1:case 2:case 4:case 5:return"[u] dddd [u] LT"}},lastDay:"[jučer u] LT",lastWeek:function(){switch(this.day()){case 0:case 3:return"[prošlu] dddd [u] LT";case 6:return"[prošle] [subote] [u] LT";case 1:case 2:case 4:case 5:return"[prošli] dddd [u] LT"}},sameElse:"L"},relativeTime:{future:"za %s",past:"prije %s",s:"par sekundi",m:b,mm:b,h:b,hh:b,d:"dan",dd:b,M:"mjesec",MM:b,y:"godinu",yy:b},ordinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:7}})}),function(a){a(vb)}(function(a){function b(a,b,c,d){var e=a;switch(c){case"s":return d||b?"néhány másodperc":"néhány másodperce";case"m":return"egy"+(d||b?" perc":" perce");case"mm":return e+(d||b?" perc":" perce");case"h":return"egy"+(d||b?" óra":" órája");case"hh":return e+(d||b?" óra":" órája");case"d":return"egy"+(d||b?" nap":" napja");case"dd":return e+(d||b?" nap":" napja");case"M":return"egy"+(d||b?" hónap":" hónapja");case"MM":return e+(d||b?" hónap":" hónapja");case"y":return"egy"+(d||b?" év":" éve");case"yy":return e+(d||b?" év":" éve")}return""}function c(a){return(a?"":"[múlt] ")+"["+d[this.day()]+"] LT[-kor]"}var d="vasárnap hétfőn kedden szerdán csütörtökön pénteken szombaton".split(" ");return a.defineLocale("hu",{months:"január_február_március_április_május_június_július_augusztus_szeptember_október_november_december".split("_"),monthsShort:"jan_feb_márc_ápr_máj_jún_júl_aug_szept_okt_nov_dec".split("_"),weekdays:"vasárnap_hétfő_kedd_szerda_csütörtök_péntek_szombat".split("_"),weekdaysShort:"vas_hét_kedd_sze_csüt_pén_szo".split("_"),weekdaysMin:"v_h_k_sze_cs_p_szo".split("_"),longDateFormat:{LT:"H:mm",LTS:"LT:ss",L:"YYYY.MM.DD.",LL:"YYYY. MMMM D.",LLL:"YYYY. MMMM D., LT",LLLL:"YYYY. MMMM D., dddd LT"},meridiemParse:/de|du/i,isPM:function(a){return"u"===a.charAt(1).toLowerCase()},meridiem:function(a,b,c){return 12>a?c===!0?"de":"DE":c===!0?"du":"DU"},calendar:{sameDay:"[ma] LT[-kor]",nextDay:"[holnap] LT[-kor]",nextWeek:function(){return c.call(this,!0)},lastDay:"[tegnap] LT[-kor]",lastWeek:function(){return c.call(this,!1)},sameElse:"L"},relativeTime:{future:"%s múlva",past:"%s",s:b,m:b,mm:b,h:b,hh:b,d:b,dd:b,M:b,MM:b,y:b,yy:b},ordinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:7}})}),function(a){a(vb)}(function(a){function b(a,b){var c={nominative:"հունվար_փետրվար_մարտ_ապրիլ_մայիս_հունիս_հուլիս_օգոստոս_սեպտեմբեր_հոկտեմբեր_նոյեմբեր_դեկտեմբեր".split("_"),accusative:"հունվարի_փետրվարի_մարտի_ապրիլի_մայիսի_հունիսի_հուլիսի_օգոստոսի_սեպտեմբերի_հոկտեմբերի_նոյեմբերի_դեկտեմբերի".split("_")},d=/D[oD]?(\[[^\[\]]*\]|\s+)+MMMM?/.test(b)?"accusative":"nominative";return c[d][a.month()]}function c(a){var b="հնվ_փտր_մրտ_ապր_մյս_հնս_հլս_օգս_սպտ_հկտ_նմբ_դկտ".split("_");return b[a.month()]}function d(a){var b="կիրակի_երկուշաբթի_երեքշաբթի_չորեքշաբթի_հինգշաբթի_ուրբաթ_շաբաթ".split("_");return b[a.day()]}return a.defineLocale("hy-am",{months:b,monthsShort:c,weekdays:d,weekdaysShort:"կրկ_երկ_երք_չրք_հնգ_ուրբ_շբթ".split("_"),weekdaysMin:"կրկ_երկ_երք_չրք_հնգ_ուրբ_շբթ".split("_"),longDateFormat:{LT:"HH:mm",LTS:"LT:ss",L:"DD.MM.YYYY",LL:"D MMMM YYYY թ.",LLL:"D MMMM YYYY թ., LT",LLLL:"dddd, D MMMM YYYY թ., LT"},calendar:{sameDay:"[այսօր] LT",nextDay:"[վաղը] LT",lastDay:"[երեկ] LT",nextWeek:function(){return"dddd [օրը ժամը] LT"},lastWeek:function(){return"[անցած] dddd [օրը ժամը] LT"},sameElse:"L"},relativeTime:{future:"%s հետո",past:"%s առաջ",s:"մի քանի վայրկյան",m:"րոպե",mm:"%d րոպե",h:"ժամ",hh:"%d ժամ",d:"օր",dd:"%d օր",M:"ամիս",MM:"%d ամիս",y:"տարի",yy:"%d տարի"},meridiemParse:/գիշերվա|առավոտվա|ցերեկվա|երեկոյան/,isPM:function(a){return/^(ցերեկվա|երեկոյան)$/.test(a)},meridiem:function(a){return 4>a?"գիշերվա":12>a?"առավոտվա":17>a?"ցերեկվա":"երեկոյան"},ordinalParse:/\d{1,2}|\d{1,2}-(ին|րդ)/,ordinal:function(a,b){switch(b){case"DDD":case"w":case"W":case"DDDo":return 1===a?a+"-ին":a+"-րդ";default:return a}},week:{dow:1,doy:7}})}),function(a){a(vb)}(function(a){return a.defineLocale("id",{months:"Januari_Februari_Maret_April_Mei_Juni_Juli_Agustus_September_Oktober_November_Desember".split("_"),monthsShort:"Jan_Feb_Mar_Apr_Mei_Jun_Jul_Ags_Sep_Okt_Nov_Des".split("_"),weekdays:"Minggu_Senin_Selasa_Rabu_Kamis_Jumat_Sabtu".split("_"),weekdaysShort:"Min_Sen_Sel_Rab_Kam_Jum_Sab".split("_"),weekdaysMin:"Mg_Sn_Sl_Rb_Km_Jm_Sb".split("_"),longDateFormat:{LT:"HH.mm",LTS:"LT.ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY [pukul] LT",LLLL:"dddd, D MMMM YYYY [pukul] LT"},meridiemParse:/pagi|siang|sore|malam/,meridiemHour:function(a,b){return 12===a&&(a=0),"pagi"===b?a:"siang"===b?a>=11?a:a+12:"sore"===b||"malam"===b?a+12:void 0},meridiem:function(a){return 11>a?"pagi":15>a?"siang":19>a?"sore":"malam"},calendar:{sameDay:"[Hari ini pukul] LT",nextDay:"[Besok pukul] LT",nextWeek:"dddd [pukul] LT",lastDay:"[Kemarin pukul] LT",lastWeek:"dddd [lalu pukul] LT",sameElse:"L"},relativeTime:{future:"dalam %s",past:"%s yang lalu",s:"beberapa detik",m:"semenit",mm:"%d menit",h:"sejam",hh:"%d jam",d:"sehari",dd:"%d hari",M:"sebulan",MM:"%d bulan",y:"setahun",yy:"%d tahun"},week:{dow:1,doy:7}})}),function(a){a(vb)}(function(a){function b(a){return a%100===11?!0:a%10===1?!1:!0}function c(a,c,d,e){var f=a+" ";switch(d){case"s":return c||e?"nokkrar sekúndur":"nokkrum sekúndum";case"m":return c?"mínúta":"mínútu";case"mm":return b(a)?f+(c||e?"mínútur":"mínútum"):c?f+"mínúta":f+"mínútu";case"hh":return b(a)?f+(c||e?"klukkustundir":"klukkustundum"):f+"klukkustund";case"d":return c?"dagur":e?"dag":"degi";case"dd":return b(a)?c?f+"dagar":f+(e?"daga":"dögum"):c?f+"dagur":f+(e?"dag":"degi");case"M":return c?"mánuður":e?"mánuð":"mánuði";case"MM":return b(a)?c?f+"mánuðir":f+(e?"mánuði":"mánuðum"):c?f+"mánuður":f+(e?"mánuð":"mánuði");case"y":return c||e?"ár":"ári";case"yy":return b(a)?f+(c||e?"ár":"árum"):f+(c||e?"ár":"ári")}}return a.defineLocale("is",{months:"janúar_febrúar_mars_apríl_maí_júní_júlí_ágúst_september_október_nóvember_desember".split("_"),monthsShort:"jan_feb_mar_apr_maí_jún_júl_ágú_sep_okt_nóv_des".split("_"),weekdays:"sunnudagur_mánudagur_þriðjudagur_miðvikudagur_fimmtudagur_föstudagur_laugardagur".split("_"),weekdaysShort:"sun_mán_þri_mið_fim_fös_lau".split("_"),weekdaysMin:"Su_Má_Þr_Mi_Fi_Fö_La".split("_"),longDateFormat:{LT:"H:mm",LTS:"LT:ss",L:"DD/MM/YYYY",LL:"D. MMMM YYYY",LLL:"D. MMMM YYYY [kl.] LT",LLLL:"dddd, D. MMMM YYYY [kl.] LT"},calendar:{sameDay:"[í dag kl.] LT",nextDay:"[á morgun kl.] LT",nextWeek:"dddd [kl.] LT",lastDay:"[í gær kl.] LT",lastWeek:"[síðasta] dddd [kl.] LT",sameElse:"L"},relativeTime:{future:"eftir %s",past:"fyrir %s síðan",s:c,m:c,mm:c,h:"klukkustund",hh:c,d:c,dd:c,M:c,MM:c,y:c,yy:c},ordinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}})}),function(a){a(vb)}(function(a){return a.defineLocale("it",{months:"gennaio_febbraio_marzo_aprile_maggio_giugno_luglio_agosto_settembre_ottobre_novembre_dicembre".split("_"),monthsShort:"gen_feb_mar_apr_mag_giu_lug_ago_set_ott_nov_dic".split("_"),weekdays:"Domenica_Lunedì_Martedì_Mercoledì_Giovedì_Venerdì_Sabato".split("_"),weekdaysShort:"Dom_Lun_Mar_Mer_Gio_Ven_Sab".split("_"),weekdaysMin:"D_L_Ma_Me_G_V_S".split("_"),longDateFormat:{LT:"HH:mm",LTS:"LT:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY LT",LLLL:"dddd, D MMMM YYYY LT"},calendar:{sameDay:"[Oggi alle] LT",nextDay:"[Domani alle] LT",nextWeek:"dddd [alle] LT",lastDay:"[Ieri alle] LT",lastWeek:function(){switch(this.day()){case 0:return"[la scorsa] dddd [alle] LT";default:return"[lo scorso] dddd [alle] LT"}},sameElse:"L"},relativeTime:{future:function(a){return(/^[0-9].+$/.test(a)?"tra":"in")+" "+a},past:"%s fa",s:"alcuni secondi",m:"un minuto",mm:"%d minuti",h:"un'ora",hh:"%d ore",d:"un giorno",dd:"%d giorni",M:"un mese",MM:"%d mesi",y:"un anno",yy:"%d anni"},ordinalParse:/\d{1,2}º/,ordinal:"%dº",week:{dow:1,doy:4}})}),function(a){a(vb)}(function(a){return a.defineLocale("ja",{months:"1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月".split("_"),monthsShort:"1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月".split("_"),weekdays:"日曜日_月曜日_火曜日_水曜日_木曜日_金曜日_土曜日".split("_"),weekdaysShort:"日_月_火_水_木_金_土".split("_"),weekdaysMin:"日_月_火_水_木_金_土".split("_"),longDateFormat:{LT:"Ah時m分",LTS:"LTs秒",L:"YYYY/MM/DD",LL:"YYYY年M月D日",LLL:"YYYY年M月D日LT",LLLL:"YYYY年M月D日LT dddd"},meridiemParse:/午前|午後/i,isPM:function(a){return"午後"===a},meridiem:function(a){return 12>a?"午前":"午後"},calendar:{sameDay:"[今日] LT",nextDay:"[明日] LT",nextWeek:"[来週]dddd LT",lastDay:"[昨日] LT",lastWeek:"[前週]dddd LT",sameElse:"L"},relativeTime:{future:"%s後",past:"%s前",s:"数秒",m:"1分",mm:"%d分",h:"1時間",hh:"%d時間",d:"1日",dd:"%d日",M:"1ヶ月",MM:"%dヶ月",y:"1年",yy:"%d年"}})}),function(a){a(vb)}(function(a){function b(a,b){var c={nominative:"იანვარი_თებერვალი_მარტი_აპრილი_მაისი_ივნისი_ივლისი_აგვისტო_სექტემბერი_ოქტომბერი_ნოემბერი_დეკემბერი".split("_"),accusative:"იანვარს_თებერვალს_მარტს_აპრილის_მაისს_ივნისს_ივლისს_აგვისტს_სექტემბერს_ოქტომბერს_ნოემბერს_დეკემბერს".split("_")},d=/D[oD] *MMMM?/.test(b)?"accusative":"nominative";return c[d][a.month()]}function c(a,b){var c={nominative:"კვირა_ორშაბათი_სამშაბათი_ოთხშაბათი_ხუთშაბათი_პარასკევი_შაბათი".split("_"),accusative:"კვირას_ორშაბათს_სამშაბათს_ოთხშაბათს_ხუთშაბათს_პარასკევს_შაბათს".split("_")},d=/(წინა|შემდეგ)/.test(b)?"accusative":"nominative";return c[d][a.day()]}return a.defineLocale("ka",{months:b,monthsShort:"იან_თებ_მარ_აპრ_მაი_ივნ_ივლ_აგვ_სექ_ოქტ_ნოე_დეკ".split("_"),weekdays:c,weekdaysShort:"კვი_ორშ_სამ_ოთხ_ხუთ_პარ_შაბ".split("_"),weekdaysMin:"კვ_ორ_სა_ოთ_ხუ_პა_შა".split("_"),longDateFormat:{LT:"h:mm A",LTS:"h:mm:ss A",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY LT",LLLL:"dddd, D MMMM YYYY LT"},calendar:{sameDay:"[დღეს] LT[-ზე]",nextDay:"[ხვალ] LT[-ზე]",lastDay:"[გუშინ] LT[-ზე]",nextWeek:"[შემდეგ] dddd LT[-ზე]",lastWeek:"[წინა] dddd LT-ზე",sameElse:"L"},relativeTime:{future:function(a){return/(წამი|წუთი|საათი|წელი)/.test(a)?a.replace(/ი$/,"ში"):a+"ში"},past:function(a){return/(წამი|წუთი|საათი|დღე|თვე)/.test(a)?a.replace(/(ი|ე)$/,"ის წინ"):/წელი/.test(a)?a.replace(/წელი$/,"წლის წინ"):void 0},s:"რამდენიმე წამი",m:"წუთი",mm:"%d წუთი",h:"საათი",hh:"%d საათი",d:"დღე",dd:"%d დღე",M:"თვე",MM:"%d თვე",y:"წელი",yy:"%d წელი"},ordinalParse:/0|1-ლი|მე-\d{1,2}|\d{1,2}-ე/,ordinal:function(a){return 0===a?a:1===a?a+"-ლი":20>a||100>=a&&a%20===0||a%100===0?"მე-"+a:a+"-ე"},week:{dow:1,doy:7}})}),function(a){a(vb)}(function(a){return a.defineLocale("km",{months:"មករា_កុម្ភៈ_មិនា_មេសា_ឧសភា_មិថុនា_កក្កដា_សីហា_កញ្ញា_តុលា_វិច្ឆិកា_ធ្នូ".split("_"),monthsShort:"មករា_កុម្ភៈ_មិនា_មេសា_ឧសភា_មិថុនា_កក្កដា_សីហា_កញ្ញា_តុលា_វិច្ឆិកា_ធ្នូ".split("_"),weekdays:"អាទិត្យ_ច័ន្ទ_អង្គារ_ពុធ_ព្រហស្បតិ៍_សុក្រ_សៅរ៍".split("_"),weekdaysShort:"អាទិត្យ_ច័ន្ទ_អង្គារ_ពុធ_ព្រហស្បតិ៍_សុក្រ_សៅរ៍".split("_"),weekdaysMin:"អាទិត្យ_ច័ន្ទ_អង្គារ_ពុធ_ព្រហស្បតិ៍_សុក្រ_សៅរ៍".split("_"),longDateFormat:{LT:"HH:mm",LTS:"LT:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY LT",LLLL:"dddd, D MMMM YYYY LT"},calendar:{sameDay:"[ថ្ងៃនៈ ម៉ោង] LT",nextDay:"[ស្អែក ម៉ោង] LT",nextWeek:"dddd [ម៉ោង] LT",lastDay:"[ម្សិលមិញ ម៉ោង] LT",lastWeek:"dddd [សប្តាហ៍មុន] [ម៉ោង] LT",sameElse:"L"},relativeTime:{future:"%sទៀត",past:"%sមុន",s:"ប៉ុន្មានវិនាទី",m:"មួយនាទី",mm:"%d នាទី",h:"មួយម៉ោង",hh:"%d ម៉ោង",d:"មួយថ្ងៃ",dd:"%d ថ្ងៃ",M:"មួយខែ",MM:"%d ខែ",y:"មួយឆ្នាំ",yy:"%d ឆ្នាំ"},week:{dow:1,doy:4}})}),function(a){a(vb)}(function(a){return a.defineLocale("ko",{months:"1월_2월_3월_4월_5월_6월_7월_8월_9월_10월_11월_12월".split("_"),monthsShort:"1월_2월_3월_4월_5월_6월_7월_8월_9월_10월_11월_12월".split("_"),weekdays:"일요일_월요일_화요일_수요일_목요일_금요일_토요일".split("_"),weekdaysShort:"일_월_화_수_목_금_토".split("_"),weekdaysMin:"일_월_화_수_목_금_토".split("_"),longDateFormat:{LT:"A h시 m분",LTS:"A h시 m분 s초",L:"YYYY.MM.DD",LL:"YYYY년 MMMM D일",LLL:"YYYY년 MMMM D일 LT",LLLL:"YYYY년 MMMM D일 dddd LT"},calendar:{sameDay:"오늘 LT",nextDay:"내일 LT",nextWeek:"dddd LT",lastDay:"어제 LT",lastWeek:"지난주 dddd LT",sameElse:"L"},relativeTime:{future:"%s 후",past:"%s 전",s:"몇초",ss:"%d초",m:"일분",mm:"%d분",h:"한시간",hh:"%d시간",d:"하루",dd:"%d일",M:"한달",MM:"%d달",y:"일년",yy:"%d년"},ordinalParse:/\d{1,2}일/,ordinal:"%d일",meridiemParse:/오전|오후/,isPM:function(a){return"오후"===a},meridiem:function(a){return 12>a?"오전":"오후"}})}),function(a){a(vb)}(function(a){function b(a,b,c){var d={m:["eng Minutt","enger Minutt"],h:["eng Stonn","enger Stonn"],d:["een Dag","engem Dag"],M:["ee Mount","engem Mount"],y:["ee Joer","engem Joer"]};return b?d[c][0]:d[c][1]}function c(a){var b=a.substr(0,a.indexOf(" "));return e(b)?"a "+a:"an "+a}function d(a){var b=a.substr(0,a.indexOf(" "));return e(b)?"viru "+a:"virun "+a}function e(a){if(a=parseInt(a,10),isNaN(a))return!1;if(0>a)return!0;if(10>a)return a>=4&&7>=a?!0:!1;if(100>a){var b=a%10,c=a/10;return e(0===b?c:b)}if(1e4>a){for(;a>=10;)a/=10;return e(a)}return a/=1e3,e(a)}return a.defineLocale("lb",{months:"Januar_Februar_Mäerz_Abrëll_Mee_Juni_Juli_August_September_Oktober_November_Dezember".split("_"),monthsShort:"Jan._Febr._Mrz._Abr._Mee_Jun._Jul._Aug._Sept._Okt._Nov._Dez.".split("_"),weekdays:"Sonndeg_Méindeg_Dënschdeg_Mëttwoch_Donneschdeg_Freideg_Samschdeg".split("_"),weekdaysShort:"So._Mé._Dë._Më._Do._Fr._Sa.".split("_"),weekdaysMin:"So_Mé_Dë_Më_Do_Fr_Sa".split("_"),longDateFormat:{LT:"H:mm [Auer]",LTS:"H:mm:ss [Auer]",L:"DD.MM.YYYY",LL:"D. MMMM YYYY",LLL:"D. MMMM YYYY LT",LLLL:"dddd, D. MMMM YYYY LT"},calendar:{sameDay:"[Haut um] LT",sameElse:"L",nextDay:"[Muer um] LT",nextWeek:"dddd [um] LT",lastDay:"[Gëschter um] LT",lastWeek:function(){switch(this.day()){case 2:case 4:return"[Leschten] dddd [um] LT";default:return"[Leschte] dddd [um] LT"}}},relativeTime:{future:c,past:d,s:"e puer Sekonnen",m:b,mm:"%d Minutten",h:b,hh:"%d Stonnen",d:b,dd:"%d Deeg",M:b,MM:"%d Méint",y:b,yy:"%d Joer"},ordinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}})}),function(a){a(vb)}(function(a){function b(a,b,c,d){return b?"kelios sekundės":d?"kelių sekundžių":"kelias sekundes"}function c(a,b,c,d){return b?e(c)[0]:d?e(c)[1]:e(c)[2] +}function d(a){return a%10===0||a>10&&20>a}function e(a){return h[a].split("_")}function f(a,b,f,g){var h=a+" ";return 1===a?h+c(a,b,f[0],g):b?h+(d(a)?e(f)[1]:e(f)[0]):g?h+e(f)[1]:h+(d(a)?e(f)[1]:e(f)[2])}function g(a,b){var c=-1===b.indexOf("dddd HH:mm"),d=i[a.day()];return c?d:d.substring(0,d.length-2)+"į"}var h={m:"minutė_minutės_minutę",mm:"minutės_minučių_minutes",h:"valanda_valandos_valandą",hh:"valandos_valandų_valandas",d:"diena_dienos_dieną",dd:"dienos_dienų_dienas",M:"mėnuo_mėnesio_mėnesį",MM:"mėnesiai_mėnesių_mėnesius",y:"metai_metų_metus",yy:"metai_metų_metus"},i="sekmadienis_pirmadienis_antradienis_trečiadienis_ketvirtadienis_penktadienis_šeštadienis".split("_");return a.defineLocale("lt",{months:"sausio_vasario_kovo_balandžio_gegužės_birželio_liepos_rugpjūčio_rugsėjo_spalio_lapkričio_gruodžio".split("_"),monthsShort:"sau_vas_kov_bal_geg_bir_lie_rgp_rgs_spa_lap_grd".split("_"),weekdays:g,weekdaysShort:"Sek_Pir_Ant_Tre_Ket_Pen_Šeš".split("_"),weekdaysMin:"S_P_A_T_K_Pn_Š".split("_"),longDateFormat:{LT:"HH:mm",LTS:"LT:ss",L:"YYYY-MM-DD",LL:"YYYY [m.] MMMM D [d.]",LLL:"YYYY [m.] MMMM D [d.], LT [val.]",LLLL:"YYYY [m.] MMMM D [d.], dddd, LT [val.]",l:"YYYY-MM-DD",ll:"YYYY [m.] MMMM D [d.]",lll:"YYYY [m.] MMMM D [d.], LT [val.]",llll:"YYYY [m.] MMMM D [d.], ddd, LT [val.]"},calendar:{sameDay:"[Šiandien] LT",nextDay:"[Rytoj] LT",nextWeek:"dddd LT",lastDay:"[Vakar] LT",lastWeek:"[Praėjusį] dddd LT",sameElse:"L"},relativeTime:{future:"po %s",past:"prieš %s",s:b,m:c,mm:f,h:c,hh:f,d:c,dd:f,M:c,MM:f,y:c,yy:f},ordinalParse:/\d{1,2}-oji/,ordinal:function(a){return a+"-oji"},week:{dow:1,doy:4}})}),function(a){a(vb)}(function(a){function b(a,b,c){var d=a.split("_");return c?b%10===1&&11!==b?d[2]:d[3]:b%10===1&&11!==b?d[0]:d[1]}function c(a,c,e){return a+" "+b(d[e],a,c)}var d={mm:"minūti_minūtes_minūte_minūtes",hh:"stundu_stundas_stunda_stundas",dd:"dienu_dienas_diena_dienas",MM:"mēnesi_mēnešus_mēnesis_mēneši",yy:"gadu_gadus_gads_gadi"};return a.defineLocale("lv",{months:"janvāris_februāris_marts_aprīlis_maijs_jūnijs_jūlijs_augusts_septembris_oktobris_novembris_decembris".split("_"),monthsShort:"jan_feb_mar_apr_mai_jūn_jūl_aug_sep_okt_nov_dec".split("_"),weekdays:"svētdiena_pirmdiena_otrdiena_trešdiena_ceturtdiena_piektdiena_sestdiena".split("_"),weekdaysShort:"Sv_P_O_T_C_Pk_S".split("_"),weekdaysMin:"Sv_P_O_T_C_Pk_S".split("_"),longDateFormat:{LT:"HH:mm",LTS:"LT:ss",L:"DD.MM.YYYY",LL:"YYYY. [gada] D. MMMM",LLL:"YYYY. [gada] D. MMMM, LT",LLLL:"YYYY. [gada] D. MMMM, dddd, LT"},calendar:{sameDay:"[Šodien pulksten] LT",nextDay:"[Rīt pulksten] LT",nextWeek:"dddd [pulksten] LT",lastDay:"[Vakar pulksten] LT",lastWeek:"[Pagājušā] dddd [pulksten] LT",sameElse:"L"},relativeTime:{future:"%s vēlāk",past:"%s agrāk",s:"dažas sekundes",m:"minūti",mm:c,h:"stundu",hh:c,d:"dienu",dd:c,M:"mēnesi",MM:c,y:"gadu",yy:c},ordinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}})}),function(a){a(vb)}(function(a){return a.defineLocale("mk",{months:"јануари_февруари_март_април_мај_јуни_јули_август_септември_октомври_ноември_декември".split("_"),monthsShort:"јан_фев_мар_апр_мај_јун_јул_авг_сеп_окт_ное_дек".split("_"),weekdays:"недела_понеделник_вторник_среда_четврток_петок_сабота".split("_"),weekdaysShort:"нед_пон_вто_сре_чет_пет_саб".split("_"),weekdaysMin:"нe_пo_вт_ср_че_пе_сa".split("_"),longDateFormat:{LT:"H:mm",LTS:"LT:ss",L:"D.MM.YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY LT",LLLL:"dddd, D MMMM YYYY LT"},calendar:{sameDay:"[Денес во] LT",nextDay:"[Утре во] LT",nextWeek:"dddd [во] LT",lastDay:"[Вчера во] LT",lastWeek:function(){switch(this.day()){case 0:case 3:case 6:return"[Во изминатата] dddd [во] LT";case 1:case 2:case 4:case 5:return"[Во изминатиот] dddd [во] LT"}},sameElse:"L"},relativeTime:{future:"после %s",past:"пред %s",s:"неколку секунди",m:"минута",mm:"%d минути",h:"час",hh:"%d часа",d:"ден",dd:"%d дена",M:"месец",MM:"%d месеци",y:"година",yy:"%d години"},ordinalParse:/\d{1,2}-(ев|ен|ти|ви|ри|ми)/,ordinal:function(a){var b=a%10,c=a%100;return 0===a?a+"-ев":0===c?a+"-ен":c>10&&20>c?a+"-ти":1===b?a+"-ви":2===b?a+"-ри":7===b||8===b?a+"-ми":a+"-ти"},week:{dow:1,doy:7}})}),function(a){a(vb)}(function(a){return a.defineLocale("ml",{months:"ജനുവരി_ഫെബ്രുവരി_മാർച്ച്_ഏപ്രിൽ_മേയ്_ജൂൺ_ജൂലൈ_ഓഗസ്റ്റ്_സെപ്റ്റംബർ_ഒക്ടോബർ_നവംബർ_ഡിസംബർ".split("_"),monthsShort:"ജനു._ഫെബ്രു._മാർ._ഏപ്രി._മേയ്_ജൂൺ_ജൂലൈ._ഓഗ._സെപ്റ്റ._ഒക്ടോ._നവം._ഡിസം.".split("_"),weekdays:"ഞായറാഴ്ച_തിങ്കളാഴ്ച_ചൊവ്വാഴ്ച_ബുധനാഴ്ച_വ്യാഴാഴ്ച_വെള്ളിയാഴ്ച_ശനിയാഴ്ച".split("_"),weekdaysShort:"ഞായർ_തിങ്കൾ_ചൊവ്വ_ബുധൻ_വ്യാഴം_വെള്ളി_ശനി".split("_"),weekdaysMin:"ഞാ_തി_ചൊ_ബു_വ്യാ_വെ_ശ".split("_"),longDateFormat:{LT:"A h:mm -നു",LTS:"A h:mm:ss -നു",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY, LT",LLLL:"dddd, D MMMM YYYY, LT"},calendar:{sameDay:"[ഇന്ന്] LT",nextDay:"[നാളെ] LT",nextWeek:"dddd, LT",lastDay:"[ഇന്നലെ] LT",lastWeek:"[കഴിഞ്ഞ] dddd, LT",sameElse:"L"},relativeTime:{future:"%s കഴിഞ്ഞ്",past:"%s മുൻപ്",s:"അൽപ നിമിഷങ്ങൾ",m:"ഒരു മിനിറ്റ്",mm:"%d മിനിറ്റ്",h:"ഒരു മണിക്കൂർ",hh:"%d മണിക്കൂർ",d:"ഒരു ദിവസം",dd:"%d ദിവസം",M:"ഒരു മാസം",MM:"%d മാസം",y:"ഒരു വർഷം",yy:"%d വർഷം"},meridiemParse:/രാത്രി|രാവിലെ|ഉച്ച കഴിഞ്ഞ്|വൈകുന്നേരം|രാത്രി/i,isPM:function(a){return/^(ഉച്ച കഴിഞ്ഞ്|വൈകുന്നേരം|രാത്രി)$/.test(a)},meridiem:function(a){return 4>a?"രാത്രി":12>a?"രാവിലെ":17>a?"ഉച്ച കഴിഞ്ഞ്":20>a?"വൈകുന്നേരം":"രാത്രി"}})}),function(a){a(vb)}(function(a){var b={1:"१",2:"२",3:"३",4:"४",5:"५",6:"६",7:"७",8:"८",9:"९",0:"०"},c={"१":"1","२":"2","३":"3","४":"4","५":"5","६":"6","७":"7","८":"8","९":"9","०":"0"};return a.defineLocale("mr",{months:"जानेवारी_फेब्रुवारी_मार्च_एप्रिल_मे_जून_जुलै_ऑगस्ट_सप्टेंबर_ऑक्टोबर_नोव्हेंबर_डिसेंबर".split("_"),monthsShort:"जाने._फेब्रु._मार्च._एप्रि._मे._जून._जुलै._ऑग._सप्टें._ऑक्टो._नोव्हें._डिसें.".split("_"),weekdays:"रविवार_सोमवार_मंगळवार_बुधवार_गुरूवार_शुक्रवार_शनिवार".split("_"),weekdaysShort:"रवि_सोम_मंगळ_बुध_गुरू_शुक्र_शनि".split("_"),weekdaysMin:"र_सो_मं_बु_गु_शु_श".split("_"),longDateFormat:{LT:"A h:mm वाजता",LTS:"A h:mm:ss वाजता",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY, LT",LLLL:"dddd, D MMMM YYYY, LT"},calendar:{sameDay:"[आज] LT",nextDay:"[उद्या] LT",nextWeek:"dddd, LT",lastDay:"[काल] LT",lastWeek:"[मागील] dddd, LT",sameElse:"L"},relativeTime:{future:"%s नंतर",past:"%s पूर्वी",s:"सेकंद",m:"एक मिनिट",mm:"%d मिनिटे",h:"एक तास",hh:"%d तास",d:"एक दिवस",dd:"%d दिवस",M:"एक महिना",MM:"%d महिने",y:"एक वर्ष",yy:"%d वर्षे"},preparse:function(a){return a.replace(/[१२३४५६७८९०]/g,function(a){return c[a]})},postformat:function(a){return a.replace(/\d/g,function(a){return b[a]})},meridiemParse:/रात्री|सकाळी|दुपारी|सायंकाळी/,meridiemHour:function(a,b){return 12===a&&(a=0),"रात्री"===b?4>a?a:a+12:"सकाळी"===b?a:"दुपारी"===b?a>=10?a:a+12:"सायंकाळी"===b?a+12:void 0},meridiem:function(a){return 4>a?"रात्री":10>a?"सकाळी":17>a?"दुपारी":20>a?"सायंकाळी":"रात्री"},week:{dow:0,doy:6}})}),function(a){a(vb)}(function(a){return a.defineLocale("ms-my",{months:"Januari_Februari_Mac_April_Mei_Jun_Julai_Ogos_September_Oktober_November_Disember".split("_"),monthsShort:"Jan_Feb_Mac_Apr_Mei_Jun_Jul_Ogs_Sep_Okt_Nov_Dis".split("_"),weekdays:"Ahad_Isnin_Selasa_Rabu_Khamis_Jumaat_Sabtu".split("_"),weekdaysShort:"Ahd_Isn_Sel_Rab_Kha_Jum_Sab".split("_"),weekdaysMin:"Ah_Is_Sl_Rb_Km_Jm_Sb".split("_"),longDateFormat:{LT:"HH.mm",LTS:"LT.ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY [pukul] LT",LLLL:"dddd, D MMMM YYYY [pukul] LT"},meridiemParse:/pagi|tengahari|petang|malam/,meridiemHour:function(a,b){return 12===a&&(a=0),"pagi"===b?a:"tengahari"===b?a>=11?a:a+12:"petang"===b||"malam"===b?a+12:void 0},meridiem:function(a){return 11>a?"pagi":15>a?"tengahari":19>a?"petang":"malam"},calendar:{sameDay:"[Hari ini pukul] LT",nextDay:"[Esok pukul] LT",nextWeek:"dddd [pukul] LT",lastDay:"[Kelmarin pukul] LT",lastWeek:"dddd [lepas pukul] LT",sameElse:"L"},relativeTime:{future:"dalam %s",past:"%s yang lepas",s:"beberapa saat",m:"seminit",mm:"%d minit",h:"sejam",hh:"%d jam",d:"sehari",dd:"%d hari",M:"sebulan",MM:"%d bulan",y:"setahun",yy:"%d tahun"},week:{dow:1,doy:7}})}),function(a){a(vb)}(function(a){var b={1:"၁",2:"၂",3:"၃",4:"၄",5:"၅",6:"၆",7:"၇",8:"၈",9:"၉",0:"၀"},c={"၁":"1","၂":"2","၃":"3","၄":"4","၅":"5","၆":"6","၇":"7","၈":"8","၉":"9","၀":"0"};return a.defineLocale("my",{months:"ဇန်နဝါရီ_ဖေဖော်ဝါရီ_မတ်_ဧပြီ_မေ_ဇွန်_ဇူလိုင်_သြဂုတ်_စက်တင်ဘာ_အောက်တိုဘာ_နိုဝင်ဘာ_ဒီဇင်ဘာ".split("_"),monthsShort:"ဇန်_ဖေ_မတ်_ပြီ_မေ_ဇွန်_လိုင်_သြ_စက်_အောက်_နို_ဒီ".split("_"),weekdays:"တနင်္ဂနွေ_တနင်္လာ_အင်္ဂါ_ဗုဒ္ဓဟူး_ကြာသပတေး_သောကြာ_စနေ".split("_"),weekdaysShort:"နွေ_လာ_င်္ဂါ_ဟူး_ကြာ_သော_နေ".split("_"),weekdaysMin:"နွေ_လာ_င်္ဂါ_ဟူး_ကြာ_သော_နေ".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY LT",LLLL:"dddd D MMMM YYYY LT"},calendar:{sameDay:"[ယနေ.] LT [မှာ]",nextDay:"[မနက်ဖြန်] LT [မှာ]",nextWeek:"dddd LT [မှာ]",lastDay:"[မနေ.က] LT [မှာ]",lastWeek:"[ပြီးခဲ့သော] dddd LT [မှာ]",sameElse:"L"},relativeTime:{future:"လာမည့် %s မှာ",past:"လွန်ခဲ့သော %s က",s:"စက္ကန်.အနည်းငယ်",m:"တစ်မိနစ်",mm:"%d မိနစ်",h:"တစ်နာရီ",hh:"%d နာရီ",d:"တစ်ရက်",dd:"%d ရက်",M:"တစ်လ",MM:"%d လ",y:"တစ်နှစ်",yy:"%d နှစ်"},preparse:function(a){return a.replace(/[၁၂၃၄၅၆၇၈၉၀]/g,function(a){return c[a]})},postformat:function(a){return a.replace(/\d/g,function(a){return b[a]})},week:{dow:1,doy:4}})}),function(a){a(vb)}(function(a){return a.defineLocale("nb",{months:"januar_februar_mars_april_mai_juni_juli_august_september_oktober_november_desember".split("_"),monthsShort:"jan_feb_mar_apr_mai_jun_jul_aug_sep_okt_nov_des".split("_"),weekdays:"søndag_mandag_tirsdag_onsdag_torsdag_fredag_lørdag".split("_"),weekdaysShort:"søn_man_tirs_ons_tors_fre_lør".split("_"),weekdaysMin:"sø_ma_ti_on_to_fr_lø".split("_"),longDateFormat:{LT:"H.mm",LTS:"LT.ss",L:"DD.MM.YYYY",LL:"D. MMMM YYYY",LLL:"D. MMMM YYYY [kl.] LT",LLLL:"dddd D. MMMM YYYY [kl.] LT"},calendar:{sameDay:"[i dag kl.] LT",nextDay:"[i morgen kl.] LT",nextWeek:"dddd [kl.] LT",lastDay:"[i går kl.] LT",lastWeek:"[forrige] dddd [kl.] LT",sameElse:"L"},relativeTime:{future:"om %s",past:"for %s siden",s:"noen sekunder",m:"ett minutt",mm:"%d minutter",h:"en time",hh:"%d timer",d:"en dag",dd:"%d dager",M:"en måned",MM:"%d måneder",y:"ett år",yy:"%d år"},ordinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}})}),function(a){a(vb)}(function(a){var b={1:"१",2:"२",3:"३",4:"४",5:"५",6:"६",7:"७",8:"८",9:"९",0:"०"},c={"१":"1","२":"2","३":"3","४":"4","५":"5","६":"6","७":"7","८":"8","९":"9","०":"0"};return a.defineLocale("ne",{months:"जनवरी_फेब्रुवरी_मार्च_अप्रिल_मई_जुन_जुलाई_अगष्ट_सेप्टेम्बर_अक्टोबर_नोभेम्बर_डिसेम्बर".split("_"),monthsShort:"जन._फेब्रु._मार्च_अप्रि._मई_जुन_जुलाई._अग._सेप्ट._अक्टो._नोभे._डिसे.".split("_"),weekdays:"आइतबार_सोमबार_मङ्गलबार_बुधबार_बिहिबार_शुक्रबार_शनिबार".split("_"),weekdaysShort:"आइत._सोम._मङ्गल._बुध._बिहि._शुक्र._शनि.".split("_"),weekdaysMin:"आइ._सो._मङ्_बु._बि._शु._श.".split("_"),longDateFormat:{LT:"Aको h:mm बजे",LTS:"Aको h:mm:ss बजे",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY, LT",LLLL:"dddd, D MMMM YYYY, LT"},preparse:function(a){return a.replace(/[१२३४५६७८९०]/g,function(a){return c[a]})},postformat:function(a){return a.replace(/\d/g,function(a){return b[a]})},meridiemParse:/राती|बिहान|दिउँसो|बेलुका|साँझ|राती/,meridiemHour:function(a,b){return 12===a&&(a=0),"राती"===b?3>a?a:a+12:"बिहान"===b?a:"दिउँसो"===b?a>=10?a:a+12:"बेलुका"===b||"साँझ"===b?a+12:void 0},meridiem:function(a){return 3>a?"राती":10>a?"बिहान":15>a?"दिउँसो":18>a?"बेलुका":20>a?"साँझ":"राती"},calendar:{sameDay:"[आज] LT",nextDay:"[भोली] LT",nextWeek:"[आउँदो] dddd[,] LT",lastDay:"[हिजो] LT",lastWeek:"[गएको] dddd[,] LT",sameElse:"L"},relativeTime:{future:"%sमा",past:"%s अगाडी",s:"केही समय",m:"एक मिनेट",mm:"%d मिनेट",h:"एक घण्टा",hh:"%d घण्टा",d:"एक दिन",dd:"%d दिन",M:"एक महिना",MM:"%d महिना",y:"एक बर्ष",yy:"%d बर्ष"},week:{dow:1,doy:7}})}),function(a){a(vb)}(function(a){var b="jan._feb._mrt._apr._mei_jun._jul._aug._sep._okt._nov._dec.".split("_"),c="jan_feb_mrt_apr_mei_jun_jul_aug_sep_okt_nov_dec".split("_");return a.defineLocale("nl",{months:"januari_februari_maart_april_mei_juni_juli_augustus_september_oktober_november_december".split("_"),monthsShort:function(a,d){return/-MMM-/.test(d)?c[a.month()]:b[a.month()]},weekdays:"zondag_maandag_dinsdag_woensdag_donderdag_vrijdag_zaterdag".split("_"),weekdaysShort:"zo._ma._di._wo._do._vr._za.".split("_"),weekdaysMin:"Zo_Ma_Di_Wo_Do_Vr_Za".split("_"),longDateFormat:{LT:"HH:mm",LTS:"LT:ss",L:"DD-MM-YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY LT",LLLL:"dddd D MMMM YYYY LT"},calendar:{sameDay:"[vandaag om] LT",nextDay:"[morgen om] LT",nextWeek:"dddd [om] LT",lastDay:"[gisteren om] LT",lastWeek:"[afgelopen] dddd [om] LT",sameElse:"L"},relativeTime:{future:"over %s",past:"%s geleden",s:"een paar seconden",m:"één minuut",mm:"%d minuten",h:"één uur",hh:"%d uur",d:"één dag",dd:"%d dagen",M:"één maand",MM:"%d maanden",y:"één jaar",yy:"%d jaar"},ordinalParse:/\d{1,2}(ste|de)/,ordinal:function(a){return a+(1===a||8===a||a>=20?"ste":"de")},week:{dow:1,doy:4}})}),function(a){a(vb)}(function(a){return a.defineLocale("nn",{months:"januar_februar_mars_april_mai_juni_juli_august_september_oktober_november_desember".split("_"),monthsShort:"jan_feb_mar_apr_mai_jun_jul_aug_sep_okt_nov_des".split("_"),weekdays:"sundag_måndag_tysdag_onsdag_torsdag_fredag_laurdag".split("_"),weekdaysShort:"sun_mån_tys_ons_tor_fre_lau".split("_"),weekdaysMin:"su_må_ty_on_to_fr_lø".split("_"),longDateFormat:{LT:"HH:mm",LTS:"LT:ss",L:"DD.MM.YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY LT",LLLL:"dddd D MMMM YYYY LT"},calendar:{sameDay:"[I dag klokka] LT",nextDay:"[I morgon klokka] LT",nextWeek:"dddd [klokka] LT",lastDay:"[I går klokka] LT",lastWeek:"[Føregåande] dddd [klokka] LT",sameElse:"L"},relativeTime:{future:"om %s",past:"for %s sidan",s:"nokre sekund",m:"eit minutt",mm:"%d minutt",h:"ein time",hh:"%d timar",d:"ein dag",dd:"%d dagar",M:"ein månad",MM:"%d månader",y:"eit år",yy:"%d år"},ordinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}})}),function(a){a(vb)}(function(a){function b(a){return 5>a%10&&a%10>1&&~~(a/10)%10!==1}function c(a,c,d){var e=a+" ";switch(d){case"m":return c?"minuta":"minutę";case"mm":return e+(b(a)?"minuty":"minut");case"h":return c?"godzina":"godzinę";case"hh":return e+(b(a)?"godziny":"godzin");case"MM":return e+(b(a)?"miesiące":"miesięcy");case"yy":return e+(b(a)?"lata":"lat")}}var d="styczeń_luty_marzec_kwiecień_maj_czerwiec_lipiec_sierpień_wrzesień_październik_listopad_grudzień".split("_"),e="stycznia_lutego_marca_kwietnia_maja_czerwca_lipca_sierpnia_września_października_listopada_grudnia".split("_");return a.defineLocale("pl",{months:function(a,b){return/D MMMM/.test(b)?e[a.month()]:d[a.month()]},monthsShort:"sty_lut_mar_kwi_maj_cze_lip_sie_wrz_paź_lis_gru".split("_"),weekdays:"niedziela_poniedziałek_wtorek_środa_czwartek_piątek_sobota".split("_"),weekdaysShort:"nie_pon_wt_śr_czw_pt_sb".split("_"),weekdaysMin:"N_Pn_Wt_Śr_Cz_Pt_So".split("_"),longDateFormat:{LT:"HH:mm",LTS:"LT:ss",L:"DD.MM.YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY LT",LLLL:"dddd, D MMMM YYYY LT"},calendar:{sameDay:"[Dziś o] LT",nextDay:"[Jutro o] LT",nextWeek:"[W] dddd [o] LT",lastDay:"[Wczoraj o] LT",lastWeek:function(){switch(this.day()){case 0:return"[W zeszłą niedzielę o] LT";case 3:return"[W zeszłą środę o] LT";case 6:return"[W zeszłą sobotę o] LT";default:return"[W zeszły] dddd [o] LT"}},sameElse:"L"},relativeTime:{future:"za %s",past:"%s temu",s:"kilka sekund",m:c,mm:c,h:c,hh:c,d:"1 dzień",dd:"%d dni",M:"miesiąc",MM:c,y:"rok",yy:c},ordinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}})}),function(a){a(vb)}(function(a){return a.defineLocale("pt-br",{months:"janeiro_fevereiro_março_abril_maio_junho_julho_agosto_setembro_outubro_novembro_dezembro".split("_"),monthsShort:"jan_fev_mar_abr_mai_jun_jul_ago_set_out_nov_dez".split("_"),weekdays:"domingo_segunda-feira_terça-feira_quarta-feira_quinta-feira_sexta-feira_sábado".split("_"),weekdaysShort:"dom_seg_ter_qua_qui_sex_sáb".split("_"),weekdaysMin:"dom_2ª_3ª_4ª_5ª_6ª_sáb".split("_"),longDateFormat:{LT:"HH:mm",LTS:"LT:ss",L:"DD/MM/YYYY",LL:"D [de] MMMM [de] YYYY",LLL:"D [de] MMMM [de] YYYY [às] LT",LLLL:"dddd, D [de] MMMM [de] YYYY [às] LT"},calendar:{sameDay:"[Hoje às] LT",nextDay:"[Amanhã às] LT",nextWeek:"dddd [às] LT",lastDay:"[Ontem às] LT",lastWeek:function(){return 0===this.day()||6===this.day()?"[Último] dddd [às] LT":"[Última] dddd [às] LT"},sameElse:"L"},relativeTime:{future:"em %s",past:"%s atrás",s:"segundos",m:"um minuto",mm:"%d minutos",h:"uma hora",hh:"%d horas",d:"um dia",dd:"%d dias",M:"um mês",MM:"%d meses",y:"um ano",yy:"%d anos"},ordinalParse:/\d{1,2}º/,ordinal:"%dº"})}),function(a){a(vb)}(function(a){return a.defineLocale("pt",{months:"janeiro_fevereiro_março_abril_maio_junho_julho_agosto_setembro_outubro_novembro_dezembro".split("_"),monthsShort:"jan_fev_mar_abr_mai_jun_jul_ago_set_out_nov_dez".split("_"),weekdays:"domingo_segunda-feira_terça-feira_quarta-feira_quinta-feira_sexta-feira_sábado".split("_"),weekdaysShort:"dom_seg_ter_qua_qui_sex_sáb".split("_"),weekdaysMin:"dom_2ª_3ª_4ª_5ª_6ª_sáb".split("_"),longDateFormat:{LT:"HH:mm",LTS:"LT:ss",L:"DD/MM/YYYY",LL:"D [de] MMMM [de] YYYY",LLL:"D [de] MMMM [de] YYYY LT",LLLL:"dddd, D [de] MMMM [de] YYYY LT"},calendar:{sameDay:"[Hoje às] LT",nextDay:"[Amanhã às] LT",nextWeek:"dddd [às] LT",lastDay:"[Ontem às] LT",lastWeek:function(){return 0===this.day()||6===this.day()?"[Último] dddd [às] LT":"[Última] dddd [às] LT"},sameElse:"L"},relativeTime:{future:"em %s",past:"há %s",s:"segundos",m:"um minuto",mm:"%d minutos",h:"uma hora",hh:"%d horas",d:"um dia",dd:"%d dias",M:"um mês",MM:"%d meses",y:"um ano",yy:"%d anos"},ordinalParse:/\d{1,2}º/,ordinal:"%dº",week:{dow:1,doy:4}})}),function(a){a(vb)}(function(a){function b(a,b,c){var d={mm:"minute",hh:"ore",dd:"zile",MM:"luni",yy:"ani"},e=" ";return(a%100>=20||a>=100&&a%100===0)&&(e=" de "),a+e+d[c]}return a.defineLocale("ro",{months:"ianuarie_februarie_martie_aprilie_mai_iunie_iulie_august_septembrie_octombrie_noiembrie_decembrie".split("_"),monthsShort:"ian._febr._mart._apr._mai_iun._iul._aug._sept._oct._nov._dec.".split("_"),weekdays:"duminică_luni_marți_miercuri_joi_vineri_sâmbătă".split("_"),weekdaysShort:"Dum_Lun_Mar_Mie_Joi_Vin_Sâm".split("_"),weekdaysMin:"Du_Lu_Ma_Mi_Jo_Vi_Sâ".split("_"),longDateFormat:{LT:"H:mm",LTS:"LT:ss",L:"DD.MM.YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY H:mm",LLLL:"dddd, D MMMM YYYY H:mm"},calendar:{sameDay:"[azi la] LT",nextDay:"[mâine la] LT",nextWeek:"dddd [la] LT",lastDay:"[ieri la] LT",lastWeek:"[fosta] dddd [la] LT",sameElse:"L"},relativeTime:{future:"peste %s",past:"%s în urmă",s:"câteva secunde",m:"un minut",mm:b,h:"o oră",hh:b,d:"o zi",dd:b,M:"o lună",MM:b,y:"un an",yy:b},week:{dow:1,doy:7}})}),function(a){a(vb)}(function(a){function b(a,b){var c=a.split("_");return b%10===1&&b%100!==11?c[0]:b%10>=2&&4>=b%10&&(10>b%100||b%100>=20)?c[1]:c[2]}function c(a,c,d){var e={mm:c?"минута_минуты_минут":"минуту_минуты_минут",hh:"час_часа_часов",dd:"день_дня_дней",MM:"месяц_месяца_месяцев",yy:"год_года_лет"};return"m"===d?c?"минута":"минуту":a+" "+b(e[d],+a)}function d(a,b){var c={nominative:"январь_февраль_март_апрель_май_июнь_июль_август_сентябрь_октябрь_ноябрь_декабрь".split("_"),accusative:"января_февраля_марта_апреля_мая_июня_июля_августа_сентября_октября_ноября_декабря".split("_")},d=/D[oD]?(\[[^\[\]]*\]|\s+)+MMMM?/.test(b)?"accusative":"nominative";return c[d][a.month()]}function e(a,b){var c={nominative:"янв_фев_март_апр_май_июнь_июль_авг_сен_окт_ноя_дек".split("_"),accusative:"янв_фев_мар_апр_мая_июня_июля_авг_сен_окт_ноя_дек".split("_")},d=/D[oD]?(\[[^\[\]]*\]|\s+)+MMMM?/.test(b)?"accusative":"nominative";return c[d][a.month()]}function f(a,b){var c={nominative:"воскресенье_понедельник_вторник_среда_четверг_пятница_суббота".split("_"),accusative:"воскресенье_понедельник_вторник_среду_четверг_пятницу_субботу".split("_")},d=/\[ ?[Вв] ?(?:прошлую|следующую|эту)? ?\] ?dddd/.test(b)?"accusative":"nominative";return c[d][a.day()]}return a.defineLocale("ru",{months:d,monthsShort:e,weekdays:f,weekdaysShort:"вс_пн_вт_ср_чт_пт_сб".split("_"),weekdaysMin:"вс_пн_вт_ср_чт_пт_сб".split("_"),monthsParse:[/^янв/i,/^фев/i,/^мар/i,/^апр/i,/^ма[й|я]/i,/^июн/i,/^июл/i,/^авг/i,/^сен/i,/^окт/i,/^ноя/i,/^дек/i],longDateFormat:{LT:"HH:mm",LTS:"LT:ss",L:"DD.MM.YYYY",LL:"D MMMM YYYY г.",LLL:"D MMMM YYYY г., LT",LLLL:"dddd, D MMMM YYYY г., LT"},calendar:{sameDay:"[Сегодня в] LT",nextDay:"[Завтра в] LT",lastDay:"[Вчера в] LT",nextWeek:function(){return 2===this.day()?"[Во] dddd [в] LT":"[В] dddd [в] LT"},lastWeek:function(a){if(a.week()===this.week())return 2===this.day()?"[Во] dddd [в] LT":"[В] dddd [в] LT";switch(this.day()){case 0:return"[В прошлое] dddd [в] LT";case 1:case 2:case 4:return"[В прошлый] dddd [в] LT";case 3:case 5:case 6:return"[В прошлую] dddd [в] LT"}},sameElse:"L"},relativeTime:{future:"через %s",past:"%s назад",s:"несколько секунд",m:c,mm:c,h:"час",hh:c,d:"день",dd:c,M:"месяц",MM:c,y:"год",yy:c},meridiemParse:/ночи|утра|дня|вечера/i,isPM:function(a){return/^(дня|вечера)$/.test(a)},meridiem:function(a){return 4>a?"ночи":12>a?"утра":17>a?"дня":"вечера"},ordinalParse:/\d{1,2}-(й|го|я)/,ordinal:function(a,b){switch(b){case"M":case"d":case"DDD":return a+"-й";case"D":return a+"-го";case"w":case"W":return a+"-я";default:return a}},week:{dow:1,doy:7}})}),function(a){a(vb)}(function(a){function b(a){return a>1&&5>a}function c(a,c,d,e){var f=a+" ";switch(d){case"s":return c||e?"pár sekúnd":"pár sekundami";case"m":return c?"minúta":e?"minútu":"minútou";case"mm":return c||e?f+(b(a)?"minúty":"minút"):f+"minútami";break;case"h":return c?"hodina":e?"hodinu":"hodinou";case"hh":return c||e?f+(b(a)?"hodiny":"hodín"):f+"hodinami";break;case"d":return c||e?"deň":"dňom";case"dd":return c||e?f+(b(a)?"dni":"dní"):f+"dňami";break;case"M":return c||e?"mesiac":"mesiacom";case"MM":return c||e?f+(b(a)?"mesiace":"mesiacov"):f+"mesiacmi";break;case"y":return c||e?"rok":"rokom";case"yy":return c||e?f+(b(a)?"roky":"rokov"):f+"rokmi"}}var d="január_február_marec_apríl_máj_jún_júl_august_september_október_november_december".split("_"),e="jan_feb_mar_apr_máj_jún_júl_aug_sep_okt_nov_dec".split("_");return a.defineLocale("sk",{months:d,monthsShort:e,monthsParse:function(a,b){var c,d=[];for(c=0;12>c;c++)d[c]=new RegExp("^"+a[c]+"$|^"+b[c]+"$","i");return d}(d,e),weekdays:"nedeľa_pondelok_utorok_streda_štvrtok_piatok_sobota".split("_"),weekdaysShort:"ne_po_ut_st_št_pi_so".split("_"),weekdaysMin:"ne_po_ut_st_št_pi_so".split("_"),longDateFormat:{LT:"H:mm",LTS:"LT:ss",L:"DD.MM.YYYY",LL:"D. MMMM YYYY",LLL:"D. MMMM YYYY LT",LLLL:"dddd D. MMMM YYYY LT"},calendar:{sameDay:"[dnes o] LT",nextDay:"[zajtra o] LT",nextWeek:function(){switch(this.day()){case 0:return"[v nedeľu o] LT";case 1:case 2:return"[v] dddd [o] LT";case 3:return"[v stredu o] LT";case 4:return"[vo štvrtok o] LT";case 5:return"[v piatok o] LT";case 6:return"[v sobotu o] LT"}},lastDay:"[včera o] LT",lastWeek:function(){switch(this.day()){case 0:return"[minulú nedeľu o] LT";case 1:case 2:return"[minulý] dddd [o] LT";case 3:return"[minulú stredu o] LT";case 4:case 5:return"[minulý] dddd [o] LT";case 6:return"[minulú sobotu o] LT"}},sameElse:"L"},relativeTime:{future:"za %s",past:"pred %s",s:c,m:c,mm:c,h:c,hh:c,d:c,dd:c,M:c,MM:c,y:c,yy:c},ordinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}})}),function(a){a(vb)}(function(a){function b(a,b,c){var d=a+" ";switch(c){case"m":return b?"ena minuta":"eno minuto";case"mm":return d+=1===a?"minuta":2===a?"minuti":3===a||4===a?"minute":"minut";case"h":return b?"ena ura":"eno uro";case"hh":return d+=1===a?"ura":2===a?"uri":3===a||4===a?"ure":"ur";case"dd":return d+=1===a?"dan":"dni";case"MM":return d+=1===a?"mesec":2===a?"meseca":3===a||4===a?"mesece":"mesecev";case"yy":return d+=1===a?"leto":2===a?"leti":3===a||4===a?"leta":"let"}}return a.defineLocale("sl",{months:"januar_februar_marec_april_maj_junij_julij_avgust_september_oktober_november_december".split("_"),monthsShort:"jan._feb._mar._apr._maj._jun._jul._avg._sep._okt._nov._dec.".split("_"),weekdays:"nedelja_ponedeljek_torek_sreda_četrtek_petek_sobota".split("_"),weekdaysShort:"ned._pon._tor._sre._čet._pet._sob.".split("_"),weekdaysMin:"ne_po_to_sr_če_pe_so".split("_"),longDateFormat:{LT:"H:mm",LTS:"LT:ss",L:"DD. MM. YYYY",LL:"D. MMMM YYYY",LLL:"D. MMMM YYYY LT",LLLL:"dddd, D. MMMM YYYY LT"},calendar:{sameDay:"[danes ob] LT",nextDay:"[jutri ob] LT",nextWeek:function(){switch(this.day()){case 0:return"[v] [nedeljo] [ob] LT";case 3:return"[v] [sredo] [ob] LT";case 6:return"[v] [soboto] [ob] LT";case 1:case 2:case 4:case 5:return"[v] dddd [ob] LT"}},lastDay:"[včeraj ob] LT",lastWeek:function(){switch(this.day()){case 0:case 3:case 6:return"[prejšnja] dddd [ob] LT";case 1:case 2:case 4:case 5:return"[prejšnji] dddd [ob] LT"}},sameElse:"L"},relativeTime:{future:"čez %s",past:"%s nazaj",s:"nekaj sekund",m:b,mm:b,h:b,hh:b,d:"en dan",dd:b,M:"en mesec",MM:b,y:"eno leto",yy:b},ordinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:7}})}),function(a){a(vb)}(function(a){return a.defineLocale("sq",{months:"Janar_Shkurt_Mars_Prill_Maj_Qershor_Korrik_Gusht_Shtator_Tetor_Nëntor_Dhjetor".split("_"),monthsShort:"Jan_Shk_Mar_Pri_Maj_Qer_Kor_Gus_Sht_Tet_Nën_Dhj".split("_"),weekdays:"E Diel_E Hënë_E Martë_E Mërkurë_E Enjte_E Premte_E Shtunë".split("_"),weekdaysShort:"Die_Hën_Mar_Mër_Enj_Pre_Sht".split("_"),weekdaysMin:"D_H_Ma_Më_E_P_Sh".split("_"),meridiemParse:/PD|MD/,isPM:function(a){return"M"===a.charAt(0)},meridiem:function(a){return 12>a?"PD":"MD"},longDateFormat:{LT:"HH:mm",LTS:"LT:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY LT",LLLL:"dddd, D MMMM YYYY LT"},calendar:{sameDay:"[Sot në] LT",nextDay:"[Nesër në] LT",nextWeek:"dddd [në] LT",lastDay:"[Dje në] LT",lastWeek:"dddd [e kaluar në] LT",sameElse:"L"},relativeTime:{future:"në %s",past:"%s më parë",s:"disa sekonda",m:"një minutë",mm:"%d minuta",h:"një orë",hh:"%d orë",d:"një ditë",dd:"%d ditë",M:"një muaj",MM:"%d muaj",y:"një vit",yy:"%d vite"},ordinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}})}),function(a){a(vb)}(function(a){var b={words:{m:["један минут","једне минуте"],mm:["минут","минуте","минута"],h:["један сат","једног сата"],hh:["сат","сата","сати"],dd:["дан","дана","дана"],MM:["месец","месеца","месеци"],yy:["година","године","година"]},correctGrammaticalCase:function(a,b){return 1===a?b[0]:a>=2&&4>=a?b[1]:b[2]},translate:function(a,c,d){var e=b.words[d];return 1===d.length?c?e[0]:e[1]:a+" "+b.correctGrammaticalCase(a,e)}};return a.defineLocale("sr-cyrl",{months:["јануар","фебруар","март","април","мај","јун","јул","август","септембар","октобар","новембар","децембар"],monthsShort:["јан.","феб.","мар.","апр.","мај","јун","јул","авг.","сеп.","окт.","нов.","дец."],weekdays:["недеља","понедељак","уторак","среда","четвртак","петак","субота"],weekdaysShort:["нед.","пон.","уто.","сре.","чет.","пет.","суб."],weekdaysMin:["не","по","ут","ср","че","пе","су"],longDateFormat:{LT:"H:mm",LTS:"LT:ss",L:"DD. MM. YYYY",LL:"D. MMMM YYYY",LLL:"D. MMMM YYYY LT",LLLL:"dddd, D. MMMM YYYY LT"},calendar:{sameDay:"[данас у] LT",nextDay:"[сутра у] LT",nextWeek:function(){switch(this.day()){case 0:return"[у] [недељу] [у] LT";case 3:return"[у] [среду] [у] LT";case 6:return"[у] [суботу] [у] LT";case 1:case 2:case 4:case 5:return"[у] dddd [у] LT"}},lastDay:"[јуче у] LT",lastWeek:function(){var a=["[прошле] [недеље] [у] LT","[прошлог] [понедељка] [у] LT","[прошлог] [уторка] [у] LT","[прошле] [среде] [у] LT","[прошлог] [четвртка] [у] LT","[прошлог] [петка] [у] LT","[прошле] [суботе] [у] LT"];return a[this.day()]},sameElse:"L"},relativeTime:{future:"за %s",past:"пре %s",s:"неколико секунди",m:b.translate,mm:b.translate,h:b.translate,hh:b.translate,d:"дан",dd:b.translate,M:"месец",MM:b.translate,y:"годину",yy:b.translate},ordinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:7}})}),function(a){a(vb)}(function(a){var b={words:{m:["jedan minut","jedne minute"],mm:["minut","minute","minuta"],h:["jedan sat","jednog sata"],hh:["sat","sata","sati"],dd:["dan","dana","dana"],MM:["mesec","meseca","meseci"],yy:["godina","godine","godina"]},correctGrammaticalCase:function(a,b){return 1===a?b[0]:a>=2&&4>=a?b[1]:b[2]},translate:function(a,c,d){var e=b.words[d];return 1===d.length?c?e[0]:e[1]:a+" "+b.correctGrammaticalCase(a,e)}};return a.defineLocale("sr",{months:["januar","februar","mart","april","maj","jun","jul","avgust","septembar","oktobar","novembar","decembar"],monthsShort:["jan.","feb.","mar.","apr.","maj","jun","jul","avg.","sep.","okt.","nov.","dec."],weekdays:["nedelja","ponedeljak","utorak","sreda","četvrtak","petak","subota"],weekdaysShort:["ned.","pon.","uto.","sre.","čet.","pet.","sub."],weekdaysMin:["ne","po","ut","sr","če","pe","su"],longDateFormat:{LT:"H:mm",LTS:"LT:ss",L:"DD. MM. YYYY",LL:"D. MMMM YYYY",LLL:"D. MMMM YYYY LT",LLLL:"dddd, D. MMMM YYYY LT"},calendar:{sameDay:"[danas u] LT",nextDay:"[sutra u] LT",nextWeek:function(){switch(this.day()){case 0:return"[u] [nedelju] [u] LT";case 3:return"[u] [sredu] [u] LT";case 6:return"[u] [subotu] [u] LT";case 1:case 2:case 4:case 5:return"[u] dddd [u] LT"}},lastDay:"[juče u] LT",lastWeek:function(){var a=["[prošle] [nedelje] [u] LT","[prošlog] [ponedeljka] [u] LT","[prošlog] [utorka] [u] LT","[prošle] [srede] [u] LT","[prošlog] [četvrtka] [u] LT","[prošlog] [petka] [u] LT","[prošle] [subote] [u] LT"];return a[this.day()]},sameElse:"L"},relativeTime:{future:"za %s",past:"pre %s",s:"nekoliko sekundi",m:b.translate,mm:b.translate,h:b.translate,hh:b.translate,d:"dan",dd:b.translate,M:"mesec",MM:b.translate,y:"godinu",yy:b.translate},ordinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:7}})}),function(a){a(vb)}(function(a){return a.defineLocale("sv",{months:"januari_februari_mars_april_maj_juni_juli_augusti_september_oktober_november_december".split("_"),monthsShort:"jan_feb_mar_apr_maj_jun_jul_aug_sep_okt_nov_dec".split("_"),weekdays:"söndag_måndag_tisdag_onsdag_torsdag_fredag_lördag".split("_"),weekdaysShort:"sön_mån_tis_ons_tor_fre_lör".split("_"),weekdaysMin:"sö_må_ti_on_to_fr_lö".split("_"),longDateFormat:{LT:"HH:mm",LTS:"LT:ss",L:"YYYY-MM-DD",LL:"D MMMM YYYY",LLL:"D MMMM YYYY LT",LLLL:"dddd D MMMM YYYY LT"},calendar:{sameDay:"[Idag] LT",nextDay:"[Imorgon] LT",lastDay:"[Igår] LT",nextWeek:"dddd LT",lastWeek:"[Förra] dddd[en] LT",sameElse:"L"},relativeTime:{future:"om %s",past:"för %s sedan",s:"några sekunder",m:"en minut",mm:"%d minuter",h:"en timme",hh:"%d timmar",d:"en dag",dd:"%d dagar",M:"en månad",MM:"%d månader",y:"ett år",yy:"%d år"},ordinalParse:/\d{1,2}(e|a)/,ordinal:function(a){var b=a%10,c=1===~~(a%100/10)?"e":1===b?"a":2===b?"a":"e";return a+c},week:{dow:1,doy:4}})}),function(a){a(vb)}(function(a){return a.defineLocale("ta",{months:"ஜனவரி_பிப்ரவரி_மார்ச்_ஏப்ரல்_மே_ஜூன்_ஜூலை_ஆகஸ்ட்_செப்டெம்பர்_அக்டோபர்_நவம்பர்_டிசம்பர்".split("_"),monthsShort:"ஜனவரி_பிப்ரவரி_மார்ச்_ஏப்ரல்_மே_ஜூன்_ஜூலை_ஆகஸ்ட்_செப்டெம்பர்_அக்டோபர்_நவம்பர்_டிசம்பர்".split("_"),weekdays:"ஞாயிற்றுக்கிழமை_திங்கட்கிழமை_செவ்வாய்கிழமை_புதன்கிழமை_வியாழக்கிழமை_வெள்ளிக்கிழமை_சனிக்கிழமை".split("_"),weekdaysShort:"ஞாயிறு_திங்கள்_செவ்வாய்_புதன்_வியாழன்_வெள்ளி_சனி".split("_"),weekdaysMin:"ஞா_தி_செ_பு_வி_வெ_ச".split("_"),longDateFormat:{LT:"HH:mm",LTS:"LT:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY, LT",LLLL:"dddd, D MMMM YYYY, LT"},calendar:{sameDay:"[இன்று] LT",nextDay:"[நாளை] LT",nextWeek:"dddd, LT",lastDay:"[நேற்று] LT",lastWeek:"[கடந்த வாரம்] dddd, LT",sameElse:"L"},relativeTime:{future:"%s இல்",past:"%s முன்",s:"ஒரு சில விநாடிகள்",m:"ஒரு நிமிடம்",mm:"%d நிமிடங்கள்",h:"ஒரு மணி நேரம்",hh:"%d மணி நேரம்",d:"ஒரு நாள்",dd:"%d நாட்கள்",M:"ஒரு மாதம்",MM:"%d மாதங்கள்",y:"ஒரு வருடம்",yy:"%d ஆண்டுகள்"},ordinalParse:/\d{1,2}வது/,ordinal:function(a){return a+"வது"},meridiemParse:/யாமம்|வைகறை|காலை|நண்பகல்|எற்பாடு|மாலை/,meridiem:function(a){return 2>a?" யாமம்":6>a?" வைகறை":10>a?" காலை":14>a?" நண்பகல்":18>a?" எற்பாடு":22>a?" மாலை":" யாமம்"},meridiemHour:function(a,b){return 12===a&&(a=0),"யாமம்"===b?2>a?a:a+12:"வைகறை"===b||"காலை"===b?a:"நண்பகல்"===b&&a>=10?a:a+12},week:{dow:0,doy:6}})}),function(a){a(vb)}(function(a){return a.defineLocale("th",{months:"มกราคม_กุมภาพันธ์_มีนาคม_เมษายน_พฤษภาคม_มิถุนายน_กรกฎาคม_สิงหาคม_กันยายน_ตุลาคม_พฤศจิกายน_ธันวาคม".split("_"),monthsShort:"มกรา_กุมภา_มีนา_เมษา_พฤษภา_มิถุนา_กรกฎา_สิงหา_กันยา_ตุลา_พฤศจิกา_ธันวา".split("_"),weekdays:"อาทิตย์_จันทร์_อังคาร_พุธ_พฤหัสบดี_ศุกร์_เสาร์".split("_"),weekdaysShort:"อาทิตย์_จันทร์_อังคาร_พุธ_พฤหัส_ศุกร์_เสาร์".split("_"),weekdaysMin:"อา._จ._อ._พ._พฤ._ศ._ส.".split("_"),longDateFormat:{LT:"H นาฬิกา m นาที",LTS:"LT s วินาที",L:"YYYY/MM/DD",LL:"D MMMM YYYY",LLL:"D MMMM YYYY เวลา LT",LLLL:"วันddddที่ D MMMM YYYY เวลา LT"},meridiemParse:/ก่อนเที่ยง|หลังเที่ยง/,isPM:function(a){return"หลังเที่ยง"===a +},meridiem:function(a){return 12>a?"ก่อนเที่ยง":"หลังเที่ยง"},calendar:{sameDay:"[วันนี้ เวลา] LT",nextDay:"[พรุ่งนี้ เวลา] LT",nextWeek:"dddd[หน้า เวลา] LT",lastDay:"[เมื่อวานนี้ เวลา] LT",lastWeek:"[วัน]dddd[ที่แล้ว เวลา] LT",sameElse:"L"},relativeTime:{future:"อีก %s",past:"%sที่แล้ว",s:"ไม่กี่วินาที",m:"1 นาที",mm:"%d นาที",h:"1 ชั่วโมง",hh:"%d ชั่วโมง",d:"1 วัน",dd:"%d วัน",M:"1 เดือน",MM:"%d เดือน",y:"1 ปี",yy:"%d ปี"}})}),function(a){a(vb)}(function(a){return a.defineLocale("tl-ph",{months:"Enero_Pebrero_Marso_Abril_Mayo_Hunyo_Hulyo_Agosto_Setyembre_Oktubre_Nobyembre_Disyembre".split("_"),monthsShort:"Ene_Peb_Mar_Abr_May_Hun_Hul_Ago_Set_Okt_Nob_Dis".split("_"),weekdays:"Linggo_Lunes_Martes_Miyerkules_Huwebes_Biyernes_Sabado".split("_"),weekdaysShort:"Lin_Lun_Mar_Miy_Huw_Biy_Sab".split("_"),weekdaysMin:"Li_Lu_Ma_Mi_Hu_Bi_Sab".split("_"),longDateFormat:{LT:"HH:mm",LTS:"LT:ss",L:"MM/D/YYYY",LL:"MMMM D, YYYY",LLL:"MMMM D, YYYY LT",LLLL:"dddd, MMMM DD, YYYY LT"},calendar:{sameDay:"[Ngayon sa] LT",nextDay:"[Bukas sa] LT",nextWeek:"dddd [sa] LT",lastDay:"[Kahapon sa] LT",lastWeek:"dddd [huling linggo] LT",sameElse:"L"},relativeTime:{future:"sa loob ng %s",past:"%s ang nakalipas",s:"ilang segundo",m:"isang minuto",mm:"%d minuto",h:"isang oras",hh:"%d oras",d:"isang araw",dd:"%d araw",M:"isang buwan",MM:"%d buwan",y:"isang taon",yy:"%d taon"},ordinalParse:/\d{1,2}/,ordinal:function(a){return a},week:{dow:1,doy:4}})}),function(a){a(vb)}(function(a){var b={1:"'inci",5:"'inci",8:"'inci",70:"'inci",80:"'inci",2:"'nci",7:"'nci",20:"'nci",50:"'nci",3:"'üncü",4:"'üncü",100:"'üncü",6:"'ncı",9:"'uncu",10:"'uncu",30:"'uncu",60:"'ıncı",90:"'ıncı"};return a.defineLocale("tr",{months:"Ocak_Şubat_Mart_Nisan_Mayıs_Haziran_Temmuz_Ağustos_Eylül_Ekim_Kasım_Aralık".split("_"),monthsShort:"Oca_Şub_Mar_Nis_May_Haz_Tem_Ağu_Eyl_Eki_Kas_Ara".split("_"),weekdays:"Pazar_Pazartesi_Salı_Çarşamba_Perşembe_Cuma_Cumartesi".split("_"),weekdaysShort:"Paz_Pts_Sal_Çar_Per_Cum_Cts".split("_"),weekdaysMin:"Pz_Pt_Sa_Ça_Pe_Cu_Ct".split("_"),longDateFormat:{LT:"HH:mm",LTS:"LT:ss",L:"DD.MM.YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY LT",LLLL:"dddd, D MMMM YYYY LT"},calendar:{sameDay:"[bugün saat] LT",nextDay:"[yarın saat] LT",nextWeek:"[haftaya] dddd [saat] LT",lastDay:"[dün] LT",lastWeek:"[geçen hafta] dddd [saat] LT",sameElse:"L"},relativeTime:{future:"%s sonra",past:"%s önce",s:"birkaç saniye",m:"bir dakika",mm:"%d dakika",h:"bir saat",hh:"%d saat",d:"bir gün",dd:"%d gün",M:"bir ay",MM:"%d ay",y:"bir yıl",yy:"%d yıl"},ordinalParse:/\d{1,2}'(inci|nci|üncü|ncı|uncu|ıncı)/,ordinal:function(a){if(0===a)return a+"'ıncı";var c=a%10,d=a%100-c,e=a>=100?100:null;return a+(b[c]||b[d]||b[e])},week:{dow:1,doy:7}})}),function(a){a(vb)}(function(a){return a.defineLocale("tzm-latn",{months:"innayr_brˤayrˤ_marˤsˤ_ibrir_mayyw_ywnyw_ywlywz_ɣwšt_šwtanbir_ktˤwbrˤ_nwwanbir_dwjnbir".split("_"),monthsShort:"innayr_brˤayrˤ_marˤsˤ_ibrir_mayyw_ywnyw_ywlywz_ɣwšt_šwtanbir_ktˤwbrˤ_nwwanbir_dwjnbir".split("_"),weekdays:"asamas_aynas_asinas_akras_akwas_asimwas_asiḍyas".split("_"),weekdaysShort:"asamas_aynas_asinas_akras_akwas_asimwas_asiḍyas".split("_"),weekdaysMin:"asamas_aynas_asinas_akras_akwas_asimwas_asiḍyas".split("_"),longDateFormat:{LT:"HH:mm",LTS:"LT:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY LT",LLLL:"dddd D MMMM YYYY LT"},calendar:{sameDay:"[asdkh g] LT",nextDay:"[aska g] LT",nextWeek:"dddd [g] LT",lastDay:"[assant g] LT",lastWeek:"dddd [g] LT",sameElse:"L"},relativeTime:{future:"dadkh s yan %s",past:"yan %s",s:"imik",m:"minuḍ",mm:"%d minuḍ",h:"saɛa",hh:"%d tassaɛin",d:"ass",dd:"%d ossan",M:"ayowr",MM:"%d iyyirn",y:"asgas",yy:"%d isgasn"},week:{dow:6,doy:12}})}),function(a){a(vb)}(function(a){return a.defineLocale("tzm",{months:"ⵉⵏⵏⴰⵢⵔ_ⴱⵕⴰⵢⵕ_ⵎⴰⵕⵚ_ⵉⴱⵔⵉⵔ_ⵎⴰⵢⵢⵓ_ⵢⵓⵏⵢⵓ_ⵢⵓⵍⵢⵓⵣ_ⵖⵓⵛⵜ_ⵛⵓⵜⴰⵏⴱⵉⵔ_ⴽⵟⵓⴱⵕ_ⵏⵓⵡⴰⵏⴱⵉⵔ_ⴷⵓⵊⵏⴱⵉⵔ".split("_"),monthsShort:"ⵉⵏⵏⴰⵢⵔ_ⴱⵕⴰⵢⵕ_ⵎⴰⵕⵚ_ⵉⴱⵔⵉⵔ_ⵎⴰⵢⵢⵓ_ⵢⵓⵏⵢⵓ_ⵢⵓⵍⵢⵓⵣ_ⵖⵓⵛⵜ_ⵛⵓⵜⴰⵏⴱⵉⵔ_ⴽⵟⵓⴱⵕ_ⵏⵓⵡⴰⵏⴱⵉⵔ_ⴷⵓⵊⵏⴱⵉⵔ".split("_"),weekdays:"ⴰⵙⴰⵎⴰⵙ_ⴰⵢⵏⴰⵙ_ⴰⵙⵉⵏⴰⵙ_ⴰⴽⵔⴰⵙ_ⴰⴽⵡⴰⵙ_ⴰⵙⵉⵎⵡⴰⵙ_ⴰⵙⵉⴹⵢⴰⵙ".split("_"),weekdaysShort:"ⴰⵙⴰⵎⴰⵙ_ⴰⵢⵏⴰⵙ_ⴰⵙⵉⵏⴰⵙ_ⴰⴽⵔⴰⵙ_ⴰⴽⵡⴰⵙ_ⴰⵙⵉⵎⵡⴰⵙ_ⴰⵙⵉⴹⵢⴰⵙ".split("_"),weekdaysMin:"ⴰⵙⴰⵎⴰⵙ_ⴰⵢⵏⴰⵙ_ⴰⵙⵉⵏⴰⵙ_ⴰⴽⵔⴰⵙ_ⴰⴽⵡⴰⵙ_ⴰⵙⵉⵎⵡⴰⵙ_ⴰⵙⵉⴹⵢⴰⵙ".split("_"),longDateFormat:{LT:"HH:mm",LTS:"LT:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY LT",LLLL:"dddd D MMMM YYYY LT"},calendar:{sameDay:"[ⴰⵙⴷⵅ ⴴ] LT",nextDay:"[ⴰⵙⴽⴰ ⴴ] LT",nextWeek:"dddd [ⴴ] LT",lastDay:"[ⴰⵚⴰⵏⵜ ⴴ] LT",lastWeek:"dddd [ⴴ] LT",sameElse:"L"},relativeTime:{future:"ⴷⴰⴷⵅ ⵙ ⵢⴰⵏ %s",past:"ⵢⴰⵏ %s",s:"ⵉⵎⵉⴽ",m:"ⵎⵉⵏⵓⴺ",mm:"%d ⵎⵉⵏⵓⴺ",h:"ⵙⴰⵄⴰ",hh:"%d ⵜⴰⵙⵙⴰⵄⵉⵏ",d:"ⴰⵙⵙ",dd:"%d oⵙⵙⴰⵏ",M:"ⴰⵢoⵓⵔ",MM:"%d ⵉⵢⵢⵉⵔⵏ",y:"ⴰⵙⴳⴰⵙ",yy:"%d ⵉⵙⴳⴰⵙⵏ"},week:{dow:6,doy:12}})}),function(a){a(vb)}(function(a){function b(a,b){var c=a.split("_");return b%10===1&&b%100!==11?c[0]:b%10>=2&&4>=b%10&&(10>b%100||b%100>=20)?c[1]:c[2]}function c(a,c,d){var e={mm:"хвилина_хвилини_хвилин",hh:"година_години_годин",dd:"день_дні_днів",MM:"місяць_місяці_місяців",yy:"рік_роки_років"};return"m"===d?c?"хвилина":"хвилину":"h"===d?c?"година":"годину":a+" "+b(e[d],+a)}function d(a,b){var c={nominative:"січень_лютий_березень_квітень_травень_червень_липень_серпень_вересень_жовтень_листопад_грудень".split("_"),accusative:"січня_лютого_березня_квітня_травня_червня_липня_серпня_вересня_жовтня_листопада_грудня".split("_")},d=/D[oD]? *MMMM?/.test(b)?"accusative":"nominative";return c[d][a.month()]}function e(a,b){var c={nominative:"неділя_понеділок_вівторок_середа_четвер_п’ятниця_субота".split("_"),accusative:"неділю_понеділок_вівторок_середу_четвер_п’ятницю_суботу".split("_"),genitive:"неділі_понеділка_вівторка_середи_четверга_п’ятниці_суботи".split("_")},d=/(\[[ВвУу]\]) ?dddd/.test(b)?"accusative":/\[?(?:минулої|наступної)? ?\] ?dddd/.test(b)?"genitive":"nominative";return c[d][a.day()]}function f(a){return function(){return a+"о"+(11===this.hours()?"б":"")+"] LT"}}return a.defineLocale("uk",{months:d,monthsShort:"січ_лют_бер_квіт_трав_черв_лип_серп_вер_жовт_лист_груд".split("_"),weekdays:e,weekdaysShort:"нд_пн_вт_ср_чт_пт_сб".split("_"),weekdaysMin:"нд_пн_вт_ср_чт_пт_сб".split("_"),longDateFormat:{LT:"HH:mm",LTS:"LT:ss",L:"DD.MM.YYYY",LL:"D MMMM YYYY р.",LLL:"D MMMM YYYY р., LT",LLLL:"dddd, D MMMM YYYY р., LT"},calendar:{sameDay:f("[Сьогодні "),nextDay:f("[Завтра "),lastDay:f("[Вчора "),nextWeek:f("[У] dddd ["),lastWeek:function(){switch(this.day()){case 0:case 3:case 5:case 6:return f("[Минулої] dddd [").call(this);case 1:case 2:case 4:return f("[Минулого] dddd [").call(this)}},sameElse:"L"},relativeTime:{future:"за %s",past:"%s тому",s:"декілька секунд",m:c,mm:c,h:"годину",hh:c,d:"день",dd:c,M:"місяць",MM:c,y:"рік",yy:c},meridiemParse:/ночі|ранку|дня|вечора/,isPM:function(a){return/^(дня|вечора)$/.test(a)},meridiem:function(a){return 4>a?"ночі":12>a?"ранку":17>a?"дня":"вечора"},ordinalParse:/\d{1,2}-(й|го)/,ordinal:function(a,b){switch(b){case"M":case"d":case"DDD":case"w":case"W":return a+"-й";case"D":return a+"-го";default:return a}},week:{dow:1,doy:7}})}),function(a){a(vb)}(function(a){return a.defineLocale("uz",{months:"январь_февраль_март_апрель_май_июнь_июль_август_сентябрь_октябрь_ноябрь_декабрь".split("_"),monthsShort:"янв_фев_мар_апр_май_июн_июл_авг_сен_окт_ноя_дек".split("_"),weekdays:"Якшанба_Душанба_Сешанба_Чоршанба_Пайшанба_Жума_Шанба".split("_"),weekdaysShort:"Якш_Душ_Сеш_Чор_Пай_Жум_Шан".split("_"),weekdaysMin:"Як_Ду_Се_Чо_Па_Жу_Ша".split("_"),longDateFormat:{LT:"HH:mm",LTS:"LT:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY LT",LLLL:"D MMMM YYYY, dddd LT"},calendar:{sameDay:"[Бугун соат] LT [да]",nextDay:"[Эртага] LT [да]",nextWeek:"dddd [куни соат] LT [да]",lastDay:"[Кеча соат] LT [да]",lastWeek:"[Утган] dddd [куни соат] LT [да]",sameElse:"L"},relativeTime:{future:"Якин %s ичида",past:"Бир неча %s олдин",s:"фурсат",m:"бир дакика",mm:"%d дакика",h:"бир соат",hh:"%d соат",d:"бир кун",dd:"%d кун",M:"бир ой",MM:"%d ой",y:"бир йил",yy:"%d йил"},week:{dow:1,doy:7}})}),function(a){a(vb)}(function(a){return a.defineLocale("vi",{months:"tháng 1_tháng 2_tháng 3_tháng 4_tháng 5_tháng 6_tháng 7_tháng 8_tháng 9_tháng 10_tháng 11_tháng 12".split("_"),monthsShort:"Th01_Th02_Th03_Th04_Th05_Th06_Th07_Th08_Th09_Th10_Th11_Th12".split("_"),weekdays:"chủ nhật_thứ hai_thứ ba_thứ tư_thứ năm_thứ sáu_thứ bảy".split("_"),weekdaysShort:"CN_T2_T3_T4_T5_T6_T7".split("_"),weekdaysMin:"CN_T2_T3_T4_T5_T6_T7".split("_"),longDateFormat:{LT:"HH:mm",LTS:"LT:ss",L:"DD/MM/YYYY",LL:"D MMMM [năm] YYYY",LLL:"D MMMM [năm] YYYY LT",LLLL:"dddd, D MMMM [năm] YYYY LT",l:"DD/M/YYYY",ll:"D MMM YYYY",lll:"D MMM YYYY LT",llll:"ddd, D MMM YYYY LT"},calendar:{sameDay:"[Hôm nay lúc] LT",nextDay:"[Ngày mai lúc] LT",nextWeek:"dddd [tuần tới lúc] LT",lastDay:"[Hôm qua lúc] LT",lastWeek:"dddd [tuần rồi lúc] LT",sameElse:"L"},relativeTime:{future:"%s tới",past:"%s trước",s:"vài giây",m:"một phút",mm:"%d phút",h:"một giờ",hh:"%d giờ",d:"một ngày",dd:"%d ngày",M:"một tháng",MM:"%d tháng",y:"một năm",yy:"%d năm"},ordinalParse:/\d{1,2}/,ordinal:function(a){return a},week:{dow:1,doy:4}})}),function(a){a(vb)}(function(a){return a.defineLocale("zh-cn",{months:"一月_二月_三月_四月_五月_六月_七月_八月_九月_十月_十一月_十二月".split("_"),monthsShort:"1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月".split("_"),weekdays:"星期日_星期一_星期二_星期三_星期四_星期五_星期六".split("_"),weekdaysShort:"周日_周一_周二_周三_周四_周五_周六".split("_"),weekdaysMin:"日_一_二_三_四_五_六".split("_"),longDateFormat:{LT:"Ah点mm",LTS:"Ah点m分s秒",L:"YYYY-MM-DD",LL:"YYYY年MMMD日",LLL:"YYYY年MMMD日LT",LLLL:"YYYY年MMMD日ddddLT",l:"YYYY-MM-DD",ll:"YYYY年MMMD日",lll:"YYYY年MMMD日LT",llll:"YYYY年MMMD日ddddLT"},meridiemParse:/凌晨|早上|上午|中午|下午|晚上/,meridiemHour:function(a,b){return 12===a&&(a=0),"凌晨"===b||"早上"===b||"上午"===b?a:"下午"===b||"晚上"===b?a+12:a>=11?a:a+12},meridiem:function(a,b){var c=100*a+b;return 600>c?"凌晨":900>c?"早上":1130>c?"上午":1230>c?"中午":1800>c?"下午":"晚上"},calendar:{sameDay:function(){return 0===this.minutes()?"[今天]Ah[点整]":"[今天]LT"},nextDay:function(){return 0===this.minutes()?"[明天]Ah[点整]":"[明天]LT"},lastDay:function(){return 0===this.minutes()?"[昨天]Ah[点整]":"[昨天]LT"},nextWeek:function(){var b,c;return b=a().startOf("week"),c=this.unix()-b.unix()>=604800?"[下]":"[本]",0===this.minutes()?c+"dddAh点整":c+"dddAh点mm"},lastWeek:function(){var b,c;return b=a().startOf("week"),c=this.unix()=11?a:a+12:"下午"===b||"晚上"===b?a+12:void 0},meridiem:function(a,b){var c=100*a+b;return 900>c?"早上":1130>c?"上午":1230>c?"中午":1800>c?"下午":"晚上"},calendar:{sameDay:"[今天]LT",nextDay:"[明天]LT",nextWeek:"[下]ddddLT",lastDay:"[昨天]LT",lastWeek:"[上]ddddLT",sameElse:"L"},ordinalParse:/\d{1,2}(日|月|週)/,ordinal:function(a,b){switch(b){case"d":case"D":case"DDD":return a+"日";case"M":return a+"月";case"w":case"W":return a+"週";default:return a}},relativeTime:{future:"%s內",past:"%s前",s:"幾秒",m:"一分鐘",mm:"%d分鐘",h:"一小時",hh:"%d小時",d:"一天",dd:"%d天",M:"一個月",MM:"%d個月",y:"一年",yy:"%d年"}})}),vb.locale("en"),Lb?module.exports=vb:"function"==typeof define&&define.amd?(define(function(a,b,c){return c.config&&c.config()&&c.config().noGlobal===!0&&(zb.moment=wb),vb}),ub(!0)):ub()}).call(this); \ No newline at end of file diff --git a/src/teams/admin.py b/src/teams/admin.py index 9fb3b571..6c99faea 100644 --- a/src/teams/admin.py +++ b/src/teams/admin.py @@ -6,12 +6,7 @@ from camps.utils import CampPropertyListFilter @admin.register(TeamTask) class TeamTaskAdmin(admin.ModelAdmin): - list_display = [ - 'id', - 'team', - 'name', - 'description', - ] + list_display = ["id", "team", "name", "description"] class TeamMemberInline(admin.TabularInline): @@ -21,45 +16,44 @@ class TeamMemberInline(admin.TabularInline): @admin.register(Team) class TeamAdmin(admin.ModelAdmin): def get_responsible(self, obj): - return ", ".join([resp.profile.public_credit_name for resp in obj.responsible_members.all()]) - get_responsible.short_description = 'Responsible' + return ", ".join( + [resp.profile.public_credit_name for resp in obj.responsible_members.all()] + ) + + get_responsible.short_description = "Responsible" list_display = [ - 'name', - 'camp', - 'get_responsible', - 'needs_members', - 'public_irc_channel_name', - 'public_irc_channel_bot', - 'public_irc_channel_managed', - 'private_irc_channel_name', - 'private_irc_channel_bot', - 'private_irc_channel_managed', + "name", + "camp", + "get_responsible", + "needs_members", + "public_irc_channel_name", + "public_irc_channel_bot", + "public_irc_channel_managed", + "private_irc_channel_name", + "private_irc_channel_bot", + "private_irc_channel_managed", ] list_filter = [ CampPropertyListFilter, - 'needs_members', - 'public_irc_channel_bot', - 'public_irc_channel_managed', - 'private_irc_channel_bot', - 'private_irc_channel_managed', + "needs_members", + "public_irc_channel_bot", + "public_irc_channel_managed", + "private_irc_channel_bot", + "private_irc_channel_managed", ] inlines = [TeamMemberInline] @admin.register(TeamMember) class TeamMemberAdmin(admin.ModelAdmin): - list_filter = [ - CampPropertyListFilter, - 'team', - 'approved', - ] + list_filter = [CampPropertyListFilter, "team", "approved"] - actions = ['approve_membership', 'remove_member'] + actions = ["approve_membership", "remove_member"] def approve_membership(self, request, queryset): - teams_count = queryset.values('team').distinct().count() + teams_count = queryset.values("team").distinct().count() updated = 0 for membership in queryset: @@ -70,15 +64,15 @@ class TeamMemberAdmin(admin.ModelAdmin): self.message_user( request, - 'Membership(s) approved: Added {} user(s) to {} team(s).'.format( - updated, - teams_count - ) + "Membership(s) approved: Added {} user(s) to {} team(s).".format( + updated, teams_count + ), ) - approve_membership.description = 'Approve membership.' + + approve_membership.description = "Approve membership." def remove_member(self, request, queryset): - teams_count = queryset.values('team').distinct().count() + teams_count = queryset.values("team").distinct().count() updated = 0 for membership in queryset: @@ -87,18 +81,12 @@ class TeamMemberAdmin(admin.ModelAdmin): updated += 1 self.message_user( - request, - 'Removed {} user(s) from {} team(s).'.format( - updated, - teams_count - ) + request, "Removed {} user(s) from {} team(s).".format(updated, teams_count) ) - remove_member.description = 'Remove a user from the team.' + remove_member.description = "Remove a user from the team." @admin.register(TeamShift) class TeamShiftAdmin(admin.ModelAdmin): - list_filter = [ - 'team', - ] + list_filter = ["team"] diff --git a/src/teams/apps.py b/src/teams/apps.py index 3dd023c4..41d75421 100644 --- a/src/teams/apps.py +++ b/src/teams/apps.py @@ -4,10 +4,17 @@ from .signal_handlers import teammember_saved, teammember_deleted class TeamsConfig(AppConfig): - name = 'teams' + name = "teams" def ready(self): # connect the post_save signal, always including a dispatch_uid to prevent it being called multiple times in corner cases - post_save.connect(teammember_saved, sender='teams.TeamMember', dispatch_uid='teammember_save_signal') - post_delete.connect(teammember_deleted, sender='teams.TeamMember', dispatch_uid='teammember_save_signal') - + post_save.connect( + teammember_saved, + sender="teams.TeamMember", + dispatch_uid="teammember_save_signal", + ) + post_delete.connect( + teammember_deleted, + sender="teams.TeamMember", + dispatch_uid="teammember_save_signal", + ) diff --git a/src/teams/email.py b/src/teams/email.py index 944f0edb..5d55b0fd 100644 --- a/src/teams/email.py +++ b/src/teams/email.py @@ -1,59 +1,51 @@ from utils.email import add_outgoing_email import logging + logger = logging.getLogger("bornhack.%s" % __name__) def add_added_membership_email(membership): - formatdict = { - 'team': membership.team.name, - 'camp': membership.team.camp.title - } + formatdict = {"team": membership.team.name, "camp": membership.team.camp.title} return add_outgoing_email( - text_template='emails/add_membership_email.txt', - html_template='emails/add_membership_email.html', + text_template="emails/add_membership_email.txt", + html_template="emails/add_membership_email.html", to_recipients=membership.user.email, formatdict=formatdict, - subject='Team update from {}'.format(membership.team.camp.title) + subject="Team update from {}".format(membership.team.camp.title), ) def add_removed_membership_email(membership): - formatdict = { - 'team': membership.team.name, - 'camp': membership.team.camp.title - } + formatdict = {"team": membership.team.name, "camp": membership.team.camp.title} if membership.approved: - text_template = 'emails/remove_membership_email.txt', - html_template = 'emails/remove_membership_email.html' + text_template = ("emails/remove_membership_email.txt",) + html_template = "emails/remove_membership_email.html" else: - text_template = 'emails/unapproved_membership_email.txt', - html_template = 'emails/unapproved_membership_email.html' + text_template = ("emails/unapproved_membership_email.txt",) + html_template = "emails/unapproved_membership_email.html" return add_outgoing_email( text_template=text_template, html_template=html_template, to_recipients=membership.user.email, formatdict=formatdict, - subject='Team update from {}'.format(membership.team.camp.title) + subject="Team update from {}".format(membership.team.camp.title), ) def add_new_membership_email(membership): - formatdict = { - 'team': membership.team.name, - 'camp': membership.team.camp.title - } + formatdict = {"team": membership.team.name, "camp": membership.team.camp.title} return add_outgoing_email( - text_template='emails/new_membership_email.txt', - html_template='emails/new_membership_email.html', - to_recipients=[resp.email for resp in membership.team.responsible_members.all()], + text_template="emails/new_membership_email.txt", + html_template="emails/new_membership_email.html", + to_recipients=[ + resp.email for resp in membership.team.responsible_members.all() + ], formatdict=formatdict, - subject='New membership request for {} at {}'.format( - membership.team.name, - membership.team.camp.title - ) + subject="New membership request for {} at {}".format( + membership.team.name, membership.team.camp.title + ), ) - diff --git a/src/teams/migrations/0001_initial.py b/src/teams/migrations/0001_initial.py index 14f544ae..a1ed6f32 100644 --- a/src/teams/migrations/0001_initial.py +++ b/src/teams/migrations/0001_initial.py @@ -12,37 +12,69 @@ class Migration(migrations.Migration): initial = True dependencies = [ - ('camps', '0020_camp_read_only'), + ("camps", "0020_camp_read_only"), migrations.swappable_dependency(settings.AUTH_USER_MODEL), ] operations = [ migrations.CreateModel( - name='Team', + name="Team", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('created', models.DateTimeField(auto_now_add=True)), - ('updated', models.DateTimeField(auto_now=True)), - ('name', models.CharField(max_length=255)), - ('description', models.TextField()), - ('camp', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='camps.Camp')), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("created", models.DateTimeField(auto_now_add=True)), + ("updated", models.DateTimeField(auto_now=True)), + ("name", models.CharField(max_length=255)), + ("description", models.TextField()), + ( + "camp", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, to="camps.Camp" + ), + ), ], - options={ - 'abstract': False, - }, + options={"abstract": False}, ), migrations.CreateModel( - name='TeamMember', + name="TeamMember", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('leader', models.BooleanField(default=False)), - ('team', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='teams.Team')), - ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("leader", models.BooleanField(default=False)), + ( + "team", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, to="teams.Team" + ), + ), + ( + "user", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + to=settings.AUTH_USER_MODEL, + ), + ), ], ), migrations.AddField( - model_name='team', - name='members', - field=models.ManyToManyField(through='teams.TeamMember', to=settings.AUTH_USER_MODEL), + model_name="team", + name="members", + field=models.ManyToManyField( + through="teams.TeamMember", to=settings.AUTH_USER_MODEL + ), ), ] diff --git a/src/teams/migrations/0002_auto_20170327_2208.py b/src/teams/migrations/0002_auto_20170327_2208.py index f6e79565..5c718491 100644 --- a/src/teams/migrations/0002_auto_20170327_2208.py +++ b/src/teams/migrations/0002_auto_20170327_2208.py @@ -7,23 +7,16 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ - ('camps', '0020_camp_read_only'), - ('teams', '0001_initial'), - ] + dependencies = [("camps", "0020_camp_read_only"), ("teams", "0001_initial")] operations = [ - migrations.AlterModelOptions( - name='team', - options={'ordering': ['name']}, - ), + migrations.AlterModelOptions(name="team", options={"ordering": ["name"]}), migrations.AddField( - model_name='team', - name='slug', + model_name="team", + name="slug", field=models.SlugField(blank=True, max_length=255), ), migrations.AlterUniqueTogether( - name='team', - unique_together=set([('slug', 'camp')]), + name="team", unique_together=set([("slug", "camp")]) ), ] diff --git a/src/teams/migrations/0003_auto_20170401_2227.py b/src/teams/migrations/0003_auto_20170401_2227.py index 996bc866..cf0d1085 100644 --- a/src/teams/migrations/0003_auto_20170401_2227.py +++ b/src/teams/migrations/0003_auto_20170401_2227.py @@ -7,14 +7,10 @@ from django.db import migrations class Migration(migrations.Migration): - dependencies = [ - ('teams', '0002_auto_20170327_2208'), - ] + dependencies = [("teams", "0002_auto_20170327_2208")] operations = [ migrations.RenameField( - model_name='teammember', - old_name='leader', - new_name='responsible', - ), + model_name="teammember", old_name="leader", new_name="responsible" + ) ] diff --git a/src/teams/migrations/0004_team_sub_team_of.py b/src/teams/migrations/0004_team_sub_team_of.py index a15e336e..69c7dc86 100644 --- a/src/teams/migrations/0004_team_sub_team_of.py +++ b/src/teams/migrations/0004_team_sub_team_of.py @@ -8,14 +8,17 @@ import django.db.models.deletion class Migration(migrations.Migration): - dependencies = [ - ('teams', '0003_auto_20170401_2227'), - ] + dependencies = [("teams", "0003_auto_20170401_2227")] operations = [ migrations.AddField( - model_name='team', - name='sub_team_of', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='teams.Team'), - ), + model_name="team", + name="sub_team_of", + field=models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.CASCADE, + to="teams.Team", + ), + ) ] diff --git a/src/teams/migrations/0005_auto_20170402_1331.py b/src/teams/migrations/0005_auto_20170402_1331.py index bd98f781..b0ce8c3d 100644 --- a/src/teams/migrations/0005_auto_20170402_1331.py +++ b/src/teams/migrations/0005_auto_20170402_1331.py @@ -10,61 +10,69 @@ import django.db.models.deletion class Migration(migrations.Migration): dependencies = [ - ('camps', '0020_camp_read_only'), + ("camps", "0020_camp_read_only"), migrations.swappable_dependency(settings.AUTH_USER_MODEL), - ('teams', '0004_team_sub_team_of'), + ("teams", "0004_team_sub_team_of"), ] operations = [ migrations.CreateModel( - name='TeamArea', + name="TeamArea", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('created', models.DateTimeField(auto_now_add=True)), - ('updated', models.DateTimeField(auto_now=True)), - ('name', models.CharField(max_length=255)), - ('camp', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='camps.Camp')), - ('responsible', models.ManyToManyField(related_name='responsible_team_areas', to=settings.AUTH_USER_MODEL)), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("created", models.DateTimeField(auto_now_add=True)), + ("updated", models.DateTimeField(auto_now=True)), + ("name", models.CharField(max_length=255)), + ( + "camp", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, to="camps.Camp" + ), + ), + ( + "responsible", + models.ManyToManyField( + related_name="responsible_team_areas", + to=settings.AUTH_USER_MODEL, + ), + ), ], - options={ - 'ordering': ['name'], - }, - ), - migrations.RemoveField( - model_name='teammember', - name='team', - ), - migrations.RemoveField( - model_name='teammember', - name='user', + options={"ordering": ["name"]}, ), + migrations.RemoveField(model_name="teammember", name="team"), + migrations.RemoveField(model_name="teammember", name="user"), migrations.AddField( - model_name='team', - name='membersnew', - field=models.ManyToManyField(related_name='teams', to=settings.AUTH_USER_MODEL), - ), - migrations.RemoveField( - model_name='team', - name='members', - ), - migrations.RemoveField( - model_name='team', - name='sub_team_of', + model_name="team", + name="membersnew", + field=models.ManyToManyField( + related_name="teams", to=settings.AUTH_USER_MODEL + ), ), + migrations.RemoveField(model_name="team", name="members"), + migrations.RemoveField(model_name="team", name="sub_team_of"), migrations.AddField( - model_name='team', - name='area', - field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.PROTECT, related_name='teams', to='teams.TeamArea'), + model_name="team", + name="area", + field=models.ForeignKey( + null=True, + on_delete=django.db.models.deletion.PROTECT, + related_name="teams", + to="teams.TeamArea", + ), ), migrations.AlterUniqueTogether( - name='team', - unique_together=set([('name', 'camp'), ('slug', 'camp')]), - ), - migrations.DeleteModel( - name='TeamMember', + name="team", unique_together=set([("name", "camp"), ("slug", "camp")]) ), + migrations.DeleteModel(name="TeamMember"), migrations.AlterUniqueTogether( - name='teamarea', - unique_together=set([('name', 'camp')]), + name="teamarea", unique_together=set([("name", "camp")]) ), ] diff --git a/src/teams/migrations/0006_auto_20170402_1331.py b/src/teams/migrations/0006_auto_20170402_1331.py index eb67736b..11543aef 100644 --- a/src/teams/migrations/0006_auto_20170402_1331.py +++ b/src/teams/migrations/0006_auto_20170402_1331.py @@ -8,19 +8,19 @@ import django.db.models.deletion class Migration(migrations.Migration): - dependencies = [ - ('teams', '0005_auto_20170402_1331'), - ] + dependencies = [("teams", "0005_auto_20170402_1331")] operations = [ migrations.RenameField( - model_name='team', - old_name='membersnew', - new_name='members', + model_name="team", old_name="membersnew", new_name="members" ), migrations.AlterField( - model_name='team', - name='area', - field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='teams', to='teams.TeamArea'), + model_name="team", + name="area", + field=models.ForeignKey( + on_delete=django.db.models.deletion.PROTECT, + related_name="teams", + to="teams.TeamArea", + ), ), ] diff --git a/src/teams/migrations/0007_teamarea_description.py b/src/teams/migrations/0007_teamarea_description.py index 23e90d79..d09408a8 100644 --- a/src/teams/migrations/0007_teamarea_description.py +++ b/src/teams/migrations/0007_teamarea_description.py @@ -7,14 +7,12 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ - ('teams', '0006_auto_20170402_1331'), - ] + dependencies = [("teams", "0006_auto_20170402_1331")] operations = [ migrations.AddField( - model_name='teamarea', - name='description', - field=models.TextField(default=''), - ), + model_name="teamarea", + name="description", + field=models.TextField(default=""), + ) ] diff --git a/src/teams/migrations/0008_team_needs_members.py b/src/teams/migrations/0008_team_needs_members.py index ff612d66..73e8a53a 100644 --- a/src/teams/migrations/0008_team_needs_members.py +++ b/src/teams/migrations/0008_team_needs_members.py @@ -7,14 +7,12 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ - ('teams', '0007_teamarea_description'), - ] + dependencies = [("teams", "0007_teamarea_description")] operations = [ migrations.AddField( - model_name='team', - name='needs_members', + model_name="team", + name="needs_members", field=models.BooleanField(default=True), - ), + ) ] diff --git a/src/teams/migrations/0009_auto_20170402_1607.py b/src/teams/migrations/0009_auto_20170402_1607.py index 54677ca3..963422d2 100644 --- a/src/teams/migrations/0009_auto_20170402_1607.py +++ b/src/teams/migrations/0009_auto_20170402_1607.py @@ -11,35 +11,53 @@ class Migration(migrations.Migration): dependencies = [ migrations.swappable_dependency(settings.AUTH_USER_MODEL), - ('teams', '0008_team_needs_members'), + ("teams", "0008_team_needs_members"), ] operations = [ migrations.CreateModel( - name='TeamMember', + name="TeamMember", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('approved', models.BooleanField(default=False)), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("approved", models.BooleanField(default=False)), ], ), migrations.AlterField( - model_name='team', - name='members', - field=models.ManyToManyField(related_name='teamsold', to=settings.AUTH_USER_MODEL), + model_name="team", + name="members", + field=models.ManyToManyField( + related_name="teamsold", to=settings.AUTH_USER_MODEL + ), ), migrations.AddField( - model_name='teammember', - name='team', - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='teams.Team'), + model_name="teammember", + name="team", + field=models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, to="teams.Team" + ), ), migrations.AddField( - model_name='teammember', - name='user', - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL), + model_name="teammember", + name="user", + field=models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL + ), ), migrations.AddField( - model_name='team', - name='membersnew', - field=models.ManyToManyField(related_name='teams', through='teams.TeamMember', to=settings.AUTH_USER_MODEL), + model_name="team", + name="membersnew", + field=models.ManyToManyField( + related_name="teams", + through="teams.TeamMember", + to=settings.AUTH_USER_MODEL, + ), ), ] diff --git a/src/teams/migrations/0010_remove_team_members.py b/src/teams/migrations/0010_remove_team_members.py index 334848b4..f4a89f78 100644 --- a/src/teams/migrations/0010_remove_team_members.py +++ b/src/teams/migrations/0010_remove_team_members.py @@ -7,13 +7,6 @@ from django.db import migrations class Migration(migrations.Migration): - dependencies = [ - ('teams', '0009_auto_20170402_1607'), - ] + dependencies = [("teams", "0009_auto_20170402_1607")] - operations = [ - migrations.RemoveField( - model_name='team', - name='members', - ), - ] + operations = [migrations.RemoveField(model_name="team", name="members")] diff --git a/src/teams/migrations/0011_auto_20170402_1608.py b/src/teams/migrations/0011_auto_20170402_1608.py index b2ffaf34..1d097bc6 100644 --- a/src/teams/migrations/0011_auto_20170402_1608.py +++ b/src/teams/migrations/0011_auto_20170402_1608.py @@ -7,14 +7,10 @@ from django.db import migrations class Migration(migrations.Migration): - dependencies = [ - ('teams', '0010_remove_team_members'), - ] + dependencies = [("teams", "0010_remove_team_members")] operations = [ migrations.RenameField( - model_name='team', - old_name='membersnew', - new_name='members', - ), + model_name="team", old_name="membersnew", new_name="members" + ) ] diff --git a/src/teams/migrations/0012_teammember_responsible.py b/src/teams/migrations/0012_teammember_responsible.py index 72ac8139..ba1c7554 100644 --- a/src/teams/migrations/0012_teammember_responsible.py +++ b/src/teams/migrations/0012_teammember_responsible.py @@ -7,14 +7,12 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ - ('teams', '0011_auto_20170402_1608'), - ] + dependencies = [("teams", "0011_auto_20170402_1608")] operations = [ migrations.AddField( - model_name='teammember', - name='responsible', + model_name="teammember", + name="responsible", field=models.BooleanField(default=False), - ), + ) ] diff --git a/src/teams/migrations/0013_auto_20170523_2046.py b/src/teams/migrations/0013_auto_20170523_2046.py index fb536ace..b94843ce 100644 --- a/src/teams/migrations/0013_auto_20170523_2046.py +++ b/src/teams/migrations/0013_auto_20170523_2046.py @@ -8,25 +8,25 @@ import django.utils.timezone class Migration(migrations.Migration): - dependencies = [ - ('teams', '0012_teammember_responsible'), - ] + dependencies = [("teams", "0012_teammember_responsible")] operations = [ migrations.AddField( - model_name='teammember', - name='created', - field=models.DateTimeField(auto_now_add=True, default=django.utils.timezone.now), + model_name="teammember", + name="created", + field=models.DateTimeField( + auto_now_add=True, default=django.utils.timezone.now + ), preserve_default=False, ), migrations.AddField( - model_name='teammember', - name='deleted', + model_name="teammember", + name="deleted", field=models.BooleanField(default=False), ), migrations.AddField( - model_name='teammember', - name='updated', + model_name="teammember", + name="updated", field=models.DateTimeField(auto_now=True), ), ] diff --git a/src/teams/migrations/0014_remove_teammember_deleted.py b/src/teams/migrations/0014_remove_teammember_deleted.py index 759afe2e..aad6b949 100644 --- a/src/teams/migrations/0014_remove_teammember_deleted.py +++ b/src/teams/migrations/0014_remove_teammember_deleted.py @@ -7,13 +7,6 @@ from django.db import migrations class Migration(migrations.Migration): - dependencies = [ - ('teams', '0013_auto_20170523_2046'), - ] + dependencies = [("teams", "0013_auto_20170523_2046")] - operations = [ - migrations.RemoveField( - model_name='teammember', - name='deleted', - ), - ] + operations = [migrations.RemoveField(model_name="teammember", name="deleted")] diff --git a/src/teams/migrations/0015_team_mailing_list.py b/src/teams/migrations/0015_team_mailing_list.py index fa089713..e2194cc0 100644 --- a/src/teams/migrations/0015_team_mailing_list.py +++ b/src/teams/migrations/0015_team_mailing_list.py @@ -7,14 +7,12 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ - ('teams', '0014_remove_teammember_deleted'), - ] + dependencies = [("teams", "0014_remove_teammember_deleted")] operations = [ migrations.AddField( - model_name='team', - name='mailing_list', + model_name="team", + name="mailing_list", field=models.EmailField(blank=True, max_length=254), - ), + ) ] diff --git a/src/teams/migrations/0016_auto_20170711_2247.py b/src/teams/migrations/0016_auto_20170711_2247.py index 6683edf3..67cc7dce 100644 --- a/src/teams/migrations/0016_auto_20170711_2247.py +++ b/src/teams/migrations/0016_auto_20170711_2247.py @@ -8,14 +8,16 @@ import django.db.models.deletion class Migration(migrations.Migration): - dependencies = [ - ('teams', '0015_team_mailing_list'), - ] + dependencies = [("teams", "0015_team_mailing_list")] operations = [ migrations.AlterField( - model_name='team', - name='camp', - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='teams', to='camps.Camp'), - ), + model_name="team", + name="camp", + field=models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="teams", + to="camps.Camp", + ), + ) ] diff --git a/src/teams/migrations/0017_auto_20171122_1928.py b/src/teams/migrations/0017_auto_20171122_1928.py index fd093ea9..e2b90076 100644 --- a/src/teams/migrations/0017_auto_20171122_1928.py +++ b/src/teams/migrations/0017_auto_20171122_1928.py @@ -8,28 +8,55 @@ import django.db.models.deletion class Migration(migrations.Migration): - dependencies = [ - ('teams', '0016_auto_20170711_2247'), - ] + dependencies = [("teams", "0016_auto_20170711_2247")] operations = [ migrations.CreateModel( - name='TeamTask', + name="TeamTask", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('created', models.DateTimeField(auto_now_add=True)), - ('updated', models.DateTimeField(auto_now=True)), - ('name', models.CharField(help_text='Short name of this task', max_length=100)), - ('slug', models.SlugField(blank=True, help_text='url slug, leave blank to autogenerate', max_length=255)), - ('description', models.TextField(help_text='Description of the task. Markdown is supported.')), - ('team', models.ForeignKey(help_text='The team this task belongs to', on_delete=django.db.models.deletion.CASCADE, to='teams.Team')), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("created", models.DateTimeField(auto_now_add=True)), + ("updated", models.DateTimeField(auto_now=True)), + ( + "name", + models.CharField( + help_text="Short name of this task", max_length=100 + ), + ), + ( + "slug", + models.SlugField( + blank=True, + help_text="url slug, leave blank to autogenerate", + max_length=255, + ), + ), + ( + "description", + models.TextField( + help_text="Description of the task. Markdown is supported." + ), + ), + ( + "team", + models.ForeignKey( + help_text="The team this task belongs to", + on_delete=django.db.models.deletion.CASCADE, + to="teams.Team", + ), + ), ], - options={ - 'ordering': ['name'], - }, + options={"ordering": ["name"]}, ), migrations.AlterUniqueTogether( - name='teamtask', - unique_together=set([('slug', 'team'), ('name', 'team')]), + name="teamtask", unique_together=set([("slug", "team"), ("name", "team")]) ), ] diff --git a/src/teams/migrations/0018_auto_20171122_2204.py b/src/teams/migrations/0018_auto_20171122_2204.py index d1a727f8..aeaccd9d 100644 --- a/src/teams/migrations/0018_auto_20171122_2204.py +++ b/src/teams/migrations/0018_auto_20171122_2204.py @@ -8,14 +8,17 @@ import django.db.models.deletion class Migration(migrations.Migration): - dependencies = [ - ('teams', '0017_auto_20171122_1928'), - ] + dependencies = [("teams", "0017_auto_20171122_1928")] operations = [ migrations.AlterField( - model_name='teamtask', - name='team', - field=models.ForeignKey(help_text='The team this task belongs to', on_delete=django.db.models.deletion.CASCADE, related_name='tasks', to='teams.Team'), - ), + model_name="teamtask", + name="team", + field=models.ForeignKey( + help_text="The team this task belongs to", + on_delete=django.db.models.deletion.CASCADE, + related_name="tasks", + to="teams.Team", + ), + ) ] diff --git a/src/teams/migrations/0019_auto_20180304_1019.py b/src/teams/migrations/0019_auto_20180304_1019.py index 019b3764..9b398623 100644 --- a/src/teams/migrations/0019_auto_20180304_1019.py +++ b/src/teams/migrations/0019_auto_20180304_1019.py @@ -7,17 +7,9 @@ from django.db import migrations class Migration(migrations.Migration): - dependencies = [ - ('teams', '0018_auto_20171122_2204'), - ] + dependencies = [("teams", "0018_auto_20171122_2204")] operations = [ - migrations.AlterUniqueTogether( - name='team', - unique_together=set([]), - ), - migrations.RemoveField( - model_name='team', - name='camp', - ), + migrations.AlterUniqueTogether(name="team", unique_together=set([])), + migrations.RemoveField(model_name="team", name="camp"), ] diff --git a/src/teams/migrations/0020_auto_20180304_1233.py b/src/teams/migrations/0020_auto_20180304_1233.py index 4cfe13a0..f5b8c2e5 100644 --- a/src/teams/migrations/0020_auto_20180304_1233.py +++ b/src/teams/migrations/0020_auto_20180304_1233.py @@ -8,14 +8,16 @@ import django.db.models.deletion class Migration(migrations.Migration): - dependencies = [ - ('teams', '0019_auto_20180304_1019'), - ] + dependencies = [("teams", "0019_auto_20180304_1019")] operations = [ migrations.AlterField( - model_name='teamarea', - name='camp', - field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='teamareas', to='camps.Camp'), - ), + model_name="teamarea", + name="camp", + field=models.ForeignKey( + on_delete=django.db.models.deletion.PROTECT, + related_name="teamareas", + to="camps.Camp", + ), + ) ] diff --git a/src/teams/migrations/0021_auto_20180318_0906.py b/src/teams/migrations/0021_auto_20180318_0906.py index e03f8214..a4584983 100644 --- a/src/teams/migrations/0021_auto_20180318_0906.py +++ b/src/teams/migrations/0021_auto_20180318_0906.py @@ -9,24 +9,31 @@ import django.db.models.deletion class Migration(migrations.Migration): - dependencies = [ - ('teams', '0020_auto_20180304_1233'), - ] + dependencies = [("teams", "0020_auto_20180304_1233")] operations = [ migrations.AlterField( - model_name='teammember', - name='team', - field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='teams.Team'), + model_name="teammember", + name="team", + field=models.ForeignKey( + on_delete=django.db.models.deletion.PROTECT, to="teams.Team" + ), ), migrations.AlterField( - model_name='teammember', - name='user', - field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to=settings.AUTH_USER_MODEL), + model_name="teammember", + name="user", + field=models.ForeignKey( + on_delete=django.db.models.deletion.PROTECT, to=settings.AUTH_USER_MODEL + ), ), migrations.AlterField( - model_name='teamtask', - name='team', - field=models.ForeignKey(help_text='The team this task belongs to', on_delete=django.db.models.deletion.PROTECT, related_name='tasks', to='teams.Team'), + model_name="teamtask", + name="team", + field=models.ForeignKey( + help_text="The team this task belongs to", + on_delete=django.db.models.deletion.PROTECT, + related_name="tasks", + to="teams.Team", + ), ), ] diff --git a/src/teams/migrations/0022_auto_20180318_1135.py b/src/teams/migrations/0022_auto_20180318_1135.py index d2707376..93281dc8 100644 --- a/src/teams/migrations/0022_auto_20180318_1135.py +++ b/src/teams/migrations/0022_auto_20180318_1135.py @@ -7,29 +7,40 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ - ('teams', '0021_auto_20180318_0906'), - ] + dependencies = [("teams", "0021_auto_20180318_0906")] operations = [ migrations.AddField( - model_name='team', - name='irc_channel', - field=models.BooleanField(default=False, help_text='Check to make the IRC bot join the team IRC channel. Leave unchecked to disable IRC bot functionality for this team entirely.'), + model_name="team", + name="irc_channel", + field=models.BooleanField( + default=False, + help_text="Check to make the IRC bot join the team IRC channel. Leave unchecked to disable IRC bot functionality for this team entirely.", + ), ), migrations.AddField( - model_name='team', - name='irc_channel_managed', - field=models.BooleanField(default=True, help_text='Check to make the bot manage the team IRC channel. The bot will register the channel with ChanServ if possible, and manage ACLs as needed.'), + model_name="team", + name="irc_channel_managed", + field=models.BooleanField( + default=True, + help_text="Check to make the bot manage the team IRC channel. The bot will register the channel with ChanServ if possible, and manage ACLs as needed.", + ), ), migrations.AddField( - model_name='team', - name='irc_channel_name', - field=models.TextField(blank=True, default='', help_text='Team IRC channel. Leave blank to generate channel name automatically, based on camp slug and team slug.'), + model_name="team", + name="irc_channel_name", + field=models.TextField( + blank=True, + default="", + help_text="Team IRC channel. Leave blank to generate channel name automatically, based on camp slug and team slug.", + ), ), migrations.AddField( - model_name='team', - name='irc_channel_private', - field=models.BooleanField(default=True, help_text='Check to make the IRC channel private for team members only, also sets +s. Leave unchecked to make the IRC channel public and open for everyone.'), + model_name="team", + name="irc_channel_private", + field=models.BooleanField( + default=True, + help_text="Check to make the IRC channel private for team members only, also sets +s. Leave unchecked to make the IRC channel public and open for everyone.", + ), ), ] diff --git a/src/teams/migrations/0023_auto_20180318_1256.py b/src/teams/migrations/0023_auto_20180318_1256.py index 3a8983cd..661bfcc2 100644 --- a/src/teams/migrations/0023_auto_20180318_1256.py +++ b/src/teams/migrations/0023_auto_20180318_1256.py @@ -7,24 +7,29 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ - ('teams', '0022_auto_20180318_1135'), - ] + dependencies = [("teams", "0022_auto_20180318_1135")] operations = [ migrations.AddField( - model_name='team', - name='shortslug', - field=models.SlugField(blank=True, help_text='Abbreviated version of the slug. Used in places like IRC channel names where space is limited'), + model_name="team", + name="shortslug", + field=models.SlugField( + blank=True, + help_text="Abbreviated version of the slug. Used in places like IRC channel names where space is limited", + ), ), migrations.AlterField( - model_name='team', - name='name', - field=models.CharField(help_text='The team name', max_length=255), + model_name="team", + name="name", + field=models.CharField(help_text="The team name", max_length=255), ), migrations.AlterField( - model_name='team', - name='slug', - field=models.SlugField(blank=True, help_text='Url slug for this team. Leave blank to generate based on team name', max_length=255), + model_name="team", + name="slug", + field=models.SlugField( + blank=True, + help_text="Url slug for this team. Leave blank to generate based on team name", + max_length=255, + ), ), ] diff --git a/src/teams/migrations/0024_populate_shortslugs.py b/src/teams/migrations/0024_populate_shortslugs.py index 4babd51e..42361880 100644 --- a/src/teams/migrations/0024_populate_shortslugs.py +++ b/src/teams/migrations/0024_populate_shortslugs.py @@ -4,19 +4,16 @@ from __future__ import unicode_literals from django.db import migrations + def populate_team_shortslugs(apps, schema_editor): - Team = apps.get_model('teams', 'Team') + Team = apps.get_model("teams", "Team") for team in Team.objects.all(): if not team.shortslug: team.shortslug = team.slug team.save() + class Migration(migrations.Migration): - dependencies = [ - ('teams', '0023_auto_20180318_1256'), - ] - - operations = [ - migrations.RunPython(populate_team_shortslugs), - ] + dependencies = [("teams", "0023_auto_20180318_1256")] + operations = [migrations.RunPython(populate_team_shortslugs)] diff --git a/src/teams/migrations/0025_auto_20180318_1318.py b/src/teams/migrations/0025_auto_20180318_1318.py index 2ad4a528..ce5d84b9 100644 --- a/src/teams/migrations/0025_auto_20180318_1318.py +++ b/src/teams/migrations/0025_auto_20180318_1318.py @@ -7,14 +7,14 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ - ('teams', '0024_populate_shortslugs'), - ] + dependencies = [("teams", "0024_populate_shortslugs")] operations = [ migrations.AlterField( - model_name='team', - name='shortslug', - field=models.SlugField(help_text='Abbreviated version of the slug. Used in places like IRC channel names where space is limited'), - ), + model_name="team", + name="shortslug", + field=models.SlugField( + help_text="Abbreviated version of the slug. Used in places like IRC channel names where space is limited" + ), + ) ] diff --git a/src/teams/migrations/0026_team_camp.py b/src/teams/migrations/0026_team_camp.py index 577bdd71..b23f7c44 100644 --- a/src/teams/migrations/0026_team_camp.py +++ b/src/teams/migrations/0026_team_camp.py @@ -9,14 +9,20 @@ import django.db.models.deletion class Migration(migrations.Migration): dependencies = [ - ('camps', '0025_auto_20180318_1250'), - ('teams', '0025_auto_20180318_1318'), + ("camps", "0025_auto_20180318_1250"), + ("teams", "0025_auto_20180318_1318"), ] operations = [ migrations.AddField( - model_name='team', - name='camp', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='teams', to='camps.Camp'), - ), + model_name="team", + name="camp", + field=models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.PROTECT, + related_name="teams", + to="camps.Camp", + ), + ) ] diff --git a/src/teams/migrations/0027_fixup_teams.py b/src/teams/migrations/0027_fixup_teams.py index 879090e0..5bcdb32e 100644 --- a/src/teams/migrations/0027_fixup_teams.py +++ b/src/teams/migrations/0027_fixup_teams.py @@ -4,10 +4,11 @@ from __future__ import unicode_literals from django.db import migrations + def add_team_camp(apps, schema_editor): - Team = apps.get_model('teams', 'Team') - TeamArea = apps.get_model('teams', 'TeamArea') - TeamMember = apps.get_model('teams', 'TeamMember') + Team = apps.get_model("teams", "Team") + TeamArea = apps.get_model("teams", "TeamArea") + TeamMember = apps.get_model("teams", "TeamMember") for team in Team.objects.all(): print("camp processing team %s..." % team.name) @@ -15,10 +16,11 @@ def add_team_camp(apps, schema_editor): team.save() print("set camp %s for team %s" % (team.camp.slug, team.name)) + def add_missing_team_responsibles(apps, schema_editor): - Team = apps.get_model('teams', 'Team') - TeamArea = apps.get_model('teams', 'TeamArea') - TeamMember = apps.get_model('teams', 'TeamMember') + Team = apps.get_model("teams", "Team") + TeamArea = apps.get_model("teams", "TeamArea") + TeamMember = apps.get_model("teams", "TeamMember") for team in Team.objects.all(): print("responsible processing team %s..." % team.name) @@ -34,27 +36,22 @@ def add_missing_team_responsibles(apps, schema_editor): membership = TeamMember.objects.get(team=team, user=responsible) if not membership.responsible: # already a member of the team, but not responsible - membership.responsible=True + membership.responsible = True membership.save() print("%s is now marked as responsible" % membership.user.username) except TeamMember.DoesNotExist: # add the responsible as a member of the team membership = TeamMember.objects.create( - team=team, - user=responsible, - responsible=True, - approved=True + team=team, user=responsible, responsible=True, approved=True ) print("new membership has been created for team %s" % team.name) + class Migration(migrations.Migration): - dependencies = [ - ('teams', '0026_team_camp'), - ] + dependencies = [("teams", "0026_team_camp")] operations = [ migrations.RunPython(add_team_camp), migrations.RunPython(add_missing_team_responsibles), ] - diff --git a/src/teams/migrations/0028_auto_20180331_1416.py b/src/teams/migrations/0028_auto_20180331_1416.py index 919fe0cf..a3e527cf 100644 --- a/src/teams/migrations/0028_auto_20180331_1416.py +++ b/src/teams/migrations/0028_auto_20180331_1416.py @@ -8,14 +8,18 @@ import django.db.models.deletion class Migration(migrations.Migration): - dependencies = [ - ('teams', '0027_fixup_teams'), - ] + dependencies = [("teams", "0027_fixup_teams")] operations = [ migrations.AlterField( - model_name='team', - name='area', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='teams', to='teams.TeamArea'), - ), + model_name="team", + name="area", + field=models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.PROTECT, + related_name="teams", + to="teams.TeamArea", + ), + ) ] diff --git a/src/teams/migrations/0029_remove_team_area.py b/src/teams/migrations/0029_remove_team_area.py index 1d86f49e..b82fb3a8 100644 --- a/src/teams/migrations/0029_remove_team_area.py +++ b/src/teams/migrations/0029_remove_team_area.py @@ -7,13 +7,6 @@ from django.db import migrations class Migration(migrations.Migration): - dependencies = [ - ('teams', '0028_auto_20180331_1416'), - ] + dependencies = [("teams", "0028_auto_20180331_1416")] - operations = [ - migrations.RemoveField( - model_name='team', - name='area', - ), - ] + operations = [migrations.RemoveField(model_name="team", name="area")] diff --git a/src/teams/migrations/0030_auto_20180402_1514.py b/src/teams/migrations/0030_auto_20180402_1514.py index b7abdabd..e2c4499f 100644 --- a/src/teams/migrations/0030_auto_20180402_1514.py +++ b/src/teams/migrations/0030_auto_20180402_1514.py @@ -7,24 +7,32 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ - ('teams', '0029_remove_team_area'), - ] + dependencies = [("teams", "0029_remove_team_area")] operations = [ migrations.AlterField( - model_name='team', - name='irc_channel_name', - field=models.TextField(blank=True, default='', help_text='Team IRC channel. Leave blank to generate channel name automatically, based on camp shortslug and team shortslug.'), + model_name="team", + name="irc_channel_name", + field=models.TextField( + blank=True, + default="", + help_text="Team IRC channel. Leave blank to generate channel name automatically, based on camp shortslug and team shortslug.", + ), ), migrations.AlterField( - model_name='team', - name='irc_channel_private', - field=models.BooleanField(default=True, help_text='Check to make the IRC channel secret and +i (private for team members only using an ACL). Leave unchecked to make the IRC channel public and open for everyone.'), + model_name="team", + name="irc_channel_private", + field=models.BooleanField( + default=True, + help_text="Check to make the IRC channel secret and +i (private for team members only using an ACL). Leave unchecked to make the IRC channel public and open for everyone.", + ), ), migrations.AlterField( - model_name='team', - name='needs_members', - field=models.BooleanField(default=True, help_text='Check to indicate that this team needs more members'), + model_name="team", + name="needs_members", + field=models.BooleanField( + default=True, + help_text="Check to indicate that this team needs more members", + ), ), ] diff --git a/src/teams/migrations/0031_auto_20180402_2146.py b/src/teams/migrations/0031_auto_20180402_2146.py index 22cef6cb..fe1f21c5 100644 --- a/src/teams/migrations/0031_auto_20180402_2146.py +++ b/src/teams/migrations/0031_auto_20180402_2146.py @@ -7,19 +7,22 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ - ('teams', '0030_auto_20180402_1514'), - ] + dependencies = [("teams", "0030_auto_20180402_1514")] operations = [ migrations.AddField( - model_name='team', - name='mailing_list_archive_public', - field=models.BooleanField(default=False, help_text='Check if the mailing list archive is public'), + model_name="team", + name="mailing_list_archive_public", + field=models.BooleanField( + default=False, help_text="Check if the mailing list archive is public" + ), ), migrations.AddField( - model_name='team', - name='mailing_list_nonmember_posts', - field=models.BooleanField(default=False, help_text='Check if the mailinglist allows non-list-members to post'), + model_name="team", + name="mailing_list_nonmember_posts", + field=models.BooleanField( + default=False, + help_text="Check if the mailinglist allows non-list-members to post", + ), ), ] diff --git a/src/teams/migrations/0032_auto_20180402_2148.py b/src/teams/migrations/0032_auto_20180402_2148.py index 421e6683..aae790d3 100644 --- a/src/teams/migrations/0032_auto_20180402_2148.py +++ b/src/teams/migrations/0032_auto_20180402_2148.py @@ -8,14 +8,16 @@ import django.db.models.deletion class Migration(migrations.Migration): - dependencies = [ - ('teams', '0031_auto_20180402_2146'), - ] + dependencies = [("teams", "0031_auto_20180402_2146")] operations = [ migrations.AlterField( - model_name='team', - name='camp', - field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='teams', to='camps.Camp'), - ), + model_name="team", + name="camp", + field=models.ForeignKey( + on_delete=django.db.models.deletion.PROTECT, + related_name="teams", + to="camps.Camp", + ), + ) ] diff --git a/src/teams/migrations/0033_auto_20180402_2204.py b/src/teams/migrations/0033_auto_20180402_2204.py index 338cc17c..f13e9843 100644 --- a/src/teams/migrations/0033_auto_20180402_2204.py +++ b/src/teams/migrations/0033_auto_20180402_2204.py @@ -7,24 +7,11 @@ from django.db import migrations class Migration(migrations.Migration): - dependencies = [ - ('teams', '0032_auto_20180402_2148'), - ] + dependencies = [("teams", "0032_auto_20180402_2148")] operations = [ - migrations.AlterUniqueTogether( - name='teamarea', - unique_together=set([]), - ), - migrations.RemoveField( - model_name='teamarea', - name='camp', - ), - migrations.RemoveField( - model_name='teamarea', - name='responsible', - ), - migrations.DeleteModel( - name='TeamArea', - ), + migrations.AlterUniqueTogether(name="teamarea", unique_together=set([])), + migrations.RemoveField(model_name="teamarea", name="camp"), + migrations.RemoveField(model_name="teamarea", name="responsible"), + migrations.DeleteModel(name="TeamArea"), ] diff --git a/src/teams/migrations/0034_auto_20180402_2334.py b/src/teams/migrations/0034_auto_20180402_2334.py index eb4a7718..f8901fb2 100644 --- a/src/teams/migrations/0034_auto_20180402_2334.py +++ b/src/teams/migrations/0034_auto_20180402_2334.py @@ -7,13 +7,10 @@ from django.db import migrations class Migration(migrations.Migration): - dependencies = [ - ('teams', '0033_auto_20180402_2204'), - ] + dependencies = [("teams", "0033_auto_20180402_2204")] operations = [ migrations.AlterModelOptions( - name='teammember', - options={'ordering': ['-responsible', 'approved']}, - ), + name="teammember", options={"ordering": ["-responsible", "approved"]} + ) ] diff --git a/src/teams/migrations/0035_auto_20180402_2344.py b/src/teams/migrations/0035_auto_20180402_2344.py index 78ea2a64..9749cd94 100644 --- a/src/teams/migrations/0035_auto_20180402_2344.py +++ b/src/teams/migrations/0035_auto_20180402_2344.py @@ -7,13 +7,10 @@ from django.db import migrations class Migration(migrations.Migration): - dependencies = [ - ('teams', '0034_auto_20180402_2334'), - ] + dependencies = [("teams", "0034_auto_20180402_2334")] operations = [ migrations.AlterModelOptions( - name='teammember', - options={'ordering': ['-responsible', '-approved']}, - ), + name="teammember", options={"ordering": ["-responsible", "-approved"]} + ) ] diff --git a/src/teams/migrations/0036_auto_20180403_0201.py b/src/teams/migrations/0036_auto_20180403_0201.py index ad6bede4..acd2d8db 100644 --- a/src/teams/migrations/0036_auto_20180403_0201.py +++ b/src/teams/migrations/0036_auto_20180403_0201.py @@ -8,13 +8,12 @@ from django.db import migrations class Migration(migrations.Migration): dependencies = [ - ('camps', '0025_auto_20180318_1250'), - ('teams', '0035_auto_20180402_2344'), + ("camps", "0025_auto_20180318_1250"), + ("teams", "0035_auto_20180402_2344"), ] operations = [ migrations.AlterUniqueTogether( - name='team', - unique_together=set([('slug', 'camp'), ('name', 'camp')]), - ), + name="team", unique_together=set([("slug", "camp"), ("name", "camp")]) + ) ] diff --git a/src/teams/migrations/0037_auto_20180408_1416.py b/src/teams/migrations/0037_auto_20180408_1416.py index 6f7f30c9..b65f06cd 100644 --- a/src/teams/migrations/0037_auto_20180408_1416.py +++ b/src/teams/migrations/0037_auto_20180408_1416.py @@ -9,34 +9,49 @@ import django.db.models.deletion class Migration(migrations.Migration): - dependencies = [ - ('teams', '0036_auto_20180403_0201'), - ] + dependencies = [("teams", "0036_auto_20180403_0201")] operations = [ migrations.AddField( - model_name='teammember', - name='irc_channel_acl_ok', - field=models.BooleanField(default=False, help_text='Maintained by the IRC bot, do not edit manually. True if the teammembers NickServ username has been added to the Team IRC channels ACL.'), + model_name="teammember", + name="irc_channel_acl_ok", + field=models.BooleanField( + default=False, + help_text="Maintained by the IRC bot, do not edit manually. True if the teammembers NickServ username has been added to the Team IRC channels ACL.", + ), ), migrations.AlterField( - model_name='teammember', - name='approved', - field=models.BooleanField(default=False, help_text='True if this membership is approved. False if not.'), + model_name="teammember", + name="approved", + field=models.BooleanField( + default=False, + help_text="True if this membership is approved. False if not.", + ), ), migrations.AlterField( - model_name='teammember', - name='responsible', - field=models.BooleanField(default=False, help_text='True if this teammember is responsible for this Team. False if not.'), + model_name="teammember", + name="responsible", + field=models.BooleanField( + default=False, + help_text="True if this teammember is responsible for this Team. False if not.", + ), ), migrations.AlterField( - model_name='teammember', - name='team', - field=models.ForeignKey(help_text='The Team this membership relates to', on_delete=django.db.models.deletion.PROTECT, to='teams.Team'), + model_name="teammember", + name="team", + field=models.ForeignKey( + help_text="The Team this membership relates to", + on_delete=django.db.models.deletion.PROTECT, + to="teams.Team", + ), ), migrations.AlterField( - model_name='teammember', - name='user', - field=models.ForeignKey(help_text='The User object this team membership relates to', on_delete=django.db.models.deletion.PROTECT, to=settings.AUTH_USER_MODEL), + model_name="teammember", + name="user", + field=models.ForeignKey( + help_text="The User object this team membership relates to", + on_delete=django.db.models.deletion.PROTECT, + to=settings.AUTH_USER_MODEL, + ), ), ] diff --git a/src/teams/migrations/0038_auto_20180412_1844.py b/src/teams/migrations/0038_auto_20180412_1844.py index 31a4c9ea..2d87f9f9 100644 --- a/src/teams/migrations/0038_auto_20180412_1844.py +++ b/src/teams/migrations/0038_auto_20180412_1844.py @@ -7,39 +7,61 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ - ('teams', '0037_auto_20180408_1416'), - ] + dependencies = [("teams", "0037_auto_20180408_1416")] operations = [ migrations.AddField( - model_name='team', - name='private_irc_channel_bot', - field=models.BooleanField(default=False, help_text='Check to make the bot join the teams private IRC channel. Leave unchecked to disable the IRC bot for this channel.'), + model_name="team", + name="private_irc_channel_bot", + field=models.BooleanField( + default=False, + help_text="Check to make the bot join the teams private IRC channel. Leave unchecked to disable the IRC bot for this channel.", + ), ), migrations.AddField( - model_name='team', - name='private_irc_channel_managed', - field=models.BooleanField(default=False, help_text='Check to make the bot manage the private IRC channel by registering it with NickServ, setting +I and maintaining the ACL.'), + model_name="team", + name="private_irc_channel_managed", + field=models.BooleanField( + default=False, + help_text="Check to make the bot manage the private IRC channel by registering it with NickServ, setting +I and maintaining the ACL.", + ), ), migrations.AddField( - model_name='team', - name='private_irc_channel_name', - field=models.CharField(blank=True, help_text='The private IRC channel for this team. Will be shown to team members on the team page. Leave empty if the team has no private IRC channel.', max_length=50, null=True, unique=True), + model_name="team", + name="private_irc_channel_name", + field=models.CharField( + blank=True, + help_text="The private IRC channel for this team. Will be shown to team members on the team page. Leave empty if the team has no private IRC channel.", + max_length=50, + null=True, + unique=True, + ), ), migrations.AddField( - model_name='team', - name='public_irc_channel_bot', - field=models.BooleanField(default=False, help_text='Check to make the bot join the teams public IRC channel. Leave unchecked to disable the IRC bot for this channel.'), + model_name="team", + name="public_irc_channel_bot", + field=models.BooleanField( + default=False, + help_text="Check to make the bot join the teams public IRC channel. Leave unchecked to disable the IRC bot for this channel.", + ), ), migrations.AddField( - model_name='team', - name='public_irc_channel_managed', - field=models.BooleanField(default=False, help_text='Check to make the bot manage the teams public IRC channel by registering it with NickServ.'), + model_name="team", + name="public_irc_channel_managed", + field=models.BooleanField( + default=False, + help_text="Check to make the bot manage the teams public IRC channel by registering it with NickServ.", + ), ), migrations.AddField( - model_name='team', - name='public_irc_channel_name', - field=models.CharField(blank=True, help_text='The public IRC channel for this team. Will be shown on the team page so people know how to reach the team. Leave empty if the team has no public IRC channel.', max_length=50, null=True, unique=True), + model_name="team", + name="public_irc_channel_name", + field=models.CharField( + blank=True, + help_text="The public IRC channel for this team. Will be shown on the team page so people know how to reach the team. Leave empty if the team has no public IRC channel.", + max_length=50, + null=True, + unique=True, + ), ), ] diff --git a/src/teams/migrations/0039_fix_irc_channels.py b/src/teams/migrations/0039_fix_irc_channels.py index cff67d54..adb7e1cd 100644 --- a/src/teams/migrations/0039_fix_irc_channels.py +++ b/src/teams/migrations/0039_fix_irc_channels.py @@ -4,30 +4,26 @@ from __future__ import unicode_literals from django.db import migrations + def fix_irc_channels(apps, schema_editor): - Team = apps.get_model('teams', 'Team') + Team = apps.get_model("teams", "Team") for team in Team.objects.filter(irc_channel=True): print("fixing irc channel for team %s" % team.name) if team.irc_channel_private: - team.private_irc_channel_name=team.irc_channel_name + team.private_irc_channel_name = team.irc_channel_name if team.irc_channel_managed: - team.private_irc_channel_managed=True - team.private_irc_channel_bot=True + team.private_irc_channel_managed = True + team.private_irc_channel_bot = True else: - team.public_irc_channel_name=team.irc_channel_name + team.public_irc_channel_name = team.irc_channel_name if team.irc_channel_managed: - team.public_irc_channel_managed=True - team.public_irc_channel_bot=True + team.public_irc_channel_managed = True + team.public_irc_channel_bot = True team.save() class Migration(migrations.Migration): - dependencies = [ - ('teams', '0038_auto_20180412_1844'), - ] - - operations = [ - migrations.RunPython(fix_irc_channels), - ] + dependencies = [("teams", "0038_auto_20180412_1844")] + operations = [migrations.RunPython(fix_irc_channels)] diff --git a/src/teams/migrations/0040_auto_20180412_2109.py b/src/teams/migrations/0040_auto_20180412_2109.py index dc0db141..6063e775 100644 --- a/src/teams/migrations/0040_auto_20180412_2109.py +++ b/src/teams/migrations/0040_auto_20180412_2109.py @@ -7,25 +7,11 @@ from django.db import migrations class Migration(migrations.Migration): - dependencies = [ - ('teams', '0039_fix_irc_channels'), - ] + dependencies = [("teams", "0039_fix_irc_channels")] operations = [ - migrations.RemoveField( - model_name='team', - name='irc_channel', - ), - migrations.RemoveField( - model_name='team', - name='irc_channel_managed', - ), - migrations.RemoveField( - model_name='team', - name='irc_channel_name', - ), - migrations.RemoveField( - model_name='team', - name='irc_channel_private', - ), + migrations.RemoveField(model_name="team", name="irc_channel"), + migrations.RemoveField(model_name="team", name="irc_channel_managed"), + migrations.RemoveField(model_name="team", name="irc_channel_name"), + migrations.RemoveField(model_name="team", name="irc_channel_private"), ] diff --git a/src/teams/migrations/0041_auto_20180412_2231.py b/src/teams/migrations/0041_auto_20180412_2231.py index 933f4868..3d59e67f 100644 --- a/src/teams/migrations/0041_auto_20180412_2231.py +++ b/src/teams/migrations/0041_auto_20180412_2231.py @@ -7,18 +7,16 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ - ('teams', '0040_auto_20180412_2109'), - ] + dependencies = [("teams", "0040_auto_20180412_2109")] operations = [ - migrations.RemoveField( - model_name='teammember', - name='irc_channel_acl_ok', - ), + migrations.RemoveField(model_name="teammember", name="irc_channel_acl_ok"), migrations.AddField( - model_name='teammember', - name='irc_acl_fix_needed', - field=models.BooleanField(default=False, help_text='Maintained by the IRC bot, manual editing should not be needed. Will be set to true when a teammember sets or changes NickServ username, and back to false after the ACL has been fixed by the bot.'), + model_name="teammember", + name="irc_acl_fix_needed", + field=models.BooleanField( + default=False, + help_text="Maintained by the IRC bot, manual editing should not be needed. Will be set to true when a teammember sets or changes NickServ username, and back to false after the ACL has been fixed by the bot.", + ), ), ] diff --git a/src/teams/migrations/0042_auto_20180413_1933.py b/src/teams/migrations/0042_auto_20180413_1933.py index 279fda50..0fc2626e 100644 --- a/src/teams/migrations/0042_auto_20180413_1933.py +++ b/src/teams/migrations/0042_auto_20180413_1933.py @@ -7,24 +7,31 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ - ('teams', '0041_auto_20180412_2231'), - ] + dependencies = [("teams", "0041_auto_20180412_2231")] operations = [ migrations.AddField( - model_name='team', - name='private_irc_channel_fix_needed', - field=models.BooleanField(default=False, help_text='Used to indicate to the IRC bot that this teams private IRC channel is in need of a permissions and ACL fix.'), + model_name="team", + name="private_irc_channel_fix_needed", + field=models.BooleanField( + default=False, + help_text="Used to indicate to the IRC bot that this teams private IRC channel is in need of a permissions and ACL fix.", + ), ), migrations.AddField( - model_name='team', - name='public_irc_channel_fix_needed', - field=models.BooleanField(default=False, help_text='Used to indicate to the IRC bot that this teams public IRC channel is in need of a permissions and ACL fix.'), + model_name="team", + name="public_irc_channel_fix_needed", + field=models.BooleanField( + default=False, + help_text="Used to indicate to the IRC bot that this teams public IRC channel is in need of a permissions and ACL fix.", + ), ), migrations.AlterField( - model_name='team', - name='public_irc_channel_managed', - field=models.BooleanField(default=False, help_text='Check to make the bot manage the teams public IRC channel by registering it with NickServ and setting +Oo for all teammembers.'), + model_name="team", + name="public_irc_channel_managed", + field=models.BooleanField( + default=False, + help_text="Check to make the bot manage the teams public IRC channel by registering it with NickServ and setting +Oo for all teammembers.", + ), ), ] diff --git a/src/teams/migrations/0043_auto_20180702_1338.py b/src/teams/migrations/0043_auto_20180702_1338.py index ad64e0dc..a0c3f352 100644 --- a/src/teams/migrations/0043_auto_20180702_1338.py +++ b/src/teams/migrations/0043_auto_20180702_1338.py @@ -7,37 +7,52 @@ import django.db.models.deletion class Migration(migrations.Migration): - dependencies = [ - ('teams', '0042_auto_20180413_1933'), - ] + dependencies = [("teams", "0042_auto_20180413_1933")] operations = [ migrations.CreateModel( - name='TeamShift', + name="TeamShift", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('created', models.DateTimeField(auto_now_add=True)), - ('updated', models.DateTimeField(auto_now=True)), - ('shift_range', django.contrib.postgres.fields.ranges.DateTimeRangeField()), - ('people_required', models.IntegerField(default=1)), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("created", models.DateTimeField(auto_now_add=True)), + ("updated", models.DateTimeField(auto_now=True)), + ( + "shift_range", + django.contrib.postgres.fields.ranges.DateTimeRangeField(), + ), + ("people_required", models.IntegerField(default=1)), ], - options={ - 'abstract': False, - }, + options={"abstract": False}, ), migrations.AddField( - model_name='team', - name='shifts_enabled', - field=models.BooleanField(default=False, help_text='Does this team have shifts? This enables defining shifts for this team.'), + model_name="team", + name="shifts_enabled", + field=models.BooleanField( + default=False, + help_text="Does this team have shifts? This enables defining shifts for this team.", + ), ), migrations.AddField( - model_name='teamshift', - name='team', - field=models.ForeignKey(help_text='The team this shift belongs to', on_delete=django.db.models.deletion.PROTECT, related_name='shifts', to='teams.Team'), + model_name="teamshift", + name="team", + field=models.ForeignKey( + help_text="The team this shift belongs to", + on_delete=django.db.models.deletion.PROTECT, + related_name="shifts", + to="teams.Team", + ), ), migrations.AddField( - model_name='teamshift', - name='team_members', - field=models.ManyToManyField(to='teams.TeamMember'), + model_name="teamshift", + name="team_members", + field=models.ManyToManyField(to="teams.TeamMember"), ), ] diff --git a/src/teams/migrations/0043_auto_20180804_1641.py b/src/teams/migrations/0043_auto_20180804_1641.py index e2460dc1..7b625f59 100644 --- a/src/teams/migrations/0043_auto_20180804_1641.py +++ b/src/teams/migrations/0043_auto_20180804_1641.py @@ -6,19 +6,23 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ - ('teams', '0042_auto_20180413_1933'), - ] + dependencies = [("teams", "0042_auto_20180413_1933")] operations = [ migrations.AddField( - model_name='teamtask', - name='completed', - field=models.BooleanField(default=False, help_text='Check to mark this task as completed.'), + model_name="teamtask", + name="completed", + field=models.BooleanField( + default=False, help_text="Check to mark this task as completed." + ), ), migrations.AddField( - model_name='teamtask', - name='when', - field=django.contrib.postgres.fields.ranges.DateTimeRangeField(blank=True, help_text='When does this task need to be started and/or finished?', null=True), + model_name="teamtask", + name="when", + field=django.contrib.postgres.fields.ranges.DateTimeRangeField( + blank=True, + help_text="When does this task need to be started and/or finished?", + null=True, + ), ), ] diff --git a/src/teams/migrations/0044_auto_20180702_1507.py b/src/teams/migrations/0044_auto_20180702_1507.py index cb19b4ac..2a4ff24d 100644 --- a/src/teams/migrations/0044_auto_20180702_1507.py +++ b/src/teams/migrations/0044_auto_20180702_1507.py @@ -5,14 +5,12 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ - ('teams', '0043_auto_20180702_1338'), - ] + dependencies = [("teams", "0043_auto_20180702_1338")] operations = [ migrations.AlterField( - model_name='teamshift', - name='team_members', - field=models.ManyToManyField(blank=True, to='teams.TeamMember'), - ), + model_name="teamshift", + name="team_members", + field=models.ManyToManyField(blank=True, to="teams.TeamMember"), + ) ] diff --git a/src/teams/migrations/0045_merge_20180805_1131.py b/src/teams/migrations/0045_merge_20180805_1131.py index 5eb121ee..6008c813 100644 --- a/src/teams/migrations/0045_merge_20180805_1131.py +++ b/src/teams/migrations/0045_merge_20180805_1131.py @@ -6,9 +6,8 @@ from django.db import migrations class Migration(migrations.Migration): dependencies = [ - ('teams', '0044_auto_20180702_1507'), - ('teams', '0043_auto_20180804_1641'), + ("teams", "0044_auto_20180702_1507"), + ("teams", "0043_auto_20180804_1641"), ] - operations = [ - ] + operations = [] diff --git a/src/teams/migrations/0046_auto_20180808_2154.py b/src/teams/migrations/0046_auto_20180808_2154.py index 513ca22d..d33c5ec2 100644 --- a/src/teams/migrations/0046_auto_20180808_2154.py +++ b/src/teams/migrations/0046_auto_20180808_2154.py @@ -5,13 +5,10 @@ from django.db import migrations class Migration(migrations.Migration): - dependencies = [ - ('teams', '0045_merge_20180805_1131'), - ] + dependencies = [("teams", "0045_merge_20180805_1131")] operations = [ migrations.AlterModelOptions( - name='teamshift', - options={'ordering': ('shift_range',)}, - ), + name="teamshift", options={"ordering": ("shift_range",)} + ) ] diff --git a/src/teams/migrations/0047_taskcomment.py b/src/teams/migrations/0047_taskcomment.py index 3dc0eada..0150ea4a 100644 --- a/src/teams/migrations/0047_taskcomment.py +++ b/src/teams/migrations/0047_taskcomment.py @@ -7,23 +7,40 @@ import uuid class Migration(migrations.Migration): - dependencies = [ - ('teams', '0046_auto_20180808_2154'), - ] + dependencies = [("teams", "0046_auto_20180808_2154")] operations = [ migrations.CreateModel( - name='TaskComment', + name="TaskComment", fields=[ - ('uuid', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)), - ('created', models.DateTimeField(auto_now_add=True)), - ('updated', models.DateTimeField(auto_now=True)), - ('content', models.TextField()), - ('author', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='teams.TeamMember')), - ('task', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='comments', to='teams.TeamTask')), + ( + "uuid", + models.UUIDField( + default=uuid.uuid4, + editable=False, + primary_key=True, + serialize=False, + ), + ), + ("created", models.DateTimeField(auto_now_add=True)), + ("updated", models.DateTimeField(auto_now=True)), + ("content", models.TextField()), + ( + "author", + models.ForeignKey( + on_delete=django.db.models.deletion.PROTECT, + to="teams.TeamMember", + ), + ), + ( + "task", + models.ForeignKey( + on_delete=django.db.models.deletion.PROTECT, + related_name="comments", + to="teams.TeamTask", + ), + ), ], - options={ - 'abstract': False, - }, - ), + options={"abstract": False}, + ) ] diff --git a/src/teams/migrations/0048_auto_20180814_1950.py b/src/teams/migrations/0048_auto_20180814_1950.py index c59f9f8c..1ce7a054 100644 --- a/src/teams/migrations/0048_auto_20180814_1950.py +++ b/src/teams/migrations/0048_auto_20180814_1950.py @@ -5,14 +5,10 @@ from django.db import migrations class Migration(migrations.Migration): - dependencies = [ - ('teams', '0047_taskcomment'), - ] + dependencies = [("teams", "0047_taskcomment")] operations = [ migrations.RenameField( - model_name='taskcomment', - old_name='content', - new_name='comment', - ), + model_name="taskcomment", old_name="content", new_name="comment" + ) ] diff --git a/src/teams/migrations/0049_auto_20180815_1119.py b/src/teams/migrations/0049_auto_20180815_1119.py index 07325294..65af6291 100644 --- a/src/teams/migrations/0049_auto_20180815_1119.py +++ b/src/teams/migrations/0049_auto_20180815_1119.py @@ -5,13 +5,10 @@ from django.db import migrations class Migration(migrations.Migration): - dependencies = [ - ('teams', '0048_auto_20180814_1950'), - ] + dependencies = [("teams", "0048_auto_20180814_1950")] operations = [ migrations.AlterModelOptions( - name='teamtask', - options={'ordering': ['completed', 'when', 'name']}, - ), + name="teamtask", options={"ordering": ["completed", "when", "name"]} + ) ] diff --git a/src/teams/migrations/0050_team_guide.py b/src/teams/migrations/0050_team_guide.py index 59375bd5..1f1bc57a 100644 --- a/src/teams/migrations/0050_team_guide.py +++ b/src/teams/migrations/0050_team_guide.py @@ -5,14 +5,17 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ - ('teams', '0049_auto_20180815_1119'), - ] + dependencies = [("teams", "0049_auto_20180815_1119")] operations = [ migrations.AddField( - model_name='team', - name='guide', - field=models.TextField(blank=True, default='\n# Preparations\n\n...\n\n# Camp setup\n\n...\n\n# During camp\n\n...\n\n# Takedown\n\n...\n\n# Notes for next year\n\n 1. Remember to take notes\n 1. ...\n', help_text='HowTo guide for this year (and next year)', verbose_name='team guide (Markdown)'), - ), + model_name="team", + name="guide", + field=models.TextField( + blank=True, + default="\n# Preparations\n\n...\n\n# Camp setup\n\n...\n\n# During camp\n\n...\n\n# Takedown\n\n...\n\n# Notes for next year\n\n 1. Remember to take notes\n 1. ...\n", + help_text="HowTo guide for this year (and next year)", + verbose_name="team guide (Markdown)", + ), + ) ] diff --git a/src/teams/migrations/0051_auto_20190312_1129.py b/src/teams/migrations/0051_auto_20190312_1129.py index 1957c28b..b1257beb 100644 --- a/src/teams/migrations/0051_auto_20190312_1129.py +++ b/src/teams/migrations/0051_auto_20190312_1129.py @@ -5,14 +5,17 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ - ('teams', '0050_team_guide'), - ] + dependencies = [("teams", "0050_team_guide")] operations = [ migrations.AlterField( - model_name='team', - name='guide', - field=models.TextField(blank=True, default='\n## Preparations\n\n...\n\n## Camp setup\n\n...\n\n## During camp\n\n...\n\n## Takedown\n\n...\n\n## Notes for next year\n\n 1. Remember to take notes\n 1. ...\n', help_text='HowTo guide for this year (and next year)', verbose_name='team guide (Markdown)'), - ), + model_name="team", + name="guide", + field=models.TextField( + blank=True, + default="\n## Preparations\n\n...\n\n## Camp setup\n\n...\n\n## During camp\n\n...\n\n## Takedown\n\n...\n\n## Notes for next year\n\n 1. Remember to take notes\n 1. ...\n", + help_text="HowTo guide for this year (and next year)", + verbose_name="team guide (Markdown)", + ), + ) ] diff --git a/src/teams/models.py b/src/teams/models.py index cd68054d..4fc52147 100644 --- a/src/teams/models.py +++ b/src/teams/models.py @@ -14,7 +14,7 @@ from utils.models import CampRelatedModel, CreatedUpdatedModel, UUIDModel logger = logging.getLogger("bornhack.%s" % __name__) -TEAM_GUIDE_TEMPLATE=""" +TEAM_GUIDE_TEMPLATE = """ ## Preparations ... @@ -40,52 +40,41 @@ TEAM_GUIDE_TEMPLATE=""" class Team(CampRelatedModel): camp = models.ForeignKey( - 'camps.Camp', - related_name="teams", - on_delete=models.PROTECT, + "camps.Camp", related_name="teams", on_delete=models.PROTECT ) - name = models.CharField( - max_length=255, - help_text='The team name', - ) + name = models.CharField(max_length=255, help_text="The team name") slug = models.SlugField( max_length=255, blank=True, - help_text='Url slug for this team. Leave blank to generate based on team name', + help_text="Url slug for this team. Leave blank to generate based on team name", ) shortslug = models.SlugField( - help_text='Abbreviated version of the slug. Used in places like IRC channel names where space is limited', + help_text="Abbreviated version of the slug. Used in places like IRC channel names where space is limited" ) description = models.TextField() needs_members = models.BooleanField( - default=True, - help_text='Check to indicate that this team needs more members', + default=True, help_text="Check to indicate that this team needs more members" ) members = models.ManyToManyField( - 'auth.User', - related_name='teams', - through='teams.TeamMember' + "auth.User", related_name="teams", through="teams.TeamMember" ) # mailing list related fields - mailing_list = models.EmailField( - blank=True - ) + mailing_list = models.EmailField(blank=True) mailing_list_archive_public = models.BooleanField( - default=False, - help_text='Check if the mailing list archive is public' + default=False, help_text="Check if the mailing list archive is public" ) mailing_list_nonmember_posts = models.BooleanField( default=False, - help_text='Check if the mailinglist allows non-list-members to post' + help_text="Check if the mailinglist allows non-list-members to post", ) # IRC related fields @@ -94,19 +83,19 @@ class Team(CampRelatedModel): null=True, unique=True, max_length=50, - help_text='The public IRC channel for this team. Will be shown on the team page so people know how to reach the team. Leave empty if the team has no public IRC channel.' + help_text="The public IRC channel for this team. Will be shown on the team page so people know how to reach the team. Leave empty if the team has no public IRC channel.", ) public_irc_channel_bot = models.BooleanField( default=False, - help_text='Check to make the bot join the teams public IRC channel. Leave unchecked to disable the IRC bot for this channel.' + help_text="Check to make the bot join the teams public IRC channel. Leave unchecked to disable the IRC bot for this channel.", ) public_irc_channel_managed = models.BooleanField( default=False, - help_text='Check to make the bot manage the teams public IRC channel by registering it with NickServ and setting +Oo for all teammembers.' + help_text="Check to make the bot manage the teams public IRC channel by registering it with NickServ and setting +Oo for all teammembers.", ) public_irc_channel_fix_needed = models.BooleanField( default=False, - help_text='Used to indicate to the IRC bot that this teams public IRC channel is in need of a permissions and ACL fix.' + help_text="Used to indicate to the IRC bot that this teams public IRC channel is in need of a permissions and ACL fix.", ) private_irc_channel_name = models.CharField( @@ -114,29 +103,29 @@ class Team(CampRelatedModel): null=True, unique=True, max_length=50, - help_text='The private IRC channel for this team. Will be shown to team members on the team page. Leave empty if the team has no private IRC channel.' + help_text="The private IRC channel for this team. Will be shown to team members on the team page. Leave empty if the team has no private IRC channel.", ) private_irc_channel_bot = models.BooleanField( default=False, - help_text='Check to make the bot join the teams private IRC channel. Leave unchecked to disable the IRC bot for this channel.' + help_text="Check to make the bot join the teams private IRC channel. Leave unchecked to disable the IRC bot for this channel.", ) private_irc_channel_managed = models.BooleanField( default=False, - help_text='Check to make the bot manage the private IRC channel by registering it with NickServ, setting +I and maintaining the ACL.' + help_text="Check to make the bot manage the private IRC channel by registering it with NickServ, setting +I and maintaining the ACL.", ) private_irc_channel_fix_needed = models.BooleanField( default=False, - help_text='Used to indicate to the IRC bot that this teams private IRC channel is in need of a permissions and ACL fix.' + help_text="Used to indicate to the IRC bot that this teams private IRC channel is in need of a permissions and ACL fix.", ) shifts_enabled = models.BooleanField( default=False, - help_text="Does this team have shifts? This enables defining shifts for this team." + help_text="Does this team have shifts? This enables defining shifts for this team.", ) class Meta: - ordering = ['name'] - unique_together = (('name', 'camp'), ('slug', 'camp')) + ordering = ["name"] + unique_together = (("name", "camp"), ("slug", "camp")) guide = models.TextField( blank=True, @@ -146,10 +135,13 @@ class Team(CampRelatedModel): ) def __str__(self): - return '{} ({})'.format(self.name, self.camp) + return "{} ({})".format(self.name, self.camp) def get_absolute_url(self): - return reverse_lazy('teams:general', kwargs={'camp_slug': self.camp.slug, 'team_slug': self.slug}) + return reverse_lazy( + "teams:general", + kwargs={"camp_slug": self.camp.slug, "team_slug": self.slug}, + ) def save(self, **kwargs): # generate slug if needed @@ -173,20 +165,52 @@ class Team(CampRelatedModel): self.private_irc_channel_name = "#%s" % self.private_irc_channel_name # make sure the channel names are not reserved - if self.public_irc_channel_name == settings.IRCBOT_PUBLIC_CHANNEL or self.public_irc_channel_name == settings.IRCBOT_VOLUNTEER_CHANNEL: - raise ValidationError('The public IRC channel name is reserved') - if self.private_irc_channel_name == settings.IRCBOT_PUBLIC_CHANNEL or self.private_irc_channel_name == settings.IRCBOT_VOLUNTEER_CHANNEL: - raise ValidationError('The private IRC channel name is reserved') + if ( + self.public_irc_channel_name == settings.IRCBOT_PUBLIC_CHANNEL + or self.public_irc_channel_name == settings.IRCBOT_VOLUNTEER_CHANNEL + ): + raise ValidationError("The public IRC channel name is reserved") + if ( + self.private_irc_channel_name == settings.IRCBOT_PUBLIC_CHANNEL + or self.private_irc_channel_name == settings.IRCBOT_VOLUNTEER_CHANNEL + ): + raise ValidationError("The private IRC channel name is reserved") # make sure public_irc_channel_name is not in use as public or private irc channel for another team, case insensitive if self.public_irc_channel_name: - if Team.objects.filter(private_irc_channel_name__iexact=self.public_irc_channel_name).exclude(pk=self.pk).exists() or Team.objects.filter(public_irc_channel_name__iexact=self.public_irc_channel_name).exclude(pk=self.pk).exists(): - raise ValidationError('The public IRC channel name is already in use on another team!') + if ( + Team.objects.filter( + private_irc_channel_name__iexact=self.public_irc_channel_name + ) + .exclude(pk=self.pk) + .exists() + or Team.objects.filter( + public_irc_channel_name__iexact=self.public_irc_channel_name + ) + .exclude(pk=self.pk) + .exists() + ): + raise ValidationError( + "The public IRC channel name is already in use on another team!" + ) # make sure private_irc_channel_name is not in use as public or private irc channel for another team, case insensitive if self.private_irc_channel_name: - if Team.objects.filter(private_irc_channel_name__iexact=self.private_irc_channel_name).exclude(pk=self.pk).exists() or Team.objects.filter(public_irc_channel_name__iexact=self.private_irc_channel_name).exclude(pk=self.pk).exists(): - raise ValidationError('The private IRC channel name is already in use on another team!') + if ( + Team.objects.filter( + private_irc_channel_name__iexact=self.private_irc_channel_name + ) + .exclude(pk=self.pk) + .exists() + or Team.objects.filter( + public_irc_channel_name__iexact=self.private_irc_channel_name + ) + .exclude(pk=self.pk) + .exists() + ): + raise ValidationError( + "The private IRC channel name is already in use on another team!" + ) @property def memberships(self): @@ -195,27 +219,21 @@ class Team(CampRelatedModel): Use self.members.all() to get User objects for all members, or use self.memberships.all() to get TeamMember objects for all members. """ - return TeamMember.objects.filter( - team=self - ) + return TeamMember.objects.filter(team=self) @property def approved_members(self): """ Returns only approved members (returns User objects, not TeamMember objects) """ - return self.members.filter( - teammember__approved=True - ) + return self.members.filter(teammember__approved=True) @property def unapproved_members(self): """ Returns only unapproved members (returns User objects, not TeamMember objects) """ - return self.members.filter( - teammember__approved=False - ) + return self.members.filter(teammember__approved=False) @property def responsible_members(self): @@ -224,8 +242,7 @@ class Team(CampRelatedModel): Used to handle permissions for team management """ return self.members.filter( - teammember__approved=True, - teammember__responsible=True + teammember__approved=True, teammember__responsible=True ) @property @@ -236,8 +253,7 @@ class Team(CampRelatedModel): Used on the people pages. """ return self.members.filter( - teammember__approved=True, - teammember__responsible=False, + teammember__approved=True, teammember__responsible=False ) @property @@ -249,48 +265,47 @@ class Team(CampRelatedModel): return self.members.filter( teammember__approved=True, teammember__responsible=False, - profile__public_credit_name_approved=False + profile__public_credit_name_approved=False, ) class TeamMember(CampRelatedModel): user = models.ForeignKey( - 'auth.User', + "auth.User", on_delete=models.PROTECT, help_text="The User object this team membership relates to", ) team = models.ForeignKey( - 'teams.Team', + "teams.Team", on_delete=models.PROTECT, - help_text="The Team this membership relates to" + help_text="The Team this membership relates to", ) approved = models.BooleanField( - default=False, - help_text="True if this membership is approved. False if not." + default=False, help_text="True if this membership is approved. False if not." ) responsible = models.BooleanField( default=False, - help_text="True if this teammember is responsible for this Team. False if not." + help_text="True if this teammember is responsible for this Team. False if not.", ) irc_acl_fix_needed = models.BooleanField( default=False, - help_text='Maintained by the IRC bot, manual editing should not be needed. Will be set to true when a teammember sets or changes NickServ username, and back to false after the ACL has been fixed by the bot.', + help_text="Maintained by the IRC bot, manual editing should not be needed. Will be set to true when a teammember sets or changes NickServ username, and back to false after the ACL has been fixed by the bot.", ) class Meta: - ordering = ['-responsible', '-approved'] + ordering = ["-responsible", "-approved"] def __str__(self): - return '{} is {} {} member of team {}'.format( + return "{} is {} {} member of team {}".format( self.user, - '' if self.approved else 'an unapproved', - '' if not self.responsible else 'a responsible', - self.team + "" if self.approved else "an unapproved", + "" if not self.responsible else "a responsible", + self.team, ) @property @@ -298,51 +313,52 @@ class TeamMember(CampRelatedModel): """ All CampRelatedModels must have a camp FK or a camp property """ return self.team.camp - camp_filter = 'team__camp' + camp_filter = "team__camp" class TeamTask(CampRelatedModel): team = models.ForeignKey( - 'teams.Team', - related_name='tasks', + "teams.Team", + related_name="tasks", on_delete=models.PROTECT, - help_text='The team this task belongs to', - ) - name = models.CharField( - max_length=100, - help_text='Short name of this task', + help_text="The team this task belongs to", ) + name = models.CharField(max_length=100, help_text="Short name of this task") slug = models.SlugField( - max_length=255, - blank=True, - help_text='url slug, leave blank to autogenerate', + max_length=255, blank=True, help_text="url slug, leave blank to autogenerate" ) description = models.TextField( - help_text='Description of the task. Markdown is supported.' + help_text="Description of the task. Markdown is supported." ) when = DateTimeRangeField( blank=True, null=True, - help_text='When does this task need to be started and/or finished?' + help_text="When does this task need to be started and/or finished?", ) completed = models.BooleanField( - help_text='Check to mark this task as completed.', - default=False + help_text="Check to mark this task as completed.", default=False ) class Meta: - ordering = ['completed', 'when', 'name'] - unique_together = (('name', 'team'), ('slug', 'team')) + ordering = ["completed", "when", "name"] + unique_together = (("name", "team"), ("slug", "team")) def get_absolute_url(self): - return reverse_lazy('teams:task_detail', kwargs={'camp_slug': self.team.camp.slug, 'team_slug': self.team.slug, 'slug': self.slug}) + return reverse_lazy( + "teams:task_detail", + kwargs={ + "camp_slug": self.team.camp.slug, + "team_slug": self.team.slug, + "slug": self.slug, + }, + ) @property def camp(self): """ All CampRelatedModels must have a camp FK or a camp property """ return self.team.camp - camp_filter = 'team__camp' + camp_filter = "team__camp" def save(self, **kwargs): # generate slug if needed @@ -352,46 +368,40 @@ class TeamTask(CampRelatedModel): class TaskComment(UUIDModel, CreatedUpdatedModel): - task = models.ForeignKey('teams.TeamTask', on_delete=models.PROTECT, related_name="comments") - author = models.ForeignKey('teams.TeamMember', on_delete=models.PROTECT) + task = models.ForeignKey( + "teams.TeamTask", on_delete=models.PROTECT, related_name="comments" + ) + author = models.ForeignKey("teams.TeamMember", on_delete=models.PROTECT) comment = models.TextField() class TeamShift(CampRelatedModel): - class Meta: ordering = ("shift_range",) team = models.ForeignKey( - 'teams.Team', - related_name='shifts', + "teams.Team", + related_name="shifts", on_delete=models.PROTECT, - help_text='The team this shift belongs to', + help_text="The team this shift belongs to", ) shift_range = DateTimeRangeField() - team_members = models.ManyToManyField( - TeamMember, - blank=True, - ) + team_members = models.ManyToManyField(TeamMember, blank=True) - people_required = models.IntegerField( - default=1 - ) + people_required = models.IntegerField(default=1) @property def camp(self): """ All CampRelatedModels must have a camp FK or a camp property """ return self.team.camp - camp_filter = 'team__camp' + camp_filter = "team__camp" def __str__(self): return "{} team shift from {} to {}".format( - self.team.name, - self.shift_range.lower, - self.shift_range.upper + self.team.name, self.shift_range.lower, self.shift_range.upper ) @property diff --git a/src/teams/signal_handlers.py b/src/teams/signal_handlers.py index 1a0fa6a6..60c37d97 100644 --- a/src/teams/signal_handlers.py +++ b/src/teams/signal_handlers.py @@ -2,6 +2,7 @@ from .email import add_new_membership_email from ircbot.utils import add_irc_message from django.conf import settings import logging + logger = logging.getLogger("bornhack.%s" % __name__) @@ -13,18 +14,23 @@ def teammember_saved(sender, instance, created, **kwargs): if created and not instance.approved: # call the mail sending function if not add_new_membership_email(instance): - logger.error('Error adding email to outgoing queue') + logger.error("Error adding email to outgoing queue") def teammember_deleted(sender, instance, **kwargs): """ This signal handler is called whenever a TeamMember instance is deleted """ - if instance.team.private_irc_channel_name and instance.team.private_irc_channel_managed: + if ( + instance.team.private_irc_channel_name + and instance.team.private_irc_channel_managed + ): # TODO: remove user from private channel ACL pass - if instance.team.public_irc_channel_name and instance.team.public_irc_channel_managed: + if ( + instance.team.public_irc_channel_name + and instance.team.public_irc_channel_managed + ): # TODO: remove user from public channel ACL pass - diff --git a/src/teams/templatetags/teams_tags.py b/src/teams/templatetags/teams_tags.py index 78ba078b..ef0a313d 100644 --- a/src/teams/templatetags/teams_tags.py +++ b/src/teams/templatetags/teams_tags.py @@ -1,14 +1,13 @@ from django import template from teams.models import TeamMember from django.utils.safestring import mark_safe + register = template.Library() @register.filter def is_team_member(user, team): - return TeamMember.objects.filter( - team=team, user=user, approved=True - ).exists() + return TeamMember.objects.filter(team=team, user=user, approved=True).exists() @register.simple_tag diff --git a/src/teams/urls.py b/src/teams/urls.py index 55d13a36..3a89e738 100644 --- a/src/teams/urls.py +++ b/src/teams/urls.py @@ -40,182 +40,157 @@ from teams.views.shifts import ( UserShifts, ) -from teams.views.guide import ( - TeamGuideView, - TeamGuidePrintView -) +from teams.views.guide import TeamGuideView, TeamGuidePrintView -app_name = 'teams' +app_name = "teams" urlpatterns = [ + path("", TeamListView.as_view(), name="list"), + path("shifts", UserShifts.as_view(), name="user_shifts"), path( - '', - TeamListView.as_view(), - name='list' - ), - path( - 'shifts', - UserShifts.as_view(), - name='user_shifts' - ), - path( - '/', include([ - path( - '', - TeamGeneralView.as_view(), - name='general' - ), - path( - 'join/', - TeamJoinView.as_view(), - name='join' - ), - path( - 'leave/', - TeamLeaveView.as_view(), - name='leave' - ), - path( - 'manage/', - TeamManageView.as_view(), - name='manage' - ), - path( - 'guide/', - TeamGuideView.as_view(), - name='guide' - ), - path( - 'guide/print/', - TeamGuidePrintView.as_view(), - name='guide_print' - ), - path( - 'fix_irc_acl/', - FixIrcAclView.as_view(), - name='fix_irc_acl', - ), - path( - 'members/', include([ - path( - '', - TeamMembersView.as_view(), - name='members' - ), - path( - '/remove/', - TeamMemberRemoveView.as_view(), - name='member_remove', - ), - path( - '/approve/', - TeamMemberApproveView.as_view(), - name='member_approve', - ), - ]), - ), - path( - 'tasks/', include([ - path( - '', - TeamTasksView.as_view(), - name='tasks', - ), - path( - 'create/', - TaskCreateView.as_view(), - name='task_create', - ), - path( - '/', include([ - path( - '', - TaskDetailView.as_view(), - name='task_detail', - ), - path( - 'update/', - TaskUpdateView.as_view(), - name='task_update', - ), - ]), - ), - - ]), - ), - path( - 'info/', - include([ - path( - '', - InfoCategoriesListView.as_view(), - name='info_categories' - ), - path( - '/', include([ - path( - 'create/', - InfoItemCreateView.as_view(), - name='info_item_create', - ), - path( - '/', include([ - path( - 'update/', - InfoItemUpdateView.as_view(), - name='info_item_update', - ), - path( - 'delete/', - InfoItemDeleteView.as_view(), - name='info_item_delete', - ), - ]), - ), - ]) - ) - ]) - ), - path('shifts/', include([ + "/", + include( + [ + path("", TeamGeneralView.as_view(), name="general"), + path("join/", TeamJoinView.as_view(), name="join"), + path("leave/", TeamLeaveView.as_view(), name="leave"), + path("manage/", TeamManageView.as_view(), name="manage"), + path("guide/", TeamGuideView.as_view(), name="guide"), + path("guide/print/", TeamGuidePrintView.as_view(), name="guide_print"), + path("fix_irc_acl/", FixIrcAclView.as_view(), name="fix_irc_acl"), path( - '', - ShiftListView.as_view(), - name="shifts" + "members/", + include( + [ + path("", TeamMembersView.as_view(), name="members"), + path( + "/remove/", + TeamMemberRemoveView.as_view(), + name="member_remove", + ), + path( + "/approve/", + TeamMemberApproveView.as_view(), + name="member_approve", + ), + ] + ), ), path( - 'create/', - ShiftCreateView.as_view(), - name="shift_create" + "tasks/", + include( + [ + path("", TeamTasksView.as_view(), name="tasks"), + path( + "create/", TaskCreateView.as_view(), name="task_create" + ), + path( + "/", + include( + [ + path( + "", + TaskDetailView.as_view(), + name="task_detail", + ), + path( + "update/", + TaskUpdateView.as_view(), + name="task_update", + ), + ] + ), + ), + ] + ), ), path( - 'create_multiple/', - ShiftCreateMultipleView.as_view(), - name="shift_create_multiple" + "info/", + include( + [ + path( + "", + InfoCategoriesListView.as_view(), + name="info_categories", + ), + path( + "/", + include( + [ + path( + "create/", + InfoItemCreateView.as_view(), + name="info_item_create", + ), + path( + "/", + include( + [ + path( + "update/", + InfoItemUpdateView.as_view(), + name="info_item_update", + ), + path( + "delete/", + InfoItemDeleteView.as_view(), + name="info_item_delete", + ), + ] + ), + ), + ] + ), + ), + ] + ), ), - path('/', include([ - path( - '', - ShiftUpdateView.as_view(), - name="shift_update" + path( + "shifts/", + include( + [ + path("", ShiftListView.as_view(), name="shifts"), + path( + "create/", + ShiftCreateView.as_view(), + name="shift_create", + ), + path( + "create_multiple/", + ShiftCreateMultipleView.as_view(), + name="shift_create_multiple", + ), + path( + "/", + include( + [ + path( + "", + ShiftUpdateView.as_view(), + name="shift_update", + ), + path( + "delete", + ShiftDeleteView.as_view(), + name="shift_delete", + ), + path( + "take", + MemberTakesShift.as_view(), + name="shift_member_take", + ), + path( + "drop", + MemberDropsShift.as_view(), + name="shift_member_drop", + ), + ] + ), + ), + ] ), - path( - 'delete', - ShiftDeleteView.as_view(), - name="shift_delete" - ), - path( - 'take', - MemberTakesShift.as_view(), - name="shift_member_take" - ), - path( - 'drop', - MemberDropsShift.as_view(), - name="shift_member_drop" - ), - ])), - ])) - ]), + ), + ] + ), ), ] - diff --git a/src/teams/utils.py b/src/teams/utils.py index ecc9ddff..700acac5 100644 --- a/src/teams/utils.py +++ b/src/teams/utils.py @@ -1,5 +1,6 @@ from .models import Team + def get_team_from_irc_channel(channel): """ Returns a Team object given an IRC channel name, if possible @@ -15,4 +16,3 @@ def get_team_from_irc_channel(channel): return Team.objects.get(public_irc_channel_name=channel) except Team.DoesNotExist: return False - diff --git a/src/teams/views/base.py b/src/teams/views/base.py index cf52084b..1fa1f80d 100644 --- a/src/teams/views/base.py +++ b/src/teams/views/base.py @@ -11,46 +11,59 @@ from .mixins import EnsureTeamResponsibleMixin from ..models import Team, TeamMember import logging + logger = logging.getLogger("bornhack.%s" % __name__) class TeamListView(CampViewMixin, ListView): template_name = "team_list.html" model = Team - context_object_name = 'teams' + context_object_name = "teams" def get_context_data(self, *, object_list=None, **kwargs): context = super().get_context_data(object_list=object_list, **kwargs) if self.request.user.is_authenticated: - context['user_teams'] = self.request.user.teammember_set.filter(team__camp=self.camp) + context["user_teams"] = self.request.user.teammember_set.filter( + team__camp=self.camp + ) return context class TeamGeneralView(CampViewMixin, DetailView): template_name = "team_general.html" - context_object_name = 'team' + context_object_name = "team" model = Team - slug_url_kwarg = 'team_slug' - active_menu = 'general' + slug_url_kwarg = "team_slug" + active_menu = "general" def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) - context['IRCBOT_SERVER_HOSTNAME'] = settings.IRCBOT_SERVER_HOSTNAME - context['IRCBOT_PUBLIC_CHANNEL'] = settings.IRCBOT_PUBLIC_CHANNEL + context["IRCBOT_SERVER_HOSTNAME"] = settings.IRCBOT_SERVER_HOSTNAME + context["IRCBOT_PUBLIC_CHANNEL"] = settings.IRCBOT_PUBLIC_CHANNEL return context class TeamManageView(CampViewMixin, EnsureTeamResponsibleMixin, UpdateView): model = Team template_name = "team_manage.html" - fields = ['description', 'needs_members', 'public_irc_channel_name', - 'public_irc_channel_bot', 'public_irc_channel_managed', - 'private_irc_channel_name', 'private_irc_channel_bot', - 'private_irc_channel_managed', 'guide'] - slug_url_kwarg = 'team_slug' + fields = [ + "description", + "needs_members", + "public_irc_channel_name", + "public_irc_channel_bot", + "public_irc_channel_managed", + "private_irc_channel_name", + "private_irc_channel_bot", + "private_irc_channel_managed", + "guide", + ] + slug_url_kwarg = "team_slug" def get_success_url(self): - return reverse_lazy('teams:general', kwargs={'camp_slug': self.camp.slug, 'team_slug': self.get_object().slug}) + return reverse_lazy( + "teams:general", + kwargs={"camp_slug": self.camp.slug, "team_slug": self.get_object().slug}, + ) def form_valid(self, form): messages.success(self.request, "Team has been saved") @@ -61,29 +74,48 @@ class FixIrcAclView(LoginRequiredMixin, CampViewMixin, UpdateView): template_name = "fix_irc_acl.html" model = Team fields = [] - slug_url_kwarg = 'team_slug' + slug_url_kwarg = "team_slug" def dispatch(self, request, *args, **kwargs): # we need to call the super().dispatch() method early so self.camp gets populated by CampViewMixin, # because the lookups below depend on self.camp being set :) - response = super().dispatch( - request, *args, **kwargs - ) + response = super().dispatch(request, *args, **kwargs) # check if the logged in user has an approved membership of this team if request.user not in self.get_object().approved_members.all(): - messages.error(request, 'No thanks') - return redirect('teams:general', camp_slug=self.get_object().camp.slug, team_slug=self.get_object().slug) + messages.error(request, "No thanks") + return redirect( + "teams:general", + camp_slug=self.get_object().camp.slug, + team_slug=self.get_object().slug, + ) # check if we manage the channel for this team - if not self.get_object().irc_channel or not self.get_object().irc_channel_managed: - messages.error(request, 'IRC functionality is disabled for this team, or the team channel is not managed by the bot') - return redirect('teams:general', camp_slug=self.get_object().camp.slug, team_slug=self.get_object().slug) + if ( + not self.get_object().irc_channel + or not self.get_object().irc_channel_managed + ): + messages.error( + request, + "IRC functionality is disabled for this team, or the team channel is not managed by the bot", + ) + return redirect( + "teams:general", + camp_slug=self.get_object().camp.slug, + team_slug=self.get_object().slug, + ) # check if user has a nickserv username if not request.user.profile.nickserv_username: - messages.error(request, 'Please go to your profile and set your NickServ username first. Make sure the account is registered with NickServ first!') - return redirect('teams:general', camp_slug=self.get_object().camp.slug, team_slug=self.get_object().slug) + messages.error( + request, + "Please go to your profile and set your NickServ username first. Make sure the account is registered with NickServ first!", + ) + return redirect( + "teams:general", + camp_slug=self.get_object().camp.slug, + team_slug=self.get_object().slug, + ) return response @@ -94,28 +126,42 @@ class FixIrcAclView(LoginRequiredMixin, CampViewMixin, UpdateView): user=request.user, team=self.get_object(), approved=True, - irc_channel_acl_ok=True + irc_channel_acl_ok=True, ) except TeamMember.DoesNotExist: # this membership is already marked as membership.irc_channel_acl_ok=False, no need to do anything - messages.error(request, 'No need, this membership is already marked as irc_channel_acl_ok=False, so the bot will fix the ACL soon') - return redirect('teams:general', camp_slug=self.get_object().camp.slug, team_slug=self.get_object().slug) - - return super().get( - request, *args, **kwargs - ) + messages.error( + request, + "No need, this membership is already marked as irc_channel_acl_ok=False, so the bot will fix the ACL soon", + ) + return redirect( + "teams:general", + camp_slug=self.get_object().camp.slug, + team_slug=self.get_object().slug, + ) + return super().get(request, *args, **kwargs) def form_valid(self, form): membership = TeamMember.objects.get( user=self.request.user, team=self.get_object(), approved=True, - irc_channel_acl_ok=True + irc_channel_acl_ok=True, ) membership.irc_channel_acl_ok = False membership.save() - messages.success(self.request, "OK, hang on while we fix the permissions for your NickServ user '%s' for IRC channel '%s'" % (self.request.user.profile.nickserv_username, form.instance.irc_channel_name)) - return redirect('teams:general', camp_slug=form.instance.camp.slug, team_slug=form.instance.slug) - + messages.success( + self.request, + "OK, hang on while we fix the permissions for your NickServ user '%s' for IRC channel '%s'" + % ( + self.request.user.profile.nickserv_username, + form.instance.irc_channel_name, + ), + ) + return redirect( + "teams:general", + camp_slug=form.instance.camp.slug, + team_slug=form.instance.slug, + ) diff --git a/src/teams/views/guide.py b/src/teams/views/guide.py index 07fdc916..0bcc8a2a 100644 --- a/src/teams/views/guide.py +++ b/src/teams/views/guide.py @@ -8,21 +8,16 @@ from ..models import Team class TeamGuideView(LoginRequiredMixin, CampViewMixin, DetailView): template_name = "team_guide.html" - context_object_name = 'team' + context_object_name = "team" model = Team - slug_url_kwarg = 'team_slug' - active_menu = 'guide' + slug_url_kwarg = "team_slug" + active_menu = "guide" def get_queryset(self): qs = CampViewMixin.get_queryset(self) - qs.filter( - teammember__approved=True, - teammember__user=self.request.user, - ) + qs.filter(teammember__approved=True, teammember__user=self.request.user) return qs class TeamGuidePrintView(TeamGuideView): template_name = "team_guide_print.html" - - diff --git a/src/teams/views/info.py b/src/teams/views/info.py index a8bc8e1d..28defeb1 100644 --- a/src/teams/views/info.py +++ b/src/teams/views/info.py @@ -9,35 +9,47 @@ from ..models import Team from .mixins import EnsureTeamResponsibleMixin, TeamViewMixin -class InfoCategoriesListView(LoginRequiredMixin, CampViewMixin, TeamViewMixin, EnsureTeamResponsibleMixin, ListView): +class InfoCategoriesListView( + LoginRequiredMixin, + CampViewMixin, + TeamViewMixin, + EnsureTeamResponsibleMixin, + ListView, +): model = InfoCategory template_name = "team_info_categories.html" - slug_field = 'anchor' - active_menu = 'info_categories' + slug_field = "anchor" + active_menu = "info_categories" def get_team(self): return Team.objects.get( - camp__slug=self.kwargs['camp_slug'], - slug=self.kwargs['team_slug'] + camp__slug=self.kwargs["camp_slug"], slug=self.kwargs["team_slug"] ) -class InfoItemCreateView(LoginRequiredMixin, CampViewMixin, TeamViewMixin, EnsureTeamResponsibleMixin, CreateView): +class InfoItemCreateView( + LoginRequiredMixin, + CampViewMixin, + TeamViewMixin, + EnsureTeamResponsibleMixin, + CreateView, +): model = InfoItem template_name = "team_info_item_form.html" - fields = ['headline', 'body', 'anchor', 'weight'] - slug_field = 'anchor' - active_menu = 'info_categories' + fields = ["headline", "body", "anchor", "weight"] + slug_field = "anchor" + active_menu = "info_categories" def get_team(self): return Team.objects.get( - camp__slug=self.kwargs['camp_slug'], - slug=self.kwargs['team_slug'] + camp__slug=self.kwargs["camp_slug"], slug=self.kwargs["team_slug"] ) def form_valid(self, form): info_item = form.save(commit=False) - category = InfoCategory.objects.get(team__camp=self.camp, anchor=self.kwargs.get('category_anchor')) + category = InfoCategory.objects.get( + team__camp=self.camp, anchor=self.kwargs.get("category_anchor") + ) info_item.category = category info_item.save() return HttpResponseRedirect(self.get_success_url()) @@ -47,49 +59,61 @@ class InfoItemCreateView(LoginRequiredMixin, CampViewMixin, TeamViewMixin, Ensur def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) - context['category'] = InfoCategory.objects.get( - team__camp__slug=self.kwargs['camp_slug'], - anchor=self.kwargs['category_anchor'] + context["category"] = InfoCategory.objects.get( + team__camp__slug=self.kwargs["camp_slug"], + anchor=self.kwargs["category_anchor"], ) return context -class InfoItemUpdateView(LoginRequiredMixin, CampViewMixin, TeamViewMixin, EnsureTeamResponsibleMixin, RevisionMixin, UpdateView): +class InfoItemUpdateView( + LoginRequiredMixin, + CampViewMixin, + TeamViewMixin, + EnsureTeamResponsibleMixin, + RevisionMixin, + UpdateView, +): model = InfoItem template_name = "team_info_item_form.html" - fields = ['headline', 'body', 'anchor', 'weight'] - slug_field = 'anchor' - slug_url_kwarg = 'item_anchor' - active_menu = 'info_categories' + fields = ["headline", "body", "anchor", "weight"] + slug_field = "anchor" + slug_url_kwarg = "item_anchor" + active_menu = "info_categories" def get_team(self): return Team.objects.get( - camp__slug=self.kwargs['camp_slug'], - slug=self.kwargs['team_slug'] + camp__slug=self.kwargs["camp_slug"], slug=self.kwargs["team_slug"] ) def get_success_url(self): - next = self.request.GET.get('next') + next = self.request.GET.get("next") if next: return next return self.team.get_absolute_url() -class InfoItemDeleteView(LoginRequiredMixin, CampViewMixin, TeamViewMixin, EnsureTeamResponsibleMixin, RevisionMixin, DeleteView): +class InfoItemDeleteView( + LoginRequiredMixin, + CampViewMixin, + TeamViewMixin, + EnsureTeamResponsibleMixin, + RevisionMixin, + DeleteView, +): model = InfoItem template_name = "team_info_item_delete_confirm.html" - slug_field = 'anchor' - slug_url_kwarg = 'item_anchor' - active_menu = 'info_categories' + slug_field = "anchor" + slug_url_kwarg = "item_anchor" + active_menu = "info_categories" def get_team(self): return Team.objects.get( - camp__slug=self.kwargs['camp_slug'], - slug=self.kwargs['team_slug'] + camp__slug=self.kwargs["camp_slug"], slug=self.kwargs["team_slug"] ) def get_success_url(self): - next = self.request.GET.get('next') + next = self.request.GET.get("next") if next: return next return self.team.get_absolute_url() diff --git a/src/teams/views/members.py b/src/teams/views/members.py index 8d050504..f5864c0b 100644 --- a/src/teams/views/members.py +++ b/src/teams/views/members.py @@ -17,86 +17,114 @@ logger = logging.getLogger("bornhack.%s" % __name__) class TeamMembersView(CampViewMixin, DetailView): template_name = "team_members.html" - context_object_name = 'team' + context_object_name = "team" model = Team - slug_url_kwarg = 'team_slug' - active_menu = 'members' + slug_url_kwarg = "team_slug" + active_menu = "members" class TeamJoinView(LoginRequiredMixin, CampViewMixin, UpdateView): template_name = "team_join.html" model = Team fields = [] - slug_url_kwarg = 'team_slug' - active_menu = 'members' + slug_url_kwarg = "team_slug" + active_menu = "members" def get(self, request, *args, **kwargs): if not Profile.objects.get(user=request.user).description: messages.warning( request, - "Please fill the description in your profile before joining a team" + "Please fill the description in your profile before joining a team", ) - return redirect('teams:list', camp_slug=self.camp.slug) + return redirect("teams:list", camp_slug=self.camp.slug) if request.user in self.get_object().members.all(): messages.warning(request, "You are already a member of this team") - return redirect('teams:list', camp_slug=self.camp.slug) + return redirect("teams:list", camp_slug=self.camp.slug) if not self.get_object().needs_members: messages.warning(request, "This team does not need members right now") - return redirect('teams:list', camp_slug=self.get_object().camp.slug) + return redirect("teams:list", camp_slug=self.get_object().camp.slug) return super().get(request, *args, **kwargs) def form_valid(self, form): TeamMember.objects.create(team=self.get_object(), user=self.request.user) - messages.success(self.request, "You request to join the team %s has been registered, thank you." % self.get_object().name) - return redirect('teams:list', camp_slug=self.get_object().camp.slug) + messages.success( + self.request, + "You request to join the team %s has been registered, thank you." + % self.get_object().name, + ) + return redirect("teams:list", camp_slug=self.get_object().camp.slug) class TeamLeaveView(LoginRequiredMixin, CampViewMixin, UpdateView): template_name = "team_leave.html" model = Team fields = [] - slug_url_kwarg = 'team_slug' - active_menu = 'members' + slug_url_kwarg = "team_slug" + active_menu = "members" def get(self, request, *args, **kwargs): if request.user not in self.get_object().members.all(): messages.warning(request, "You are not a member of this team") - return redirect('teams:list', camp_slug=self.get_object().camp.slug) + return redirect("teams:list", camp_slug=self.get_object().camp.slug) return super().get(request, *args, **kwargs) def form_valid(self, form): - TeamMember.objects.filter(team=self.get_object(), user=self.request.user).delete() - messages.success(self.request, "You are no longer a member of the team %s" % self.get_object().name) - return redirect('teams:list', camp_slug=self.get_object().camp.slug) + TeamMember.objects.filter( + team=self.get_object(), user=self.request.user + ).delete() + messages.success( + self.request, + "You are no longer a member of the team %s" % self.get_object().name, + ) + return redirect("teams:list", camp_slug=self.get_object().camp.slug) -class TeamMemberRemoveView(LoginRequiredMixin, CampViewMixin, TeamViewMixin, EnsureTeamMemberResponsibleMixin, UpdateView): +class TeamMemberRemoveView( + LoginRequiredMixin, + CampViewMixin, + TeamViewMixin, + EnsureTeamMemberResponsibleMixin, + UpdateView, +): template_name = "teammember_remove.html" model = TeamMember fields = [] - active_menu = 'members' + active_menu = "members" def form_valid(self, form): form.instance.delete() if add_removed_membership_email(form.instance): messages.success(self.request, "Team member removed") else: - messages.success(self.request, "Team member removed (unable to add email to outgoing queue).") - logger.error( - 'Unable to add removed email to outgoing queue for teammember: {}'.format(form.instance) + messages.success( + self.request, + "Team member removed (unable to add email to outgoing queue).", ) - return redirect('teams:general', camp_slug=self.camp.slug, team_slug=form.instance.team.slug) + logger.error( + "Unable to add removed email to outgoing queue for teammember: {}".format( + form.instance + ) + ) + return redirect( + "teams:general", camp_slug=self.camp.slug, team_slug=form.instance.team.slug + ) -class TeamMemberApproveView(LoginRequiredMixin, CampViewMixin, TeamViewMixin, EnsureTeamMemberResponsibleMixin, UpdateView): +class TeamMemberApproveView( + LoginRequiredMixin, + CampViewMixin, + TeamViewMixin, + EnsureTeamMemberResponsibleMixin, + UpdateView, +): template_name = "teammember_approve.html" model = TeamMember fields = [] - active_menu = 'members' + active_menu = "members" def form_valid(self, form): form.instance.approved = True @@ -104,8 +132,15 @@ class TeamMemberApproveView(LoginRequiredMixin, CampViewMixin, TeamViewMixin, En if add_added_membership_email(form.instance): messages.success(self.request, "Team member approved") else: - messages.success(self.request, "Team member removed (unable to add email to outgoing queue).") - logger.error( - 'Unable to add approved email to outgoing queue for teammember: {}'.format(form.instance) + messages.success( + self.request, + "Team member removed (unable to add email to outgoing queue).", ) - return redirect('teams:general', camp_slug=self.camp.slug, team_slug=form.instance.team.slug) + logger.error( + "Unable to add approved email to outgoing queue for teammember: {}".format( + form.instance + ) + ) + return redirect( + "teams:general", camp_slug=self.camp.slug, team_slug=form.instance.team.slug + ) diff --git a/src/teams/views/mixins.py b/src/teams/views/mixins.py index 34608b0e..53a35f08 100644 --- a/src/teams/views/mixins.py +++ b/src/teams/views/mixins.py @@ -9,39 +9,42 @@ class EnsureTeamResponsibleMixin(object): """ Use to make sure request.user is responsible for the team specified by kwargs['team_slug'] """ - def dispatch(self, request, *args, **kwargs): - self.team = Team.objects.get(slug=kwargs['team_slug'], camp=self.camp) - if request.user not in self.team.responsible_members.all(): - messages.error(request, 'No thanks') - return redirect('teams:general', camp_slug=self.camp.slug, team_slug=self.team.slug) - return super().dispatch( - request, *args, **kwargs - ) + def dispatch(self, request, *args, **kwargs): + self.team = Team.objects.get(slug=kwargs["team_slug"], camp=self.camp) + if request.user not in self.team.responsible_members.all(): + messages.error(request, "No thanks") + return redirect( + "teams:general", camp_slug=self.camp.slug, team_slug=self.team.slug + ) + + return super().dispatch(request, *args, **kwargs) class EnsureTeamMemberResponsibleMixin(SingleObjectMixin): """ Use to make sure request.user is responsible for the team which TeamMember belongs to """ + model = TeamMember def dispatch(self, request, *args, **kwargs): if request.user not in self.get_object().team.responsible_members.all(): - messages.error(request, 'No thanks') - return redirect('teams:general', camp_slug=self.get_object().team.camp.slug, team_slug=self.get_object().team.slug) + messages.error(request, "No thanks") + return redirect( + "teams:general", + camp_slug=self.get_object().team.camp.slug, + team_slug=self.get_object().team.slug, + ) - return super().dispatch( - request, *args, **kwargs - ) + return super().dispatch(request, *args, **kwargs) class TeamViewMixin: - def get_team(self): return self.get_object().team def get_context_data(self, *args, **kwargs): context = super().get_context_data(**kwargs) - context['team'] = self.get_team() + context["team"] = self.get_team() return context diff --git a/src/teams/views/shifts.py b/src/teams/views/shifts.py index 9b218dc7..af46ac48 100644 --- a/src/teams/views/shifts.py +++ b/src/teams/views/shifts.py @@ -9,7 +9,7 @@ from django.views.generic import ( ListView, FormView, DeleteView, - TemplateView + TemplateView, ) from django import forms from django.utils import timezone @@ -19,11 +19,7 @@ from psycopg2.extras import DateTimeTZRange from camps.mixins import CampViewMixin -from ..models import ( - Team, - TeamMember, - TeamShift, -) +from ..models import Team, TeamMember, TeamShift class ShiftListView(LoginRequiredMixin, CampViewMixin, ListView): @@ -34,13 +30,12 @@ class ShiftListView(LoginRequiredMixin, CampViewMixin, ListView): def get_queryset(self): queryset = super().get_queryset() - return queryset.filter(team__slug=self.kwargs['team_slug']) + return queryset.filter(team__slug=self.kwargs["team_slug"]) def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) - context['team'] = Team.objects.get( - camp=self.camp, - slug=self.kwargs['team_slug'] + context["team"] = Team.objects.get( + camp=self.camp, slug=self.kwargs["team_slug"] ) return context @@ -61,8 +56,7 @@ def date_choices(camp): for hour in range(0, 24): for minute in minute_choices: time_label = "{hour:02d}:{minutes:02d}".format( - hour=hour, - minutes=minute + hour=hour, minutes=minute ) choice_value = "{} {}".format(date, time_label) time_choices.append((choice_value, choice_value)) @@ -73,10 +67,7 @@ def date_choices(camp): current_date = camp.buildup.lower.date() while current_date != camp.teardown.upper.date(): choices.append( - ( - current_date, - get_time_choices(current_date.strftime("%Y-%m-%d")) - ) + (current_date, get_time_choices(current_date.strftime("%Y-%m-%d"))) ) current_date += timezone.timedelta(days=1) return choices @@ -85,46 +76,40 @@ def date_choices(camp): class ShiftForm(forms.ModelForm): class Meta: model = TeamShift - fields = [ - 'from_datetime', - 'to_datetime', - 'people_required' - ] + fields = ["from_datetime", "to_datetime", "people_required"] def __init__(self, instance=None, **kwargs): - camp = kwargs.pop('camp') + camp = kwargs.pop("camp") super().__init__(instance=instance, **kwargs) - self.fields['from_datetime'].widget = forms.Select(choices=date_choices(camp)) - self.fields['to_datetime'].widget = forms.Select(choices=date_choices(camp)) + self.fields["from_datetime"].widget = forms.Select(choices=date_choices(camp)) + self.fields["to_datetime"].widget = forms.Select(choices=date_choices(camp)) if instance: current_tz = timezone.get_current_timezone() - lower = instance.shift_range.lower.astimezone(current_tz).strftime("%Y-%m-%d %H:%M") - upper = instance.shift_range.upper.astimezone(current_tz).strftime("%Y-%m-%d %H:%M") - self.fields['from_datetime'].initial = lower - self.fields['to_datetime'].initial = upper + lower = instance.shift_range.lower.astimezone(current_tz).strftime( + "%Y-%m-%d %H:%M" + ) + upper = instance.shift_range.upper.astimezone(current_tz).strftime( + "%Y-%m-%d %H:%M" + ) + self.fields["from_datetime"].initial = lower + self.fields["to_datetime"].initial = upper from_datetime = forms.DateTimeField() to_datetime = forms.DateTimeField() def _get_from_datetime(self): current_timezone = timezone.get_current_timezone() - return ( - self.cleaned_data['from_datetime'] - .astimezone(current_timezone) - ) + return self.cleaned_data["from_datetime"].astimezone(current_timezone) def _get_to_datetime(self): current_timezone = timezone.get_current_timezone() - return ( - self.cleaned_data['to_datetime'] - .astimezone(current_timezone) - ) + return self.cleaned_data["to_datetime"].astimezone(current_timezone) def clean(self): self.lower = self._get_from_datetime() self.upper = self._get_to_datetime() if self.lower > self.upper: - raise forms.ValidationError('Start can not be after end.') + raise forms.ValidationError("Start can not be after end.") def save(self, commit=True): # self has .lower and .upper from .clean() @@ -140,28 +125,21 @@ class ShiftCreateView(LoginRequiredMixin, CampViewMixin, CreateView): def get_form_kwargs(self): kwargs = super().get_form_kwargs() - kwargs['camp'] = self.camp + kwargs["camp"] = self.camp return kwargs def form_valid(self, form): shift = form.save(commit=False) - shift.team = Team.objects.get( - camp=self.camp, - slug=self.kwargs['team_slug'] - ) + shift.team = Team.objects.get(camp=self.camp, slug=self.kwargs["team_slug"]) return super().form_valid(form) def get_success_url(self): - return reverse( - 'teams:shifts', - kwargs=self.kwargs - ) + return reverse("teams:shifts", kwargs=self.kwargs) def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) - context['team'] = Team.objects.get( - camp=self.camp, - slug=self.kwargs['team_slug'] + context["team"] = Team.objects.get( + camp=self.camp, slug=self.kwargs["team_slug"] ) return context @@ -174,19 +152,16 @@ class ShiftUpdateView(LoginRequiredMixin, CampViewMixin, UpdateView): def get_form_kwargs(self): kwargs = super().get_form_kwargs() - kwargs['camp'] = self.camp + kwargs["camp"] = self.camp return kwargs def get_success_url(self): - self.kwargs.pop('pk') - return reverse( - 'teams:shifts', - kwargs=self.kwargs - ) + self.kwargs.pop("pk") + return reverse("teams:shifts", kwargs=self.kwargs) def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) - context['team'] = self.object.team + context["team"] = self.object.team return context @@ -197,32 +172,25 @@ class ShiftDeleteView(LoginRequiredMixin, CampViewMixin, DeleteView): def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) - context['team'] = Team.objects.get( - camp=self.camp, - slug=self.kwargs['team_slug'] + context["team"] = Team.objects.get( + camp=self.camp, slug=self.kwargs["team_slug"] ) return context def get_success_url(self): - self.kwargs.pop('pk') - return reverse( - 'teams:shifts', - kwargs=self.kwargs - ) + self.kwargs.pop("pk") + return reverse("teams:shifts", kwargs=self.kwargs) class MultipleShiftForm(forms.Form): - def __init__(self, instance=None, **kwargs): - camp = kwargs.pop('camp') + camp = kwargs.pop("camp") super().__init__(**kwargs) - self.fields['from_datetime'].widget = forms.Select(choices=date_choices(camp)) + self.fields["from_datetime"].widget = forms.Select(choices=date_choices(camp)) from_datetime = forms.DateTimeField() - number_of_shifts = forms.IntegerField( - help_text="How many shifts?" - ) + number_of_shifts = forms.IntegerField(help_text="How many shifts?") shift_length = forms.IntegerField( help_text="How long should a shift be in minutes?" @@ -238,23 +206,17 @@ class ShiftCreateMultipleView(LoginRequiredMixin, CampViewMixin, FormView): def get_form_kwargs(self): kwargs = super().get_form_kwargs() - kwargs['camp'] = self.camp + kwargs["camp"] = self.camp return kwargs def form_valid(self, form): - team = Team.objects.get( - camp=self.camp, - slug=self.kwargs['team_slug'] - ) + team = Team.objects.get(camp=self.camp, slug=self.kwargs["team_slug"]) current_timezone = timezone.get_current_timezone() - start_datetime = ( - form.cleaned_data['from_datetime'] - .astimezone(current_timezone) - ) - number_of_shifts = form.cleaned_data['number_of_shifts'] - shift_length = form.cleaned_data['shift_length'] - people_required = form.cleaned_data['people_required'] + start_datetime = form.cleaned_data["from_datetime"].astimezone(current_timezone) + number_of_shifts = form.cleaned_data["number_of_shifts"] + shift_length = form.cleaned_data["shift_length"] + people_required = form.cleaned_data["people_required"] shifts = [] for index in range(number_of_shifts): @@ -262,11 +224,11 @@ class ShiftCreateMultipleView(LoginRequiredMixin, CampViewMixin, FormView): start_datetime, start_datetime + timezone.timedelta(minutes=shift_length), ) - shifts.append(TeamShift( - team=team, - people_required=people_required, - shift_range=shift_range - )) + shifts.append( + TeamShift( + team=team, people_required=people_required, shift_range=shift_range + ) + ) start_datetime += timezone.timedelta(minutes=shift_length) TeamShift.objects.bulk_create(shifts) @@ -274,96 +236,78 @@ class ShiftCreateMultipleView(LoginRequiredMixin, CampViewMixin, FormView): return super().form_valid(form) def get_success_url(self): - return reverse( - 'teams:shifts', - kwargs=self.kwargs - ) + return reverse("teams:shifts", kwargs=self.kwargs) def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) - context['team'] = Team.objects.get( - camp=self.camp, - slug=self.kwargs['team_slug'] + context["team"] = Team.objects.get( + camp=self.camp, slug=self.kwargs["team_slug"] ) return context class MemberTakesShift(LoginRequiredMixin, CampViewMixin, View): - http_methods = ['get'] + http_methods = ["get"] def get(self, request, **kwargs): - shift = TeamShift.objects.get(id=kwargs['pk']) - team = Team.objects.get( - camp=self.camp, - slug=kwargs['team_slug'] - ) + shift = TeamShift.objects.get(id=kwargs["pk"]) + team = Team.objects.get(camp=self.camp, slug=kwargs["team_slug"]) team_member = TeamMember.objects.get(team=team, user=request.user) overlapping_shifts = TeamShift.objects.filter( team__camp=self.camp, team_members__user=request.user, - shift_range__overlap=shift.shift_range + shift_range__overlap=shift.shift_range, ) if overlapping_shifts.exists(): - template = Template("""You have shifts overlapping with the one you are trying to assign:
    + template = Template( + """You have shifts overlapping with the one you are trying to assign:
      {% for shift in shifts %}
    • {{ shift }}
    • {% endfor %}
    - """) + """ + ) messages.error( - request, - template.render(Context({"shifts": overlapping_shifts})) + request, template.render(Context({"shifts": overlapping_shifts})) ) else: shift.team_members.add(team_member) - kwargs.pop('pk') + kwargs.pop("pk") - return HttpResponseRedirect( - reverse( - 'teams:shifts', - kwargs=kwargs - ) - ) + return HttpResponseRedirect(reverse("teams:shifts", kwargs=kwargs)) class MemberDropsShift(LoginRequiredMixin, CampViewMixin, View): - http_methods = ['get'] + http_methods = ["get"] def get(self, request, **kwargs): - shift = TeamShift.objects.get(id=kwargs['pk']) - team = Team.objects.get( - camp=self.camp, - slug=kwargs['team_slug'] - ) + shift = TeamShift.objects.get(id=kwargs["pk"]) + team = Team.objects.get(camp=self.camp, slug=kwargs["team_slug"]) team_member = TeamMember.objects.get(team=team, user=request.user) shift.team_members.remove(team_member) - kwargs.pop('pk') + kwargs.pop("pk") - return HttpResponseRedirect( - reverse( - 'teams:shifts', - kwargs=kwargs - ) - ) + return HttpResponseRedirect(reverse("teams:shifts", kwargs=kwargs)) class UserShifts(CampViewMixin, TemplateView): - template_name = 'team_user_shifts.html' + template_name = "team_user_shifts.html" def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) - context['user_teams'] = self.request.user.teammember_set.filter(team__camp=self.camp) - context['user_shifts'] = TeamShift.objects.filter( - team__camp=self.camp, - team_members__user=self.request.user + context["user_teams"] = self.request.user.teammember_set.filter( + team__camp=self.camp ) - return context \ No newline at end of file + context["user_shifts"] = TeamShift.objects.filter( + team__camp=self.camp, team_members__user=self.request.user + ) + return context diff --git a/src/teams/views/tasks.py b/src/teams/views/tasks.py index da21f7bd..4f1cd280 100644 --- a/src/teams/views/tasks.py +++ b/src/teams/views/tasks.py @@ -12,33 +12,33 @@ from .mixins import EnsureTeamResponsibleMixin, TeamViewMixin class TeamTasksView(CampViewMixin, DetailView): template_name = "team_tasks.html" - context_object_name = 'team' + context_object_name = "team" model = Team - slug_url_kwarg = 'team_slug' - active_menu = 'tasks' + slug_url_kwarg = "team_slug" + active_menu = "tasks" class TaskCommentForm(forms.ModelForm): class Meta: model = TaskComment - fields = ['comment'] + fields = ["comment"] class TaskDetailView(CampViewMixin, TeamViewMixin, DetailView): template_name = "task_detail.html" context_object_name = "task" model = TeamTask - active_menu = 'tasks' + active_menu = "tasks" def get_context_data(self, *args, **kwargs): context = super().get_context_data(*args, **kwargs) - context['comment_form'] = TaskCommentForm() + context["comment_form"] = TaskCommentForm() return context def post(self, request, **kwargs): task = self.get_object() if request.user not in task.team.members.all(): - return HttpResponseNotAllowed('Nope') + return HttpResponseNotAllowed("Nope") form = TaskCommentForm(request.POST) if form.is_valid(): @@ -55,30 +55,31 @@ class TaskDetailView(CampViewMixin, TeamViewMixin, DetailView): class TaskForm(forms.ModelForm): class Meta: model = TeamTask - fields = ['name', 'description', 'when', 'completed'] + fields = ["name", "description", "when", "completed"] def __init__(self, **kwargs): super().__init__(**kwargs) - self.fields['when'].widget.widgets = [ - forms.DateTimeInput( - attrs={"placeholder": "Start"} - ), - forms.DateTimeInput( - attrs={"placeholder": "End"} - ) + self.fields["when"].widget.widgets = [ + forms.DateTimeInput(attrs={"placeholder": "Start"}), + forms.DateTimeInput(attrs={"placeholder": "End"}), ] -class TaskCreateView(LoginRequiredMixin, CampViewMixin, TeamViewMixin, EnsureTeamResponsibleMixin, CreateView): +class TaskCreateView( + LoginRequiredMixin, + CampViewMixin, + TeamViewMixin, + EnsureTeamResponsibleMixin, + CreateView, +): model = TeamTask template_name = "task_form.html" form_class = TaskForm - active_menu = 'tasks' + active_menu = "tasks" def get_team(self): return Team.objects.get( - camp__slug=self.kwargs['camp_slug'], - slug=self.kwargs['team_slug'] + camp__slug=self.kwargs["camp_slug"], slug=self.kwargs["team_slug"] ) def form_valid(self, form): @@ -93,15 +94,21 @@ class TaskCreateView(LoginRequiredMixin, CampViewMixin, TeamViewMixin, EnsureTea return self.get_object().get_absolute_url() -class TaskUpdateView(LoginRequiredMixin, CampViewMixin, TeamViewMixin, EnsureTeamResponsibleMixin, UpdateView): +class TaskUpdateView( + LoginRequiredMixin, + CampViewMixin, + TeamViewMixin, + EnsureTeamResponsibleMixin, + UpdateView, +): model = TeamTask template_name = "task_form.html" form_class = TaskForm - active_menu = 'tasks' + active_menu = "tasks" def get_context_data(self, *args, **kwargs): context = super().get_context_data(**kwargs) - context['team'] = self.team + context["team"] = self.team return context def form_valid(self, form): diff --git a/src/tickets/__init__.py b/src/tickets/__init__.py index 56457177..f54c3a1b 100644 --- a/src/tickets/__init__.py +++ b/src/tickets/__init__.py @@ -1,2 +1 @@ -default_app_config = 'tickets.apps.TicketsConfig' - +default_app_config = "tickets.apps.TicketsConfig" diff --git a/src/tickets/admin.py b/src/tickets/admin.py index 031eb926..45a28a25 100644 --- a/src/tickets/admin.py +++ b/src/tickets/admin.py @@ -1,53 +1,33 @@ from django.contrib import admin -from .models import ( - TicketType, - SponsorTicket, - DiscountTicket, - ShopTicket -) +from .models import TicketType, SponsorTicket, DiscountTicket, ShopTicket class BaseTicketAdmin(admin.ModelAdmin): - actions = ['generate_pdf'] - exclude = ['qrcode_base64'] + actions = ["generate_pdf"] + exclude = ["qrcode_base64"] def generate_pdf(self, request, queryset): for ticket in queryset.all(): ticket.generate_pdf() - generate_pdf.description = 'Generate PDF for the ticket' + + generate_pdf.description = "Generate PDF for the ticket" @admin.register(TicketType) class TicketTypeAdmin(admin.ModelAdmin): - list_display = [ - 'name', - 'camp', - ] + list_display = ["name", "camp"] - list_filter = [ - 'name', - 'camp', - ] + list_filter = ["name", "camp"] @admin.register(SponsorTicket) class SponsorTicketAdmin(BaseTicketAdmin): - list_display = [ - 'pk', - 'ticket_type', - 'sponsor', - 'checked_in', - ] + list_display = ["pk", "ticket_type", "sponsor", "checked_in"] - list_filter = [ - 'ticket_type__camp', - 'checked_in', - 'ticket_type', - 'sponsor', - ] + list_filter = ["ticket_type__camp", "checked_in", "ticket_type", "sponsor"] - search_fields = ['pk', 'sponsor__name'] + search_fields = ["pk", "sponsor__name"] @admin.register(DiscountTicket) @@ -64,24 +44,18 @@ class ShopTicketAdmin(BaseTicketAdmin): return obj.order.paid list_display = [ - 'pk', - 'user_email', - 'is_paid', - 'ticket_type', - 'order', - 'product', - 'checked_in', + "pk", + "user_email", + "is_paid", + "ticket_type", + "order", + "product", + "checked_in", ] - list_filter = [ - 'ticket_type__camp', - 'checked_in', - 'ticket_type', - 'order', - 'product', - ] + list_filter = ["ticket_type__camp", "checked_in", "ticket_type", "order", "product"] - search_fields = ['uuid', 'order__id', 'order__user__email', 'name', 'email'] + search_fields = ["uuid", "order__id", "order__user__email", "name", "email"] class ShopTicketInline(admin.TabularInline): diff --git a/src/tickets/apps.py b/src/tickets/apps.py index 7559fae7..c7851b57 100644 --- a/src/tickets/apps.py +++ b/src/tickets/apps.py @@ -2,13 +2,17 @@ from django.apps import AppConfig from django.db.models.signals import post_save from .signals import ticket_changed import logging + logger = logging.getLogger("bornhack.%s" % __name__) class TicketsConfig(AppConfig): - name = 'tickets' + name = "tickets" def ready(self): # connect the post_save signal, including a dispatch_uid to prevent it being called multiple times in corner cases - post_save.connect(ticket_changed, sender='tickets.ShopTicket', dispatch_uid='shopticket_save_signal') - + post_save.connect( + ticket_changed, + sender="tickets.ShopTicket", + dispatch_uid="shopticket_save_signal", + ) diff --git a/src/tickets/migrations/0001_initial.py b/src/tickets/migrations/0001_initial.py index 2c350430..07ffdce3 100644 --- a/src/tickets/migrations/0001_initial.py +++ b/src/tickets/migrations/0001_initial.py @@ -12,83 +12,157 @@ class Migration(migrations.Migration): initial = True dependencies = [ - ('camps', '0022_camp_colour'), - ('sponsors', '0006_auto_20170715_1110'), - ('shop', '0047_auto_20170522_1942'), + ("camps", "0022_camp_colour"), + ("sponsors", "0006_auto_20170715_1110"), + ("shop", "0047_auto_20170522_1942"), ] operations = [ migrations.CreateModel( - name='DiscountTicket', + name="DiscountTicket", fields=[ - ('uuid', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)), - ('created', models.DateTimeField(auto_now_add=True)), - ('updated', models.DateTimeField(auto_now=True)), - ('qrcode_base64', models.TextField(blank=True, null=True)), - ('checked_in', models.BooleanField(default=False)), - ('price', models.IntegerField(help_text='Price of the discounted ticket (in DKK, including VAT).')), + ( + "uuid", + models.UUIDField( + default=uuid.uuid4, + editable=False, + primary_key=True, + serialize=False, + ), + ), + ("created", models.DateTimeField(auto_now_add=True)), + ("updated", models.DateTimeField(auto_now=True)), + ("qrcode_base64", models.TextField(blank=True, null=True)), + ("checked_in", models.BooleanField(default=False)), + ( + "price", + models.IntegerField( + help_text="Price of the discounted ticket (in DKK, including VAT)." + ), + ), ], - options={ - 'abstract': False, - }, + options={"abstract": False}, ), migrations.CreateModel( - name='ShopTicket', + name="ShopTicket", fields=[ - ('uuid', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)), - ('created', models.DateTimeField(auto_now_add=True)), - ('updated', models.DateTimeField(auto_now=True)), - ('qrcode_base64', models.TextField(blank=True, null=True)), - ('checked_in', models.BooleanField(default=False)), - ('name', models.CharField(blank=True, help_text='Name of the person this ticket belongs to. This can be different from the buying user.', max_length=100, null=True)), - ('email', models.EmailField(blank=True, max_length=254, null=True)), - ('order', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='shoptickets', to='shop.Order')), - ('product', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='shop.Product')), + ( + "uuid", + models.UUIDField( + default=uuid.uuid4, + editable=False, + primary_key=True, + serialize=False, + ), + ), + ("created", models.DateTimeField(auto_now_add=True)), + ("updated", models.DateTimeField(auto_now=True)), + ("qrcode_base64", models.TextField(blank=True, null=True)), + ("checked_in", models.BooleanField(default=False)), + ( + "name", + models.CharField( + blank=True, + help_text="Name of the person this ticket belongs to. This can be different from the buying user.", + max_length=100, + null=True, + ), + ), + ("email", models.EmailField(blank=True, max_length=254, null=True)), + ( + "order", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="shoptickets", + to="shop.Order", + ), + ), + ( + "product", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, to="shop.Product" + ), + ), ], - options={ - 'abstract': False, - }, + options={"abstract": False}, ), migrations.CreateModel( - name='SponsorTicket', + name="SponsorTicket", fields=[ - ('uuid', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)), - ('created', models.DateTimeField(auto_now_add=True)), - ('updated', models.DateTimeField(auto_now=True)), - ('qrcode_base64', models.TextField(blank=True, null=True)), - ('checked_in', models.BooleanField(default=False)), - ('sponsor', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='sponsors.Sponsor')), + ( + "uuid", + models.UUIDField( + default=uuid.uuid4, + editable=False, + primary_key=True, + serialize=False, + ), + ), + ("created", models.DateTimeField(auto_now_add=True)), + ("updated", models.DateTimeField(auto_now=True)), + ("qrcode_base64", models.TextField(blank=True, null=True)), + ("checked_in", models.BooleanField(default=False)), + ( + "sponsor", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + to="sponsors.Sponsor", + ), + ), ], - options={ - 'abstract': False, - }, + options={"abstract": False}, ), migrations.CreateModel( - name='TicketType', + name="TicketType", fields=[ - ('uuid', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)), - ('created', models.DateTimeField(auto_now_add=True)), - ('updated', models.DateTimeField(auto_now=True)), - ('name', models.TextField()), - ('camp', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='camps.Camp')), + ( + "uuid", + models.UUIDField( + default=uuid.uuid4, + editable=False, + primary_key=True, + serialize=False, + ), + ), + ("created", models.DateTimeField(auto_now_add=True)), + ("updated", models.DateTimeField(auto_now=True)), + ("name", models.TextField()), + ( + "camp", + models.ForeignKey( + null=True, + on_delete=django.db.models.deletion.CASCADE, + to="camps.Camp", + ), + ), ], - options={ - 'abstract': False, - }, + options={"abstract": False}, ), migrations.AddField( - model_name='sponsorticket', - name='ticket_type', - field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='tickets.TicketType'), + model_name="sponsorticket", + name="ticket_type", + field=models.ForeignKey( + null=True, + on_delete=django.db.models.deletion.CASCADE, + to="tickets.TicketType", + ), ), migrations.AddField( - model_name='shopticket', - name='ticket_type', - field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='tickets.TicketType'), + model_name="shopticket", + name="ticket_type", + field=models.ForeignKey( + null=True, + on_delete=django.db.models.deletion.CASCADE, + to="tickets.TicketType", + ), ), migrations.AddField( - model_name='discountticket', - name='ticket_type', - field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='tickets.TicketType'), + model_name="discountticket", + name="ticket_type", + field=models.ForeignKey( + null=True, + on_delete=django.db.models.deletion.CASCADE, + to="tickets.TicketType", + ), ), ] diff --git a/src/tickets/migrations/0002_auto_20170819_2222.py b/src/tickets/migrations/0002_auto_20170819_2222.py index decabb8a..0452e2ec 100644 --- a/src/tickets/migrations/0002_auto_20170819_2222.py +++ b/src/tickets/migrations/0002_auto_20170819_2222.py @@ -8,29 +8,35 @@ import django.db.models.deletion class Migration(migrations.Migration): - dependencies = [ - ('tickets', '0001_initial'), - ] + dependencies = [("tickets", "0001_initial")] operations = [ migrations.AlterField( - model_name='discountticket', - name='ticket_type', - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='tickets.TicketType'), + model_name="discountticket", + name="ticket_type", + field=models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, to="tickets.TicketType" + ), ), migrations.AlterField( - model_name='shopticket', - name='ticket_type', - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='tickets.TicketType'), + model_name="shopticket", + name="ticket_type", + field=models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, to="tickets.TicketType" + ), ), migrations.AlterField( - model_name='sponsorticket', - name='ticket_type', - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='tickets.TicketType'), + model_name="sponsorticket", + name="ticket_type", + field=models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, to="tickets.TicketType" + ), ), migrations.AlterField( - model_name='tickettype', - name='camp', - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='camps.Camp'), + model_name="tickettype", + name="camp", + field=models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, to="camps.Camp" + ), ), ] diff --git a/src/tickets/migrations/0003_auto_20170819_2309.py b/src/tickets/migrations/0003_auto_20170819_2309.py index 64a1cef1..97d46b24 100644 --- a/src/tickets/migrations/0003_auto_20170819_2309.py +++ b/src/tickets/migrations/0003_auto_20170819_2309.py @@ -7,21 +7,10 @@ from django.db import migrations class Migration(migrations.Migration): - dependencies = [ - ('tickets', '0002_auto_20170819_2222'), - ] + dependencies = [("tickets", "0002_auto_20170819_2222")] operations = [ - migrations.RemoveField( - model_name='discountticket', - name='qrcode_base64', - ), - migrations.RemoveField( - model_name='shopticket', - name='qrcode_base64', - ), - migrations.RemoveField( - model_name='sponsorticket', - name='qrcode_base64', - ), + migrations.RemoveField(model_name="discountticket", name="qrcode_base64"), + migrations.RemoveField(model_name="shopticket", name="qrcode_base64"), + migrations.RemoveField(model_name="sponsorticket", name="qrcode_base64"), ] diff --git a/src/tickets/migrations/0004_auto_20170823_1228.py b/src/tickets/migrations/0004_auto_20170823_1228.py index d8f12e85..b639398b 100644 --- a/src/tickets/migrations/0004_auto_20170823_1228.py +++ b/src/tickets/migrations/0004_auto_20170823_1228.py @@ -7,24 +7,22 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ - ('tickets', '0003_auto_20170819_2309'), - ] + dependencies = [("tickets", "0003_auto_20170819_2309")] operations = [ migrations.AddField( - model_name='discountticket', - name='badge_handed_out', + model_name="discountticket", + name="badge_handed_out", field=models.BooleanField(default=False), ), migrations.AddField( - model_name='shopticket', - name='badge_handed_out', + model_name="shopticket", + name="badge_handed_out", field=models.BooleanField(default=False), ), migrations.AddField( - model_name='sponsorticket', - name='badge_handed_out', + model_name="sponsorticket", + name="badge_handed_out", field=models.BooleanField(default=False), ), ] diff --git a/src/tickets/migrations/0005_auto_20180318_0906.py b/src/tickets/migrations/0005_auto_20180318_0906.py index adb2c53b..1cf9dbf2 100644 --- a/src/tickets/migrations/0005_auto_20180318_0906.py +++ b/src/tickets/migrations/0005_auto_20180318_0906.py @@ -8,44 +8,58 @@ import django.db.models.deletion class Migration(migrations.Migration): - dependencies = [ - ('tickets', '0004_auto_20170823_1228'), - ] + dependencies = [("tickets", "0004_auto_20170823_1228")] operations = [ migrations.AlterField( - model_name='discountticket', - name='ticket_type', - field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='tickets.TicketType'), + model_name="discountticket", + name="ticket_type", + field=models.ForeignKey( + on_delete=django.db.models.deletion.PROTECT, to="tickets.TicketType" + ), ), migrations.AlterField( - model_name='shopticket', - name='order', - field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='shoptickets', to='shop.Order'), + model_name="shopticket", + name="order", + field=models.ForeignKey( + on_delete=django.db.models.deletion.PROTECT, + related_name="shoptickets", + to="shop.Order", + ), ), migrations.AlterField( - model_name='shopticket', - name='product', - field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='shop.Product'), + model_name="shopticket", + name="product", + field=models.ForeignKey( + on_delete=django.db.models.deletion.PROTECT, to="shop.Product" + ), ), migrations.AlterField( - model_name='shopticket', - name='ticket_type', - field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='tickets.TicketType'), + model_name="shopticket", + name="ticket_type", + field=models.ForeignKey( + on_delete=django.db.models.deletion.PROTECT, to="tickets.TicketType" + ), ), migrations.AlterField( - model_name='sponsorticket', - name='sponsor', - field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='sponsors.Sponsor'), + model_name="sponsorticket", + name="sponsor", + field=models.ForeignKey( + on_delete=django.db.models.deletion.PROTECT, to="sponsors.Sponsor" + ), ), migrations.AlterField( - model_name='sponsorticket', - name='ticket_type', - field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='tickets.TicketType'), + model_name="sponsorticket", + name="ticket_type", + field=models.ForeignKey( + on_delete=django.db.models.deletion.PROTECT, to="tickets.TicketType" + ), ), migrations.AlterField( - model_name='tickettype', - name='camp', - field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='camps.Camp'), + model_name="tickettype", + name="camp", + field=models.ForeignKey( + on_delete=django.db.models.deletion.PROTECT, to="camps.Camp" + ), ), ] diff --git a/src/tickets/models.py b/src/tickets/models.py index 8295c4ae..1f2e6cd7 100644 --- a/src/tickets/models.py +++ b/src/tickets/models.py @@ -5,27 +5,25 @@ import qrcode from django.conf import settings from django.urls import reverse_lazy from django.utils.translation import ugettext_lazy as _ -from utils.models import ( - UUIDModel, - CampRelatedModel, -) +from utils.models import UUIDModel, CampRelatedModel from utils.pdf import generate_pdf_letter from django.db import models import logging + logger = logging.getLogger("bornhack.%s" % __name__) # TicketType can be full week, one day. etc. class TicketType(CampRelatedModel, UUIDModel): name = models.TextField() - camp = models.ForeignKey('camps.Camp', on_delete=models.PROTECT) + camp = models.ForeignKey("camps.Camp", on_delete=models.PROTECT) def __str__(self): - return '{} ({})'.format(self.name, self.camp.title) + return "{} ({})".format(self.name, self.camp.title) class BaseTicket(CampRelatedModel, UUIDModel): - ticket_type = models.ForeignKey('TicketType', on_delete=models.PROTECT) + ticket_type = models.ForeignKey("TicketType", on_delete=models.PROTECT) checked_in = models.BooleanField(default=False) badge_handed_out = models.BooleanField(default=False) @@ -38,41 +36,40 @@ class BaseTicket(CampRelatedModel, UUIDModel): def _get_token(self): return hashlib.sha256( - '{_id}{secret_key}'.format( - _id=self.pk, - secret_key=settings.SECRET_KEY, - ).encode('utf-8') + "{_id}{secret_key}".format( + _id=self.pk, secret_key=settings.SECRET_KEY + ).encode("utf-8") ).hexdigest() def get_qr_code_base64(self): qr = qrcode.make( self._get_token(), version=1, - error_correction=qrcode.constants.ERROR_CORRECT_H + error_correction=qrcode.constants.ERROR_CORRECT_H, ).resize((250, 250)) file_like = io.BytesIO() - qr.save(file_like, format='png') + qr.save(file_like, format="png") qrcode_base64 = base64.b64encode(file_like.getvalue()) return qrcode_base64 def get_qr_code_url(self): - return 'data:image/png;base64,{}'.format( - self.get_qr_code_base64().decode('utf-8') + return "data:image/png;base64,{}".format( + self.get_qr_code_base64().decode("utf-8") ) def generate_pdf(self): return generate_pdf_letter( - filename='{}_ticket_{}.pdf'.format(self.shortname, self.pk), - formatdict={'ticket': self}, - template='pdf/ticket.html' + filename="{}_ticket_{}.pdf".format(self.shortname, self.pk), + formatdict={"ticket": self}, + template="pdf/ticket.html", ) class SponsorTicket(BaseTicket): - sponsor = models.ForeignKey('sponsors.Sponsor', on_delete=models.PROTECT) + sponsor = models.ForeignKey("sponsors.Sponsor", on_delete=models.PROTECT) def __str__(self): - return 'SponsorTicket: {}'.format(self.pk) + return "SponsorTicket: {}".format(self.pk) @property def shortname(self): @@ -81,11 +78,11 @@ class SponsorTicket(BaseTicket): class DiscountTicket(BaseTicket): price = models.IntegerField( - help_text=_('Price of the discounted ticket (in DKK, including VAT).') + help_text=_("Price of the discounted ticket (in DKK, including VAT).") ) def __str__(self): - return 'DiscountTicket: {}'.format(self.pk) + return "DiscountTicket: {}".format(self.pk) @property def shortname(self): @@ -94,51 +91,38 @@ class DiscountTicket(BaseTicket): class ShopTicket(BaseTicket): order = models.ForeignKey( - 'shop.Order', - related_name='shoptickets', - on_delete=models.PROTECT + "shop.Order", related_name="shoptickets", on_delete=models.PROTECT ) - product = models.ForeignKey('shop.Product', on_delete=models.PROTECT) + product = models.ForeignKey("shop.Product", on_delete=models.PROTECT) name = models.CharField( max_length=100, help_text=( - 'Name of the person this ticket belongs to. ' - 'This can be different from the buying user.' + "Name of the person this ticket belongs to. " + "This can be different from the buying user." ), null=True, blank=True, ) - email = models.EmailField( - null=True, - blank=True, - ) + email = models.EmailField(null=True, blank=True) # overwrite the _get_token method because old tickets use the user_id def _get_token(self): return hashlib.sha256( - '{_id}{user_id}{secret_key}'.format( - _id=self.pk, - user_id=self.order.user.pk, - secret_key=settings.SECRET_KEY, - ).encode('utf-8') + "{_id}{user_id}{secret_key}".format( + _id=self.pk, user_id=self.order.user.pk, secret_key=settings.SECRET_KEY + ).encode("utf-8") ).hexdigest() def __str__(self): - return 'Ticket {user} {product}'.format( - user=self.order.user, - product=self.product + return "Ticket {user} {product}".format( + user=self.order.user, product=self.product ) def get_absolute_url(self): - return str( - reverse_lazy('tickets:shopticket_edit', kwargs={'pk': self.pk}) - ) + return str(reverse_lazy("tickets:shopticket_edit", kwargs={"pk": self.pk})) @property def shortname(self): return "shop" - - - diff --git a/src/tickets/signals.py b/src/tickets/signals.py index 136923c9..d0bf757c 100644 --- a/src/tickets/signals.py +++ b/src/tickets/signals.py @@ -1,12 +1,10 @@ from django.conf import settings -from datetime import ( - timedelta, - datetime -) +from datetime import timedelta, datetime from django.db.models import Count from django.utils import timezone from events.handler import handle_team_event + def ticket_changed(sender, instance, created, **kwargs): """ This signal is called every time a ShopTicket is saved @@ -24,20 +22,16 @@ def ticket_changed(sender, instance, created, **kwargs): stats = ", ".join( [ "{}: {}".format( - tickettype['product__name'].replace( - "{} ".format(ticket_prefix), - "" - ), - tickettype['total'] - ) for tickettype in ShopTicket.objects.filter( + tickettype["product__name"].replace("{} ".format(ticket_prefix), ""), + tickettype["total"], + ) + for tickettype in ShopTicket.objects.filter( product__name__startswith=ticket_prefix - ).exclude( - product__name__startswith="{} One Day".format(ticket_prefix) - ).values( - 'product__name' - ).annotate( - total=Count('product__name') - ).order_by('-total') + ) + .exclude(product__name__startswith="{} One Day".format(ticket_prefix)) + .values("product__name") + .annotate(total=Count("product__name")) + .order_by("-total") ] ) @@ -50,16 +44,12 @@ def ticket_changed(sender, instance, created, **kwargs): # queue the messages handle_team_event( - eventtype='ticket_created', - irc_message="%s sold!" % instance.product.name + eventtype="ticket_created", irc_message="%s sold!" % instance.product.name ) # limit this one to a length of 200 because IRC is nice handle_team_event( - eventtype='ticket_created', + eventtype="ticket_created", irc_message="Totals: {}, 1day: {}, 1day child: {}".format( - stats, - onedaystats, - onedaychildstats - )[:200] + stats, onedaystats, onedaychildstats + )[:200], ) - diff --git a/src/tickets/urls.py b/src/tickets/urls.py index e6d40f9c..92e6ac8b 100644 --- a/src/tickets/urls.py +++ b/src/tickets/urls.py @@ -1,27 +1,15 @@ from django.urls import path -from .views import ( - ShopTicketListView, - ShopTicketDownloadView, - ShopTicketDetailView -) +from .views import ShopTicketListView, ShopTicketDownloadView, ShopTicketDetailView -app_name = 'tickets' +app_name = "tickets" urlpatterns = [ + path("", ShopTicketListView.as_view(), name="shopticket_list"), path( - '', - ShopTicketListView.as_view(), - name='shopticket_list' - ), - path( - '/download/', + "/download/", ShopTicketDownloadView.as_view(), - name='shopticket_download' - ), - path( - '/edit/', - ShopTicketDetailView.as_view(), - name='shopticket_edit' + name="shopticket_download", ), + path("/edit/", ShopTicketDetailView.as_view(), name="shopticket_edit"), ] diff --git a/src/tickets/views.py b/src/tickets/views.py index 4fc50b88..7641664d 100644 --- a/src/tickets/views.py +++ b/src/tickets/views.py @@ -3,25 +3,18 @@ import logging from django.contrib import messages from django.contrib.auth.mixins import LoginRequiredMixin from django.views.generic.detail import SingleObjectMixin -from django.views.generic import ( - DetailView, - UpdateView, - ListView, - View -) -from django.http import ( - HttpResponse, - Http404 -) +from django.views.generic import DetailView, UpdateView, ListView, View +from django.http import HttpResponse, Http404 from .models import ShopTicket + logger = logging.getLogger("bornhack.%s" % __name__) class ShopTicketListView(LoginRequiredMixin, ListView): model = ShopTicket - template_name = 'tickets/ticket_list.html' - context_object_name = 'tickets' + template_name = "tickets/ticket_list.html" + context_object_name = "tickets" def get_queryset(self): tickets = super(ShopTicketListView, self).get_queryset() @@ -39,10 +32,11 @@ class ShopTicketDownloadView(LoginRequiredMixin, SingleObjectMixin, View): return super().dispatch(request, *args, **kwargs) def get(self, request, *args, **kwargs): - response = HttpResponse(content_type='application/pdf') - response['Content-Disposition'] = 'attachment; filename="{type}_ticket_{pk}.pdf"'.format( - type=self.get_object().shortname, - pk=self.get_object().pk + response = HttpResponse(content_type="application/pdf") + response[ + "Content-Disposition" + ] = 'attachment; filename="{type}_ticket_{pk}.pdf"'.format( + type=self.get_object().shortname, pk=self.get_object().pk ) response.write(self.get_object().generate_pdf().getvalue()) return response @@ -50,12 +44,12 @@ class ShopTicketDownloadView(LoginRequiredMixin, SingleObjectMixin, View): class ShopTicketDetailView(LoginRequiredMixin, UpdateView, DetailView): model = ShopTicket - template_name = 'tickets/ticket_detail.html' - context_object_name = 'ticket' - fields = ['name', 'email'] + template_name = "tickets/ticket_detail.html" + context_object_name = "ticket" + fields = ["name", "email"] def form_valid(self, form): - messages.info(self.request, 'Ticket updated!') + messages.info(self.request, "Ticket updated!") return super().form_valid(form) def dispatch(self, request, *args, **kwargs): diff --git a/src/tokens/admin.py b/src/tokens/admin.py index a13a67a4..3d8b6a52 100644 --- a/src/tokens/admin.py +++ b/src/tokens/admin.py @@ -1,16 +1,16 @@ from django.contrib import admin from .models import Token, TokenFind + @admin.register(Token) class InfoCategorydmin(admin.ModelAdmin): - list_filter = ['camp',] - list_display = ['token', 'description', 'camp'] - search_fields = ['token', 'description'] + list_filter = ["camp"] + list_display = ["token", "description", "camp"] + search_fields = ["token", "description"] @admin.register(TokenFind) class InfoCategorydmin(admin.ModelAdmin): - list_filter = ['token__camp', 'user'] - list_display = ['token', 'user', 'created'] - search_fields = ['user', 'token'] - + list_filter = ["token__camp", "user"] + list_display = ["token", "user", "created"] + search_fields = ["user", "token"] diff --git a/src/tokens/apps.py b/src/tokens/apps.py index 440d98a8..8eaa2982 100644 --- a/src/tokens/apps.py +++ b/src/tokens/apps.py @@ -2,4 +2,4 @@ from django.apps import AppConfig class TokensConfig(AppConfig): - name = 'tokens' + name = "tokens" diff --git a/src/tokens/migrations/0001_initial.py b/src/tokens/migrations/0001_initial.py index 52954c3c..e274601f 100644 --- a/src/tokens/migrations/0001_initial.py +++ b/src/tokens/migrations/0001_initial.py @@ -8,23 +8,38 @@ class Migration(migrations.Migration): initial = True - dependencies = [ - ('camps', '0029_auto_20180815_2018'), - ] + dependencies = [("camps", "0029_auto_20180815_2018")] operations = [ migrations.CreateModel( - name='Token', + name="Token", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('created', models.DateTimeField(auto_now_add=True)), - ('updated', models.DateTimeField(auto_now=True)), - ('token', models.CharField(help_text='The secret token', max_length=32)), - ('description', models.TextField(help_text='The description of the token')), - ('camp', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='camps.Camp')), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("created", models.DateTimeField(auto_now_add=True)), + ("updated", models.DateTimeField(auto_now=True)), + ( + "token", + models.CharField(help_text="The secret token", max_length=32), + ), + ( + "description", + models.TextField(help_text="The description of the token"), + ), + ( + "camp", + models.ForeignKey( + on_delete=django.db.models.deletion.PROTECT, to="camps.Camp" + ), + ), ], - options={ - 'abstract': False, - }, - ), + options={"abstract": False}, + ) ] diff --git a/src/tokens/migrations/0002_tokenfind.py b/src/tokens/migrations/0002_tokenfind.py index ea7f6fa3..b85af43f 100644 --- a/src/tokens/migrations/0002_tokenfind.py +++ b/src/tokens/migrations/0002_tokenfind.py @@ -9,21 +9,38 @@ class Migration(migrations.Migration): dependencies = [ migrations.swappable_dependency(settings.AUTH_USER_MODEL), - ('tokens', '0001_initial'), + ("tokens", "0001_initial"), ] operations = [ migrations.CreateModel( - name='TokenFind', + name="TokenFind", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('created', models.DateTimeField(auto_now_add=True)), - ('updated', models.DateTimeField(auto_now=True)), - ('token', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='tokens.Token')), - ('user', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to=settings.AUTH_USER_MODEL)), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("created", models.DateTimeField(auto_now_add=True)), + ("updated", models.DateTimeField(auto_now=True)), + ( + "token", + models.ForeignKey( + on_delete=django.db.models.deletion.PROTECT, to="tokens.Token" + ), + ), + ( + "user", + models.ForeignKey( + on_delete=django.db.models.deletion.PROTECT, + to=settings.AUTH_USER_MODEL, + ), + ), ], - options={ - 'abstract': False, - }, - ), + options={"abstract": False}, + ) ] diff --git a/src/tokens/migrations/0003_token_category.py b/src/tokens/migrations/0003_token_category.py index c9a75997..51ba26c4 100644 --- a/src/tokens/migrations/0003_token_category.py +++ b/src/tokens/migrations/0003_token_category.py @@ -5,15 +5,16 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ - ('tokens', '0002_tokenfind'), - ] + dependencies = [("tokens", "0002_tokenfind")] operations = [ migrations.AddField( - model_name='token', - name='category', - field=models.TextField(default='', help_text='The category/hint for this token (physical, website, whatever)'), + model_name="token", + name="category", + field=models.TextField( + default="", + help_text="The category/hint for this token (physical, website, whatever)", + ), preserve_default=False, - ), + ) ] diff --git a/src/tokens/migrations/0004_auto_20180819_1743.py b/src/tokens/migrations/0004_auto_20180819_1743.py index 35b380a7..b0a4c580 100644 --- a/src/tokens/migrations/0004_auto_20180819_1743.py +++ b/src/tokens/migrations/0004_auto_20180819_1743.py @@ -8,12 +8,11 @@ class Migration(migrations.Migration): dependencies = [ migrations.swappable_dependency(settings.AUTH_USER_MODEL), - ('tokens', '0003_token_category'), + ("tokens", "0003_token_category"), ] operations = [ migrations.AlterUniqueTogether( - name='tokenfind', - unique_together={('user', 'token')}, - ), + name="tokenfind", unique_together={("user", "token")} + ) ] diff --git a/src/tokens/migrations/0005_auto_20190327_2025.py b/src/tokens/migrations/0005_auto_20190327_2025.py index 8209091b..03c72de0 100644 --- a/src/tokens/migrations/0005_auto_20190327_2025.py +++ b/src/tokens/migrations/0005_auto_20190327_2025.py @@ -5,13 +5,8 @@ from django.db import migrations class Migration(migrations.Migration): - dependencies = [ - ('tokens', '0004_auto_20180819_1743'), - ] + dependencies = [("tokens", "0004_auto_20180819_1743")] operations = [ - migrations.AlterModelOptions( - name='token', - options={'ordering': ['camp']}, - ), + migrations.AlterModelOptions(name="token", options={"ordering": ["camp"]}) ] diff --git a/src/tokens/models.py b/src/tokens/models.py index 337d9584..00dc77e6 100644 --- a/src/tokens/models.py +++ b/src/tokens/models.py @@ -3,28 +3,20 @@ from utils.models import CampRelatedModel class Token(CampRelatedModel): - camp = models.ForeignKey( - 'camps.Camp', - on_delete=models.PROTECT - ) + camp = models.ForeignKey("camps.Camp", on_delete=models.PROTECT) - token = models.CharField( - max_length=32, - help_text="The secret token" - ) + token = models.CharField(max_length=32, help_text="The secret token") category = models.TextField( help_text="The category/hint for this token (physical, website, whatever)" ) - description = models.TextField( - help_text="The description of the token" - ) + description = models.TextField(help_text="The description of the token") - camp_filter = 'camp' + camp_filter = "camp" def __str__(self): - return '%s (%s)' % (self.description, self.camp) + return "%s (%s)" % (self.description, self.camp) class Meta: ordering = ["camp"] @@ -32,24 +24,17 @@ class Token(CampRelatedModel): class TokenFind(CampRelatedModel): class Meta: - unique_together = (('user', 'token')) + unique_together = ("user", "token") - token = models.ForeignKey( - 'tokens.Token', - on_delete=models.PROTECT - ) + token = models.ForeignKey("tokens.Token", on_delete=models.PROTECT) - user = models.ForeignKey( - 'auth.User', - on_delete=models.PROTECT, - ) + user = models.ForeignKey("auth.User", on_delete=models.PROTECT) - camp_filter = 'token__camp' + camp_filter = "token__camp" def __str__(self): - return '%s found by %s' % (self.token, self.user) + return "%s found by %s" % (self.token, self.user) @property def camp(self): return self.token.camp - diff --git a/src/tokens/templatetags/token_tags.py b/src/tokens/templatetags/token_tags.py index 630c22fa..3b605009 100644 --- a/src/tokens/templatetags/token_tags.py +++ b/src/tokens/templatetags/token_tags.py @@ -12,4 +12,3 @@ def found_by_user(token, user): return tokenfind.created except TokenFind.DoesNotExist: return False - diff --git a/src/tokens/urls.py b/src/tokens/urls.py index 6c783db3..60d3f31a 100644 --- a/src/tokens/urls.py +++ b/src/tokens/urls.py @@ -1,14 +1,9 @@ from django.urls import re_path, path from .views import TokenDetailView, TokenFindListView -app_name = 'tokens' +app_name = "tokens" urlpatterns = [ - path('', TokenFindListView.as_view(), name='tokenfind_list'), - re_path( - '(?P[0-9a-zA-Z\.@]+)/$', - TokenDetailView.as_view(), - name='details' - ), + path("", TokenFindListView.as_view(), name="tokenfind_list"), + re_path("(?P[0-9a-zA-Z\.@]+)/$", TokenDetailView.as_view(), name="details"), ] - diff --git a/src/tokens/views.py b/src/tokens/views.py index 6143c233..ea415454 100644 --- a/src/tokens/views.py +++ b/src/tokens/views.py @@ -7,14 +7,13 @@ from .models import Token, TokenFind class TokenDetailView(LoginRequiredMixin, DetailView): template_name = "token_detail.html" model = Token - slug_field = 'token' - slug_url_kwarg = 'token' + slug_field = "token" + slug_url_kwarg = "token" def get(self, request, *args, **kwargs): # register this tokenview if it isn't already token, created = TokenFind.objects.get_or_create( - token=self.get_object(), - user=request.user + token=self.get_object(), user=request.user ) return super().get(request, *args, **kwargs) @@ -26,7 +25,8 @@ class TokenFindListView(LoginRequiredMixin, ListView): def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) # find the tokens the user still needs to find - tokenfinds = TokenFind.objects.filter(user=self.request.user).values_list('token__id', flat=True) - context['unfound_list'] = Token.objects.all().exclude(id__in=tokenfinds) + tokenfinds = TokenFind.objects.filter(user=self.request.user).values_list( + "token__id", flat=True + ) + context["unfound_list"] = Token.objects.all().exclude(id__in=tokenfinds) return context - diff --git a/src/utils/apps.py b/src/utils/apps.py index d487c6b0..3e82e497 100644 --- a/src/utils/apps.py +++ b/src/utils/apps.py @@ -1,7 +1,5 @@ - - from django.apps import AppConfig class UtilsConfig(AppConfig): - name = 'utils' + name = "utils" diff --git a/src/utils/email.py b/src/utils/email.py index e3f5ec31..67821bf4 100644 --- a/src/utils/email.py +++ b/src/utils/email.py @@ -6,6 +6,7 @@ from django.conf import settings from django.template.loader import render_to_string from .models import OutgoingEmail import logging, magic + logger = logging.getLogger("bornhack.%s" % __name__) @@ -15,10 +16,10 @@ def _send_email( to_recipients=[], cc_recipients=[], bcc_recipients=[], - html_template='', - sender='BornHack ', + html_template="", + sender="BornHack ", attachment=None, - attachment_filename='' + attachment_filename="", ): if not isinstance(to_recipients, list): to_recipients = [to_recipients] @@ -30,16 +31,15 @@ def _send_email( text_template, sender, to_recipients, - bcc_recipients + [settings.ARCHIVE_EMAIL] if bcc_recipients else [settings.ARCHIVE_EMAIL], - cc_recipients + bcc_recipients + [settings.ARCHIVE_EMAIL] + if bcc_recipients + else [settings.ARCHIVE_EMAIL], + cc_recipients, ) # is there a html version of this email? if html_template: - msg.attach_alternative( - html_template, - 'text/html' - ) + msg.attach_alternative(html_template, "text/html") # is there an attachment to this mail? if attachment: @@ -47,14 +47,14 @@ def _send_email( mimetype = magic.from_buffer(attachment, mime=True) msg.attach(attachment_filename, attachment, mimetype) except Exception as e: - logger.exception('exception while rendering email: {}'.format(e)) + logger.exception("exception while rendering email: {}".format(e)) return False # send the email try: msg.send(fail_silently=False) except Exception as e: - logger.exception('exception while sending email: {}'.format(e)) + logger.exception("exception while sending email: {}".format(e)) return False return True @@ -67,10 +67,10 @@ def add_outgoing_email( to_recipients=[], cc_recipients=[], bcc_recipients=[], - html_template='', - sender='BornHack ', + html_template="", + sender="BornHack ", attachment=None, - attachment_filename='' + attachment_filename="", ): """ adds an email to the outgoing queue recipients is a list of to recipients @@ -96,7 +96,7 @@ def add_outgoing_email( sender=sender, to_recipients=to_recipients, cc_recipients=cc_recipients, - bcc_recipients=bcc_recipients + bcc_recipients=bcc_recipients, ) if attachment: diff --git a/src/utils/factories.py b/src/utils/factories.py index aed2c5b5..55993727 100644 --- a/src/utils/factories.py +++ b/src/utils/factories.py @@ -4,9 +4,8 @@ from factory.django import DjangoModelFactory class UserFactory(DjangoModelFactory): class Meta: - model = 'auth.User' - django_get_or_create = ('username',) - - username = factory.Faker('word') - email = factory.Faker('ascii_email') + model = "auth.User" + django_get_or_create = ("username",) + username = factory.Faker("word") + email = factory.Faker("ascii_email") diff --git a/src/utils/management/commands/bootstrap-devsite.py b/src/utils/management/commands/bootstrap-devsite.py index 6187e331..ea297f27 100644 --- a/src/utils/management/commands/bootstrap-devsite.py +++ b/src/utils/management/commands/bootstrap-devsite.py @@ -5,11 +5,7 @@ from camps.models import Camp from news.models import NewsItem from info.models import InfoCategory, InfoItem from villages.models import Village -from shop.models import ( - ProductCategory, - Product, - Order -) +from shop.models import ProductCategory, Product, Order from program.models import ( EventType, Event, @@ -18,37 +14,30 @@ from program.models import ( EventLocation, EventTrack, ) -from tickets.models import ( - TicketType -) -from teams.models import ( - Team, - TeamTask, - TeamMember -) -from events.models import ( - Type, - Routing -) +from tickets.models import TicketType +from teams.models import Team, TeamTask, TeamMember +from events.models import Type, Routing from django.contrib.auth.models import User from allauth.account.models import EmailAddress from django.utils.text import slugify class Command(BaseCommand): - args = 'none' - help = 'Create mock data for development instances' + args = "none" + help = "Create mock data for development instances" def output(self, message): - self.stdout.write('%s: %s' % (timezone.now().strftime("%Y-%m-%d %H:%M:%S"), message)) + self.stdout.write( + "%s: %s" % (timezone.now().strftime("%Y-%m-%d %H:%M:%S"), message) + ) def handle(self, *args, **options): - self.output('Creating camps...') + self.output("Creating camps...") camp2016 = Camp.objects.create( - title='BornHack 2016', - tagline='Initial Commit', - slug='bornhack-2016', - shortslug='bh2016', + title="BornHack 2016", + tagline="Initial Commit", + slug="bornhack-2016", + shortslug="bh2016", buildup=( timezone.datetime(2016, 8, 25, 12, 0, tzinfo=timezone.utc), timezone.datetime(2016, 8, 27, 11, 59, tzinfo=timezone.utc), @@ -61,14 +50,14 @@ class Command(BaseCommand): timezone.datetime(2016, 9, 4, 12, 0, tzinfo=timezone.utc), timezone.datetime(2016, 9, 6, 12, 0, tzinfo=timezone.utc), ), - colour='#004dff', + colour="#004dff", ) camp2017 = Camp.objects.create( - title='BornHack 2017', - tagline='Make Tradition', - slug='bornhack-2017', - shortslug='bh2017', + title="BornHack 2017", + tagline="Make Tradition", + slug="bornhack-2017", + shortslug="bh2017", buildup=( timezone.datetime(2017, 8, 25, 12, 0, tzinfo=timezone.utc), timezone.datetime(2017, 8, 27, 11, 59, tzinfo=timezone.utc), @@ -81,14 +70,14 @@ class Command(BaseCommand): timezone.datetime(2017, 9, 4, 12, 0, tzinfo=timezone.utc), timezone.datetime(2017, 9, 6, 12, 0, tzinfo=timezone.utc), ), - colour='#750787', + colour="#750787", ) camp2018 = Camp.objects.create( - title='BornHack 2018', - tagline='scale it', - slug='bornhack-2018', - shortslug='bh2018', + title="BornHack 2018", + tagline="scale it", + slug="bornhack-2018", + shortslug="bh2018", call_for_participation_open=True, call_for_sponsors_open=True, buildup=( @@ -103,591 +92,460 @@ class Command(BaseCommand): timezone.datetime(2018, 9, 4, 12, 0, tzinfo=timezone.utc), timezone.datetime(2018, 9, 6, 12, 0, tzinfo=timezone.utc), ), - colour='#008026', + colour="#008026", ) self.output("Creating users...") - user1 = User.objects.create_user( - username='user1', - password='user1', - ) - user1.profile.name = 'John Doe' - user1.profile.description = 'one that once was' - user1.profile.public_credit_name = 'PublicDoe' + user1 = User.objects.create_user(username="user1", password="user1") + user1.profile.name = "John Doe" + user1.profile.description = "one that once was" + user1.profile.public_credit_name = "PublicDoe" user1.profile.public_credit_name_approved = True user1.profile.save() email = EmailAddress.objects.create( - user=user1, - email='user1@example.com', - primary=False, - verified=True + user=user1, email="user1@example.com", primary=False, verified=True ) email.set_as_primary() - user2 = User.objects.create_user( - username='user2', - password='user2', - ) - user2.profile.name = 'Jane Doe' - user2.profile.description = 'one that once was' + user2 = User.objects.create_user(username="user2", password="user2") + user2.profile.name = "Jane Doe" + user2.profile.description = "one that once was" user2.profile.save() email = EmailAddress.objects.create( - user=user2, - email='user2@example.com', - primary=False, - verified=True + user=user2, email="user2@example.com", primary=False, verified=True ) email.set_as_primary() - user3 = User.objects.create_user( - username='user3', - password='user3', - ) - user3.profile.name = 'Lorem Ipsum' - user3.profile.description = 'just a user' - user3.profile.public_credit_name = 'Lorem Ipsum' + user3 = User.objects.create_user(username="user3", password="user3") + user3.profile.name = "Lorem Ipsum" + user3.profile.description = "just a user" + user3.profile.public_credit_name = "Lorem Ipsum" user3.profile.save() email = EmailAddress.objects.create( - user=user3, - email='user3@example.com', - primary=False, - verified=True + user=user3, email="user3@example.com", primary=False, verified=True ) email.set_as_primary() - user4 = User.objects.create_user( - username='user4', - password='user4', - ) - user4.profile.name = 'Ethe Reum' - user4.profile.description = 'I prefer doge' - user4.profile.public_credit_name = 'Dogefan' + user4 = User.objects.create_user(username="user4", password="user4") + user4.profile.name = "Ethe Reum" + user4.profile.description = "I prefer doge" + user4.profile.public_credit_name = "Dogefan" user4.profile.public_credit_name_approved = True user4.profile.save() email = EmailAddress.objects.create( - user=user4, - email='user4@example.com', - primary=False, - verified=True + user=user4, email="user4@example.com", primary=False, verified=True ) email.set_as_primary() - user5 = User.objects.create_user( - username='user5', - password='user5', - ) - user5.profile.name = 'Pyra Mid' - user5.profile.description = 'This is not a scam' - user5.profile.public_credit_name = 'Ponziarne' + user5 = User.objects.create_user(username="user5", password="user5") + user5.profile.name = "Pyra Mid" + user5.profile.description = "This is not a scam" + user5.profile.public_credit_name = "Ponziarne" user5.profile.public_credit_name_approved = True user5.profile.save() email = EmailAddress.objects.create( - user=user5, - email='user5@example.com', - primary=False, - verified=True + user=user5, email="user5@example.com", primary=False, verified=True ) email.set_as_primary() - user6 = User.objects.create_user( - username='user6', - password='user6', - ) - user6.profile.name = 'User Number 6' - user6.profile.description = 'some description' - user6.profile.public_credit_name = 'bruger 6' + user6 = User.objects.create_user(username="user6", password="user6") + user6.profile.name = "User Number 6" + user6.profile.description = "some description" + user6.profile.public_credit_name = "bruger 6" user6.profile.public_credit_name_approved = True user6.profile.save() email = EmailAddress.objects.create( - user=user6, - email='user6@example.com', - primary=False, - verified=True + user=user6, email="user6@example.com", primary=False, verified=True ) email.set_as_primary() - user7 = User.objects.create_user( - username='user7', - password='user7', - ) - user7.profile.name = 'Assembly Hacker' - user7.profile.description = 'Low level is best level' - user7.profile.public_credit_name = 'asm' + user7 = User.objects.create_user(username="user7", password="user7") + user7.profile.name = "Assembly Hacker" + user7.profile.description = "Low level is best level" + user7.profile.public_credit_name = "asm" user7.profile.public_credit_name_approved = True user7.profile.save() email = EmailAddress.objects.create( - user=user7, - email='user7@example.com', - primary=False, - verified=True + user=user7, email="user7@example.com", primary=False, verified=True ) email.set_as_primary() - user8 = User.objects.create_user( - username='user8', - password='user8', - ) - user8.profile.name = 'TCL' - user8.profile.description = 'Expect me' - user8.profile.public_credit_name = 'TCL lover' + user8 = User.objects.create_user(username="user8", password="user8") + user8.profile.name = "TCL" + user8.profile.description = "Expect me" + user8.profile.public_credit_name = "TCL lover" user8.profile.public_credit_name_approved = True user8.profile.save() email = EmailAddress.objects.create( - user=user8, - email='user8@example.com', - primary=False, - verified=True + user=user8, email="user8@example.com", primary=False, verified=True ) email.set_as_primary() - user9 = User.objects.create_user( - username='user9', - password='user9', - ) - user9.profile.name = 'John Windows' - user9.profile.description = 'Microsoft is best soft' - user9.profile.public_credit_name = 'msboy' + user9 = User.objects.create_user(username="user9", password="user9") + user9.profile.name = "John Windows" + user9.profile.description = "Microsoft is best soft" + user9.profile.public_credit_name = "msboy" user9.profile.save() email = EmailAddress.objects.create( - user=user9, - email='user9@example.com', - primary=False, - verified=True + user=user9, email="user9@example.com", primary=False, verified=True ) email.set_as_primary() admin = User.objects.create_superuser( - username='admin', - email='admin@example.com', - password='admin', + username="admin", email="admin@example.com", password="admin" ) admin.profile.name = "Ad min" - admin.profile.description = 'I can administer the admin rights' + admin.profile.description = "I can administer the admin rights" admin.profile.save() email = EmailAddress.objects.create( - user=admin, - email='admin@example.com', - verified=True + user=admin, email="admin@example.com", verified=True ) email.set_as_primary() self.output("Creating event types...") workshop = EventType.objects.create( - name='Workshop', - slug='workshop', - color='#ff9900', + name="Workshop", + slug="workshop", + color="#ff9900", light_text=False, public=True, - description='Workshops actively involve the participants in the learning experience', - icon='toolbox', - host_title='Host', + description="Workshops actively involve the participants in the learning experience", + icon="toolbox", + host_title="Host", ) talk = EventType.objects.create( - name='Talk', - slug='talk', - color='#2D9595', + name="Talk", + slug="talk", + color="#2D9595", light_text=True, public=True, - description='A presentation on a stage', - icon='chalkboard-teacher', - host_title='Speaker', + description="A presentation on a stage", + icon="chalkboard-teacher", + host_title="Speaker", ) lightning = EventType.objects.create( - name='Lightning Talk', - slug='lightning-talk', - color='#ff0000', + name="Lightning Talk", + slug="lightning-talk", + color="#ff0000", light_text=True, public=True, - description='A short 5-10 minute presentation', - icon='bolt', - host_title='Speaker', + description="A short 5-10 minute presentation", + icon="bolt", + host_title="Speaker", ) music = EventType.objects.create( - name='Music Act', - slug='music', - color='#1D0095', + name="Music Act", + slug="music", + color="#1D0095", light_text=True, public=True, - description='A musical performance', - icon='music', - host_title='Artist', + description="A musical performance", + icon="music", + host_title="Artist", ) keynote = EventType.objects.create( - name='Keynote', - slug='keynote', - color='#FF3453', + name="Keynote", + slug="keynote", + color="#FF3453", light_text=True, - description='A keynote presentation', - icon='star', - host_title='Speaker', + description="A keynote presentation", + icon="star", + host_title="Speaker", ) debate = EventType.objects.create( - name='Debate', - slug='debate', - color='#F734C3', + name="Debate", + slug="debate", + color="#F734C3", light_text=True, - description='A panel debate with invited guests', - icon='users', - host_title='Guest', + description="A panel debate with invited guests", + icon="users", + host_title="Guest", public=True, ) facility = EventType.objects.create( - name='Facilities', - slug='facilities', - color='#cccccc', + name="Facilities", + slug="facilities", + color="#cccccc", light_text=False, include_in_event_list=False, - description='Events involving facilities like bathrooms, food area and so on', - icon='home', - host_title='Host', + description="Events involving facilities like bathrooms, food area and so on", + icon="home", + host_title="Host", ) slack = EventType.objects.create( - name='Recreational Event', - slug='recreational-event', - color='#0000ff', + name="Recreational Event", + slug="recreational-event", + color="#0000ff", light_text=True, public=True, - description='Events of a recreational nature', - icon='dice', - host_title='Host', + description="Events of a recreational nature", + icon="dice", + host_title="Host", ) self.output("Creating productcategories...") transportation = ProductCategory.objects.create( - name='Transportation', - slug='transportation' + name="Transportation", slug="transportation" ) merchandise = ProductCategory.objects.create( - name='Merchandise', - slug='merchandise' - ) - tickets = ProductCategory.objects.create( - name='Tickets', - slug='tickets' - ) - villages = ProductCategory.objects.create( - name='Villages', - slug='villages' + name="Merchandise", slug="merchandise" ) + tickets = ProductCategory.objects.create(name="Tickets", slug="tickets") + villages = ProductCategory.objects.create(name="Villages", slug="villages") NewsItem.objects.create( - title='unpublished news item', - content='unpublished news body here', + title="unpublished news item", content="unpublished news body here" ) - self.output('Creating products...') - name = 'PROSA bus transport (PROSA members only)' + self.output("Creating products...") + name = "PROSA bus transport (PROSA members only)" product0 = Product.objects.create( name=name, category=transportation, price=125, - description='PROSA is sponsoring a bustrip from Copenhagen to the venue and back.', + description="PROSA is sponsoring a bustrip from Copenhagen to the venue and back.", available_in=( timezone.datetime(2017, 3, 1, 11, 0, tzinfo=timezone.utc), timezone.datetime(2017, 10, 30, 11, 30, tzinfo=timezone.utc), ), - slug='{}'.format(slugify(name)), + slug="{}".format(slugify(name)), ) - name = 'PROSA bus transport (open for everyone)' + name = "PROSA bus transport (open for everyone)" product1 = Product.objects.create( name=name, category=transportation, price=125, - description='PROSA is sponsoring a bustrip from Copenhagen to the venue and back.', + description="PROSA is sponsoring a bustrip from Copenhagen to the venue and back.", available_in=( timezone.datetime(2017, 3, 1, 11, 0, tzinfo=timezone.utc), timezone.datetime(2017, 10, 30, 11, 30, tzinfo=timezone.utc), ), - slug='{}'.format(slugify(name)), + slug="{}".format(slugify(name)), ) - name = 'T-shirt (large)' + name = "T-shirt (large)" product2 = Product.objects.create( name=name, category=merchandise, price=160, - description='Get a nice t-shirt', + description="Get a nice t-shirt", available_in=( timezone.datetime(2017, 3, 1, 11, 0, tzinfo=timezone.utc), timezone.datetime(2017, 10, 30, 11, 30, tzinfo=timezone.utc), ), - slug='{}'.format(slugify(name)), + slug="{}".format(slugify(name)), ) - name = 'Village tent 3x3 meters, no floor' + name = "Village tent 3x3 meters, no floor" tent1 = Product.objects.create( name=name, - description='A description of the tent goes here', + description="A description of the tent goes here", price=3325, category=villages, available_in=( timezone.datetime(2017, 3, 1, 12, 0, tzinfo=timezone.utc), timezone.datetime(2017, 8, 20, 12, 0, tzinfo=timezone.utc), ), - slug='{}'.format(slugify(name)), + slug="{}".format(slugify(name)), ) - name = 'Village tent 3x3 meters, with floor' + name = "Village tent 3x3 meters, with floor" tent2 = Product.objects.create( name=name, - description='A description of the tent goes here', + description="A description of the tent goes here", price=3675, category=villages, available_in=( timezone.datetime(2017, 3, 1, 12, 0, tzinfo=timezone.utc), timezone.datetime(2017, 8, 20, 12, 0, tzinfo=timezone.utc), ), - slug='{}'.format(slugify(name)), + slug="{}".format(slugify(name)), ) for camp in [camp2016, camp2017, camp2018]: year = camp.camp.lower.year - self.output('Creating tickettypes for {}...'.format(year)) + self.output("Creating tickettypes for {}...".format(year)) adult_full_week = TicketType.objects.create( - name='Adult Full Week', - camp=camp - ) - adult_one_day = TicketType.objects.create( - name='Adult One Day', - camp=camp + name="Adult Full Week", camp=camp ) + adult_one_day = TicketType.objects.create(name="Adult One Day", camp=camp) child_full_week = TicketType.objects.create( - name='Child Full Week', - camp=camp - ) - child_one_day = TicketType.objects.create( - name='Child One Day', - camp=camp + name="Child Full Week", camp=camp ) + child_one_day = TicketType.objects.create(name="Child One Day", camp=camp) - name = 'BornHack {} Standard ticket'.format(year) + name = "BornHack {} Standard ticket".format(year) ticket1 = Product.objects.create( name=name, - description='A ticket', + description="A ticket", price=1200, category=tickets, available_in=( timezone.datetime(year, 1, 1, 12, 0, tzinfo=timezone.utc), timezone.datetime(year, 12, 20, 12, 0, tzinfo=timezone.utc), ), - slug='{}'.format(slugify(name)), - ticket_type=adult_full_week + slug="{}".format(slugify(name)), + ticket_type=adult_full_week, ) - name = 'BornHack {} Hacker ticket'.format(year) + name = "BornHack {} Hacker ticket".format(year) ticket2 = Product.objects.create( name=name, - description='Another ticket', + description="Another ticket", price=1337, category=tickets, available_in=( timezone.datetime(year, 1, 1, 12, 0, tzinfo=timezone.utc), timezone.datetime(year, 12, 20, 12, 0, tzinfo=timezone.utc), ), - slug='{}'.format(slugify(name)), - ticket_type=adult_full_week + slug="{}".format(slugify(name)), + ticket_type=adult_full_week, ) - self.output('Creating orders...') + self.output("Creating orders...") order0 = Order.objects.create( - user=user1, - payment_method='cash', - open=None, - paid=True - ) - order0.orderproductrelation_set.create( - product=ticket1, - quantity=1, - ) - order0.orderproductrelation_set.create( - product=tent1, - quantity=1, + user=user1, payment_method="cash", open=None, paid=True ) + order0.orderproductrelation_set.create(product=ticket1, quantity=1) + order0.orderproductrelation_set.create(product=tent1, quantity=1) order0.mark_as_paid(request=None) - order1 = Order.objects.create( - user=user2, - payment_method='cash', - open=None, - ) - order1.orderproductrelation_set.create( - product=ticket1, - quantity=1, - ) - order1.orderproductrelation_set.create( - product=tent2, - quantity=1, - ) + order1 = Order.objects.create(user=user2, payment_method="cash", open=None) + order1.orderproductrelation_set.create(product=ticket1, quantity=1) + order1.orderproductrelation_set.create(product=tent2, quantity=1) order1.mark_as_paid(request=None) - order2 = Order.objects.create( - user=user3, - payment_method='cash', - open=None, - ) - order2.orderproductrelation_set.create( - product=ticket2, - quantity=1, - ) - order2.orderproductrelation_set.create( - product=ticket1, - quantity=1, - ) - order2.orderproductrelation_set.create( - product=tent2, - quantity=1, - ) + order2 = Order.objects.create(user=user3, payment_method="cash", open=None) + order2.orderproductrelation_set.create(product=ticket2, quantity=1) + order2.orderproductrelation_set.create(product=ticket1, quantity=1) + order2.orderproductrelation_set.create(product=tent2, quantity=1) order2.mark_as_paid(request=None) - order3 = Order.objects.create( - user=user4, - payment_method='cash', - open=None, - ) - order3.orderproductrelation_set.create( - product=product0, - quantity=1, - ) - order3.orderproductrelation_set.create( - product=ticket2, - quantity=1, - ) - order3.orderproductrelation_set.create( - product=tent1, - quantity=1, - ) + order3 = Order.objects.create(user=user4, payment_method="cash", open=None) + order3.orderproductrelation_set.create(product=product0, quantity=1) + order3.orderproductrelation_set.create(product=ticket2, quantity=1) + order3.orderproductrelation_set.create(product=tent1, quantity=1) order3.mark_as_paid(request=None) - self.output('Creating eventtracks for {}...'.format(year)) + self.output("Creating eventtracks for {}...".format(year)) track = EventTrack.objects.create( - camp=camp, - name="BornHack", - slug=camp.slug, + camp=camp, name="BornHack", slug=camp.slug ) - self.output('Creating eventlocations for {}...'.format(year)) + self.output("Creating eventlocations for {}...".format(year)) speakers_tent = EventLocation.objects.create( - name='Speakers Tent', - slug='speakers-tent', - icon='comment', - camp=camp + name="Speakers Tent", slug="speakers-tent", icon="comment", camp=camp ) workshop_room = EventLocation.objects.create( - name='Workshop rooms', - slug='workshop-rooms', - icon='briefcase', - camp=camp + name="Workshop rooms", + slug="workshop-rooms", + icon="briefcase", + camp=camp, ) bar_area = EventLocation.objects.create( - name='Bar Area', - slug='bar-area', - icon='glass', - camp=camp + name="Bar Area", slug="bar-area", icon="glass", camp=camp ) food_area = EventLocation.objects.create( - name='Food Area', - slug='food-area', - icon='cutlery', - camp=camp + name="Food Area", slug="food-area", icon="cutlery", camp=camp ) - self.output('Creating news for {}...'.format(year)) + self.output("Creating news for {}...".format(year)) NewsItem.objects.create( - title='Welcome to {}'.format(camp.title), - content='news body here with html support', - published_at=timezone.datetime(year, 8, 27, 12, 0, tzinfo=timezone.utc) + title="Welcome to {}".format(camp.title), + content="news body here with html support", + published_at=timezone.datetime(year, 8, 27, 12, 0, tzinfo=timezone.utc), ) NewsItem.objects.create( - title='{} is over'.format(camp.title), - content='news body here', - published_at=timezone.datetime(year, 9, 4, 12, 0, tzinfo=timezone.utc) + title="{} is over".format(camp.title), + content="news body here", + published_at=timezone.datetime(year, 9, 4, 12, 0, tzinfo=timezone.utc), ) self.output("Creating events for {}...".format(year)) ev1 = Event.objects.create( - title='Developing the BornHack website', - abstract='abstract here, bla bla bla', + title="Developing the BornHack website", + abstract="abstract here, bla bla bla", event_type=talk, - track=track + track=track, ) ev2 = Event.objects.create( - title='State of the world', - abstract='abstract here, bla bla bla', + title="State of the world", + abstract="abstract here, bla bla bla", event_type=keynote, - track=track + track=track, ) ev3 = Event.objects.create( - title='Welcome to bornhack!', - abstract='abstract here, bla bla bla', + title="Welcome to bornhack!", + abstract="abstract here, bla bla bla", event_type=talk, - track=track + track=track, ) ev4 = Event.objects.create( - title='bar is open', - abstract='the bar is open, yay', + title="bar is open", + abstract="the bar is open, yay", event_type=facility, - track=track + track=track, ) ev5 = Event.objects.create( - title='Network something', - abstract='abstract here, bla bla bla', + title="Network something", + abstract="abstract here, bla bla bla", event_type=talk, - track=track + track=track, ) ev6 = Event.objects.create( - title='State of outer space', - abstract='abstract here, bla bla bla', + title="State of outer space", + abstract="abstract here, bla bla bla", event_type=talk, - track=track + track=track, ) ev9 = Event.objects.create( - title='The Alternative Welcoming', - abstract='Why does The Alternative support BornHack? Why does The Alternative think IT is an overlooked topic? A quick runt-hrough of our program and workshops. We will bring an IT political debate to both the stage and the beer tents.', + title="The Alternative Welcoming", + abstract="Why does The Alternative support BornHack? Why does The Alternative think IT is an overlooked topic? A quick runt-hrough of our program and workshops. We will bring an IT political debate to both the stage and the beer tents.", event_type=talk, - track=track + track=track, ) ev10 = Event.objects.create( - title='Words and Power - are we making the most of online activism?', - abstract='For years, big names like Ed Snowden and Chelsea Manning have given up their lives in order to protect regular people like you and me from breaches of our privacy. But we are still struggling with getting people interested in internet privacy. Why is this, and what can we do? Using experience from communicating privacy issues on multiple levels for a couple of years, I have encountered some deep seated issues in the way we talk about what privacy means. Are we good enough at letting people know whats going on?', + title="Words and Power - are we making the most of online activism?", + abstract="For years, big names like Ed Snowden and Chelsea Manning have given up their lives in order to protect regular people like you and me from breaches of our privacy. But we are still struggling with getting people interested in internet privacy. Why is this, and what can we do? Using experience from communicating privacy issues on multiple levels for a couple of years, I have encountered some deep seated issues in the way we talk about what privacy means. Are we good enough at letting people know whats going on?", event_type=keynote, - track=track + track=track, ) ev11 = Event.objects.create( - title='r4d1o hacking 101', - abstract='Learn how to enable the antenna part of your ccc badge and get started with receiving narrow band FM. In the workshop you will have the opportunity to sneak peak on the organizers radio communications using your SDR. If there is more time we will look at WiFi radar or your protocol of choice.', + title="r4d1o hacking 101", + abstract="Learn how to enable the antenna part of your ccc badge and get started with receiving narrow band FM. In the workshop you will have the opportunity to sneak peak on the organizers radio communications using your SDR. If there is more time we will look at WiFi radar or your protocol of choice.", event_type=workshop, - track=track + track=track, ) ev12 = Event.objects.create( - title='Introduction to Sustainable Growth in a Digital World', - abstract='Free Choice is the underestimated key to secure value creation in a complex economy, where GDP-models only measure commercial profit and ignore the environment. We reconstruct the model thinking about Utility, Production, Security and Environment around the 5 Criteria for Sustainability.', + title="Introduction to Sustainable Growth in a Digital World", + abstract="Free Choice is the underestimated key to secure value creation in a complex economy, where GDP-models only measure commercial profit and ignore the environment. We reconstruct the model thinking about Utility, Production, Security and Environment around the 5 Criteria for Sustainability.", event_type=workshop, - track=track + track=track, ) ev13 = Event.objects.create( - title='American Fuzzy Lop and Address Sanitizer', - abstract=''' + title="American Fuzzy Lop and Address Sanitizer", + abstract=""" We have powerful and easy to use tools that can vastly improve the quality and security of the code we use everyday. Code written in C and C++ is often riddled with bugs in the memory management. Out of bounds accesses, use after free errors and other issues can hamper the security and stability of applications. Unfortunately many free software developers don't use freely available tools that easily allow finding and eliminating many of these bugs. The talk will encourage developers to change that and integrate these tools into their development process. Slides: [https://www.int21.de/slides/bornhack2016-fuzzing/](https://www.int21.de/slides/bornhack2016-fuzzing/) - ''', + """, event_type=talk, - track=track + track=track, ) ev14 = Event.objects.create( - title='PGP Keysigning Party', - abstract=''' + title="PGP Keysigning Party", + abstract=""" Let's verify each other's digital PGP keys at BornHack so that we can authenticate each other when we are not together at the island. For people who haven't attended a PGP keysigning party before, we will guide you through it @@ -696,13 +554,13 @@ For people who haven't attended a PGP keysigning party before, we will guide you 1. Bring the output of `gpg --fingerprint $YOUR_KEY_ID` on some pieces of paper to hand out. 2. (Optional) Bring some government-issued identification paper (passport, drivers license, etc.). The ID should contain a picture of yourself. You can leave this out, but then it will be a bit harder for others to verify your key properly. - ''', + """, event_type=workshop, - track=track + track=track, ) ev15 = Event.objects.create( - title='Bluetooth Low Energy', - abstract=''' + title="Bluetooth Low Energy", + abstract=""" BLE provides versatile wireless communication at a very low power consumption, especially compared to classic Bluetooth and WiFi. @@ -726,13 +584,13 @@ This talk explains how the low power consumption is achieved, what the possible topologies are, and how this affects the types of applications you can build on top. Finally, a low-level demonstration of interfacing with a BLE controller is performed. - ''', + """, event_type=talk, - track=track + track=track, ) ev16 = Event.objects.create( - title='TLS attacks and the burden of faulty TLS implementations', - abstract=''' + title="TLS attacks and the burden of faulty TLS implementations", + abstract=""" TLS is by far the most important cryptographic protocol in use today. In recent years TLS received much more attention from security researchers. Implementation errors like Heartbleed and protocol bugs @@ -748,19 +606,19 @@ happened in various TLS stacks and will shed light on this underappreciated problem. Slides: [https://www.int21.de/slides/bornhack2016-tls/](https://www.int21.de/slides/bornhack2016-tls/) - ''', + """, event_type=talk, - track=track + track=track, ) ev17 = Event.objects.create( - title='State of the Network', - abstract='Come and meet the network team who will talk about the design and operation of the network at BornHack.', + title="State of the Network", + abstract="Come and meet the network team who will talk about the design and operation of the network at BornHack.", event_type=talk, - track=track + track=track, ) ev18 = Event.objects.create( - title='Running Exit Nodes in the North', - abstract=''' + title="Running Exit Nodes in the North", + abstract=""" Tor is free software and an open network that helps you defend against traffic analysis, a form of network surveillance that threatens personal freedom and privacy, confidential business activities and relationships, @@ -782,25 +640,25 @@ of law enforcement agencies. In Finland, Juha Nurmi has been establishing good relationships with ISPs and law enforcement agencies to keep Finnish exit nodes online. - ''', + """, event_type=talk, - track=track + track=track, ) ev19 = Event.objects.create( - title='Hacker Jeopardy Qualifier', - abstract='Hacker Jeopardy qualifying', + title="Hacker Jeopardy Qualifier", + abstract="Hacker Jeopardy qualifying", event_type=slack, - track=track + track=track, ) ev20 = Event.objects.create( - title='Hacker Jeopardy Finals', - abstract='Hacker Jeopardy Finals between the winners of the qualifying games', + title="Hacker Jeopardy Finals", + abstract="Hacker Jeopardy Finals between the winners of the qualifying games", event_type=slack, - track=track + track=track, ) ev21 = Event.objects.create( - title='Incompleteness Phenomena in Mathematics: From Kurt Gödel to Harvey Friedman', - abstract=''' + title="Incompleteness Phenomena in Mathematics: From Kurt Gödel to Harvey Friedman", + abstract=""" In the first half of the 20th century the dreams of a complete and consistent formalization of mathematics was destroyed, when Kurt Gödel proved the existence of true but unprovable sentences in every @@ -812,13 +670,13 @@ in general. Since then various incompleteness phenomena have been discovered and many of these (relative) unprovable sentences are of genuine mathematical interest. In recent years Harvey Friedman have taken this enterprise to a new level by constructing sentences about "low level" mathematics and showed that these sentences are provably equivalent to the consistency of axiomatic systems far stronger than classical set theory (ZFC). In this talk I will try to introduce concepts of mathematical logic together with some highlights in the history of incompleteness phenomena and discuss the philosophical implications of these. Note that these (early 20th century) developments also play an important role in developing the theoretical computer. - ''', + """, event_type=talk, - track=track + track=track, ) ev22 = Event.objects.create( - title='Infocalypse Now - and how to Survive It?', - abstract=''' + title="Infocalypse Now - and how to Survive It?", + abstract=""" Digitalization is on everybodys mind - and so is control and registration of citizens. States and businesses all choose sadly unsecure data-silo-systems and piles up sensitive data without securing anything. @@ -829,31 +687,31 @@ used, our money system, personal data and administrations are doomed in a world of greedy blackhats, cyberwarfare-troops, autonomous drones, herfbombs, solarstorms and intelligence agencies on steroids The Beast is unleashed, can it be stopped, or is it anyone for him self? - ''', + """, event_type=keynote, - track=track + track=track, ) ev23 = Event.objects.create( - title='Liquid Democracy (Introduction and Debate)', - abstract=''' + title="Liquid Democracy (Introduction and Debate)", + abstract=""" A lot has happened ever since the German pirates developed the first visions about a dynamic representational democracy. Google and other big players have experimented with the disciplines, and the idea of a more modern form of democracy has grown steadily. Monday will primarily be focused around The Alternatives experiment with Liquid Democracy and a constructive debate about how liquid democracy can improve The Alternative. Rolf Bjerre leads the process. - ''', + """, event_type=talk, - track=track + track=track, ) ev24 = Event.objects.create( - title='Badge Workshop', - abstract=''' + title="Badge Workshop", + abstract=""" In this workshop you can learn how to solder and get help assembling your badge. We will have soldering irons and other tools to help things along. You can also discuss your ideas for badge hacks and modifications with the other participants and the host, Thomas Flummer. - ''', + """, event_type=workshop, - track=track + track=track, ) ev25 = Event.objects.create( - title='Checking a Distributed Hash Table for Correctness', - abstract=''' + title="Checking a Distributed Hash Table for Correctness", + abstract=""" Distributed Hash Tables are used as name-lookups in large decentralized distributed systems such as peer-to-peer networks and loosely connected machine clusters. @@ -873,13 +731,13 @@ specification into isolated parts and then reassembling those parts into a full model. It is intended to give people an overview of how to attack larger code bases with (semi-) formal methods. - ''', + """, event_type=talk, - track=track + track=track, ) ev26 = Event.objects.create( - title='GraphQL - A Data Language', - abstract=''' + title="GraphQL - A Data Language", + abstract=""" GraphQL is a query-language for data, intended for the modern internet clients on the web and inside mobile phones, invented inside Facebook around 2012, it is currently @@ -902,118 +760,118 @@ This talk presents GraphQL itself, and also presents how one goes about building an implementation of the language. The running example is a GraphQL compiler written for Erlang. - ''', + """, event_type=talk, - track=track + track=track, ) ev27 = Event.objects.create( - title='Visualisation of Public Datasets', - abstract=''' + title="Visualisation of Public Datasets", + abstract=""" At the same time as society is getting more complex, the amount of data is growing exponentially. How are everyday citizens to relate to National budgets used in the media? I am going to talk about one of the ways I think will make it easier to understand the datasets used in the media. I will present some portals where it is possible to get public datasets. Afterwards we will reflect about the use of these datasets. Towards the end we will open up to debate about how to use these resources or if there are other solutions. - ''', + """, event_type=workshop, - track=track + track=track, ) ev28 = Event.objects.create( - title='Local delicacies', - abstract='Come taste delicacies from bornholm', + title="Local delicacies", + abstract="Come taste delicacies from bornholm", event_type=facility, - track=track + track=track, ) ev29 = Event.objects.create( - title='Local delicacies from the world', - abstract='An attempt to create an event where we all prepare local delicacies for each other', + title="Local delicacies from the world", + abstract="An attempt to create an event where we all prepare local delicacies for each other", event_type=facility, - track=track + track=track, ) self.output("Creating speakers for {}...".format(year)) sp1 = Speaker.objects.create( - name='Henrik Kramse', - biography='Henrik is an internet samurai working in internet and security around the world.', - slug='henrik-kramshj', + name="Henrik Kramse", + biography="Henrik is an internet samurai working in internet and security around the world.", + slug="henrik-kramshj", camp=camp, email="email@email.lol", ) sp1.events.add(ev5) sp2 = Speaker.objects.create( - name='Thomas Tykling', - biography='random danish hacker', - slug='thomas-tykling', + name="Thomas Tykling", + biography="random danish hacker", + slug="thomas-tykling", camp=camp, email="email@email.lol", ) sp2.events.add(ev3, ev1) sp3 = Speaker.objects.create( - name='Alex Ahf', - biography='functional alcoholic', - slug='alex-ahf', + name="Alex Ahf", + biography="functional alcoholic", + slug="alex-ahf", camp=camp, email="email@email.lol", ) sp3.events.add(ev4, ev2) sp4 = Speaker.objects.create( - name='Jesper Arp', - biography='Representative from The Alternative with focus in data visualization.', - slug='jesper-arp', + name="Jesper Arp", + biography="Representative from The Alternative with focus in data visualization.", + slug="jesper-arp", camp=camp, email="email@email.lol", ) sp4.events.add(ev9, ev27) sp5 = Speaker.objects.create( - name='Rolf Bjerre', - biography='The green pirate', - slug='rolf-bjerre', + name="Rolf Bjerre", + biography="The green pirate", + slug="rolf-bjerre", camp=camp, email="email@email.lol", ) sp5.events.add(ev9, ev23) sp6 = Speaker.objects.create( - name='Emma Holten', - biography='Emma Holten is a feminist and human rights activist. She is co-founder and editor of the standard critical magazine Friktion and also a student at the University of Copenhagen. She speaks in both national and global contexts of feminism, digital activism and why privacy on the internet is crucial to a democracy, where everyone is equal.', - slug='emma-holten', + name="Emma Holten", + biography="Emma Holten is a feminist and human rights activist. She is co-founder and editor of the standard critical magazine Friktion and also a student at the University of Copenhagen. She speaks in both national and global contexts of feminism, digital activism and why privacy on the internet is crucial to a democracy, where everyone is equal.", + slug="emma-holten", camp=camp, email="email@email.lol", ) sp6.events.add(ev10) sp7 = Speaker.objects.create( - name='Christoffer Jerkeby', - biography='Hacker and phone phreaker from Stockholm bent on radio. Researching security and privacy in wireless protocols.', - slug='christoffer-jerkeby', + name="Christoffer Jerkeby", + biography="Hacker and phone phreaker from Stockholm bent on radio. Researching security and privacy in wireless protocols.", + slug="christoffer-jerkeby", camp=camp, email="email@email.lol", ) sp7.events.add(ev11) sp8 = Speaker.objects.create( - name='Stephan Engberg', - biography='Stephan Engberg is a Computer Scientist specializing in Innovation Strategist working with Digital Business when he realized the Digital World is designed through our approach to security models and economic models. He then dedicated himself to Privacy/Security by Design in Open Business Innovation making numerous breakthroughs in security and engaged in EU research activities he was e.g. member of the Strategic Advisory Board for FP7 Security Research Roadmapping and started manufacturing of RFID computer chips based on Privacy by Design with zero-knowledge based computing in passive chips without battery or ultra-low memory and computational capabilities. In 2003, he was selected by an a transatlantic panel of researchers in ethics as a Moral Example in the Computer Profession.', - slug='stephan-engberg', + name="Stephan Engberg", + biography="Stephan Engberg is a Computer Scientist specializing in Innovation Strategist working with Digital Business when he realized the Digital World is designed through our approach to security models and economic models. He then dedicated himself to Privacy/Security by Design in Open Business Innovation making numerous breakthroughs in security and engaged in EU research activities he was e.g. member of the Strategic Advisory Board for FP7 Security Research Roadmapping and started manufacturing of RFID computer chips based on Privacy by Design with zero-knowledge based computing in passive chips without battery or ultra-low memory and computational capabilities. In 2003, he was selected by an a transatlantic panel of researchers in ethics as a Moral Example in the Computer Profession.", + slug="stephan-engberg", camp=camp, email="email@email.lol", ) sp8.events.add(ev12) sp9 = Speaker.objects.create( - name='Hanno Böck', - biography=''' + name="Hanno Böck", + biography=""" Hanno Böck started the Fuzzing Project in 2014 as an effort to improve the security of free software code. In May the Linux Foundation's Core Infrastructure Initiative decided to fund this work. He is also working as a freelance journalist and regularly writes about IT security issues for various publications. He is the author of the monthly Bulletproof TLS Newsletter. - ''', - slug='hanno-bock', + """, + slug="hanno-bock", camp=camp, email="email@email.lol", ) sp9.events.add(ev13, ev16) sp10 = Speaker.objects.create( - name='Ximin Luo', - biography=''' + name="Ximin Luo", + biography=""" I'm Ximin Luo, a Debian Developer and security research engineer. I work on secure protocols and decentralized systems. I prefer to use high-level checked languages such as Rust, OCaml, or Haskell. I work for the Reproducible Builds @@ -1021,90 +879,90 @@ project and have previously worked for MEGA, Tor, Google and Freenet. I also like music, cooking, sci-fi and cats, in an order indistinguishable from a truly random sequence by a polynomial-time-bounded computational adversary. - ''', - slug='ximin-luo', + """, + slug="ximin-luo", camp=camp, email="email@email.lol", ) sp10.events.add(ev14) sp11 = Speaker.objects.create( - name='Michael Knudsen', - biography=''' + name="Michael Knudsen", + biography=""" Michael has been involved in various open source-related projects. His dayjob involves writing firmware for a BT/wifi controller for a semiconductor company. - ''', - slug='michael-knudsen', + """, + slug="michael-knudsen", camp=camp, email="email@email.lol", ) sp11.events.add(ev15) sp12 = Speaker.objects.create( - name='BornHack Network Team', - biography='The team you won\'t notice if everything goes as it should. Please bring them rum or beer if they look too stressed.', - slug='bornhack-network-team', + name="BornHack Network Team", + biography="The team you won't notice if everything goes as it should. Please bring them rum or beer if they look too stressed.", + slug="bornhack-network-team", camp=camp, email="email@email.lol", ) sp12.events.add(ev17) sp13 = Speaker.objects.create( - name='Juha Nurmi', - biography=''' + name="Juha Nurmi", + biography=""" Juha Nurmi (age 28) is the founder and project leader of the Ahmia search engine project. He is a security researcher and has been involved in numerous projects funded by both the commercial and government spheres, including DARPA Memex project in the Silicon Valley. Juha is also a noted lecturer and public speaker. Juha's work on Ahmia has been in part sponsored by the Google Summer of Code. - ''', - slug='juha-nurmi', + """, + slug="juha-nurmi", camp=camp, email="email@email.lol", ) sp13.events.add(ev18) sp14 = Speaker.objects.create( - name='Lasse Andersen', - biography=''' + name="Lasse Andersen", + biography=""" My educational background is a masters degree in philosophy & mathematics and a PhD in applied mathematics and road engineering. My personal interests cover philosophy of IT, philosophy of math, programming, machine learning, road engineering. Also, I enjoy nature quite a bit. Presently, I work at the Danish Road Directorate with rolling resistance modelling and pavement management as the main focus. Besides doing a lot of programming at work (primarily Python) I also experiment with Erlang in my spare time trying to build peer2peer software. - ''', - slug='lasse-andersen', + """, + slug="lasse-andersen", camp=camp, email="email@email.lol", ) sp14.events.add(ev21) sp15 = Speaker.objects.create( - name='Anders Kjærulff', - biography=''' + name="Anders Kjærulff", + biography=""" Anders Kjærulff is a jounalist, poet, technology-critic and radiohost with a weekly, one hour radioshow on privacy and data protection. He is currently working on a dystopic book about the end of all privacy and the dim future, that lies ahead. Website: [aflyttet.dk](https://aflyttet.dk) - ''', - slug='anders-kjrulff', + """, + slug="anders-kjrulff", camp=camp, email="email@email.lol", ) sp15.events.add(ev22) sp16 = Speaker.objects.create( - name='Thomas Flummer', - biography=''' + name="Thomas Flummer", + biography=""" Thomas is an electronics engineer, though he is mostly doing software development in his professional life. For the past 7 years Thomas has been a member of the hackerspace Labitat, where he has been doing various projects, mostly with electronics, 3D printing and video documentation. - ''', - slug='thomas-flummer', + """, + slug="thomas-flummer", camp=camp, email="email@email.lol", ) sp16.events.add(ev24) sp17 = Speaker.objects.create( - name='Jesper Louis Andersen', - biography=''' + name="Jesper Louis Andersen", + biography=""" Jesper Louis Andersen bridges the gap between theory and practice. He has a curiosity for programming language theory, math, and logic, but dabbles in many other @@ -1113,8 +971,8 @@ science as well. His main interest is to move state-of-the-art computer science research into real world use whenever possible. His dayjob involves functional programming for a danish startup. - ''', - slug='jesper-louis-andersen', + """, + slug="jesper-louis-andersen", camp=camp, email="email@email.lol", ) @@ -1127,7 +985,7 @@ programming for a danish startup. when=( timezone.datetime(year, 8, 27, 12, 0, tzinfo=timezone.utc), timezone.datetime(year, 8, 27, 13, 0, tzinfo=timezone.utc), - ) + ), ) EventInstance.objects.create( event=ev1, @@ -1135,7 +993,7 @@ programming for a danish startup. when=( timezone.datetime(year, 8, 28, 12, 0, tzinfo=timezone.utc), timezone.datetime(year, 8, 28, 13, 0, tzinfo=timezone.utc), - ) + ), ) EventInstance.objects.create( event=ev2, @@ -1143,7 +1001,7 @@ programming for a danish startup. when=( timezone.datetime(year, 8, 29, 12, 0, tzinfo=timezone.utc), timezone.datetime(year, 8, 29, 13, 0, tzinfo=timezone.utc), - ) + ), ) EventInstance.objects.create( event=ev4, @@ -1151,7 +1009,7 @@ programming for a danish startup. when=( timezone.datetime(year, 8, 27, 12, 0, tzinfo=timezone.utc), timezone.datetime(year, 8, 28, 5, 0, tzinfo=timezone.utc), - ) + ), ) EventInstance.objects.create( event=ev4, @@ -1159,7 +1017,7 @@ programming for a danish startup. when=( timezone.datetime(year, 8, 28, 12, 0, tzinfo=timezone.utc), timezone.datetime(year, 8, 29, 5, 0, tzinfo=timezone.utc), - ) + ), ) EventInstance.objects.create( event=ev4, @@ -1167,7 +1025,7 @@ programming for a danish startup. when=( timezone.datetime(year, 8, 29, 12, 0, tzinfo=timezone.utc), timezone.datetime(year, 8, 30, 5, 0, tzinfo=timezone.utc), - ) + ), ) EventInstance.objects.create( event=ev4, @@ -1175,7 +1033,7 @@ programming for a danish startup. when=( timezone.datetime(year, 8, 30, 12, 0, tzinfo=timezone.utc), timezone.datetime(year, 8, 31, 5, 0, tzinfo=timezone.utc), - ) + ), ) EventInstance.objects.create( event=ev4, @@ -1183,7 +1041,7 @@ programming for a danish startup. when=( timezone.datetime(year, 8, 31, 12, 0, tzinfo=timezone.utc), timezone.datetime(year, 9, 1, 5, 0, tzinfo=timezone.utc), - ) + ), ) EventInstance.objects.create( event=ev4, @@ -1191,7 +1049,7 @@ programming for a danish startup. when=( timezone.datetime(year, 9, 1, 12, 0, tzinfo=timezone.utc), timezone.datetime(year, 9, 2, 5, 0, tzinfo=timezone.utc), - ) + ), ) EventInstance.objects.create( event=ev4, @@ -1199,7 +1057,7 @@ programming for a danish startup. when=( timezone.datetime(year, 9, 2, 12, 0, tzinfo=timezone.utc), timezone.datetime(year, 9, 3, 5, 0, tzinfo=timezone.utc), - ) + ), ) EventInstance.objects.create( event=ev5, @@ -1207,7 +1065,7 @@ programming for a danish startup. when=( timezone.datetime(year, 8, 28, 12, 0, tzinfo=timezone.utc), timezone.datetime(year, 8, 28, 13, 0, tzinfo=timezone.utc), - ) + ), ) EventInstance.objects.create( event=ev6, @@ -1215,7 +1073,7 @@ programming for a danish startup. when=( timezone.datetime(year, 8, 29, 12, 0, tzinfo=timezone.utc), timezone.datetime(year, 8, 29, 13, 0, tzinfo=timezone.utc), - ) + ), ) EventInstance.objects.create( event=ev9, @@ -1223,7 +1081,7 @@ programming for a danish startup. when=( timezone.datetime(year, 8, 30, 11, 0, tzinfo=timezone.utc), timezone.datetime(year, 8, 30, 11, 30, tzinfo=timezone.utc), - ) + ), ) EventInstance.objects.create( event=ev10, @@ -1231,7 +1089,7 @@ programming for a danish startup. when=( timezone.datetime(year, 8, 30, 12, 0, tzinfo=timezone.utc), timezone.datetime(year, 8, 30, 13, 0, tzinfo=timezone.utc), - ) + ), ) EventInstance.objects.create( event=ev12, @@ -1239,7 +1097,7 @@ programming for a danish startup. when=( timezone.datetime(year, 8, 30, 9, 0, tzinfo=timezone.utc), timezone.datetime(year, 8, 30, 11, 30, tzinfo=timezone.utc), - ) + ), ) EventInstance.objects.create( event=ev11, @@ -1247,7 +1105,7 @@ programming for a danish startup. when=( timezone.datetime(year, 8, 31, 14, 0, tzinfo=timezone.utc), timezone.datetime(year, 8, 31, 16, 0, tzinfo=timezone.utc), - ) + ), ) EventInstance.objects.create( event=ev18, @@ -1255,7 +1113,7 @@ programming for a danish startup. when=( timezone.datetime(year, 9, 2, 14, 0, tzinfo=timezone.utc), timezone.datetime(year, 9, 2, 15, 0, tzinfo=timezone.utc), - ) + ), ) EventInstance.objects.create( event=ev17, @@ -1263,7 +1121,7 @@ programming for a danish startup. when=( timezone.datetime(year, 9, 2, 16, 0, tzinfo=timezone.utc), timezone.datetime(year, 9, 2, 17, 0, tzinfo=timezone.utc), - ) + ), ) EventInstance.objects.create( event=ev15, @@ -1271,7 +1129,7 @@ programming for a danish startup. when=( timezone.datetime(year, 9, 1, 15, 0, tzinfo=timezone.utc), timezone.datetime(year, 9, 1, 16, 0, tzinfo=timezone.utc), - ) + ), ) EventInstance.objects.create( event=ev14, @@ -1279,7 +1137,7 @@ programming for a danish startup. when=( timezone.datetime(year, 8, 31, 21, 0, tzinfo=timezone.utc), timezone.datetime(year, 8, 31, 22, 0, tzinfo=timezone.utc), - ) + ), ) EventInstance.objects.create( event=ev16, @@ -1287,7 +1145,7 @@ programming for a danish startup. when=( timezone.datetime(year, 9, 1, 14, 0, tzinfo=timezone.utc), timezone.datetime(year, 9, 1, 15, 0, tzinfo=timezone.utc), - ) + ), ) EventInstance.objects.create( event=ev13, @@ -1295,7 +1153,7 @@ programming for a danish startup. when=( timezone.datetime(year, 8, 31, 17, 0, tzinfo=timezone.utc), timezone.datetime(year, 8, 31, 18, 0, tzinfo=timezone.utc), - ) + ), ) EventInstance.objects.create( event=ev19, @@ -1303,7 +1161,7 @@ programming for a danish startup. when=( timezone.datetime(year, 8, 30, 22, 0, tzinfo=timezone.utc), timezone.datetime(year, 8, 30, 23, 0, tzinfo=timezone.utc), - ) + ), ) EventInstance.objects.create( event=ev19, @@ -1311,7 +1169,7 @@ programming for a danish startup. when=( timezone.datetime(year, 8, 29, 22, 0, tzinfo=timezone.utc), timezone.datetime(year, 8, 29, 23, 0, tzinfo=timezone.utc), - ) + ), ) EventInstance.objects.create( event=ev19, @@ -1319,7 +1177,7 @@ programming for a danish startup. when=( timezone.datetime(year, 8, 28, 22, 0, tzinfo=timezone.utc), timezone.datetime(year, 8, 28, 23, 0, tzinfo=timezone.utc), - ) + ), ) EventInstance.objects.create( event=ev19, @@ -1327,7 +1185,7 @@ programming for a danish startup. when=( timezone.datetime(year, 8, 31, 22, 0, tzinfo=timezone.utc), timezone.datetime(year, 8, 31, 23, 0, tzinfo=timezone.utc), - ) + ), ) EventInstance.objects.create( event=ev19, @@ -1335,7 +1193,7 @@ programming for a danish startup. when=( timezone.datetime(year, 9, 1, 22, 0, tzinfo=timezone.utc), timezone.datetime(year, 9, 1, 23, 0, tzinfo=timezone.utc), - ) + ), ) EventInstance.objects.create( event=ev20, @@ -1343,7 +1201,7 @@ programming for a danish startup. when=( timezone.datetime(year, 9, 2, 20, 0, tzinfo=timezone.utc), timezone.datetime(year, 9, 2, 22, 0, tzinfo=timezone.utc), - ) + ), ) EventInstance.objects.create( event=ev21, @@ -1351,7 +1209,7 @@ programming for a danish startup. when=( timezone.datetime(year, 8, 28, 12, 0, tzinfo=timezone.utc), timezone.datetime(year, 8, 28, 13, 0, tzinfo=timezone.utc), - ) + ), ) EventInstance.objects.create( event=ev22, @@ -1359,7 +1217,7 @@ programming for a danish startup. when=( timezone.datetime(year, 8, 28, 18, 0, tzinfo=timezone.utc), timezone.datetime(year, 8, 28, 19, 0, tzinfo=timezone.utc), - ) + ), ) EventInstance.objects.create( event=ev23, @@ -1367,7 +1225,7 @@ programming for a danish startup. when=( timezone.datetime(year, 8, 29, 9, 0, tzinfo=timezone.utc), timezone.datetime(year, 8, 29, 11, 30, tzinfo=timezone.utc), - ) + ), ) EventInstance.objects.create( event=ev24, @@ -1375,7 +1233,7 @@ programming for a danish startup. when=( timezone.datetime(year, 8, 29, 20, 0, tzinfo=timezone.utc), timezone.datetime(year, 8, 29, 22, 0, tzinfo=timezone.utc), - ) + ), ) EventInstance.objects.create( event=ev25, @@ -1383,7 +1241,7 @@ programming for a danish startup. when=( timezone.datetime(year, 9, 1, 17, 0, tzinfo=timezone.utc), timezone.datetime(year, 9, 1, 18, 0, tzinfo=timezone.utc), - ) + ), ) EventInstance.objects.create( event=ev26, @@ -1391,7 +1249,7 @@ programming for a danish startup. when=( timezone.datetime(year, 8, 30, 11, 0, tzinfo=timezone.utc), timezone.datetime(year, 8, 30, 12, 0, tzinfo=timezone.utc), - ) + ), ) EventInstance.objects.create( event=ev26, @@ -1399,7 +1257,7 @@ programming for a danish startup. when=( timezone.datetime(year, 9, 1, 11, 45, tzinfo=timezone.utc), timezone.datetime(year, 9, 1, 12, 30, tzinfo=timezone.utc), - ) + ), ) EventInstance.objects.create( event=ev28, @@ -1407,7 +1265,7 @@ programming for a danish startup. when=( timezone.datetime(year, 9, 1, 18, 30, tzinfo=timezone.utc), timezone.datetime(year, 9, 1, 21, 30, tzinfo=timezone.utc), - ) + ), ) EventInstance.objects.create( event=ev29, @@ -1415,210 +1273,154 @@ programming for a danish startup. when=( timezone.datetime(year, 8, 29, 18, 30, tzinfo=timezone.utc), timezone.datetime(year, 8, 29, 23, 30, tzinfo=timezone.utc), - ) + ), ) self.output("Creating villages for {}...".format(year)) Village.objects.create( contact=user1, camp=camp, - name='Baconsvin', - slug='baconsvin', - description='The camp with the doorbell-pig! Baconsvin is a group of happy people from Denmark doing a lot of open source, and are always happy to talk about infosec, hacking, BSD, and much more. A lot of the organizers of BornHack live in Baconsvin village. Come by and squeeze the pig and sign our guestbook!' + name="Baconsvin", + slug="baconsvin", + description="The camp with the doorbell-pig! Baconsvin is a group of happy people from Denmark doing a lot of open source, and are always happy to talk about infosec, hacking, BSD, and much more. A lot of the organizers of BornHack live in Baconsvin village. Come by and squeeze the pig and sign our guestbook!", ) Village.objects.create( contact=user2, camp=camp, - name='NetworkWarriors', - slug='networkwarriors', - description='We will have a tent which house the NOC people, various lab equipment people can play with, and have fun. If you want to talk about networking, come by, and if you have trouble with the Bornhack network contact us.' + name="NetworkWarriors", + slug="networkwarriors", + description="We will have a tent which house the NOC people, various lab equipment people can play with, and have fun. If you want to talk about networking, come by, and if you have trouble with the Bornhack network contact us.", ) Village.objects.create( contact=user3, camp=camp, - name='TheCamp.dk', - slug='the-camp', - description='This village is representing TheCamp.dk, an annual danish tech camp held in July. The official subjects for this event is open source software, network and security. In reality we are interested in anything from computers to illumination soap bubbles and irish coffee' + name="TheCamp.dk", + slug="the-camp", + description="This village is representing TheCamp.dk, an annual danish tech camp held in July. The official subjects for this event is open source software, network and security. In reality we are interested in anything from computers to illumination soap bubbles and irish coffee", ) self.output("Creating teams for {}...".format(year)) orga_team = Team.objects.create( name="Orga", description="The Orga team are the main organisers. All tasks are Orga responsibility until they are delegated to another team", - camp=camp + camp=camp, ) noc_team = Team.objects.create( name="NOC", description="The NOC team is in charge of establishing and running a network onsite.", - camp=camp + camp=camp, ) bar_team = Team.objects.create( name="Bar", description="The Bar team plans, builds and run the IRL bar!", - camp=camp + camp=camp, ) self.output("Creating TeamTasks for {}...".format(year)) TeamTask.objects.create( team=noc_team, name="Setup private networks", - description="All the private networks need to be setup" + description="All the private networks need to be setup", ) TeamTask.objects.create( team=noc_team, name="Setup public networks", - description="All the public networks need to be setup" + description="All the public networks need to be setup", ) TeamTask.objects.create( team=noc_team, name="Deploy access points", - description="All access points need to be deployed" + description="All access points need to be deployed", ) TeamTask.objects.create( team=noc_team, name="Deploy fiber cables", - description="We need the fiber deployed where necessary" + description="We need the fiber deployed where necessary", ) TeamTask.objects.create( team=bar_team, name="List of booze", - description="A list of the different booze we need to have in the bar durng bornhack" + description="A list of the different booze we need to have in the bar durng bornhack", ) TeamTask.objects.create( team=bar_team, name="Chairs", - description="We need a solution for chairs" + description="We need a solution for chairs", ) TeamTask.objects.create( - team=bar_team, - name="Taps", - description="Taps must be ordered" + team=bar_team, name="Taps", description="Taps must be ordered" ) TeamTask.objects.create( team=bar_team, name="Coffee", - description="We need to get some coffee for our coffee machine" + description="We need to get some coffee for our coffee machine", ) TeamTask.objects.create( team=bar_team, name="Ice", - description="We need ice cubes and crushed ice in the bar" + description="We need ice cubes and crushed ice in the bar", ) self.output("Setting team members for {}...".format(year)) # noc team TeamMember.objects.create( - team=noc_team, - user=user4, - approved=True, - responsible=True - ) - TeamMember.objects.create( - team=noc_team, - user=user1, - approved=True, - ) - TeamMember.objects.create( - team=noc_team, - user=user5, - approved=True, - ) - TeamMember.objects.create( - team=noc_team, - user=user6, + team=noc_team, user=user4, approved=True, responsible=True ) + TeamMember.objects.create(team=noc_team, user=user1, approved=True) + TeamMember.objects.create(team=noc_team, user=user5, approved=True) + TeamMember.objects.create(team=noc_team, user=user6) # bar team TeamMember.objects.create( - team=bar_team, - user=user1, - approved=True, - responsible=True + team=bar_team, user=user1, approved=True, responsible=True ) TeamMember.objects.create( - team=bar_team, - user=user3, - approved=True, - responsible=True - ) - TeamMember.objects.create( - team=bar_team, - user=user2, - approved=True, - ) - TeamMember.objects.create( - team=bar_team, - user=user7, - approved=True, - ) - TeamMember.objects.create( - team=bar_team, - user=user8, + team=bar_team, user=user3, approved=True, responsible=True ) + TeamMember.objects.create(team=bar_team, user=user2, approved=True) + TeamMember.objects.create(team=bar_team, user=user7, approved=True) + TeamMember.objects.create(team=bar_team, user=user8) # orga team TeamMember.objects.create( - team=orga_team, - user=user1, - approved=True, - responsible=True + team=orga_team, user=user1, approved=True, responsible=True ) TeamMember.objects.create( - team=orga_team, - user=user3, - approved=True, - responsible=True - ) - TeamMember.objects.create( - team=orga_team, - user=user8, - approved=True, - ) - TeamMember.objects.create( - team=orga_team, - user=user9, - approved=True, - ) - TeamMember.objects.create( - team=orga_team, - user=user4, + team=orga_team, user=user3, approved=True, responsible=True ) + TeamMember.objects.create(team=orga_team, user=user8, approved=True) + TeamMember.objects.create(team=orga_team, user=user9, approved=True) + TeamMember.objects.create(team=orga_team, user=user4) self.output("Creating infocategories for {}...".format(year)) info_cat1 = InfoCategory.objects.create( - team=orga_team, - headline='When is BornHack happening?', - anchor='when' + team=orga_team, headline="When is BornHack happening?", anchor="when" ) info_cat2 = InfoCategory.objects.create( - team=orga_team, - headline='Travel Information', - anchor='travel' + team=orga_team, headline="Travel Information", anchor="travel" ) info_cat3 = InfoCategory.objects.create( - team=orga_team, - headline='Where do I sleep?', - anchor='sleep' + team=orga_team, headline="Where do I sleep?", anchor="sleep" ) self.output("Creating infoitems for {}...".format(year)) InfoItem.objects.create( category=info_cat1, - headline='Opening', - anchor='opening', - body='BornHack 2016 starts saturday, august 27th, at noon (12:00). It will be possible to access the venue before noon if for example you arrive early in the morning with the ferry. But please dont expect everything to be ready before noon :)' + headline="Opening", + anchor="opening", + body="BornHack 2016 starts saturday, august 27th, at noon (12:00). It will be possible to access the venue before noon if for example you arrive early in the morning with the ferry. But please dont expect everything to be ready before noon :)", ) InfoItem.objects.create( category=info_cat1, - headline='Closing', - anchor='closing', - body='BornHack 2016 ends saturday, september 3rd, at noon (12:00). Rented village tents must be empty and cleaned at this time, ready to take down. Participants must leave the site no later than 17:00 on the closing day (or stay and help us clean up).' + headline="Closing", + anchor="closing", + body="BornHack 2016 ends saturday, september 3rd, at noon (12:00). Rented village tents must be empty and cleaned at this time, ready to take down. Participants must leave the site no later than 17:00 on the closing day (or stay and help us clean up).", ) InfoItem.objects.create( category=info_cat2, - headline='Public Transportation', - anchor='public-transportation', - body=''' + headline="Public Transportation", + anchor="public-transportation", + body=""" From/Via Copenhagen There are several ways to get to Bornholm from Copenhagen. A domestic plane departs from Copenhagen Airport, and you can get from Copenhagen Central station by either bus or train via Ystad or the Køge-Rønne ferry connection. @@ -1655,53 +1457,49 @@ Kolobrzeg (Poland) Getting from Rønne to the Venue The venue is 24km from Rønne. We will have a shuttle bus that will pick people up and take them to the venue. It is also possible to take a public bus to near the venue. Local taxis can also get you here. The company operating on Bornholm is called Dantaxi and the local phonenumber is +4556952301. - ''' + """, ) InfoItem.objects.create( category=info_cat1, - headline='Bus to and from BornHack', - anchor='bus-to-and-from-bornhack', - body='PROSA, the union of IT-professionals in Denmark, has set up a great deal for BornHack attendees travelling from Copenhagen to BornHack. For only 125kr, about 17 euros, you can be transported to the camp on opening day, and back to Copenhagen at the end of the camp!' - + headline="Bus to and from BornHack", + anchor="bus-to-and-from-bornhack", + body="PROSA, the union of IT-professionals in Denmark, has set up a great deal for BornHack attendees travelling from Copenhagen to BornHack. For only 125kr, about 17 euros, you can be transported to the camp on opening day, and back to Copenhagen at the end of the camp!", ) InfoItem.objects.create( category=info_cat1, - headline='Driving and Parking', - anchor='driving-and-parking', - body=''' + headline="Driving and Parking", + anchor="driving-and-parking", + body=""" A car is very convenient when bringing lots of equipment, and we know that hackers like to bring all the things. We welcome cars and vans at BornHack. We have ample parking space very close (less than 50 meters) to the main entrance. Please note that sleeping in the parking lot is not permitted. If you want to sleep in your car/RV/autocamper/caravan please contact us, and we will work something out. - ''' + """, ) InfoItem.objects.create( category=info_cat3, - headline='Camping', - anchor='camping', - body='BornHack is first and foremost a tent camp. You need to bring a tent to sleep in. Most people go with some friends and make a camp somewhere at the venue. See also the section on Villages - you might be able to find some likeminded people to camp with.' + headline="Camping", + anchor="camping", + body="BornHack is first and foremost a tent camp. You need to bring a tent to sleep in. Most people go with some friends and make a camp somewhere at the venue. See also the section on Villages - you might be able to find some likeminded people to camp with.", ) InfoItem.objects.create( category=info_cat3, - headline='Cabins', - anchor='cabins', - body='We rent out a few cabins at the venue with 8 beds each for people who don\'t want to sleep in tents for some reason. A tent is the cheapest sleeping option (you just need a ticket), but the cabins are there if you want them.' + headline="Cabins", + anchor="cabins", + body="We rent out a few cabins at the venue with 8 beds each for people who don't want to sleep in tents for some reason. A tent is the cheapest sleeping option (you just need a ticket), but the cabins are there if you want them.", ) self.output("Adding event routing...") Routing.objects.create( team=orga_team, - eventtype=Type.objects.get(name="public_credit_name_changed") + eventtype=Type.objects.get(name="public_credit_name_changed"), ) Routing.objects.create( - team=orga_team, - eventtype=Type.objects.get(name="ticket_created") + team=orga_team, eventtype=Type.objects.get(name="ticket_created") ) - self.output("marking 2016 and 2017 as read_only...") camp2016.read_only = True camp2016.save() camp2017.read_only = True camp2017.save() self.output("done!") - diff --git a/src/utils/management/commands/run_managepy_worker.py b/src/utils/management/commands/run_managepy_worker.py index 6b3c098e..000b6675 100644 --- a/src/utils/management/commands/run_managepy_worker.py +++ b/src/utils/management/commands/run_managepy_worker.py @@ -4,26 +4,25 @@ import signal, sys import logging, importlib logging.basicConfig(level=logging.INFO) -logger = logging.getLogger('bornhack.%s' % __name__) +logger = logging.getLogger("bornhack.%s" % __name__) class Command(BaseCommand): - args = 'none' - help = 'Run a worker. Takes the worker module as the first positional argument and calls the do_work() function in it. Optional arguments can be seen with -h / --help' + args = "none" + help = "Run a worker. Takes the worker module as the first positional argument and calls the do_work() function in it. Optional arguments can be seen with -h / --help" exit_now = False - def add_arguments(self, parser): parser.add_argument( - 'workermodule', + "workermodule", type=str, - help='The dotted path to the module which contains the do_work() function to call periodically.' + help="The dotted path to the module which contains the do_work() function to call periodically.", ) parser.add_argument( - '--sleep', + "--sleep", type=int, default=60, - help='The number of seconds to sleep between calls' + help="The number of seconds to sleep between calls", ) def reload_worker(self, signum, frame): @@ -33,16 +32,14 @@ class Command(BaseCommand): logger.info("Signal %s (SIGHUP) received, exiting gracefully..." % signum) self.exit_now = True - def clean_exit(self, signum, frame): logger.info("Signal %s (INT or TERM) received, exiting gracefully..." % signum) self.exit_now = True - def handle(self, *args, **options): logger.info("Importing worker module...") - self.workermodule = importlib.import_module(options['workermodule']) - if not hasattr(self.workermodule, 'do_work'): + self.workermodule = importlib.import_module(options["workermodule"]) + if not hasattr(self.workermodule, "do_work"): logger.error("module %s must have a do_work() method to call") sys.exit(1) @@ -55,18 +52,19 @@ class Command(BaseCommand): while True: try: # run worker code - getattr(self.workermodule, 'do_work')() + getattr(self.workermodule, "do_work")() except Exception as E: - logger.exception("Got exception inside do_work for %s" % self.workermodule) + logger.exception( + "Got exception inside do_work for %s" % self.workermodule + ) sys.exit(1) # sleep for N seconds before calling worker code again i = 0 - while i < options['sleep']: + while i < options["sleep"]: # but check self.exit_now every second if self.exit_now: sys.exit(0) else: i += 1 sleep(1) - diff --git a/src/utils/migrations/0001_initial.py b/src/utils/migrations/0001_initial.py index 96ada4b1..241dca54 100644 --- a/src/utils/migrations/0001_initial.py +++ b/src/utils/migrations/0001_initial.py @@ -9,26 +9,31 @@ class Migration(migrations.Migration): initial = True - dependencies = [ - ] + dependencies = [] operations = [ migrations.CreateModel( - name='OutgoingEmail', + name="OutgoingEmail", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('created', models.DateTimeField(auto_now_add=True)), - ('updated', models.DateTimeField(auto_now=True)), - ('subject', models.CharField(max_length=500)), - ('text_template', models.TextField()), - ('html_template', models.TextField(blank=True)), - ('recipient', models.CharField(max_length=500)), - ('sender', models.CharField(max_length=500)), - ('attachment', models.FileField(blank=True, upload_to='')), - ('processed', models.BooleanField(default=False)), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("created", models.DateTimeField(auto_now_add=True)), + ("updated", models.DateTimeField(auto_now=True)), + ("subject", models.CharField(max_length=500)), + ("text_template", models.TextField()), + ("html_template", models.TextField(blank=True)), + ("recipient", models.CharField(max_length=500)), + ("sender", models.CharField(max_length=500)), + ("attachment", models.FileField(blank=True, upload_to="")), + ("processed", models.BooleanField(default=False)), ], - options={ - 'abstract': False, - }, - ), + options={"abstract": False}, + ) ] diff --git a/src/utils/migrations/0002_remove_outgoingemail_recipient.py b/src/utils/migrations/0002_remove_outgoingemail_recipient.py index 65e857b9..95c7a402 100644 --- a/src/utils/migrations/0002_remove_outgoingemail_recipient.py +++ b/src/utils/migrations/0002_remove_outgoingemail_recipient.py @@ -7,13 +7,6 @@ from django.db import migrations class Migration(migrations.Migration): - dependencies = [ - ('utils', '0001_initial'), - ] + dependencies = [("utils", "0001_initial")] - operations = [ - migrations.RemoveField( - model_name='outgoingemail', - name='recipient', - ), - ] + operations = [migrations.RemoveField(model_name="outgoingemail", name="recipient")] diff --git a/src/utils/migrations/0003_auto_20170521_1932.py b/src/utils/migrations/0003_auto_20170521_1932.py index 4867c105..110abf87 100644 --- a/src/utils/migrations/0003_auto_20170521_1932.py +++ b/src/utils/migrations/0003_auto_20170521_1932.py @@ -8,24 +8,37 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ - ('utils', '0002_remove_outgoingemail_recipient'), - ] + dependencies = [("utils", "0002_remove_outgoingemail_recipient")] operations = [ migrations.AddField( - model_name='outgoingemail', - name='bcc_recipients', - field=django.contrib.postgres.fields.ArrayField(base_field=models.CharField(blank=True, max_length=500), blank=True, null=True, size=None), + model_name="outgoingemail", + name="bcc_recipients", + field=django.contrib.postgres.fields.ArrayField( + base_field=models.CharField(blank=True, max_length=500), + blank=True, + null=True, + size=None, + ), ), migrations.AddField( - model_name='outgoingemail', - name='cc_recipients', - field=django.contrib.postgres.fields.ArrayField(base_field=models.CharField(blank=True, max_length=500), blank=True, null=True, size=None), + model_name="outgoingemail", + name="cc_recipients", + field=django.contrib.postgres.fields.ArrayField( + base_field=models.CharField(blank=True, max_length=500), + blank=True, + null=True, + size=None, + ), ), migrations.AddField( - model_name='outgoingemail', - name='to_recipients', - field=django.contrib.postgres.fields.ArrayField(base_field=models.CharField(blank=True, max_length=500), blank=True, null=True, size=None), + model_name="outgoingemail", + name="to_recipients", + field=django.contrib.postgres.fields.ArrayField( + base_field=models.CharField(blank=True, max_length=500), + blank=True, + null=True, + size=None, + ), ), ] diff --git a/src/utils/mixins.py b/src/utils/mixins.py index dec55f7a..d61fe2ba 100644 --- a/src/utils/mixins.py +++ b/src/utils/mixins.py @@ -7,6 +7,7 @@ class StaffMemberRequiredMixin(object): """ A CBV mixin for when a view should only be permitted for staff users """ + def dispatch(self, request, *args, **kwargs): # only permit staff users if not request.user.is_staff: @@ -22,5 +23,5 @@ class RaisePermissionRequiredMixin(PermissionRequiredMixin): A subclass of PermissionRequiredMixin which raises an exception to return 403 rather than a redirect to the login page We use this to avoid a redirect loop since our login page redirects back to the ?next= url when a user is logged in... """ - raise_exception = True + raise_exception = True diff --git a/src/utils/models.py b/src/utils/models.py index 9fd2998e..82734f59 100644 --- a/src/utils/models.py +++ b/src/utils/models.py @@ -4,6 +4,7 @@ from django.core.exceptions import ValidationError from django.contrib import messages from django.db import models import logging + logger = logging.getLogger("bornhack.%s" % __name__) @@ -23,7 +24,7 @@ class CleanedModel(models.Model): self.validate_unique(exclude=None) except ValidationError as e: message = "Got ValidationError while saving: %s" % e - if hasattr(self, 'request'): + if hasattr(self, "request"): messages.error(self.request, message) logger.error(message) # dont save, re-raise the exception @@ -35,11 +36,7 @@ class UUIDModel(CleanedModel): class Meta: abstract = True - uuid = models.UUIDField( - primary_key=True, - default=uuid.uuid4, - editable=False, - ) + uuid = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False) class CreatedUpdatedModel(CleanedModel): @@ -52,24 +49,24 @@ class CreatedUpdatedModel(CleanedModel): class CampRelatedModel(CreatedUpdatedModel): - camp_filter = 'camp' + camp_filter = "camp" class Meta: abstract = True def save(self, **kwargs): if self.camp.read_only: - if hasattr(self, 'request'): - messages.error(self.request, 'Camp is in read only mode.') - raise ValidationError('This camp is in read only mode.') + if hasattr(self, "request"): + messages.error(self.request, "Camp is in read only mode.") + raise ValidationError("This camp is in read only mode.") super().save(**kwargs) def delete(self, **kwargs): if self.camp.read_only: - if hasattr(self, 'request'): - messages.error(self.request, 'Camp is in read only mode.') - raise ValidationError('This camp is in read only mode.') + if hasattr(self, "request"): + messages.error(self.request, "Camp is in read only mode.") + raise ValidationError("This camp is in read only mode.") super().delete(**kwargs) @@ -84,30 +81,28 @@ class OutgoingEmail(CreatedUpdatedModel): html_template = models.TextField(blank=True) sender = models.CharField(max_length=500) to_recipients = ArrayField( - models.CharField(max_length=500, blank=True), - null=True, - blank=True + models.CharField(max_length=500, blank=True), null=True, blank=True ) cc_recipients = ArrayField( - models.CharField(max_length=500, blank=True), - null=True, - blank=True + models.CharField(max_length=500, blank=True), null=True, blank=True ) bcc_recipients = ArrayField( - models.CharField(max_length=500, blank=True), - null=True, - blank=True + models.CharField(max_length=500, blank=True), null=True, blank=True ) attachment = models.FileField(blank=True) processed = models.BooleanField(default=False) def __str__(self): - return 'OutgoingEmail Object id: {} '.format(self.id) + return "OutgoingEmail Object id: {} ".format(self.id) def clean(self): - if not self.to_recipients \ - and not self.bcc_recipients \ - and not self.cc_recipients: + if ( + not self.to_recipients + and not self.bcc_recipients + and not self.cc_recipients + ): raise ValidationError( - {'recipient': 'either to_recipient, bcc_recipient or cc_recipient required.'} + { + "recipient": "either to_recipient, bcc_recipient or cc_recipient required." + } ) diff --git a/src/utils/outgoingemailworker.py b/src/utils/outgoingemailworker.py index 01355f7f..67bd4991 100644 --- a/src/utils/outgoingemailworker.py +++ b/src/utils/outgoingemailworker.py @@ -1,8 +1,9 @@ from .models import OutgoingEmail from .email import _send_email import logging + logging.basicConfig(level=logging.INFO) -logger = logging.getLogger('bornhack.%s' % __name__) +logger = logging.getLogger("bornhack.%s" % __name__) def do_work(): @@ -13,14 +14,12 @@ def do_work(): not_processed_email = OutgoingEmail.objects.filter(processed=False) if len(not_processed_email) > 0: - logger.debug('about to process {} emails'.format( - len(not_processed_email)) - ) + logger.debug("about to process {} emails".format(len(not_processed_email))) for email in not_processed_email: attachment = None - attachment_filename = '' + attachment_filename = "" if email.attachment: attachment = email.attachment.read() attachment_filename = email.attachment.name @@ -33,11 +32,11 @@ def do_work(): bcc_recipients=email.bcc_recipients, html_template=email.html_template, attachment=attachment, - attachment_filename=attachment_filename + attachment_filename=attachment_filename, ) if mail_send_success: email.processed = True email.save() - logger.debug('successfully sent {}'.format(email)) + logger.debug("successfully sent {}".format(email)) else: - logger.error('unable to sent {}'.format(email)) + logger.error("unable to sent {}".format(email)) diff --git a/src/utils/pdf.py b/src/utils/pdf.py index b038ee12..932bf4d6 100644 --- a/src/utils/pdf.py +++ b/src/utils/pdf.py @@ -7,12 +7,13 @@ from wkhtmltopdf.views import PDFTemplateResponse from PyPDF2 import PdfFileWriter, PdfFileReader from django.test.client import RequestFactory from django.conf import settings + logger = logging.getLogger("bornhack.%s" % __name__) def generate_pdf_letter(filename, template, formatdict): # conjure up a fake request for PDFTemplateResponse - request = RequestFactory().get('/') + request = RequestFactory().get("/") request.user = AnonymousUser() request.session = {} @@ -21,10 +22,7 @@ def generate_pdf_letter(filename, template, formatdict): request=request, template=template, context=formatdict, - cmd_options={ - 'margin-top': 50, - 'margin-bottom': 50, - }, + cmd_options={"margin-top": 50, "margin-bottom": 50}, ) textonlypdf = io.BytesIO() textonlypdf.write(pdfgenerator.rendered_content) @@ -39,11 +37,9 @@ def generate_pdf_letter(filename, template, formatdict): watermark = PdfFileReader( open( os.path.join( - settings.STATICFILES_DIRS[0], - 'pdf', - settings.PDF_LETTERHEAD_FILENAME + settings.STATICFILES_DIRS[0], "pdf", settings.PDF_LETTERHEAD_FILENAME ), - 'rb' + "rb", ) ) @@ -60,9 +56,9 @@ def generate_pdf_letter(filename, template, formatdict): # save the generated pdf to the archive fullpath = os.path.join(settings.PDF_ARCHIVE_PATH, filename) - with open(fullpath, 'wb') as fh: + with open(fullpath, "wb") as fh: finalpdf.write(fh) - logger.info('Saved pdf to archive: %s' % fullpath) + logger.info("Saved pdf to archive: %s" % fullpath) returnfile = io.BytesIO() finalpdf.write(returnfile) diff --git a/src/utils/templatetags/bornhack.py b/src/utils/templatetags/bornhack.py index b2503f6c..d9c40612 100644 --- a/src/utils/templatetags/bornhack.py +++ b/src/utils/templatetags/bornhack.py @@ -13,4 +13,3 @@ def truefalseicon(value): return mark_safe("") else: return mark_safe("") - diff --git a/src/utils/templatetags/dateutils.py b/src/utils/templatetags/dateutils.py index 54b4c307..16ea45ee 100644 --- a/src/utils/templatetags/dateutils.py +++ b/src/utils/templatetags/dateutils.py @@ -1,8 +1,11 @@ from django import template from django.utils.dateparse import parse_date + register = template.Library() + @register.simple_tag def get_weekday(year, month, day): - return parse_date("%(year)s-%(month)s-%(day)s" % {'year': year, 'month': month, 'day': day}).strftime("%A") - + return parse_date( + "%(year)s-%(month)s-%(day)s" % {"year": year, "month": month, "day": day} + ).strftime("%A") diff --git a/src/utils/templatetags/imageutils.py b/src/utils/templatetags/imageutils.py index 9909a1bc..379618a0 100644 --- a/src/utils/templatetags/imageutils.py +++ b/src/utils/templatetags/imageutils.py @@ -2,7 +2,9 @@ from django import template from django.contrib.staticfiles.templatetags.staticfiles import static register = template.Library() -@register.inclusion_tag('thumbnail.html') + + +@register.inclusion_tag("thumbnail.html") def thumbnail(path, filename, description): """ Returns the HTML to show an image including thumbnail. @@ -10,9 +12,4 @@ def thumbnail(path, filename, description): Path should be relative inside static root. Description is used for alt-text and mouseover. """ - return { - 'path': static('') + path, - 'filename': filename, - 'description': description, - } - + return {"path": static("") + path, "filename": filename, "description": description} diff --git a/src/utils/templatetags/menubutton.py b/src/utils/templatetags/menubutton.py index 5d4029e4..fad651d4 100644 --- a/src/utils/templatetags/menubutton.py +++ b/src/utils/templatetags/menubutton.py @@ -2,10 +2,13 @@ from django import template register = template.Library() + @register.simple_tag(takes_context=True) def menubuttonclass(context, appname): - if appname == context['request'].resolver_match.func.view_class.__module__.split(".")[0]: + if ( + appname + == context["request"].resolver_match.func.view_class.__module__.split(".")[0] + ): return "btn-primary" else: return "btn-default" - diff --git a/src/villages/admin.py b/src/villages/admin.py index d2dd122e..08c301da 100644 --- a/src/villages/admin.py +++ b/src/villages/admin.py @@ -5,15 +5,6 @@ from .models import Village @admin.register(Village) class VillageAdmin(admin.ModelAdmin): - list_display = [ - 'name', - 'camp', - 'private', - 'deleted', - ] + list_display = ["name", "camp", "private", "deleted"] - list_filter = [ - 'camp', - 'private', - 'deleted', - ] + list_filter = ["camp", "private", "deleted"] diff --git a/src/villages/apps.py b/src/villages/apps.py index 473aafca..924aa68a 100644 --- a/src/villages/apps.py +++ b/src/villages/apps.py @@ -2,4 +2,4 @@ from django.apps import AppConfig class VillagesConfig(AppConfig): - name = 'villages' + name = "villages" diff --git a/src/villages/migrations/0001_initial.py b/src/villages/migrations/0001_initial.py index 4660b84d..df465605 100644 --- a/src/villages/migrations/0001_initial.py +++ b/src/villages/migrations/0001_initial.py @@ -13,26 +13,49 @@ class Migration(migrations.Migration): initial = True dependencies = [ - ('camps', '0005_auto_20160510_2011'), + ("camps", "0005_auto_20160510_2011"), migrations.swappable_dependency(settings.AUTH_USER_MODEL), ] operations = [ migrations.CreateModel( - name='Village', + name="Village", fields=[ - ('uuid', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)), - ('created', models.DateTimeField(auto_now_add=True)), - ('updated', models.DateTimeField(auto_now=True)), - ('name', models.CharField(max_length=255)), - ('slug', models.SlugField(blank=True, max_length=255)), - ('description', models.TextField()), - ('open', models.BooleanField(default=False, help_text='Is this village open for others to join?')), - ('camp', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='camps.Camp')), - ('contact', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), + ( + "uuid", + models.UUIDField( + default=uuid.uuid4, + editable=False, + primary_key=True, + serialize=False, + ), + ), + ("created", models.DateTimeField(auto_now_add=True)), + ("updated", models.DateTimeField(auto_now=True)), + ("name", models.CharField(max_length=255)), + ("slug", models.SlugField(blank=True, max_length=255)), + ("description", models.TextField()), + ( + "open", + models.BooleanField( + default=False, + help_text="Is this village open for others to join?", + ), + ), + ( + "camp", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, to="camps.Camp" + ), + ), + ( + "contact", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + to=settings.AUTH_USER_MODEL, + ), + ), ], - options={ - 'ordering': ['name'], - }, - ), + options={"ordering": ["name"]}, + ) ] diff --git a/src/villages/migrations/0002_auto_20160705_2154.py b/src/villages/migrations/0002_auto_20160705_2154.py index f46e6a3d..76c7dc9a 100644 --- a/src/villages/migrations/0002_auto_20160705_2154.py +++ b/src/villages/migrations/0002_auto_20160705_2154.py @@ -7,18 +7,15 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ - ('villages', '0001_initial'), - ] + dependencies = [("villages", "0001_initial")] operations = [ - migrations.RemoveField( - model_name='village', - name='open', - ), + migrations.RemoveField(model_name="village", name="open"), migrations.AddField( - model_name='village', - name='private', - field=models.BooleanField(default=True, help_text='Check if your village is privately organized'), + model_name="village", + name="private", + field=models.BooleanField( + default=True, help_text="Check if your village is privately organized" + ), ), ] diff --git a/src/villages/migrations/0003_auto_20160705_2159.py b/src/villages/migrations/0003_auto_20160705_2159.py index 5c9072e6..1c5bac1d 100644 --- a/src/villages/migrations/0003_auto_20160705_2159.py +++ b/src/villages/migrations/0003_auto_20160705_2159.py @@ -7,14 +7,14 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ - ('villages', '0002_auto_20160705_2154'), - ] + dependencies = [("villages", "0002_auto_20160705_2154")] operations = [ migrations.AlterField( - model_name='village', - name='private', - field=models.BooleanField(default=False, help_text='Check if your village is privately organized'), - ), + model_name="village", + name="private", + field=models.BooleanField( + default=False, help_text="Check if your village is privately organized" + ), + ) ] diff --git a/src/villages/migrations/0004_village_deleted.py b/src/villages/migrations/0004_village_deleted.py index 61af5a18..2c0c8249 100644 --- a/src/villages/migrations/0004_village_deleted.py +++ b/src/villages/migrations/0004_village_deleted.py @@ -7,14 +7,12 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ - ('villages', '0003_auto_20160705_2159'), - ] + dependencies = [("villages", "0003_auto_20160705_2159")] operations = [ migrations.AddField( - model_name='village', - name='deleted', + model_name="village", + name="deleted", field=models.BooleanField(default=False), - ), + ) ] diff --git a/src/villages/migrations/0005_auto_20160712_2036.py b/src/villages/migrations/0005_auto_20160712_2036.py index bbaa256c..baf384f2 100644 --- a/src/villages/migrations/0005_auto_20160712_2036.py +++ b/src/villages/migrations/0005_auto_20160712_2036.py @@ -7,14 +7,14 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ - ('villages', '0004_village_deleted'), - ] + dependencies = [("villages", "0004_village_deleted")] operations = [ migrations.AlterField( - model_name='village', - name='description', - field=models.TextField(help_text='A descriptive text about your village. Markdown is supported.'), - ), + model_name="village", + name="description", + field=models.TextField( + help_text="A descriptive text about your village. Markdown is supported." + ), + ) ] diff --git a/src/villages/migrations/0006_remove_village_camp.py b/src/villages/migrations/0006_remove_village_camp.py index b6a6c746..fe46e2c9 100644 --- a/src/villages/migrations/0006_remove_village_camp.py +++ b/src/villages/migrations/0006_remove_village_camp.py @@ -7,13 +7,6 @@ from django.db import migrations class Migration(migrations.Migration): - dependencies = [ - ('villages', '0005_auto_20160712_2036'), - ] + dependencies = [("villages", "0005_auto_20160712_2036")] - operations = [ - migrations.RemoveField( - model_name='village', - name='camp', - ), - ] + operations = [migrations.RemoveField(model_name="village", name="camp")] diff --git a/src/villages/migrations/0007_village_camp.py b/src/villages/migrations/0007_village_camp.py index 8d284673..6f9bf715 100644 --- a/src/villages/migrations/0007_village_camp.py +++ b/src/villages/migrations/0007_village_camp.py @@ -9,14 +9,16 @@ import django.db.models.deletion class Migration(migrations.Migration): dependencies = [ - ('camps', '0011_auto_20161228_1750'), - ('villages', '0006_remove_village_camp'), + ("camps", "0011_auto_20161228_1750"), + ("villages", "0006_remove_village_camp"), ] operations = [ migrations.AddField( - model_name='village', - name='camp', - field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='camps.Camp'), - ), + model_name="village", + name="camp", + field=models.ForeignKey( + null=True, on_delete=django.db.models.deletion.CASCADE, to="camps.Camp" + ), + ) ] diff --git a/src/villages/migrations/0008_auto_20161228_2209.py b/src/villages/migrations/0008_auto_20161228_2209.py index a3b25669..297afd7a 100644 --- a/src/villages/migrations/0008_auto_20161228_2209.py +++ b/src/villages/migrations/0008_auto_20161228_2209.py @@ -8,14 +8,14 @@ import django.db.models.deletion class Migration(migrations.Migration): - dependencies = [ - ('villages', '0007_village_camp'), - ] + dependencies = [("villages", "0007_village_camp")] operations = [ migrations.AlterField( - model_name='village', - name='camp', - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='camps.Camp'), - ), + model_name="village", + name="camp", + field=models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, to="camps.Camp" + ), + ) ] diff --git a/src/villages/migrations/0009_auto_20161229_2143.py b/src/villages/migrations/0009_auto_20161229_2143.py index 78906282..1dcf336c 100644 --- a/src/villages/migrations/0009_auto_20161229_2143.py +++ b/src/villages/migrations/0009_auto_20161229_2143.py @@ -7,14 +7,15 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ - ('villages', '0008_auto_20161228_2209'), - ] + dependencies = [("villages", "0008_auto_20161228_2209")] operations = [ migrations.AlterField( - model_name='village', - name='private', - field=models.BooleanField(default=False, help_text='Check if your village is invite only. Leave unchecked to welcome strangers.'), - ), + model_name="village", + name="private", + field=models.BooleanField( + default=False, + help_text="Check if your village is invite only. Leave unchecked to welcome strangers.", + ), + ) ] diff --git a/src/villages/migrations/0010_auto_20170318_1506.py b/src/villages/migrations/0010_auto_20170318_1506.py index c4b1c4a5..c4f61d18 100644 --- a/src/villages/migrations/0010_auto_20170318_1506.py +++ b/src/villages/migrations/0010_auto_20170318_1506.py @@ -8,13 +8,12 @@ from django.db import migrations class Migration(migrations.Migration): dependencies = [ - ('camps', '0020_camp_read_only'), - ('villages', '0009_auto_20161229_2143'), + ("camps", "0020_camp_read_only"), + ("villages", "0009_auto_20161229_2143"), ] operations = [ migrations.AlterUniqueTogether( - name='village', - unique_together=set([('slug', 'camp')]), - ), + name="village", unique_together=set([("slug", "camp")]) + ) ] diff --git a/src/villages/migrations/0011_auto_20180318_0906.py b/src/villages/migrations/0011_auto_20180318_0906.py index 07f6759c..3d96d395 100644 --- a/src/villages/migrations/0011_auto_20180318_0906.py +++ b/src/villages/migrations/0011_auto_20180318_0906.py @@ -9,19 +9,21 @@ import django.db.models.deletion class Migration(migrations.Migration): - dependencies = [ - ('villages', '0010_auto_20170318_1506'), - ] + dependencies = [("villages", "0010_auto_20170318_1506")] operations = [ migrations.AlterField( - model_name='village', - name='camp', - field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='camps.Camp'), + model_name="village", + name="camp", + field=models.ForeignKey( + on_delete=django.db.models.deletion.PROTECT, to="camps.Camp" + ), ), migrations.AlterField( - model_name='village', - name='contact', - field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to=settings.AUTH_USER_MODEL), + model_name="village", + name="contact", + field=models.ForeignKey( + on_delete=django.db.models.deletion.PROTECT, to=settings.AUTH_USER_MODEL + ), ), ] diff --git a/src/villages/mixins.py b/src/villages/mixins.py index a6356ed2..0016bd03 100644 --- a/src/villages/mixins.py +++ b/src/villages/mixins.py @@ -10,7 +10,7 @@ class EnsureWritableCampMixin(SingleObjectMixin): if self.camp.read_only: messages.error(request, "No thanks") return redirect( - reverse('village_list', kwargs={'camp_slug': self.camp.slug}) + reverse("village_list", kwargs={"camp_slug": self.camp.slug}) ) # alright, continue with the request diff --git a/src/villages/models.py b/src/villages/models.py index 5f625ccd..3fadeb51 100644 --- a/src/villages/models.py +++ b/src/villages/models.py @@ -5,13 +5,12 @@ from utils.models import UUIDModel, CampRelatedModel class Village(UUIDModel, CampRelatedModel): - class Meta: - ordering = ['name'] - unique_together = ('slug', 'camp') + ordering = ["name"] + unique_together = ("slug", "camp") - contact = models.ForeignKey('auth.User', on_delete=models.PROTECT) - camp = models.ForeignKey('camps.Camp', on_delete=models.PROTECT) + contact = models.ForeignKey("auth.User", on_delete=models.PROTECT) + camp = models.ForeignKey("camps.Camp", on_delete=models.PROTECT) name = models.CharField(max_length=255) slug = models.SlugField(max_length=255, blank=True) description = models.TextField( @@ -20,24 +19,24 @@ class Village(UUIDModel, CampRelatedModel): private = models.BooleanField( default=False, - help_text='Check if your village is invite only. Leave unchecked to welcome strangers.' + help_text="Check if your village is invite only. Leave unchecked to welcome strangers.", ) - deleted = models.BooleanField( - default=False, - ) + deleted = models.BooleanField(default=False) def __str__(self): return "%s (%s)" % (self.name, self.camp.title) def get_absolute_url(self): - return reverse_lazy('village_detail', kwargs={'camp_slug': self.camp.slug, 'slug': self.slug}) + return reverse_lazy( + "village_detail", kwargs={"camp_slug": self.camp.slug, "slug": self.slug} + ) def save(self, **kwargs): if ( - not self.pk or - not self.slug or - Village.objects.filter(slug=self.slug).count() > 1 + not self.pk + or not self.slug + or Village.objects.filter(slug=self.slug).count() > 1 ): slug = slugify(self.name) if not slug: @@ -47,12 +46,9 @@ class Village(UUIDModel, CampRelatedModel): # We have to make sure that the slug won't clash with current slugs while Village.objects.filter(slug=slug).exists(): if incrementer == 1: - slug = '{}-1'.format(slug) + slug = "{}-1".format(slug) else: - slug = '{}-{}'.format( - '-'.join(slug.split('-')[:-1]), - incrementer - ) + slug = "{}-{}".format("-".join(slug.split("-")[:-1]), incrementer) incrementer += 1 self.slug = slug @@ -61,4 +57,3 @@ class Village(UUIDModel, CampRelatedModel): def delete(self, using=None, keep_parents=False): self.deleted = True self.save() - diff --git a/src/villages/urls.py b/src/villages/urls.py index a36c5a13..93aac938 100644 --- a/src/villages/urls.py +++ b/src/villages/urls.py @@ -2,12 +2,12 @@ from django.urls import path from .views import * -app_name = 'villages' +app_name = "villages" urlpatterns = [ - path('', VillageListView.as_view(), name='list'), - path('create/', VillageCreateView.as_view(), name='create'), - path('/delete/', VillageDeleteView.as_view(), name='delete'), - path('/edit/', VillageUpdateView.as_view(), name='update'), - path('/', VillageDetailView.as_view(), name='detail'), + path("", VillageListView.as_view(), name="list"), + path("create/", VillageCreateView.as_view(), name="create"), + path("/delete/", VillageDeleteView.as_view(), name="delete"), + path("/edit/", VillageUpdateView.as_view(), name="update"), + path("/", VillageDetailView.as_view(), name="detail"), ] diff --git a/src/villages/views.py b/src/villages/views.py index 38766e45..57345c0a 100644 --- a/src/villages/views.py +++ b/src/villages/views.py @@ -2,7 +2,13 @@ from django.http import Http404 from django.contrib.auth.mixins import LoginRequiredMixin from django.urls import reverse_lazy from django.http import HttpResponseRedirect -from django.views.generic import ListView, DetailView, CreateView, UpdateView, DeleteView +from django.views.generic import ( + ListView, + DetailView, + CreateView, + UpdateView, + DeleteView, +) from django.views.generic.detail import SingleObjectMixin from .models import Village from camps.models import Camp @@ -12,8 +18,8 @@ from .mixins import EnsureWritableCampMixin class VillageListView(CampViewMixin, ListView): model = Village - template_name = 'village_list.html' - context_object_name = 'villages' + template_name = "village_list.html" + context_object_name = "villages" def get_queryset(self): return super().get_queryset().filter(deleted=False) @@ -21,29 +27,31 @@ class VillageListView(CampViewMixin, ListView): class VillageDetailView(CampViewMixin, DetailView): model = Village - template_name = 'village_detail.html' - context_object_name = 'village' + template_name = "village_detail.html" + context_object_name = "village" def get_queryset(self): return super().get_queryset().filter(deleted=False) -class VillageCreateView(CampViewMixin, LoginRequiredMixin, EnsureWritableCampMixin, CreateView): +class VillageCreateView( + CampViewMixin, LoginRequiredMixin, EnsureWritableCampMixin, CreateView +): model = Village - template_name = 'village_form.html' - fields = ['name', 'description', 'private'] + template_name = "village_form.html" + fields = ["name", "description", "private"] def form_valid(self, form): village = form.save(commit=False) village.contact = self.request.user - village.camp = Camp.objects.get(slug=self.request.session['campslug']) + village.camp = Camp.objects.get(slug=self.request.session["campslug"]) if not village.name: village.name = "noname" village.save() return HttpResponseRedirect(village.get_absolute_url()) def get_success_url(self): - return reverse_lazy('village_list', kwargs={"camp_slug": self.object.camp.slug}) + return reverse_lazy("village_list", kwargs={"camp_slug": self.object.camp.slug}) class EnsureUserOwnsVillageMixin(SingleObjectMixin): @@ -60,10 +68,16 @@ class EnsureUserOwnsVillageMixin(SingleObjectMixin): ) -class VillageUpdateView(CampViewMixin, EnsureUserOwnsVillageMixin, LoginRequiredMixin, EnsureWritableCampMixin, UpdateView): +class VillageUpdateView( + CampViewMixin, + EnsureUserOwnsVillageMixin, + LoginRequiredMixin, + EnsureWritableCampMixin, + UpdateView, +): model = Village - template_name = 'village_form.html' - fields = ['name', 'description', 'private'] + template_name = "village_form.html" + fields = ["name", "description", "private"] def form_valid(self, form): village = form.save(commit=False) @@ -78,11 +92,16 @@ class VillageUpdateView(CampViewMixin, EnsureUserOwnsVillageMixin, LoginRequired return super().get_queryset().filter(deleted=False) -class VillageDeleteView(CampViewMixin, EnsureUserOwnsVillageMixin, LoginRequiredMixin, EnsureWritableCampMixin, DeleteView): +class VillageDeleteView( + CampViewMixin, + EnsureUserOwnsVillageMixin, + LoginRequiredMixin, + EnsureWritableCampMixin, + DeleteView, +): model = Village - template_name = 'village_confirm_delete.html' - context_object_name = 'village' + template_name = "village_confirm_delete.html" + context_object_name = "village" def get_success_url(self): - return reverse_lazy('village_list', kwargs={"camp_slug": self.object.camp.slug}) - + return reverse_lazy("village_list", kwargs={"camp_slug": self.object.camp.slug})
").addClass("cw").text("#"));c.isBefore(f.clone().endOf("w"));)b.append(a("").addClass("dow").text(c.format("dd"))),c.add(1,"d");o.find(".datepicker-days thead").append(b)},N=function(a){return d.disabledDates[a.format("YYYY-MM-DD")]===!0},O=function(a){return d.enabledDates[a.format("YYYY-MM-DD")]===!0},P=function(a){return d.disabledHours[a.format("H")]===!0},Q=function(a){return d.enabledHours[a.format("H")]===!0},R=function(b,c){if(!b.isValid())return!1;if(d.disabledDates&&"d"===c&&N(b))return!1;if(d.enabledDates&&"d"===c&&!O(b))return!1;if(d.minDate&&b.isBefore(d.minDate,c))return!1;if(d.maxDate&&b.isAfter(d.maxDate,c))return!1;if(d.daysOfWeekDisabled&&"d"===c&&d.daysOfWeekDisabled.indexOf(b.day())!==-1)return!1;if(d.disabledHours&&("h"===c||"m"===c||"s"===c)&&P(b))return!1;if(d.enabledHours&&("h"===c||"m"===c||"s"===c)&&!Q(b))return!1;if(d.disabledTimeIntervals&&("h"===c||"m"===c||"s"===c)){var e=!1;if(a.each(d.disabledTimeIntervals,function(){if(b.isBetween(this[0],this[1]))return e=!0,!1}),e)return!1}return!0},S=function(){for(var b=[],c=f.clone().startOf("y").startOf("d");c.isSame(f,"y");)b.push(a("").attr("data-action","selectMonth").addClass("month").text(c.format("MMM"))),c.add(1,"M");o.find(".datepicker-months td").empty().append(b)},T=function(){var b=o.find(".datepicker-months"),c=b.find("th"),g=b.find("tbody").find("span");c.eq(0).find("span").attr("title",d.tooltips.prevYear),c.eq(1).attr("title",d.tooltips.selectYear),c.eq(2).find("span").attr("title",d.tooltips.nextYear),b.find(".disabled").removeClass("disabled"),R(f.clone().subtract(1,"y"),"y")||c.eq(0).addClass("disabled"),c.eq(1).text(f.year()),R(f.clone().add(1,"y"),"y")||c.eq(2).addClass("disabled"),g.removeClass("active"),e.isSame(f,"y")&&!m&&g.eq(e.month()).addClass("active"),g.each(function(b){R(f.clone().month(b),"M")||a(this).addClass("disabled")})},U=function(){var a=o.find(".datepicker-years"),b=a.find("th"),c=f.clone().subtract(5,"y"),g=f.clone().add(6,"y"),h="";for(b.eq(0).find("span").attr("title",d.tooltips.prevDecade),b.eq(1).attr("title",d.tooltips.selectDecade),b.eq(2).find("span").attr("title",d.tooltips.nextDecade),a.find(".disabled").removeClass("disabled"),d.minDate&&d.minDate.isAfter(c,"y")&&b.eq(0).addClass("disabled"),b.eq(1).text(c.year()+"-"+g.year()),d.maxDate&&d.maxDate.isBefore(g,"y")&&b.eq(2).addClass("disabled");!c.isAfter(g,"y");)h+=''+c.year()+"",c.add(1,"y");a.find("td").html(h)},V=function(){var a,c=o.find(".datepicker-decades"),g=c.find("th"),h=b({y:f.year()-f.year()%100-1}),i=h.clone().add(100,"y"),j=h.clone(),k=!1,l=!1,m="";for(g.eq(0).find("span").attr("title",d.tooltips.prevCentury),g.eq(2).find("span").attr("title",d.tooltips.nextCentury),c.find(".disabled").removeClass("disabled"),(h.isSame(b({y:1900}))||d.minDate&&d.minDate.isAfter(h,"y"))&&g.eq(0).addClass("disabled"),g.eq(1).text(h.year()+"-"+i.year()),(h.isSame(b({y:2e3}))||d.maxDate&&d.maxDate.isBefore(i,"y"))&&g.eq(2).addClass("disabled");!h.isAfter(i,"y");)a=h.year()+12,k=d.minDate&&d.minDate.isAfter(h,"y")&&d.minDate.year()<=a,l=d.maxDate&&d.maxDate.isAfter(h,"y")&&d.maxDate.year()<=a,m+=''+(h.year()+1)+" - "+(h.year()+12)+"",h.add(12,"y");m+="",c.find("td").html(m),g.eq(1).text(j.year()+1+"-"+h.year())},W=function(){var b,c,g,h=o.find(".datepicker-days"),i=h.find("th"),j=[],k=[];if(B()){for(i.eq(0).find("span").attr("title",d.tooltips.prevMonth),i.eq(1).attr("title",d.tooltips.selectMonth),i.eq(2).find("span").attr("title",d.tooltips.nextMonth),h.find(".disabled").removeClass("disabled"),i.eq(1).text(f.format(d.dayViewHeaderFormat)),R(f.clone().subtract(1,"M"),"M")||i.eq(0).addClass("disabled"),R(f.clone().add(1,"M"),"M")||i.eq(2).addClass("disabled"),b=f.clone().startOf("M").startOf("w").startOf("d"),g=0;g<42;g++)0===b.weekday()&&(c=a("
'+b.week()+"'+b.date()+"
'+c.format(h?"HH":"hh")+"
'+c.format("mm")+"
'+c.format("ss")+"