├── .Python ├── .flake8 ├── .github ├── ISSUE_TEMPLATE │ ├── bug_report.md │ └── feature_request.md └── PULL_REQUEST_TEMPLATE │ └── pull_request_template.md ├── .gitignore ├── .pre-commit-config.yaml ├── .prettierignore ├── .travis.yml ├── Aptfile ├── LICENSE ├── Procfile ├── README.md ├── SECURITY.md ├── bin ├── activate ├── activate.csh ├── activate.fish ├── activate.ps1 ├── activate.xsh ├── activate_this.py ├── django-admin ├── django-admin.py ├── pip ├── pip3 ├── pip3.7 ├── python ├── python-config ├── python3 ├── python3.7 └── sqlformat ├── create_state_fixtures.py ├── dev_reqs.txt ├── docs ├── .gitignore ├── README.md ├── blog │ ├── 2020-06-09-welcome.md │ └── 2020-07-10-test.md ├── docs │ ├── access1.md │ ├── api1.md │ ├── django1.md │ ├── django2.md │ ├── doc1.md │ ├── doc2.md │ ├── docasaurus1.md │ ├── docasaurus2.md │ ├── geodjango.md │ ├── postgres.md │ ├── prod.md │ ├── server.md │ ├── setup.md │ ├── setup2.md │ ├── vanillaviz1.md │ └── vanillaviz2.md ├── docusaurus.config.js ├── package-lock.json ├── package.json ├── sidebars.js ├── src │ ├── css │ │ └── custom.css │ └── pages │ │ ├── index.js │ │ └── styles.module.css ├── static │ └── img │ │ ├── clone.png │ │ ├── favicon.ico │ │ ├── graphic.svg │ │ └── logo.svg └── yarn.lock ├── gpl-v3.tmpl ├── main ├── __init__.py ├── admin.py ├── apps.py ├── choices.py ├── context_processors │ └── mixpanel.py ├── fixtures │ ├── report_test.json │ ├── single_org.json │ └── states.json ├── forms.py ├── management │ └── commands │ │ └── addtags.py ├── migrations │ ├── 0001_initial.py │ ├── 0002_auto_20191219_1156.py │ ├── 0003_delete_issue.py │ ├── 0003_organization.py │ ├── 0004_auto_20200409_1923.py │ ├── 0004_remove_communityentry_my_community.py │ ├── 0005_auto_20200423_0217.py │ ├── 0006_auto_20200423_0243.py │ ├── 0007_auto_20200423_0559.py │ ├── 0008_auto_20200423_1943.py │ ├── 0009_auto_20200423_2013.py │ ├── 0010_auto_20200424_0648.py │ ├── 0011_auto_20200424_0946.py │ ├── 0012_auto_20200424_1013.py │ ├── 0013_communityentry_organization.py │ ├── 0014_auto_20200501_0001.py │ ├── 0014_merge_20200501_1523.py │ ├── 0015_merge_20200501_1625.py │ ├── 0016_auto_20200519_1627.py │ ├── 0016_communityentry_user_name.py │ ├── 0017_auto_20200519_1631.py │ ├── 0018_auto_20200517_2309.py │ ├── 0018_campaigntoken.py │ ├── 0019_auto_20200518_0111.py │ ├── 0019_communityentry_campaign.py │ ├── 0020_address.py │ ├── 0021_auto_20200520_0357.py │ ├── 0022_address_city.py │ ├── 0023_auto_20200520_1755.py │ ├── 0024_merge_20200521_1950.py │ ├── 0025_auto_20200522_0011.py │ ├── 0026_populatecampaignslug.py │ ├── 0027_auto_20200523_0436.py │ ├── 0028_communityentry_created_at.py │ ├── 0029_auto_20200526_0556.py │ ├── 0030_remove_communityentry_user_phone.py │ ├── 0031_auto_20200611_2139.py │ ├── 0032_auto_20200626_1624.py │ ├── 0032_state.py │ ├── 0033_auto_20200624_1549.py │ ├── 0034_auto_20200624_1554.py │ ├── 0035_auto_20200624_1933.py │ ├── 0036_auto_20200624_1941.py │ ├── 0037_auto_20200624_1947.py │ ├── 0038_auto_20200624_1948.py │ ├── 0039_auto_20200624_2247.py │ ├── 0040_auto_20200626_2045.py │ ├── 0041_merge_20200626_2055.py │ ├── 0042_auto_20200629_1138.py │ ├── 0043_auto_20200703_1953.py │ ├── 0044_auto_20200703_1957.py │ ├── 0045_auto_20200704_0622.py │ ├── 0046_auto_20200721_0540.py │ ├── 0046_auto_20200727_0712.py │ ├── 0046_auto_20200727_2002.py │ ├── 0046_report.py │ ├── 0047_auto_20200721_0731.py │ ├── 0047_merge_20200728_0101.py │ ├── 0048_merge_20200729_1341.py │ ├── 0048_merge_20200730_2027.py │ ├── 0049_auto_20200731_2122.py │ ├── 0050_drive_private.py │ ├── 0050_merge_20200803_1853.py │ ├── 0051_allowlist_drive.py │ ├── 0051_auto_20200811_1632.py │ ├── 0052_auto_20200811_1737.py │ ├── 0052_communityentry_private.py │ ├── 0053_auto_20200811_1829.py │ ├── 0053_merge_20200811_0708.py │ ├── 0054_auto_20200811_1830.py │ ├── 0054_auto_20200811_1957.py │ ├── 0055_auto_20200907_2034.py │ ├── 0056_auto_20200908_1604.py │ ├── 0057_auto_20201022_1603.py │ ├── 0057_auto_20201023_0846.py │ ├── 0057_auto_20201120_0559.py │ ├── 0057_merge_20201020_2006.py │ ├── 0058_auto_20201023_0855.py │ ├── 0058_auto_20201026_1544.py │ ├── 0059_communityentry_state.py │ ├── 0059_merge_20201201_0226.py │ ├── 0059_merge_20201201_0250.py │ ├── 0060_merge_20201201_1009.py │ ├── 0061_merge_20201201_1427.py │ ├── 0062_auto_20201201_1733.py │ ├── 0063_auto_20201201_1739.py │ ├── 0064_merge_20201201_1831.py │ ├── 0065_auto_20201202_0159.py │ ├── 0066_auto_20201223_0731.py │ ├── 0066_communityentry_population.py │ ├── 0066_merge_20201229_2049.py │ ├── 0067_frequentlyaskedquestion_glossarydefinition.py │ ├── 0068_frequentlyaskedquestion_type.py │ ├── 0069_auto_20201229_2232.py │ ├── 0070_communityentry_state_obj.py │ ├── 0071_merge_20201231_1930.py │ ├── 0072_signature.py │ ├── 0073_merge_20210104_0517.py │ ├── 0074_auto_20210301_1943.py │ ├── 0074_censusblock.py │ ├── 0074_organization_verified.py │ ├── 0075_merge_20210319_1913.py │ ├── 0076_auto_20210414_1921.py │ ├── 0077_auto_20210422_1442.py │ ├── 0078_merge_20210503_1654.py │ ├── 0079_auto_20210510_1636.py │ ├── 0079_communityentry_census_blocks.py │ ├── 0080_auto_20210505_1516.py │ ├── 0080_drive_custom_question_example.py │ ├── 0081_merge_20210514_0226.py │ ├── 0081_merge_20210514_0335.py │ ├── 0082_auto_20210602_1439.py │ ├── 0082_merge_20210604_0716.py │ ├── 0083_merge_20210608_1613.py │ ├── 0083_merge_20210608_1746.py │ ├── 0083_merge_20210609_0044.py │ ├── 0084_auto_20210608_1629.py │ ├── 0084_merge_20210611_1406.py │ ├── 0085_auto_20210611_1406.py │ ├── 0086_merge_20210617_1455.py │ ├── 0087_auto_20210622_2021.py │ ├── 0087_auto_20210629_1823.py │ ├── 0087_communityentry_test.py │ ├── 0088_auto_20210629_2018.py │ ├── 0088_auto_20210630_2027.py │ ├── 0088_image.py │ ├── 0089_auto_20210629_2238.py │ ├── 0089_organization_logo.py │ ├── 0090_auto_20210701_1746.py │ ├── 0090_remove_communityentry_community_hash.py │ ├── 0091_merge_20210713_1631.py │ ├── 0092_auto_20210714_2017.py │ ├── 0093_auto_20210719_1642.py │ ├── 0094_merge_20210720_1637.py │ ├── 0094_merge_20210720_2115.py │ ├── 0095_auto_20210720_1637.py │ ├── 0095_auto_20210720_2234.py │ ├── 0095_auto_20210723_1545.py │ ├── 0096_merge_20210727_2309.py │ ├── 0097_auto_20210727_2309.py │ ├── 0098_drive_draw_layer.py │ ├── 0099_auto_20211210_1822.py │ ├── 0100_auto_20211213_0809.py │ └── __init__.py ├── models.py ├── static │ ├── img │ │ ├── DaneCountySeal.png │ │ ├── Representable-Infographic.pdf │ │ ├── apple-touch-icon.png │ │ ├── citizens.svg │ │ ├── city_icon-2.svg │ │ ├── community-name-page.svg │ │ ├── community_input.svg │ │ ├── confetti.svg │ │ ├── drive_preview.png │ │ ├── education-1.png │ │ ├── education-1.svg │ │ ├── education-2.svg │ │ ├── education-3.svg │ │ ├── example-comm-face.jpg │ │ ├── example-comm.png │ │ ├── facebook-gray-logo.svg │ │ ├── favicon.ico │ │ ├── gifs │ │ │ └── representablegif.gif │ │ ├── home-bg.svg │ │ ├── home-hands.svg │ │ ├── home-people.svg │ │ ├── home-preview-bg.svg │ │ ├── home-shapes-1.svg │ │ ├── home-shapes-2.svg │ │ ├── home-shapes-3.svg │ │ ├── home-shapes-4.svg │ │ ├── home-shapes-5.svg │ │ ├── how-it-works-1.svg │ │ ├── how-it-works-2.svg │ │ ├── how-it-works-3.svg │ │ ├── ig-gray-logo.svg │ │ ├── illustration.svg │ │ ├── logo-gradient.svg │ │ ├── logo-lowres.svg │ │ ├── logo.svg │ │ ├── map-info.svg │ │ ├── map-preview.png │ │ ├── mapping.svg │ │ ├── network.svg │ │ ├── noun_Search_1384314.svg │ │ ├── num1-circle.svg │ │ ├── num2-circle.svg │ │ ├── num3-circle.svg │ │ ├── one-pager.png │ │ ├── org-guide.png │ │ ├── partner-logos.png │ │ ├── polydrawSnap.png │ │ ├── redistrict-1.svg │ │ ├── rep-link-cover.png │ │ ├── representable-text.svg │ │ ├── state-info-1.svg │ │ ├── state-info-2.svg │ │ ├── state-info-3.svg │ │ ├── state-info-bg.svg │ │ ├── thanks-comm.svg │ │ ├── thanks-district.svg │ │ ├── thanks-email.svg │ │ ├── twitter-gray-logo.svg │ │ ├── upload_photo.png │ │ ├── verified.svg │ │ ├── voting.svg │ │ ├── webinar-deck.png │ │ └── yt-gray-logo.svg │ └── main │ │ ├── css │ │ └── style.css │ │ ├── feature-lookup-tables │ │ ├── ansi-state.csv │ │ ├── feature-lookup-tables.js │ │ ├── lookup-table-scraper.py │ │ ├── mapbox-boundaries-adm2-v3_2.json │ │ ├── mapbox-boundaries-leg2-v3_2.json │ │ ├── mapbox-boundaries-leg3-v3_2.json │ │ ├── mapbox-boundaries-leg4-v3_2.json │ │ ├── mapbox-boundaries-pos4-v3_2.json │ │ ├── mapbox-boundaries-sta5-v3_2.json │ │ └── state-codes.js │ │ ├── fonts │ │ ├── Inter │ │ │ ├── Inter-Black.woff │ │ │ ├── Inter-Black.woff2 │ │ │ ├── Inter-BlackItalic.woff │ │ │ ├── Inter-BlackItalic.woff2 │ │ │ ├── Inter-Bold.woff │ │ │ ├── Inter-Bold.woff2 │ │ │ ├── Inter-BoldItalic.woff │ │ │ ├── Inter-BoldItalic.woff2 │ │ │ ├── Inter-ExtraBold.woff │ │ │ ├── Inter-ExtraBold.woff2 │ │ │ ├── Inter-ExtraBoldItalic.woff │ │ │ ├── Inter-ExtraBoldItalic.woff2 │ │ │ ├── Inter-ExtraLight.woff │ │ │ ├── Inter-ExtraLight.woff2 │ │ │ ├── Inter-ExtraLightItalic.woff │ │ │ ├── Inter-ExtraLightItalic.woff 2 │ │ │ ├── Inter-ExtraLightItalic.woff2 │ │ │ ├── Inter-ExtraLightItalic.woff2 2 │ │ │ ├── Inter-Italic.woff │ │ │ ├── Inter-Italic.woff2 │ │ │ ├── Inter-Light.woff │ │ │ ├── Inter-Light.woff2 │ │ │ ├── Inter-LightItalic.woff │ │ │ ├── Inter-LightItalic.woff2 │ │ │ ├── Inter-Medium.woff │ │ │ ├── Inter-Medium.woff2 │ │ │ ├── Inter-MediumItalic.woff │ │ │ ├── Inter-MediumItalic.woff2 │ │ │ ├── Inter-Regular.woff │ │ │ ├── Inter-Regular.woff2 │ │ │ ├── Inter-SemiBold.woff │ │ │ ├── Inter-SemiBold.woff2 │ │ │ ├── Inter-SemiBoldItalic.woff │ │ │ ├── Inter-SemiBoldItalic.woff2 │ │ │ ├── Inter-Thin.woff │ │ │ ├── Inter-Thin.woff2 │ │ │ ├── Inter-ThinItalic.woff │ │ │ ├── Inter-ThinItalic.woff2 │ │ │ ├── Inter-italic.var.woff2 │ │ │ ├── Inter-upright.var.woff2 │ │ │ ├── Inter.var.woff2 │ │ │ └── inter.css │ │ └── LICENSE.txt │ │ ├── js │ │ ├── LICENSE.md │ │ ├── auth.js │ │ ├── base.js │ │ ├── components │ │ │ ├── dropdown.js │ │ │ ├── jquery.vmap.min.js │ │ │ ├── jquery.vmap.usa.js │ │ │ ├── keys.js │ │ │ └── states.js │ │ ├── dash_review.js │ │ ├── drive.js │ │ ├── geo.js │ │ ├── js.cookie.js │ │ ├── main.js │ │ ├── map-common.js │ │ ├── map.js │ │ ├── mixpanel.js │ │ ├── organization_dashboard.js │ │ ├── review.js │ │ ├── submission.js │ │ ├── wicket-leaflet.js │ │ └── wicket.js │ │ └── readme │ │ ├── README_csv.txt │ │ └── README_geojson.txt ├── templates │ ├── account │ │ ├── base.html │ │ ├── email │ │ │ ├── debug_email_confirmation_message.txt │ │ │ ├── debug_email_confirmation_subject.txt │ │ │ ├── email_confirmation_message.html │ │ │ ├── email_confirmation_signup_message.html │ │ │ ├── email_confirmation_signup_subject.txt │ │ │ ├── email_confirmation_subject.txt │ │ │ ├── email_template_do_not_delete.html │ │ │ ├── password_reset_key_message.html │ │ │ └── password_reset_key_subject.txt │ │ ├── email_confirm.html │ │ ├── login.html │ │ ├── logout.html │ │ ├── password_change.html │ │ ├── password_reset.html │ │ ├── password_reset_done.html │ │ ├── password_reset_from_key.html │ │ ├── password_reset_from_key_done.html │ │ ├── password_set.html │ │ ├── signup.html │ │ ├── signup_login.html │ │ └── verification_sent.html │ ├── forms │ │ └── widgets │ │ │ ├── radio.html │ │ │ └── radio_option.html │ └── main │ │ ├── base.html │ │ ├── dashboard │ │ ├── drives │ │ │ ├── create.html │ │ │ ├── edit.html │ │ │ └── index.html │ │ ├── entries │ │ │ ├── index.html │ │ │ ├── list.html │ │ │ └── review.html │ │ ├── index.html │ │ └── partners │ │ │ ├── allowlist_manage.html │ │ │ ├── allowlist_upload.html │ │ │ ├── create.html │ │ │ ├── edit.html │ │ │ ├── index.html │ │ │ ├── member_form.html │ │ │ ├── membership.html │ │ │ ├── review.html │ │ │ └── thanks.html │ │ ├── drives │ │ ├── dane-county-page.html │ │ ├── index.html │ │ ├── page copy.html │ │ └── page.html │ │ ├── entry.html │ │ ├── entry_address.html │ │ ├── entry_map.html │ │ ├── entry_preview.html │ │ ├── entry_privacy.html │ │ ├── entry_survey.html │ │ ├── export.html │ │ ├── exportcsv.html │ │ ├── index.html │ │ ├── layouts │ │ └── base-page.html │ │ ├── map.html │ │ ├── pages │ │ ├── about.html │ │ ├── faq.html │ │ ├── glossary.html │ │ ├── privacy.html │ │ ├── resources.html │ │ └── terms.html │ │ ├── partners │ │ ├── get_started copy.html │ │ ├── get_started.html │ │ ├── index.html │ │ ├── map.html │ │ └── page.html │ │ ├── review.html │ │ ├── state.html │ │ ├── state_info.html │ │ ├── state_selection.html │ │ ├── submission-copy.html │ │ ├── submission.html │ │ ├── thanks.html │ │ └── zipcode.html ├── templatetags │ ├── __init__.py │ └── representable_extras.py ├── test_entry.py ├── test_organization.py ├── test_report.py ├── tests.py ├── urls.py ├── users │ └── adapter.py ├── utils.py └── views │ ├── __init__.py │ ├── dashboard.py │ ├── drives.py │ ├── main.py │ └── partners.py ├── manage.py ├── models.png ├── new_models.png ├── package-lock.json ├── pyproject.toml ├── pyvenv.cfg ├── representable.code-profile ├── representable ├── locale │ ├── ar │ │ └── LC_MESSAGES │ │ │ ├── django.mo │ │ │ └── django.po │ ├── es │ │ └── LC_MESSAGES │ │ │ ├── django 2.mo │ │ │ ├── django.mo │ │ │ └── django.po │ └── hmn │ │ └── LC_MESSAGES │ │ ├── django.mo │ │ └── django.po ├── __init__.py ├── custom_storage.py ├── settings │ ├── __init__.py │ ├── base.py │ ├── dev.py │ └── prod.py ├── storage.py ├── templates │ ├── 404.html │ └── base.html ├── urls.py └── wsgi.py ├── requirements copy.txt ├── requirements.txt ├── runtime.txt ├── state_abbrev.py └── translate.py /.Python: -------------------------------------------------------------------------------- 1 | /usr/local/Cellar/python/3.7.7/Frameworks/Python.framework/Versions/3.7/Python -------------------------------------------------------------------------------- /.flake8: -------------------------------------------------------------------------------- 1 | [flake8] 2 | max-line-length = 79 3 | max-complexity = 18 4 | select = B,C,E,F,W,T4,B9 5 | ignore = E203, E266, E501, W503, F403, F401 6 | exclude = .git,*migrations* 7 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior: 15 | 1. Go to '...' 16 | 2. Click on '....' 17 | 3. Scroll down to '....' 18 | 4. See error 19 | 20 | **Expected behavior** 21 | A clear and concise description of what you expected to happen. 22 | 23 | **Screenshots** 24 | If applicable, add screenshots to help explain your problem. 25 | 26 | **Desktop (please complete the following information):** 27 | - OS: [e.g. iOS] 28 | - Browser [e.g. chrome, safari] 29 | - Version [e.g. 22] 30 | 31 | **Smartphone (please complete the following information):** 32 | - Device: [e.g. iPhone6] 33 | - OS: [e.g. iOS8.1] 34 | - Browser [e.g. stock browser, safari] 35 | - Version [e.g. 22] 36 | 37 | **Additional context** 38 | Add any other context about the problem here. 39 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE/pull_request_template.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: '' 3 | about: '' 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Key changes:** 11 | 12 | **Steps to replicate:** 13 | 14 | **Screenshots:** 15 | 16 | **Issues this PR resolves:** 17 | Type `resolves #{pr}` to automatically link and close issues. 18 | -------------------------------------------------------------------------------- /.pre-commit-config.yaml: -------------------------------------------------------------------------------- 1 | repos: 2 | - repo: https://github.com/ambv/black 3 | rev: 21.5b2 4 | hooks: 5 | - id: black 6 | language_version: python3.7 7 | - repo: https://github.com/prettier/prettier 8 | rev: "2.3.0" 9 | hooks: 10 | - id: prettier 11 | name: prettier 12 | entry: prettier --write 13 | files: "\\.(\ 14 | css|less|scss\ 15 | |graphql|gql\ 16 | |js|jsx\ 17 | |json\ 18 | |md|markdown|mdown|mkdn\ 19 | |mdx\ 20 | |ts|tsx\ 21 | )$" 22 | - repo: https://github.com/pre-commit/pre-commit-hooks 23 | rev: v1.2.3 24 | hooks: 25 | - id: flake8 26 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | js.cookie.js 2 | *.min.* 3 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | # https://medium.com/@MicroPyramid/set-up-travis-ci-for-django-project-427d6dd2f46c 2 | # https://github.com/ndarville/pony-forum/blob/master/.travis.yml 3 | dist: xenial # required for Python >= 3.7 4 | language: python 5 | python: 6 | - "3.7" 7 | 8 | env: 9 | global: 10 | - DJANGO_SETTINGS_MODULE="representable.settings" 11 | - PYTHONPATH="/home/travis/build/representable/representable" 12 | - PIP_USE_MIRRORS=true 13 | - SECRET_KEY="testkey-travisci" 14 | # Install the version of PostGIS that matches your PostgreSQL version, 15 | # and activate the PostGIS extension using: 16 | services: 17 | - postgresql 18 | addons: 19 | apt: 20 | packages: 21 | - postgresql-11 22 | - postgresql-11-postgis-2.5 23 | - postgresql-11-postgis-2.5-scripts 24 | # https://github.com/hisener/postgresql-travis 25 | before_install: 26 | - sudo sed -i 's/port = 5433/port = 5432/' /etc/postgresql/11/main/postgresql.conf 27 | - sudo cp /etc/postgresql/{10,11}/main/pg_hba.conf 28 | - sudo service postgresql stop 29 | - sudo service postgresql start 11 30 | # command to install dependencies 31 | install: 32 | - pip install -r requirements.txt 33 | - pip install coverage 34 | 35 | # Run before script. 36 | before_script: 37 | - psql --version 38 | - psql -c 'create database travis_ci_test;' -U postgres 39 | - psql -U postgres -c "create extension postgis;" 40 | 41 | # command to run tests 42 | script: 43 | - python3 manage.py collectstatic --settings=representable.settings.dev 44 | - coverage run manage.py test --settings=representable.settings.dev 45 | 46 | after_success: 47 | - bash <(curl -s https://codecov.io/bash) 48 | -------------------------------------------------------------------------------- /Aptfile: -------------------------------------------------------------------------------- 1 | gdal-bin 2 | -------------------------------------------------------------------------------- /Procfile: -------------------------------------------------------------------------------- 1 | release: python manage.py migrate 2 | web: gunicorn representable.wsgi 3 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | # Security Policy 2 | 3 | ## Reporting a Vulnerability 4 | 5 | To report a security vulnerability, please send an email to representableteam@gmail.com with "Security Issue" in the subject line. We take security issues very seriously and aim to respond to your complaint within a week and begin working to resolve the issue as soon as we are aware of it. We greatly appreciate your help in ensuring that Representable is secure and reliable. 6 | -------------------------------------------------------------------------------- /bin/activate.csh: -------------------------------------------------------------------------------- 1 | # This file must be used with "source bin/activate.csh" *from csh*. 2 | # You cannot run it directly. 3 | # Created by Davide Di Blasi . 4 | 5 | set newline='\ 6 | ' 7 | 8 | alias deactivate 'test $?_OLD_VIRTUAL_PATH != 0 && setenv PATH "$_OLD_VIRTUAL_PATH:q" && unset _OLD_VIRTUAL_PATH; rehash; test $?_OLD_VIRTUAL_PROMPT != 0 && set prompt="$_OLD_VIRTUAL_PROMPT:q" && unset _OLD_VIRTUAL_PROMPT; unsetenv VIRTUAL_ENV; test "\!:*" != "nondestructive" && unalias deactivate && unalias pydoc' 9 | 10 | # Unset irrelevant variables. 11 | deactivate nondestructive 12 | 13 | setenv VIRTUAL_ENV "/Users/okusiokusio/Documents/GitHub/representable" 14 | 15 | set _OLD_VIRTUAL_PATH="$PATH:q" 16 | setenv PATH "$VIRTUAL_ENV:q/bin:$PATH:q" 17 | 18 | 19 | 20 | if ("" != "") then 21 | set env_name = "" 22 | else 23 | set env_name = "$VIRTUAL_ENV:t:q" 24 | endif 25 | 26 | # Could be in a non-interactive environment, 27 | # in which case, $prompt is undefined and we wouldn't 28 | # care about the prompt anyway. 29 | if ( $?prompt ) then 30 | set _OLD_VIRTUAL_PROMPT="$prompt:q" 31 | if ( "$prompt:q" =~ *"$newline:q"* ) then 32 | : 33 | else 34 | set prompt = "[$env_name:q] $prompt:q" 35 | endif 36 | endif 37 | 38 | unset env_name 39 | 40 | alias pydoc python -m pydoc 41 | 42 | rehash 43 | -------------------------------------------------------------------------------- /bin/activate.ps1: -------------------------------------------------------------------------------- 1 | # This file must be dot sourced from PoSh; you cannot run it directly. Do this: . ./activate.ps1 2 | 3 | $script:THIS_PATH = $myinvocation.mycommand.path 4 | $script:BASE_DIR = split-path (resolve-path "$THIS_PATH/..") -Parent 5 | 6 | function global:deactivate([switch] $NonDestructive) 7 | { 8 | if (test-path variable:_OLD_VIRTUAL_PATH) 9 | { 10 | $env:PATH = $variable:_OLD_VIRTUAL_PATH 11 | remove-variable "_OLD_VIRTUAL_PATH" -scope global 12 | } 13 | 14 | if (test-path function:_old_virtual_prompt) 15 | { 16 | $function:prompt = $function:_old_virtual_prompt 17 | remove-item function:\_old_virtual_prompt 18 | } 19 | 20 | if ($env:VIRTUAL_ENV) 21 | { 22 | $old_env = split-path $env:VIRTUAL_ENV -leaf 23 | remove-item env:VIRTUAL_ENV -erroraction silentlycontinue 24 | } 25 | 26 | if (!$NonDestructive) 27 | { 28 | # Self destruct! 29 | remove-item function:deactivate 30 | remove-item function:pydoc 31 | } 32 | } 33 | 34 | function global:pydoc 35 | { 36 | python -m pydoc $args 37 | } 38 | 39 | # unset irrelevant variables 40 | deactivate -nondestructive 41 | 42 | $VIRTUAL_ENV = $BASE_DIR 43 | $env:VIRTUAL_ENV = $VIRTUAL_ENV 44 | 45 | $global:_OLD_VIRTUAL_PATH = $env:PATH 46 | $env:PATH = "$env:VIRTUAL_ENV/bin:" + $env:PATH 47 | if (!$env:VIRTUAL_ENV_DISABLE_PROMPT) 48 | { 49 | function global:_old_virtual_prompt 50 | { 51 | "" 52 | } 53 | $function:_old_virtual_prompt = $function:prompt 54 | function global:prompt 55 | { 56 | # Add a prefix to the current prompt, but don't discard it. 57 | write-host "($( split-path $env:VIRTUAL_ENV -leaf )) " -nonewline 58 | & $function:_old_virtual_prompt 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /bin/activate.xsh: -------------------------------------------------------------------------------- 1 | """Xonsh activate script for virtualenv""" 2 | from xonsh.tools import get_sep as _get_sep 3 | 4 | def _deactivate(args): 5 | if "pydoc" in aliases: 6 | del aliases["pydoc"] 7 | 8 | if ${...}.get("_OLD_VIRTUAL_PATH", ""): 9 | $PATH = $_OLD_VIRTUAL_PATH 10 | del $_OLD_VIRTUAL_PATH 11 | 12 | if ${...}.get("_OLD_VIRTUAL_PYTHONHOME", ""): 13 | $PYTHONHOME = $_OLD_VIRTUAL_PYTHONHOME 14 | del $_OLD_VIRTUAL_PYTHONHOME 15 | 16 | if "VIRTUAL_ENV" in ${...}: 17 | del $VIRTUAL_ENV 18 | 19 | if "nondestructive" not in args: 20 | # Self destruct! 21 | del aliases["deactivate"] 22 | 23 | 24 | # unset irrelevant variables 25 | _deactivate(["nondestructive"]) 26 | aliases["deactivate"] = _deactivate 27 | 28 | $VIRTUAL_ENV = r"/Users/okusiokusio/Documents/GitHub/representable" 29 | 30 | $_OLD_VIRTUAL_PATH = $PATH 31 | $PATH = $PATH[:] 32 | $PATH.add($VIRTUAL_ENV + _get_sep() + "bin", front=True, replace=True) 33 | 34 | if ${...}.get("PYTHONHOME", ""): 35 | # unset PYTHONHOME if set 36 | $_OLD_VIRTUAL_PYTHONHOME = $PYTHONHOME 37 | del $PYTHONHOME 38 | 39 | aliases["pydoc"] = ["python", "-m", "pydoc"] 40 | -------------------------------------------------------------------------------- /bin/activate_this.py: -------------------------------------------------------------------------------- 1 | """Activate virtualenv for current interpreter: 2 | 3 | Use exec(open(this_file).read(), {'__file__': this_file}). 4 | 5 | This can be used when you must use an existing Python interpreter, not the virtualenv bin/python. 6 | """ 7 | import os 8 | import site 9 | import sys 10 | 11 | try: 12 | __file__ 13 | except NameError: 14 | raise AssertionError("You must use exec(open(this_file).read(), {'__file__': this_file}))") 15 | 16 | # prepend bin to PATH (this file is inside the bin directory) 17 | bin_dir = os.path.dirname(os.path.abspath(__file__)) 18 | os.environ["PATH"] = os.pathsep.join([bin_dir] + os.environ.get("PATH", "").split(os.pathsep)) 19 | 20 | base = os.path.dirname(bin_dir) 21 | 22 | # virtual env is right above bin directory 23 | os.environ["VIRTUAL_ENV"] = base 24 | 25 | # add the virtual environments site-package to the host python import mechanism 26 | IS_PYPY = hasattr(sys, "pypy_version_info") 27 | IS_JYTHON = sys.platform.startswith("java") 28 | if IS_JYTHON: 29 | site_packages = os.path.join(base, "Lib", "site-packages") 30 | elif IS_PYPY: 31 | site_packages = os.path.join(base, "site-packages") 32 | else: 33 | IS_WIN = sys.platform == "win32" 34 | if IS_WIN: 35 | site_packages = os.path.join(base, "Lib", "site-packages") 36 | else: 37 | site_packages = os.path.join(base, "lib", "python{}".format(sys.version[:3]), "site-packages") 38 | 39 | prev = set(sys.path) 40 | site.addsitedir(site_packages) 41 | sys.real_prefix = sys.prefix 42 | sys.prefix = base 43 | 44 | # Move the added items to the front of the path, in place 45 | new = list(sys.path) 46 | sys.path[:] = [i for i in new if i not in prev] + [i for i in new if i in prev] 47 | -------------------------------------------------------------------------------- /bin/django-admin: -------------------------------------------------------------------------------- 1 | #!/Users/okusiokusio/Documents/GitHub/representable/bin/python3.7 2 | # -*- coding: utf-8 -*- 3 | import re 4 | import sys 5 | from django.core.management import execute_from_command_line 6 | if __name__ == '__main__': 7 | sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) 8 | sys.exit(execute_from_command_line()) 9 | -------------------------------------------------------------------------------- /bin/django-admin.py: -------------------------------------------------------------------------------- 1 | #!/Users/okusiokusio/Documents/GitHub/representable/bin/python3.7 2 | # When the django-admin.py deprecation ends, remove this script. 3 | import warnings 4 | 5 | from django.core import management 6 | 7 | try: 8 | from django.utils.deprecation import RemovedInDjango40Warning 9 | except ImportError: 10 | raise ImportError( 11 | 'django-admin.py was deprecated in Django 3.1 and removed in Django ' 12 | '4.0. Please manually remove this script from your virtual environment ' 13 | 'and use django-admin instead.' 14 | ) 15 | 16 | if __name__ == "__main__": 17 | warnings.warn( 18 | 'django-admin.py is deprecated in favor of django-admin.', 19 | RemovedInDjango40Warning, 20 | ) 21 | management.execute_from_command_line() 22 | -------------------------------------------------------------------------------- /bin/pip: -------------------------------------------------------------------------------- 1 | #!/Users/okusiokusio/Documents/GitHub/representable/bin/python3.7 2 | # -*- coding: utf-8 -*- 3 | import re 4 | import sys 5 | 6 | from pip._internal.cli.main import main 7 | 8 | if __name__ == '__main__': 9 | sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0]) 10 | sys.exit(main()) 11 | -------------------------------------------------------------------------------- /bin/pip3: -------------------------------------------------------------------------------- 1 | #!/Users/okusiokusio/Documents/GitHub/representable/bin/python3.7 2 | # -*- coding: utf-8 -*- 3 | import re 4 | import sys 5 | 6 | from pip._internal.cli.main import main 7 | 8 | if __name__ == '__main__': 9 | sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0]) 10 | sys.exit(main()) 11 | -------------------------------------------------------------------------------- /bin/pip3.7: -------------------------------------------------------------------------------- 1 | #!/Users/okusiokusio/Documents/GitHub/representable/bin/python3.7 2 | # -*- coding: utf-8 -*- 3 | import re 4 | import sys 5 | 6 | from pip._internal.cli.main import main 7 | 8 | if __name__ == '__main__': 9 | sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0]) 10 | sys.exit(main()) 11 | -------------------------------------------------------------------------------- /bin/python: -------------------------------------------------------------------------------- 1 | python3.7 -------------------------------------------------------------------------------- /bin/python3: -------------------------------------------------------------------------------- 1 | python3.7 -------------------------------------------------------------------------------- /bin/python3.7: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Representable/representable/57b66291b0df1ea113b588c8ffc235f1e26bfb92/bin/python3.7 -------------------------------------------------------------------------------- /bin/sqlformat: -------------------------------------------------------------------------------- 1 | #!/Users/okusiokusio/Documents/GitHub/representable/bin/python3.7 2 | # -*- coding: utf-8 -*- 3 | import re 4 | import sys 5 | from sqlparse.__main__ import main 6 | if __name__ == '__main__': 7 | sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) 8 | sys.exit(main()) 9 | -------------------------------------------------------------------------------- /create_state_fixtures.py: -------------------------------------------------------------------------------- 1 | from state_abbrev import us_state_abbrev as dicta 2 | import json 3 | 4 | 5 | def make_content(key, value): 6 | return "

Redistricting information for " + key + " is on its way!

" 7 | 8 | 9 | def main(): 10 | jsondict = [] 11 | 12 | i = 1 13 | for key, value in dicta.items(): 14 | currdict = {} 15 | currdict["model"] = "main.state" 16 | currdict["pk"] = i 17 | fields = {} 18 | fields["name"] = key 19 | fields["abbr"] = value 20 | fields["content1"] = make_content(key, value) 21 | currdict["fields"] = fields 22 | jsondict.append(currdict) 23 | i += 1 24 | 25 | with open("./main/fixtures/states.json", "w") as outfile: 26 | json.dump(jsondict, outfile) 27 | 28 | 29 | if __name__ == "__main__": 30 | main() 31 | -------------------------------------------------------------------------------- /dev_reqs.txt: -------------------------------------------------------------------------------- 1 | graphviz==0.14.1 2 | pydotplus==2.0.2 3 | pygraphviz==1.6 -------------------------------------------------------------------------------- /docs/.gitignore: -------------------------------------------------------------------------------- 1 | # Dependencies 2 | /node_modules 3 | 4 | # Production 5 | /build 6 | 7 | # Generated files 8 | .docusaurus 9 | .cache-loader 10 | 11 | # Misc 12 | .DS_Store 13 | .env.local 14 | .env.development.local 15 | .env.test.local 16 | .env.production.local 17 | 18 | npm-debug.log* 19 | yarn-debug.log* 20 | yarn-error.log* -------------------------------------------------------------------------------- /docs/README.md: -------------------------------------------------------------------------------- 1 | # Representable Docs 2 | 3 | [![Netlify Status](https://api.netlify.com/api/v1/badges/d1c8c80c-5c8a-4153-95a4-03ff8b54bc91/deploy-status)](https://app.netlify.com/sites/representable-docs/deploys) 4 | 5 | This website is built using [Docusaurus 2](https://v2.docusaurus.io/), a modern static website generator. 6 | 7 | ### Installation 8 | 9 | ``` 10 | $ yarn 11 | ``` 12 | 13 | ### Local Development 14 | 15 | ``` 16 | $ yarn start 17 | ``` 18 | 19 | This command starts a local development server and open up a browser window. Most changes are reflected live without having to restart the server. 20 | 21 | ### Build 22 | 23 | ``` 24 | $ yarn build 25 | ``` 26 | 27 | This command generates static content into the `build` directory and can be served using any static contents hosting service. 28 | 29 | ### Deployment 30 | 31 | Deploys automatically to netlify when you push to main. 32 | -------------------------------------------------------------------------------- /docs/blog/2020-06-09-welcome.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: welcome 3 | title: Welcome 4 | author: Lauren Johnston 5 | author_title: Engineer @ Representable 6 | author_url: https://github.com/lauren-johnston 7 | author_image_url: https://avatars3.githubusercontent.com/u/8892509?s=460&u=710a92147d93378daa9ef1435ca242ab38909f28&v=4 8 | tags: [hello] 9 | --- 10 | 11 | Welcome to the Representable.org Docs! We'll use this blog as a place to document code releases as well as engineering updates. 12 | -------------------------------------------------------------------------------- /docs/blog/2020-07-10-test.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: testing 3 | title: testing 4 | author: edward 5 | author_title: Engineer @ Representable 6 | author_url: https://github.com/lauren-johnston 7 | author_image_url: https://avatars3.githubusercontent.com/u/8892509?s=460&u=710a92147d93378daa9ef1435ca242ab38909f28&v=4 8 | tags: [hello] 9 | --- 10 | 11 | We may be posting more content on this blog. Keep looking here! 12 | -------------------------------------------------------------------------------- /docs/docs/access1.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: access1 3 | title: Accessibility Overview 4 | --- 5 | 6 | Accessibility is important! While writing code, it's good to keep these things in mind, so that we can maintain and improve our accessibility. This is primarily HTML/CSS related. 7 | 8 | We follow the [Web Content Accessibility Guidelines](https://www.w3.org/WAI/standards-guidelines/wcag/) (WCAG). 9 | 10 | ### Alt Text 11 | Any time you add an image to the site, add alt text! `alt="Image description goes here"` 12 | 13 | ### Labels 14 | All form areas should have labels which allow for easy access with screen readers. If you don't want to make these visible, use `class="sr-only"` to make it so that it's only present for screen readers. 15 | 16 | ### Context and Roles 17 | When possible, use more straightforward html element types: ` 23 |

{% trans "Making an account helps us protect legitimate submissions." %}

24 | 25 | 26 | {% else %} 27 | 28 | 29 | {% url 'account_email' as email_url %} 30 | 31 |

{% blocktrans trimmed %}This e-mail confirmation link expired or is invalid. Please issue a new e-mail confirmation request.{% endblocktrans %}

32 | {% endif %} 33 | 34 | 35 | 36 | 37 | 38 | {% endblock %} -------------------------------------------------------------------------------- /main/templates/account/logout.html: -------------------------------------------------------------------------------- 1 | {% extends "account/base.html" %} 2 | 3 | {% load i18n %} 4 | 5 | {% block head_title %}{% trans "Sign Out" %}{% endblock %} 6 | 7 | {% block content %} 8 |
9 |
10 |
11 |

{% trans 'Are you sure you want to sign out?' %} 12 |
13 |

14 |
15 | {% csrf_token %} 16 | {% if redirect_field_value %} 17 | 18 | {% endif %} 19 | 20 |
21 |
22 |
23 |
24 | {% endblock %} 25 | -------------------------------------------------------------------------------- /main/templates/account/password_change.html: -------------------------------------------------------------------------------- 1 | {% extends "account/base.html" %} 2 | 3 | {% load i18n %} 4 | {% load account %} 5 | {% load widget_tweaks %} 6 | {% block head_title %}{% trans "Change Password" %}{% endblock %} 7 | 8 | 9 | {% block content %} 10 |
11 |
12 |
13 | 23 |
24 |
25 |
26 | {% endblock %} 27 | -------------------------------------------------------------------------------- /main/templates/account/password_reset.html: -------------------------------------------------------------------------------- 1 | {% extends "account/base.html" %} 2 | 3 | 4 | {% load i18n %} 5 | {% load account %} 6 | {% load widget_tweaks %} 7 | 8 | {% block content %} 9 |
10 |
11 |
12 | 37 |
38 |
39 |
40 | {% endblock %} 41 | -------------------------------------------------------------------------------- /main/templates/account/password_reset_done.html: -------------------------------------------------------------------------------- 1 | {% extends "account/base.html" %} 2 | 3 | {% load i18n %} 4 | {% load account %} 5 | 6 | {% block head_title %}{% trans "Password Reset" %}{% endblock %} 7 | 8 | {% block content %} 9 |
10 |
11 |
12 | 24 |
25 |
26 |
27 | {% endblock %} -------------------------------------------------------------------------------- /main/templates/account/password_reset_from_key.html: -------------------------------------------------------------------------------- 1 | {% extends "account/base.html" %} 2 | 3 | {% load i18n %} 4 | {% block head_title %}{% trans "Change Password" %}{% endblock %} 5 | 6 | {% block content %} 7 | 8 |
9 |
10 |
11 | 31 |
32 |
33 |
34 | {% endblock %} -------------------------------------------------------------------------------- /main/templates/account/password_reset_from_key_done.html: -------------------------------------------------------------------------------- 1 | {% extends "account/base.html" %} 2 | 3 | {% load i18n %} 4 | {% block head_title %}{% trans "Change Password" %}{% endblock %} 5 | 6 | {% block content %} 7 |
8 |
9 |
10 | 16 |
17 |
18 |
19 | 20 | {% endblock %} -------------------------------------------------------------------------------- /main/templates/account/password_set.html: -------------------------------------------------------------------------------- 1 | {% extends "account/base.html" %} 2 | 3 | {% load i18n %} 4 | {% load account %} 5 | {% load widget_tweaks %} 6 | {% block head_title %}{% trans "Change Password" %}{% endblock %} 7 | 8 | 9 | {% block content %} 10 |
11 |
12 |
13 | 24 |
25 |
26 |
27 | 28 | {% endblock %} -------------------------------------------------------------------------------- /main/templates/account/signup_login.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | {% extends "account/base.html" %} 4 | {% load static %} 5 | {% load i18n %} 6 | {% load account socialaccount %} 7 | {% load widget_tweaks %} 8 | 9 | {% block content %} 10 |
11 | {% if redirect_field_value %} 12 |
13 |
14 | 17 |
18 |
19 | {% endif %} 20 |
21 | {% include './signup.html'%} 22 | 23 |
24 |
25 |
26 | 27 | {% include './login.html'%} 28 |
29 | 30 |
31 | {% endblock %} 32 | 33 | {% block script %} 34 | 35 | {% endblock %} 36 | -------------------------------------------------------------------------------- /main/templates/account/verification_sent.html: -------------------------------------------------------------------------------- 1 | {% extends "account/base.html" %} 2 | 3 | {% load i18n %} 4 | 5 | {% block head_title %}{% trans "Verify Your E-mail Address" %}{% endblock %} 6 | 7 | {% block content %} 8 | 9 |
10 |
11 |
12 | 19 |
20 |
21 |
22 | {% endblock %} -------------------------------------------------------------------------------- /main/templates/forms/widgets/radio.html: -------------------------------------------------------------------------------- 1 | {% with id=widget.attrs.id %} 2 | {% for group, options, index in widget.optgroups %}{% if group %} 3 | { group }} 4 | {% endif %}{% for option in options %} 5 | {% include option.template_name with widget=option %}{% endfor %} 6 | {% if group %} 7 | {% endif %}{% endfor %} 8 | {% endwith %} 9 | -------------------------------------------------------------------------------- /main/templates/forms/widgets/radio_option.html: -------------------------------------------------------------------------------- 1 |
2 |  {% endif %}{% if widget.wrap_label %}{{ widget.label }}{% endif %} 4 |
5 | -------------------------------------------------------------------------------- /main/templates/main/base.html: -------------------------------------------------------------------------------- 1 | {% extends 'base.html' %} 2 | -------------------------------------------------------------------------------- /main/templates/main/dashboard/entries/index.html: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Representable/representable/57b66291b0df1ea113b588c8ffc235f1e26bfb92/main/templates/main/dashboard/entries/index.html -------------------------------------------------------------------------------- /main/templates/main/dashboard/entries/list.html: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Representable/representable/57b66291b0df1ea113b588c8ffc235f1e26bfb92/main/templates/main/dashboard/entries/list.html -------------------------------------------------------------------------------- /main/templates/main/dashboard/entries/review.html: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Representable/representable/57b66291b0df1ea113b588c8ffc235f1e26bfb92/main/templates/main/dashboard/entries/review.html -------------------------------------------------------------------------------- /main/templates/main/dashboard/partners/allowlist_upload.html: -------------------------------------------------------------------------------- 1 | {% extends 'main/base.html' %} 2 | {% load static %} 3 | {% load widget_tweaks %} 4 | 5 | {% block content %} 6 |
7 |
8 |
9 | 35 |
36 |
37 |
38 | {% endblock %} 39 | -------------------------------------------------------------------------------- /main/templates/main/drives/index.html: -------------------------------------------------------------------------------- 1 | {% extends "main/base.html" %} 2 | {% load static %} 3 | 4 | {% block content %} 5 |

{% trans "Drives" %}

6 | 11 | {% endblock %} 12 | -------------------------------------------------------------------------------- /main/templates/main/export.html: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Representable/representable/57b66291b0df1ea113b588c8ffc235f1e26bfb92/main/templates/main/export.html -------------------------------------------------------------------------------- /main/templates/main/exportcsv.html: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Representable/representable/57b66291b0df1ea113b588c8ffc235f1e26bfb92/main/templates/main/exportcsv.html -------------------------------------------------------------------------------- /main/templates/main/layouts/base-page.html: -------------------------------------------------------------------------------- 1 | {% extends 'main/base.html' %} 2 | {% load static %} 3 | 4 | {% block content %} 5 |
6 |
7 |
8 |

9 | {% block title %} 10 | {% endblock %} 11 |

12 | {% block page-content %} 13 | {% endblock %} 14 |
15 | 16 |
17 |
18 | {% endblock %} -------------------------------------------------------------------------------- /main/templates/main/partners/page.html: -------------------------------------------------------------------------------- 1 | {% extends "main/base.html" %} 2 | {% load static %} 3 | {% load i18n %} 4 | 5 | {% block content %} 6 |
7 |
8 |
9 |

10 | {{object.name}} 11 | {% if object.verified %} 12 | 13 | {% endif %} 14 |

15 |
16 |

17 | {% for state in object.states %} 18 | {{state}} 19 | {% endfor %} 20 |

21 |

{{object.description}}

22 | {% trans "Return to Partners" %} 23 | {% trans "Link to organization map" %} 24 | {% if object.ext_link %} 25 | {% trans "Visit Partner Site" %} 26 | {% endif %} 27 |
28 |
29 | {% endblock %} 30 | -------------------------------------------------------------------------------- /main/templates/main/state_selection.html: -------------------------------------------------------------------------------- 1 | 2 | {% extends 'main/base.html' %} 3 | {% load leaflet_tags %} 4 | {% load static %} 5 | {% load i18n %} 6 | 7 | {% block head %} 8 | {% leaflet_js %} 9 | {% leaflet_css %} 10 | 11 | 12 | 13 | 14 | 15 | {% endblock %} 16 | 17 | {% block content %} 18 |
19 |
20 |

{% trans "Select your state." %}

21 |

{% trans "Select your state." %}

22 | 23 | 26 |
27 |
28 |
29 |
30 |
31 | {% endblock %} 32 | 33 | {% block script %} 34 | 37 | 38 | 39 | 40 | 41 | {% endblock %} 42 | -------------------------------------------------------------------------------- /main/templates/main/zipcode.html: -------------------------------------------------------------------------------- 1 | {% extends 'main/base.html' %} 2 | {% load leaflet_tags %} 3 | {% load static %} 4 | {% block head %} 5 | {% leaflet_js %} 6 | {% leaflet_css %} 7 | 8 | 9 | 10 | 11 | 12 | {% endblock %} 13 | 14 | 15 | 16 | {% block content %} 17 |
18 | 26 |
27 | 28 | {% endblock %} 29 | 30 | {% block script %} 31 | 42 | {% endblock %} 43 | -------------------------------------------------------------------------------- /main/templatetags/__init__.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (c) 2019- Representable Team (Theodor Marcu, Lauren Johnston, Somya Arora, Kyle Barnes, Preeti Iyer). 3 | # 4 | # This file is part of Representable 5 | # (see http://representable.org). 6 | # 7 | # This program is free software: you can redistribute it and/or modify 8 | # it under the terms of the GNU General Public License as published by 9 | # the Free Software Foundation, either version 3 of the License, or 10 | # (at your option) any later version. 11 | # 12 | # This program is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with this program. If not, see . 19 | # 20 | -------------------------------------------------------------------------------- /main/templatetags/representable_extras.py: -------------------------------------------------------------------------------- 1 | from django import template 2 | 3 | register = template.Library() 4 | 5 | @register.filter 6 | def addstr(arg1, arg2): 7 | """concatenate arg1 & arg2""" 8 | return str(arg1) + str(arg2) 9 | 10 | @register.filter 11 | def get_item(value, key): 12 | return value[key] 13 | 14 | @register.filter 15 | def set_export_name(organization, drive): 16 | """return drive if it exists""" 17 | if drive: 18 | return drive.replace(" ", "_") 19 | else: 20 | return organization.replace(" ", "_") 21 | 22 | @register.filter 23 | def replace_spaces(arg1): 24 | return str(arg1).replace(" ", "_") 25 | -------------------------------------------------------------------------------- /main/users/adapter.py: -------------------------------------------------------------------------------- 1 | from django.conf import settings 2 | from allauth.account.adapter import DefaultAccountAdapter 3 | 4 | 5 | class DebugAdapter(DefaultAccountAdapter): 6 | """ 7 | This class overrides the default Django All-auth account 8 | adapter by implementing custom functionality. 9 | 10 | This adapter only works in dev. 11 | 12 | Documentation docs: https://django-allauth.readthedocs.io/en/latest/advanced.html#sending-email 13 | Django Default Adapter Source Code: 14 | https://github.com/pennersr/django-allauth/blob/master/allauth/account/adapter.py 15 | """ 16 | 17 | def send_mail(self, template_prefix, email, context): 18 | """ 19 | Overrides the default send_mail method. 20 | """ 21 | # Use the 'templates/account/email/debug_email_confirmation_*' files instead of the 22 | # default ones. 23 | print(template_prefix) 24 | template_prefix = "account/email/debug_email_confirmation" 25 | return super().send_mail(template_prefix, email, context) 26 | -------------------------------------------------------------------------------- /main/utils.py: -------------------------------------------------------------------------------- 1 | from django.utils.text import slugify 2 | import uuid 3 | import hashlib 4 | 5 | 6 | def generate_unique_slug(model, field): 7 | """ 8 | return unique slug if origin slug is exist. 9 | eg: `foo-bar` => `foo-bar-1` 10 | 11 | :param `model` is Class model. 12 | :param `field` is specific field for title. 13 | 14 | Source: https://djangosnippets.org/snippets/10643/ 15 | """ 16 | origin_slug = slugify(field) 17 | if origin_slug == "": 18 | origin_slug = "partner" 19 | unique_slug = origin_slug 20 | numb = 1 21 | while model.objects.filter(slug=unique_slug).exists(): 22 | unique_slug = "%s-%d" % (origin_slug, numb) 23 | numb += 1 24 | return unique_slug 25 | 26 | 27 | def generate_unique_token(drive): 28 | # adapted from: https://stackoverflow.com/questions/55062799/how-can-i-send-url-with-users-unique-id-and-token-in-django 29 | salt = uuid.uuid4().hex + drive 30 | return hashlib.sha256(salt.encode("utf-8")).hexdigest() 31 | -------------------------------------------------------------------------------- /main/views/__init__.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (c) 2019- Representable Team (Theodor Marcu, Lauren Johnston, Somya Arora, Kyle Barnes, Preeti Iyer). 3 | # 4 | # This file is part of Representable 5 | # (see http://representable.org). 6 | # 7 | # This program is free software: you can redistribute it and/or modify 8 | # it under the terms of the GNU General Public License as published by 9 | # the Free Software Foundation, either version 3 of the License, or 10 | # (at your option) any later version. 11 | # 12 | # This program is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with this program. If not, see . 19 | # 20 | from .main import * 21 | from .dashboard import * 22 | from .partners import * 23 | from .drives import * 24 | -------------------------------------------------------------------------------- /main/views/drives.py: -------------------------------------------------------------------------------- 1 | from ..models import ( 2 | Drive, 3 | State, 4 | # Image 5 | ) 6 | from django.urls import reverse, reverse_lazy 7 | from django.contrib.auth.mixins import LoginRequiredMixin, UserPassesTestMixin 8 | 9 | # from django.views.generic.detail import SingleObjectMixin 10 | from django.views.generic import ( 11 | ListView, 12 | DetailView, 13 | ) 14 | 15 | # from django.shortcuts import render 16 | # # from ..forms import ImageForm 17 | 18 | class IndexView(ListView): 19 | model = Drive 20 | template_name = "main/drives/index.html" 21 | pk_url_kwarg = "cam_pk" 22 | 23 | 24 | class DriveView(DetailView): 25 | model = Drive 26 | template_name = "main/drives/page.html" 27 | pk_url_kwarg = "cam_pk" 28 | 29 | def get_context_data(self, **kwargs): 30 | context = super().get_context_data(**kwargs) 31 | # Get Drive State object 32 | drive_slug = self.kwargs["slug"] 33 | drive = Drive.objects.get(slug=drive_slug) 34 | if (State.objects.filter(abbr=drive.state)): 35 | context["state"] = State.objects.filter(abbr=drive.state)[0] 36 | context["page_type"] = "drive-page" 37 | return context 38 | 39 | 40 | # def showimage(request): 41 | # lastimage= Image.objects.last() 42 | # imagefile= lastimage.imagefile 43 | 44 | # form= ImageForm(request.POST or None, request.FILES or None) 45 | # if form.is_valid(): 46 | # form.save() 47 | 48 | # context= {'imagefile': imagefile, 49 | # 'form': form 50 | # } 51 | 52 | # return render(request, 'Blog/images.html', context) 53 | -------------------------------------------------------------------------------- /manage.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # 3 | # Copyright (c) 2019- Representable Team (Theodor Marcu, Lauren Johnston, Somya Arora, Kyle Barnes, Preeti Iyer). 4 | # 5 | # This file is part of Representable 6 | # (see http://representable.org). 7 | # 8 | # This program is free software: you can redistribute it and/or modify 9 | # it under the terms of the GNU General Public License as published by 10 | # the Free Software Foundation, either version 3 of the License, or 11 | # (at your option) any later version. 12 | # 13 | # This program is distributed in the hope that it will be useful, 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | # GNU General Public License for more details. 17 | # 18 | # You should have received a copy of the GNU General Public License 19 | # along with this program. If not, see . 20 | # 21 | import os 22 | import sys 23 | 24 | if __name__ == "__main__": 25 | os.environ.setdefault("DJANGO_SETTINGS_MODULE", "representable.settings") 26 | try: 27 | from django.core.management import execute_from_command_line 28 | except ImportError as exc: 29 | raise ImportError( 30 | "Couldn't import Django. Are you sure it's installed and " 31 | "available on your PYTHONPATH environment variable? Did you " 32 | "forget to activate a virtual environment?" 33 | ) from exc 34 | execute_from_command_line(sys.argv) 35 | -------------------------------------------------------------------------------- /models.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Representable/representable/57b66291b0df1ea113b588c8ffc235f1e26bfb92/models.png -------------------------------------------------------------------------------- /new_models.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Representable/representable/57b66291b0df1ea113b588c8ffc235f1e26bfb92/new_models.png -------------------------------------------------------------------------------- /pyproject.toml: -------------------------------------------------------------------------------- 1 | [tool.black] 2 | line-length = 79 3 | include = '\.pyi?$' 4 | exclude = ''' 5 | /( 6 | \.git 7 | | \.hg 8 | | \.mypy_cache 9 | | \.tox 10 | | \.venv 11 | | _build 12 | | buck-out 13 | | build 14 | | dist 15 | | migrations 16 | )/ 17 | ''' 18 | -------------------------------------------------------------------------------- /pyvenv.cfg: -------------------------------------------------------------------------------- 1 | home = /Library/Frameworks/Python.framework/Versions/3.7/bin 2 | include-system-site-packages = false 3 | version = 3.7.9 4 | -------------------------------------------------------------------------------- /representable/locale/ar/LC_MESSAGES/django.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Representable/representable/57b66291b0df1ea113b588c8ffc235f1e26bfb92/representable/locale/ar/LC_MESSAGES/django.mo -------------------------------------------------------------------------------- /representable/locale/es/LC_MESSAGES/django 2.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Representable/representable/57b66291b0df1ea113b588c8ffc235f1e26bfb92/representable/locale/es/LC_MESSAGES/django 2.mo -------------------------------------------------------------------------------- /representable/locale/es/LC_MESSAGES/django.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Representable/representable/57b66291b0df1ea113b588c8ffc235f1e26bfb92/representable/locale/es/LC_MESSAGES/django.mo -------------------------------------------------------------------------------- /representable/locale/hmn/LC_MESSAGES/django.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Representable/representable/57b66291b0df1ea113b588c8ffc235f1e26bfb92/representable/locale/hmn/LC_MESSAGES/django.mo -------------------------------------------------------------------------------- /representable/__init__.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (c) 2019- Representable Team (Theodor Marcu, Lauren Johnston, Somya Arora, Kyle Barnes, Preeti Iyer). 3 | # 4 | # This file is part of Representable 5 | # (see http://representable.org). 6 | # 7 | # This program is free software: you can redistribute it and/or modify 8 | # it under the terms of the GNU General Public License as published by 9 | # the Free Software Foundation, either version 3 of the License, or 10 | # (at your option) any later version. 11 | # 12 | # This program is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with this program. If not, see . 19 | # 20 | -------------------------------------------------------------------------------- /representable/custom_storage.py: -------------------------------------------------------------------------------- 1 | from storages.backends.s3boto3 import S3Boto3Storage 2 | 3 | class MediaStorage(S3Boto3Storage): 4 | bucket_name = 'representable-media' 5 | 6 | -------------------------------------------------------------------------------- /representable/settings/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Representable/representable/57b66291b0df1ea113b588c8ffc235f1e26bfb92/representable/settings/__init__.py -------------------------------------------------------------------------------- /representable/settings/dev.py: -------------------------------------------------------------------------------- 1 | from .base import * 2 | import os 3 | 4 | ALLOWED_HOSTS = ["*"] 5 | 6 | SECURE_SSL_REDIRECT = False 7 | 8 | DEBUG = True 9 | # DEBUG = False 10 | 11 | # Dev Email Settings - Print to Console 12 | EMAIL_BACKEND = "django.core.mail.backends.console.EmailBackend" 13 | # Use Custom Debugging Email Adapter that prints a simple text message. 14 | # See docs for context: https://django-allauth.readthedocs.io/en/latest/advanced.html#sending-email 15 | # ACCOUNT_ADAPTER = "main.users.adapter.DebugAdapter" 16 | 17 | # Production Email Settings 18 | EMAIL_BACKEND = "django.core.mail.backends.smtp.EmailBackend" 19 | # Uses default Account Adapter. 20 | # SMTP Server Settings 21 | SENDGRID_API_KEY = os.getenv("SENDGRID_API_KEY") 22 | EMAIL_HOST = "smtp.sendgrid.net" 23 | EMAIL_HOST_USER = "apikey" 24 | EMAIL_HOST_PASSWORD = SENDGRID_API_KEY 25 | EMAIL_PORT = 587 26 | EMAIL_USE_TLS = True 27 | 28 | 29 | MIXPANEL_TOKEN = "ce31fc3e8e15a16619bb3672f9c25407" 30 | 31 | # testing keys - if you want to do work with recaptcha on dev, copy the public 32 | # keys from prod -- if you don't have the recaptcha private key in your 33 | # os environment, it won't work if we verify on the backend. It's available in the bitwarden. the checkbox will 34 | # still need to be checked unless you change the CHECK_CAPTCHA_SUBMIT setting here 35 | RECAPTCHA_PUBLIC = "6LeIxAcTAAAAAJcZVRqyHh71UMIEGNQ_MXjiZKhI" 36 | RECAPTCHA_PRIVATE = os.getenv("RECAPTCHA_PRIVATE_DEV") 37 | CHECK_CAPTCHA_SUBMIT = False 38 | 39 | LOGGING = { 40 | 'version': 1, 41 | 'disable_existing_loggers': False, 42 | 'handlers': { 43 | 'file': { 44 | 'level': 'DEBUG', 45 | 'class': 'logging.FileHandler', 46 | 'filename': 'debug.log', 47 | }, 48 | }, 49 | 'loggers': { 50 | 'django': { 51 | 'handlers': ['file'], 52 | 'level': 'DEBUG', 53 | 'propagate': True, 54 | }, 55 | }, 56 | } -------------------------------------------------------------------------------- /representable/storage.py: -------------------------------------------------------------------------------- 1 | from whitenoise.storage import CompressedManifestStaticFilesStorage 2 | 3 | class WhiteNoiseStaticFilesStorage(CompressedManifestStaticFilesStorage): 4 | manifest_strict = False -------------------------------------------------------------------------------- /representable/templates/404.html: -------------------------------------------------------------------------------- 1 | {% extends 'base.html' %} 2 | {% load static %} 3 | {% block content %} 4 |
5 |
6 |
7 | 14 |
15 |
16 |
17 | {% endblock %} -------------------------------------------------------------------------------- /representable/wsgi.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (c) 2019- Representable Team (Theodor Marcu, Lauren Johnston, Somya Arora, Kyle Barnes, Preeti Iyer). 3 | # 4 | # This file is part of Representable 5 | # (see http://representable.org). 6 | # 7 | # This program is free software: you can redistribute it and/or modify 8 | # it under the terms of the GNU General Public License as published by 9 | # the Free Software Foundation, either version 3 of the License, or 10 | # (at your option) any later version. 11 | # 12 | # This program is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with this program. If not, see . 19 | # 20 | """ 21 | WSGI config for representable project. 22 | 23 | It exposes the WSGI callable as a module-level variable named ``application``. 24 | 25 | For more information on this file, see 26 | https://docs.djangoproject.com/en/2.1/howto/deployment/wsgi/ 27 | """ 28 | 29 | import os 30 | 31 | from django.core.wsgi import get_wsgi_application 32 | 33 | os.environ.setdefault("DJANGO_SETTINGS_MODULE", "representable.settings") 34 | 35 | application = get_wsgi_application() 36 | -------------------------------------------------------------------------------- /runtime.txt: -------------------------------------------------------------------------------- 1 | python-3.7.2 2 | -------------------------------------------------------------------------------- /state_abbrev.py: -------------------------------------------------------------------------------- 1 | # TODO where should this file go? 2 | # from https://gist.github.com/rogerallen/1583593 3 | us_state_abbrev = { 4 | "Alabama": "AL", 5 | "Alaska": "AK", 6 | "Arizona": "AZ", 7 | "Arkansas": "AR", 8 | "California": "CA", 9 | "Colorado": "CO", 10 | "Connecticut": "CT", 11 | "Delaware": "DE", 12 | "District of Columbia": "DC", 13 | "Florida": "FL", 14 | "Georgia": "GA", 15 | "Hawaii": "HI", 16 | "Idaho": "ID", 17 | "Illinois": "IL", 18 | "Indiana": "IN", 19 | "Iowa": "IA", 20 | "Kansas": "KS", 21 | "Kentucky": "KY", 22 | "Louisiana": "LA", 23 | "Maine": "ME", 24 | "Maryland": "MD", 25 | "Massachusetts": "MA", 26 | "Michigan": "MI", 27 | "Minnesota": "MN", 28 | "Mississippi": "MS", 29 | "Missouri": "MO", 30 | "Montana": "MT", 31 | "Nebraska": "NE", 32 | "Nevada": "NV", 33 | "New Hampshire": "NH", 34 | "New Jersey": "NJ", 35 | "New Mexico": "NM", 36 | "New York": "NY", 37 | "North Carolina": "NC", 38 | "North Dakota": "ND", 39 | "Northern Mariana Islands": "MP", 40 | "Ohio": "OH", 41 | "Oklahoma": "OK", 42 | "Oregon": "OR", 43 | "Palau": "PW", 44 | "Pennsylvania": "PA", 45 | "Puerto Rico": "PR", 46 | "Rhode Island": "RI", 47 | "South Carolina": "SC", 48 | "South Dakota": "SD", 49 | "Tennessee": "TN", 50 | "Texas": "TX", 51 | "Utah": "UT", 52 | "Vermont": "VT", 53 | "Virgin Islands": "VI", 54 | "Virginia": "VA", 55 | "Washington": "WA", 56 | "West Virginia": "WV", 57 | "Wisconsin": "WI", 58 | "Wyoming": "WY", 59 | } 60 | --------------------------------------------------------------------------------