diff --git a/.travis.yml b/.travis.yml index 42f565c01b4..21525e274a9 100755 --- a/.travis.yml +++ b/.travis.yml @@ -15,7 +15,9 @@ before_script: script: - npm test - flake8 network-api/ -- python network-api/manage.py test +- coverage run --source './network-api/networkapi' network-api/manage.py test networkapi +after_success: +- coveralls env: global: - DEBUG=True diff --git a/README.md b/README.md index d17c705feb6..eb36d547d21 100755 --- a/README.md +++ b/README.md @@ -4,6 +4,7 @@ [![Dependency Status](https://david-dm.org/mozilla/network.svg)](https://david-dm.org/mozilla/network) [![Dev Dependency Status](https://david-dm.org/mozilla/network/dev-status.svg)](https://david-dm.org/mozilla/network/?type=dev) [![Uses Mofo Standards](https://MozillaFoundation.github.io/mofo-standards/badge.svg)](https://github.com/MozillaFoundation/mofo-standards) +[![Code Coverage](https://coveralls.io/repos/github/mozilla/foundation.mozilla.org/badge.svg?branch=master)](https://coveralls.io/github/mozilla/foundation.mozilla.org) ## Development @@ -47,29 +48,28 @@ Install all dependencies into the virtual environment: - `pip install -r ../requirements.txt` -#### Run migrate and load fixtures +#### Run migrate and load fake model data Migrate the database to the latest schema: - `python manage.py migrate` -By default, Django sets the site domain to `example.com`, but the mock data needs the domain to be `localhost:8000`. Run the following command to update the site domain automatically +By default, Django sets the site domain to `example.com`, but the fake data needs the domain to be `localhost:8000`. Run the following command to update the site domain automatically - `python manage.py update_site_domain` -Mock data can be loaded into your dev site with the following command +Fake model data can be loaded into your dev site with the following command -- `python manage.py loaddata networkapi/fixtures/test_data.json` +- `python manage.py load_fake_data` -This will set up a default superuser account for you to use: +Create an admin user using the following command -- username: `testuser` -- pass: `networktest` +- `python manage.py createsuperuser` #### From scratch database -If you'd prefer not to load in the fixture data, you can use the following commands to get started: +If you'd prefer not to load in fake model data, you can use the following commands to get started: ```bash python manage.py migrate @@ -86,10 +86,29 @@ The site should now be accessible at `https://localhost:8000` To log in to the admin UI, visit: http://localhost:8000/admin +#### Generating a new set of fake model data + +You can empty your database and create a full new set of fake model data using the following command + +- `python manage.py load_fake_data --delete` + +You can generate a specific set of fake model data by entering a seed value + +- `python manage.py load_fake_data --delete --seed VALUE` + +If a seed is not provided, a pseudorandom one will be generated and logged to the console. You can share this value with others if you need them to generate the same set of data that you have. + #### Running the project for front-end development - At the root of the project you can run: `npm start`, which will start the server as well as watch tasks for recompiling changes to Pug, JS, and Sass files. +#### Tests + +When relevant, we encourage you to write tests. +You can run the tests using the following command + +- `python manage.py test` + --- ### Stack @@ -164,7 +183,7 @@ The `DEBUG` flag does all sorts of magical things, to the point where testing wi - Django uses its own built-in static content server, in which template tags may behave *differently* from the Mezzanine static server, which can lead to `400 Bad Request` errors in `DEBUG=False` setting. - Django bypasses the `ALLOWED_HOST` restrictions, which again can lead to `400 Bad Request` errors in `DEBUG=False` setting. -- Rather than HTTP error pages, Django will generate stack traces pages that expose pretty much all enviroment variables except any that match certain substrings such as `KEY`, `PASS`, etc. for obvious security reasons. +- Rather than HTTP error pages, Django will generate stack traces pages that expose pretty much all environment variables except any that match certain substrings such as `KEY`, `PASS`, etc. for obvious security reasons. - ...there are probably more gotchas just for `DEBUG` so if you find any please add them to this list. #### Use of `{ static "...." }` in templates @@ -197,7 +216,7 @@ Default environment variables are declared in `env.default`. If you wish to over The domain used to fetch static content from Network Pulse can be customized by specifying `PULSE_API_DOMAIN`. By default it uses `network-pulse-api-production.herokuapp.com`. -The URL for fetching static content from the Network API can be customized by specifying `NETWORK_SITE_URL`. By default it uses `https://foundation.mozilla.org`. NOTE: this variable must include a protocol (such as `https://`) +The URL for fetching static content from the Network API can be customized by specifying `NETWORK_SITE_URL`. By default it uses `https://foundation.mozilla.org`. **NOTE: this variable must include a protocol (such as `https://`)** --- ### Security diff --git a/app.json b/app.json index 0cb0eb1c988..11641a4bacf 100644 --- a/app.json +++ b/app.json @@ -48,7 +48,7 @@ "CSP_MEDIA_SRC": "'self'", "CSP_CHILD_SRC": "'self'", "CSP_FORM_ACTION": "'self' https://www.mozilla.org/en-US/newsletter/", - "LOAD_FIXTURE": "True" + "EXECUTE_FAKE_DATA": "True" }, "buildpacks": [ { diff --git a/network-api/media/images/placeholders/generic/computerandcoffee.jpg b/network-api/media/images/placeholders/generic/computerandcoffee.jpg new file mode 100644 index 00000000000..f76697ca829 Binary files /dev/null and b/network-api/media/images/placeholders/generic/computerandcoffee.jpg differ diff --git a/network-api/media/images/placeholders/generic/hotair.jpg b/network-api/media/images/placeholders/generic/hotair.jpg new file mode 100644 index 00000000000..2d106f38f0a Binary files /dev/null and b/network-api/media/images/placeholders/generic/hotair.jpg differ diff --git a/network-api/media/images/placeholders/generic/photographer.jpg b/network-api/media/images/placeholders/generic/photographer.jpg new file mode 100644 index 00000000000..8af9eb0dda4 Binary files /dev/null and b/network-api/media/images/placeholders/generic/photographer.jpg differ diff --git a/network-api/media/images/placeholders/generic/tigerparrot.jpg b/network-api/media/images/placeholders/generic/tigerparrot.jpg new file mode 100644 index 00000000000..0e2b014d18f Binary files /dev/null and b/network-api/media/images/placeholders/generic/tigerparrot.jpg differ diff --git a/network-api/media/images/placeholders/generic/windfarm.jpg b/network-api/media/images/placeholders/generic/windfarm.jpg new file mode 100644 index 00000000000..fb839db5536 Binary files /dev/null and b/network-api/media/images/placeholders/generic/windfarm.jpg differ diff --git a/network-api/media/images/placeholders/people/dino.jpg b/network-api/media/images/placeholders/people/dino.jpg new file mode 100644 index 00000000000..2f1fef426c4 Binary files /dev/null and b/network-api/media/images/placeholders/people/dino.jpg differ diff --git a/network-api/media/images/placeholders/people/man.jpg b/network-api/media/images/placeholders/people/man.jpg new file mode 100644 index 00000000000..6973ef65d34 Binary files /dev/null and b/network-api/media/images/placeholders/people/man.jpg differ diff --git a/network-api/media/images/placeholders/people/woman.jpg b/network-api/media/images/placeholders/people/woman.jpg new file mode 100644 index 00000000000..0036969101d Binary files /dev/null and b/network-api/media/images/placeholders/people/woman.jpg differ diff --git a/network-api/networkapi/fixtures/test_data.json b/network-api/networkapi/fixtures/test_data.json deleted file mode 100644 index 622e254ff76..00000000000 --- a/network-api/networkapi/fixtures/test_data.json +++ /dev/null @@ -1,4922 +0,0 @@ -[ - { - "model": "contenttypes.contenttype", - "fields": { - "app_label": "admin", - "model": "logentry" - } - }, - { - "model": "contenttypes.contenttype", - "fields": { - "app_label": "auth", - "model": "user" - } - }, - { - "model": "contenttypes.contenttype", - "fields": { - "app_label": "auth", - "model": "group" - } - }, - { - "model": "contenttypes.contenttype", - "fields": { - "app_label": "auth", - "model": "permission" - } - }, - { - "model": "contenttypes.contenttype", - "fields": { - "app_label": "contenttypes", - "model": "contenttype" - } - }, - { - "model": "contenttypes.contenttype", - "fields": { - "app_label": "sessions", - "model": "session" - } - }, - { - "model": "contenttypes.contenttype", - "fields": { - "app_label": "people", - "model": "internethealthissue" - } - }, - { - "model": "contenttypes.contenttype", - "fields": { - "app_label": "people", - "model": "affiliation" - } - }, - { - "model": "contenttypes.contenttype", - "fields": { - "app_label": "people", - "model": "person" - } - }, - { - "model": "contenttypes.contenttype", - "fields": { - "app_label": "opportunities", - "model": "opportunity" - } - }, - { - "model": "contenttypes.contenttype", - "fields": { - "app_label": "news", - "model": "news" - } - }, - { - "model": "contenttypes.contenttype", - "fields": { - "app_label": "sites", - "model": "site" - } - }, - { - "model": "contenttypes.contenttype", - "fields": { - "app_label": "redirects", - "model": "redirect" - } - }, - { - "model": "contenttypes.contenttype", - "fields": { - "app_label": "conf", - "model": "setting" - } - }, - { - "model": "contenttypes.contenttype", - "fields": { - "app_label": "core", - "model": "sitepermission" - } - }, - { - "model": "contenttypes.contenttype", - "fields": { - "app_label": "generic", - "model": "keyword" - } - }, - { - "model": "contenttypes.contenttype", - "fields": { - "app_label": "generic", - "model": "assignedkeyword" - } - }, - { - "model": "contenttypes.contenttype", - "fields": { - "app_label": "generic", - "model": "rating" - } - }, - { - "model": "contenttypes.contenttype", - "fields": { - "app_label": "generic", - "model": "threadedcomment" - } - }, - { - "model": "contenttypes.contenttype", - "fields": { - "app_label": "pages", - "model": "page" - } - }, - { - "model": "contenttypes.contenttype", - "fields": { - "app_label": "pages", - "model": "richtextpage" - } - }, - { - "model": "contenttypes.contenttype", - "fields": { - "app_label": "pages", - "model": "link" - } - }, - { - "model": "contenttypes.contenttype", - "fields": { - "app_label": "forms", - "model": "form" - } - }, - { - "model": "contenttypes.contenttype", - "fields": { - "app_label": "forms", - "model": "field" - } - }, - { - "model": "contenttypes.contenttype", - "fields": { - "app_label": "forms", - "model": "formentry" - } - }, - { - "model": "contenttypes.contenttype", - "fields": { - "app_label": "forms", - "model": "fieldentry" - } - }, - { - "model": "contenttypes.contenttype", - "fields": { - "app_label": "django_comments", - "model": "comment" - } - }, - { - "model": "contenttypes.contenttype", - "fields": { - "app_label": "django_comments", - "model": "commentflag" - } - }, - { - "model": "contenttypes.contenttype", - "fields": { - "app_label": "features", - "model": "feature" - } - }, - { - "model": "contenttypes.contenttype", - "fields": { - "app_label": "landingpage", - "model": "signup" - } - }, - { - "model": "contenttypes.contenttype", - "fields": { - "app_label": "landingpage", - "model": "landingpage" - } - }, - { - "model": "contenttypes.contenttype", - "fields": { - "app_label": "social_django", - "model": "nonce" - } - }, - { - "model": "contenttypes.contenttype", - "fields": { - "app_label": "social_django", - "model": "code" - } - }, - { - "model": "contenttypes.contenttype", - "fields": { - "app_label": "social_django", - "model": "usersocialauth" - } - }, - { - "model": "contenttypes.contenttype", - "fields": { - "app_label": "social_django", - "model": "association" - } - }, - { - "model": "contenttypes.contenttype", - "fields": { - "app_label": "social_django", - "model": "partial" - } - }, - { - "model": "contenttypes.contenttype", - "fields": { - "app_label": "creators", - "model": "creator" - } - }, - { - "model": "contenttypes.contenttype", - "fields": { - "app_label": "entries", - "model": "entry" - } - }, - { - "model": "contenttypes.contenttype", - "fields": { - "app_label": "issues", - "model": "issue" - } - }, - { - "model": "contenttypes.contenttype", - "fields": { - "app_label": "tags", - "model": "tag" - } - }, - { - "model": "contenttypes.contenttype", - "fields": { - "app_label": "userprofile", - "model": "userprofile" - } - }, - { - "model": "contenttypes.contenttype", - "fields": { - "app_label": "userprofile", - "model": "userbookmark" - } - }, - { - "model": "contenttypes.contenttype", - "fields": { - "app_label": "highlights", - "model": "highlight" - } - }, - { - "model": "contenttypes.contenttype", - "fields": { - "app_label": "milestones", - "model": "milestone" - } - }, - { - "model": "contenttypes.contenttype", - "fields": { - "app_label": "homepage", - "model": "homepagehighlights" - } - }, - { - "model": "contenttypes.contenttype", - "fields": { - "app_label": "homepage", - "model": "homepageleaders" - } - }, - { - "model": "contenttypes.contenttype", - "fields": { - "app_label": "homepage", - "model": "homepagenews" - } - }, - { - "model": "contenttypes.contenttype", - "fields": { - "app_label": "homepage", - "model": "homepage" - } - }, - { - "model": "pages.page", - "pk": 1, - "fields": { - "keywords_string": "", - "site": [ - "localhost:8000" - ], - "title": "Opportunity", - "slug": "opportunity", - "_meta_title": "", - "description": "WAIT STOP", - "gen_description": true, - "created": "2017-04-24T14:28:50.287Z", - "updated": "2017-08-31T17:52:45.484Z", - "status": 2, - "publish_date": "2017-04-24T14:28:50Z", - "expiry_date": null, - "short_url": null, - "in_sitemap": true, - "_order": 0, - "content_model": "landingpage", - "parent": null, - "in_menus": "1,2,3", - "titles": "Opportunity", - "login_required": false - } - }, - { - "model": "pages.page", - "pk": 4, - "fields": { - "keywords_string": "", - "site": [ - "localhost:8000" - ], - "title": "Fellowships + Research", - "slug": "opportunity/fellowships", - "_meta_title": "", - "description": "At Mozilla, we’re committed to providing research funding, mentorship, and project-based learning opportunities for community leaders who want to contribute to an open and inclusive web throughout art, science, media, security, policy and advocacy domains.", - "gen_description": true, - "created": "2017-04-24T15:17:18.805Z", - "updated": "2017-06-09T20:38:58.230Z", - "status": 2, - "publish_date": "2017-04-24T15:17:18Z", - "expiry_date": null, - "short_url": null, - "in_sitemap": true, - "_order": 0, - "content_model": "landingpage", - "parent": 1, - "in_menus": "1,2,3", - "titles": "Opportunities / Fellowships + Research", - "login_required": false - } - }, - { - "model": "pages.page", - "pk": 5, - "fields": { - "keywords_string": "", - "site": [ - "localhost:8000" - ], - "title": "Leadership Training", - "slug": "opportunity/training", - "_meta_title": "", - "description": "The skills you need to build a healthy web.\nOpen Leadership 101 is your introduction to “working open.” Learn the basics of participation, collaboration, and sharing on community-driven projects. Discover what working open can do for your project, and explore open projects from across the Network. Think of this free, hour-long online course as your launchpad into the Leadership Network.", - "gen_description": true, - "created": "2017-04-24T15:43:30.444Z", - "updated": "2017-08-03T17:34:36.720Z", - "status": 2, - "publish_date": "2017-04-24T15:43:30Z", - "expiry_date": null, - "short_url": null, - "in_sitemap": true, - "_order": 1, - "content_model": "landingpage", - "parent": 1, - "in_menus": "1,2,3", - "titles": "Opportunities / Leadership Training", - "login_required": false - } - }, - { - "model": "pages.page", - "pk": 6, - "fields": { - "keywords_string": "", - "site": [ - "localhost:8000" - ], - "title": "Internet Health Report", - "slug": "opportunity/internet-health-report", - "_meta_title": "", - "description": "Mozilla’s Internet Health Report is an open source initiative that combines research from multiple sources to document what’s healthy and unhealthy.", - "gen_description": true, - "created": "2017-04-24T15:45:46.250Z", - "updated": "2017-06-12T16:48:43.885Z", - "status": 2, - "publish_date": "2017-04-24T15:45:46Z", - "expiry_date": null, - "short_url": null, - "in_sitemap": true, - "_order": 2, - "content_model": "landingpage", - "parent": 1, - "in_menus": "1,2,3", - "titles": "Opportunities / Internet Health Report", - "login_required": false - } - }, - { - "model": "pages.page", - "pk": 8, - "fields": { - "keywords_string": "", - "site": [ - "localhost:8000" - ], - "title": "Network Feedback", - "slug": "opportunity/network-feedback", - "_meta_title": "", - "description": "", - "gen_description": true, - "created": "2017-05-17T20:24:31.491Z", - "updated": "2017-05-19T19:14:01.945Z", - "status": 1, - "publish_date": "2017-05-17T20:24:31Z", - "expiry_date": null, - "short_url": null, - "in_sitemap": true, - "_order": 3, - "content_model": "landingpage", - "parent": 1, - "in_menus": "1,2,3", - "titles": "Opportunities / Network Feedback", - "login_required": false - } - }, - { - "model": "pages.page", - "pk": 9, - "fields": { - "keywords_string": "", - "site": [ - "localhost:8000" - ], - "title": "Network 50", - "slug": "opportunity/network-50", - "_meta_title": "", - "description": "50 People Who Made the Internet a Better Place in 2016\n", - "gen_description": true, - "created": "2017-05-19T19:37:39.715Z", - "updated": "2017-08-17T15:43:19.947Z", - "status": 2, - "publish_date": "2017-05-19T19:37:39Z", - "expiry_date": null, - "short_url": null, - "in_sitemap": true, - "_order": 4, - "content_model": "landingpage", - "parent": 1, - "in_menus": "1,2,3", - "titles": "Opportunities / Network 50", - "login_required": false - } - }, - { - "model": "pages.page", - "pk": 11, - "fields": { - "keywords_string": "", - "site": [ - "localhost:8000" - ], - "title": "Tech Policy Fellowship", - "slug": "opportunity/2017-tech-policy-fellows", - "_meta_title": "", - "description": "Bringing together tech policy experts from around the world to participate in policy efforts to improve the health of the Internet.", - "gen_description": false, - "created": "2017-06-05T21:06:20.213Z", - "updated": "2017-08-25T21:36:08.110Z", - "status": 2, - "publish_date": "2017-06-05T14:05:20Z", - "expiry_date": null, - "short_url": null, - "in_sitemap": true, - "_order": 5, - "content_model": "landingpage", - "parent": 1, - "in_menus": "1,2,3", - "titles": "Opportunities / Tech Policy Fellowship", - "login_required": false - } - }, - { - "model": "pages.page", - "pk": 13, - "fields": { - "keywords_string": "", - "site": [ - "localhost:8000" - ], - "title": "Mozilla Information Trust Initiative", - "slug": "opportunity/miti", - "_meta_title": "", - "description": "We are investing in people, programs, and projects that disrupt misinformation online.\nMozilla is working to surface new ideas that seek to address misinformation, cognitive bias, “belief echos,” and algorithmic “filter bubbles.” The initiative will launch efforts in four areas: products, research, visualization, and literacy. If you would like to help with this initiative, or receive updates as we announce the specifics, just use the sign-up form on the right.", - "gen_description": true, - "created": "2017-08-23T18:26:55.597Z", - "updated": "2017-09-19T19:12:45.423Z", - "status": 1, - "publish_date": "2017-08-23T18:26:55Z", - "expiry_date": null, - "short_url": null, - "in_sitemap": true, - "_order": 6, - "content_model": "landingpage", - "parent": 1, - "in_menus": "1,2,3", - "titles": "Opportunity / Mozilla Information Trust Initiative", - "login_required": false - } - }, - { - "model": "homepage.homepage", - "pk": 1, - "fields": {} - }, - { - "model": "homepage.homepageleaders", - "pk": 1, - "fields": { - "_order": 0, - "leader": 22, - "homepage": 1 - } - }, - { - "model": "homepage.homepageleaders", - "pk": 2, - "fields": { - "_order": 1, - "leader": 8, - "homepage": 1 - } - }, - { - "model": "homepage.homepageleaders", - "pk": 3, - "fields": { - "_order": 2, - "leader": 20, - "homepage": 1 - } - }, - { - "model": "homepage.homepageleaders", - "pk": 4, - "fields": { - "_order": 3, - "leader": 32, - "homepage": 1 - } - }, - { - "model": "homepage.homepagenews", - "pk": 1, - "fields": { - "_order": 0, - "news": 48, - "homepage": 1 - } - }, - { - "model": "homepage.homepagenews", - "pk": 2, - "fields": { - "_order": 1, - "news": 20, - "homepage": 1 - } - }, - { - "model": "homepage.homepagenews", - "pk": 3, - "fields": { - "_order": 2, - "news": 37, - "homepage": 1 - } - }, - { - "model": "homepage.homepagenews", - "pk": 4, - "fields": { - "_order": 3, - "news": 24, - "homepage": 1 - } - }, - { - "model": "homepage.homepagehighlights", - "pk": 1, - "fields": { - "_order": 0, - "highlights": 3, - "homepage": 1 - } - }, - { - "model": "homepage.homepagehighlights", - "pk": 2, - "fields": { - "_order": 1, - "highlights": 2, - "homepage": 1 - } - }, - { - "model": "homepage.homepagehighlights", - "pk": 3, - "fields": { - "_order": 2, - "highlights": 1, - "homepage": 1 - } - }, - { - "model": "people.internethealthissue", - "pk": 1, - "fields": { - "name": "Online Privacy & Security" - } - }, - { - "model": "people.internethealthissue", - "pk": 2, - "fields": { - "name": "Decentralization" - } - }, - { - "model": "people.internethealthissue", - "pk": 3, - "fields": { - "name": "Open Innovation" - } - }, - { - "model": "people.internethealthissue", - "pk": 4, - "fields": { - "name": "Web Literacy" - } - }, - { - "model": "people.internethealthissue", - "pk": 5, - "fields": { - "name": "Digital Inclusion" - } - }, - { - "model": "people.person", - "pk": 1, - "fields": { - "name": "Joe McNamee", - "role": "Open Web Fellow Host", - "location": "Brussels, Belgium", - "quote": "The biggest challenge we face in Europe is the role that internet companies play in achieving public policy goals.", - "bio": "- Executive Director of European Digital Rights (EDRi), an association of civil and human rights organisations that defends citizens\u2019 rights and freedoms in the digital environment \r\n - Focuses on data protection, surveillance, copyright, and network neutrality \r\n - Expert in public affairs, intellectual property, cybercrime, and telecoms policy", - "image": "images/people/joe-mcnamee_1493154070.jpg", - "partnership_logo": "images/people/joe-mcnamee_partnership_1489437254.png", - "twitter_url": "https://twitter.com/edri", - "linkedin_url": "https://www.linkedin.com/in/joemcnamee", - "interview_url": null, - "featured": true, - "publish_after": "2017-04-05T21:29:58Z", - "expires": null, - "order": 8, - "internet_health_issues": [ - 1, - 2, - 3 - ] - } - }, - { - "model": "people.person", - "pk": 4, - "fields": { - "name": "Solana Larsen", - "role": "Staff", - "location": "Berlin, Germany", - "quote": "", - "bio": "- Danish-Puerto Rican writer and editor based in Berlin, Germany\r\n - Believer and practitioner in use of the Internet for good\r\n - Former Managing Editor of GlobalVoices.org", - "image": "images/people/solana-larsen_1489446811.jpg", - "partnership_logo": "", - "twitter_url": "https://www.twitter.com/Solanasaurus", - "linkedin_url": "", - "interview_url": null, - "featured": false, - "publish_after": "2017-04-05T21:29:58.985Z", - "expires": null, - "order": 29, - "internet_health_issues": [ - 1, - 2, - 3, - 4, - 5 - ] - } - }, - { - "model": "people.person", - "pk": 5, - "fields": { - "name": "Th\u00e9o Chevalier", - "role": "Staff", - "location": "London, UK", - "quote": "", - "bio": "- Supporting our global community for translating Mozilla Foundation projects\r\n - Advancing Mozilla\u2019s localization QA tool, Transvision\r\n - Localizing Mozilla projects into French", - "image": "images/people/theo-chevalier_1489446935.jpg", - "partnership_logo": "", - "twitter_url": "https://twitter.com/t_chevalier", - "linkedin_url": "https://www.linkedin.com/in/theochevalier", - "interview_url": null, - "featured": false, - "publish_after": "2017-04-05T21:29:58.985Z", - "expires": null, - "order": 31, - "internet_health_issues": [ - 5 - ] - } - }, - { - "model": "people.person", - "pk": 6, - "fields": { - "name": "Brenda Hernandez", - "role": "Staff", - "location": "Chicago, IL, USA", - "quote": "I am fascinated with the complexities the internet brings to our understanding of culture, humor, and aesthetics.", - "bio": "- I am a Chicago-born, Mexican-raised experiential learning enthusiast, and practitioner.\r\n- Before my current role as Portfolio Strategist, I was a program manager at Yollocalli Arts Reach of the National Museum of Mexican Art - a place dear to my heart as I was a student there during my youth!\r\n- I am fascinated with the complexities the internet brings to our understanding of culture, humor, and aesthetics. I miss the days of custom cursors and crude myspace hacks.", - "image": "images/people/brenda-hernandez_1489447100.jpg", - "partnership_logo": "", - "twitter_url": "https://www.twitter.com/tactilenotes", - "linkedin_url": "", - "interview_url": null, - "featured": false, - "publish_after": "2017-04-05T21:29:58.985Z", - "expires": null, - "order": 18, - "internet_health_issues": [ - 3, - 4, - 5 - ] - } - }, - { - "model": "people.person", - "pk": 8, - "fields": { - "name": "Kylee Durant", - "role": "Web Literacy Partner", - "location": "Lakewood, WA, USA", - "quote": "It was really powerful to see somebody from Mozilla who didn't just think about a great idea \u2014 but how to actually turn that idea into action.", - "bio": "- Chief Operating Officer, RallyPoint/6 \r\n - Provides career resources and peer assistance for service members, veterans, and military families", - "image": "images/people/kylee-durant_1489447643.jpg", - "partnership_logo": "", - "twitter_url": "https://twitter.com/kyleedurant", - "linkedin_url": "https://www.linkedin.com/in/kylee-durant-38160490", - "interview_url": "https://storyengine.io/stories/digital-inclusion/kylee-durant/", - "featured": true, - "publish_after": "2017-04-05T21:29:58Z", - "expires": null, - "order": 11, - "internet_health_issues": [ - 4, - 5 - ] - } - }, - { - "model": "people.person", - "pk": 9, - "fields": { - "name": "Diego Naranjo", - "role": "Open Web Fellow Host", - "location": "Brussels, Belgium", - "quote": "", - "bio": "- Diego Naranjo is a qualified lawyer and co-founder of the Andalusian human rights organisation Grupo 17 de Marzo.\r\n - Diego joined EDRi in October 2014 where he works as Senior Policy Advisor. He advocates for the protection of citizens' fundamental rights and freedoms online in the fields of data protection, surveillance and copyright. \r\n - In the past, Diego gained experience in the International Criminal Tribunal for former Yugoslavia, the EU Fundamental Rights Agency (FRA) and the Free Software Foundation Europe. Previously to all that he worked as a lawyer in Spain.", - "image": "images/people/diego-naranjo_1489447951.jpg", - "partnership_logo": "images/people/diego-naranjo_partnership_1489534033.svg", - "twitter_url": "https://twitter.com/DNBSevilla", - "linkedin_url": "https://www.linkedin.com/in/diego-naranjo-barroso", - "interview_url": null, - "featured": false, - "publish_after": "2017-04-05T21:29:58.985Z", - "expires": null, - "order": 25, - "internet_health_issues": [ - 1, - 3 - ] - } - }, - { - "model": "people.person", - "pk": 10, - "fields": { - "name": "Karolina Andersdotter", - "role": "Copyright Partner", - "location": "The Hague, Netherlands", - "quote": "The Internet is the collective intelligence of humankind - much like a library.", - "bio": "- Librarian and digital asset and media manager.\r\n- Believes Internet is the collective intelligence of humankind - much like a library.\r\n- Enjoys talking copyright, digital privacy, and how to make data less scary.", - "image": "images/people/karolina-andersdotter_1489534552.jpg", - "partnership_logo": "images/people/karolina-andersdotter_partnership_1489451198.png", - "twitter_url": "https://twitter.com/Karolingva", - "linkedin_url": "", - "interview_url": null, - "featured": true, - "publish_after": "2017-04-05T21:29:58.985Z", - "expires": null, - "order": 5, - "internet_health_issues": [ - 1, - 4 - ] - } - }, - { - "model": "people.person", - "pk": 11, - "fields": { - "name": "Georgia Bullen", - "role": "Copyright Partner", - "location": "Washington, DC, USA", - "quote": "", - "bio": "- Human Centered Designer with a focus on data, technology and policy\r\n- Passionate about visualization, spreadsheets, usability, maps, access, cities and open source\r\n- Lives by a philosophy of organized chaos", - "image": "images/people/georgia-bullen_1489596473.jpg", - "partnership_logo": "images/people/georgia-bullen_partnership_1489534111.png", - "twitter_url": "https://www.twitter.com/georgiamoon", - "linkedin_url": "https://www.linkedin.com/in/georgiabullen/", - "interview_url": null, - "featured": false, - "publish_after": "2017-04-05T21:29:58.985Z", - "expires": null, - "order": 13, - "internet_health_issues": [ - 1, - 2, - 3, - 4, - 5 - ] - } - }, - { - "model": "people.person", - "pk": 12, - "fields": { - "name": "\u00c9ireann Leverett", - "role": "Open Web Fellow", - "location": "London, UK", - "quote": "", - "bio": "- As an Open Web Fellow, Eireann is working with Privacy International\u2019s Tech Team to analyze surveillance documentation and data, identify and analyze new technologies, and help develop briefings and educational programming with a technical understanding.\r\n - \u00c9ireann is fascinated by malware, vulnerabilities, cryptography, networks, information theory, and economics \u2014 and he believes hacking can win victories for humanity.", - "image": "images/people/eireann-leverett_1489534657.jpg", - "partnership_logo": "", - "twitter_url": "https://twitter.com/blackswanburst", - "linkedin_url": "", - "interview_url": null, - "featured": false, - "publish_after": "2017-04-05T21:29:58.985Z", - "expires": null, - "order": 12, - "internet_health_issues": [ - 1 - ] - } - }, - { - "model": "people.person", - "pk": 13, - "fields": { - "name": "Jennifer Helsby", - "role": "Open Web Fellow", - "location": "Bay Area, CA, USA", - "quote": "", - "bio": "- Jennifer is a data scientist and researcher passionate about using data and technology to catalyze social change. \r\n - Previously, she was a postdoctoral researcher at the Center for Data Science and Public Policy at the University of Chicago, where she worked on applying machine learning methods to problems in public policy. \r\n - As an Open Web Fellow, Jennifer is working with the Freedom of the Press Foundation to improve SecureDrop, an anonymous whistleblowing platform.", - "image": "images/people/jennifer-helsby_1489451722.jpg", - "partnership_logo": "", - "twitter_url": "https://twitter.com/redshiftzero", - "linkedin_url": "", - "interview_url": null, - "featured": false, - "publish_after": "2017-04-05T21:29:58.985Z", - "expires": null, - "order": 16, - "internet_health_issues": [ - 1 - ] - } - }, - { - "model": "people.person", - "pk": 14, - "fields": { - "name": "Kirstie Whitaker", - "role": "Mozilla Science Fellow", - "location": "Cambridge, UK", - "quote": "", - "bio": "- Postdoctoral researcher in the Brain Mapping Unit at the University of Cambridge\r\n - She studies adolescent brain development and is particularly interested in the emergence of mental health disorders during the teenage years. \r\n - She's the founder and lead developer of the STEMM Role Models project which provides a database of experts from traditionally under-represented groups to ensure conference organizers are able to invite the most diverse and exciting speakers to their events.", - "image": "images/people/kirstie-whitaker_1489452019.jpg", - "partnership_logo": "", - "twitter_url": "https://twitter.com/kirstie_j", - "linkedin_url": "http://www.linkedin.com/in/kirstiewhitaker", - "interview_url": null, - "featured": false, - "publish_after": "2017-04-05T21:29:58.985Z", - "expires": null, - "order": 0, - "internet_health_issues": [ - 3, - 5 - ] - } - }, - { - "model": "people.person", - "pk": 15, - "fields": { - "name": "Bruno Miguel Pereira Vieira", - "role": "Mozilla Science Fellow", - "location": "London, UK", - "quote": "", - "bio": "- Bioinformatics and population genomics PhD student at WurmLab (Queen Mary University of London) researching how genetic diversity is affected by sociality in insects.\r\n - Founded the open source community Bionode.io with the goal of improving modularity and reusability of tools and code in bioinformatics by leveraging innovation coming from the Node.js and Web communities.", - "image": "images/people/bruno-miguel-pereira-vieira_1489452146.jpg", - "partnership_logo": "", - "twitter_url": "https://twitter.com/bmpvieira", - "linkedin_url": "", - "interview_url": null, - "featured": false, - "publish_after": "2017-04-05T21:29:58.985Z", - "expires": null, - "order": 21, - "internet_health_issues": [ - 2, - 4 - ] - } - }, - { - "model": "people.person", - "pk": 16, - "fields": { - "name": "Danielle Robinson", - "role": "Mozilla Science Fellow", - "location": "Portland, OR, USA", - "quote": "", - "bio": "- Passionate about improving reproducibility and digital literacy in the sciences\r\n - Co-organizes Open Insight PDX, which seeks to build skills that enhance research reproducibility and facilitate discussion of issues surrounding publishing, data sharing, and copyright. \r\n - She is a founding member of Women in Science Portland and an organizer for Science Hack Day Portland.", - "image": "images/people/danielle-robinson_1489452257.jpg", - "partnership_logo": "", - "twitter_url": "https://twitter.com/daniellecrobins", - "linkedin_url": "", - "interview_url": null, - "featured": false, - "publish_after": "2017-04-05T21:29:58.985Z", - "expires": null, - "order": 22, - "internet_health_issues": [ - 1, - 4, - 5 - ] - } - }, - { - "model": "people.person", - "pk": 17, - "fields": { - "name": "Teon Brooks", - "role": "Mozilla Science Fellow", - "location": "San Francisco, CA, USA", - "quote": "", - "bio": "- He studies the cognitive processes and temporal dynamics of the brain during reading.\r\n - Core developer for MNE, a community-driven project for analyzing time-series brain data in Python; and OpenEXP, an open science platform founded to be a \"GitHub for Experiments\" and a tool for running both behavioral and physiological experiments using open-source web-based tools.\r\n - Develops curriculum, DIYCogSci, for teaching experimental research methods and coding using low-cost electronics and open-source hardware.", - "image": "images/people/teon-brooks_1489452391.jpg", - "partnership_logo": "", - "twitter_url": "https://twitter.com/teon_io", - "linkedin_url": "", - "interview_url": "", - "featured": false, - "publish_after": "2017-04-05T21:29:58Z", - "expires": null, - "order": 1, - "internet_health_issues": [ - 2, - 3, - 5, - 4 - ] - } - }, - { - "model": "people.person", - "pk": 18, - "fields": { - "name": "Alex Wafula", - "role": "Mozilla Rep", - "location": "Nairobi, Kenya", - "quote": "The people are a big part of why I joined Mozilla \u2014 and the reason I continue to contribute.", - "bio": "- Software professional and community activist \r\n - Leader in the Kenya + East Africa Mozilla community \r\n - Digital Skills Observatory contributor", - "image": "images/people/alex-wafula_1489452645.jpg", - "partnership_logo": "", - "twitter_url": "https://twitter.com/xelawafs", - "linkedin_url": "", - "interview_url": null, - "featured": true, - "publish_after": "2017-04-05T21:29:58.985Z", - "expires": null, - "order": 17, - "internet_health_issues": [ - 4, - 5 - ] - } - }, - { - "model": "people.person", - "pk": 19, - "fields": { - "name": "Mmaki Jantjies", - "role": "Regional Coordinator, Mozilla Women & Girls Clubs", - "location": "Cape Town, South Africa", - "quote": "The Mozilla Women & Girls clubs have become a space of trust \u2014 people open up about challenges they face on a daily basis.", - "bio": "- Head of Department of Information Systems at the University of the Western Cape and Regional Coordinator for the Mozilla Women & Girls Clubs \r\n - Lectures on IT security, IT project management, and other IT-related modules \r\n - Recruits women who want to give back to the community", - "image": "images/people/mmaki-jantjies_1489452793.jpg", - "partnership_logo": "", - "twitter_url": "https://twitter.com/mmakij", - "linkedin_url": "https://www.linkedin.com/in/mmaki-jantjies-2b389b116", - "interview_url": null, - "featured": true, - "publish_after": "2017-04-05T21:29:58.985Z", - "expires": null, - "order": 23, - "internet_health_issues": [ - 4, - 5 - ] - } - }, - { - "model": "people.person", - "pk": 20, - "fields": { - "name": "Anthony Negron", - "role": "HiveNYC", - "location": "New York, NY, USA", - "quote": "You have an experience with an organization where you gel so perfectly that you start thinking about other ways to collaborate.", - "bio": "- Manager of Digital Programming, NYSCI\r\n- Longtime member of HiveNYC\r\n- Values parternships formed via Hive", - "image": "images/people/anthony-negron_1489453007.jpg", - "partnership_logo": "", - "twitter_url": "", - "linkedin_url": "https://www.linkedin.com/in/anthony-negron-439a736/", - "interview_url": null, - "featured": true, - "publish_after": "2017-04-05T21:29:58Z", - "expires": null, - "order": 2, - "internet_health_issues": [ - 4, - 5 - ] - } - }, - { - "model": "people.person", - "pk": 21, - "fields": { - "name": "Egle Marija Ramanauskaite", - "role": "Open Science, MozFest", - "location": "Vilnius, Lithuania", - "quote": "Finally, we\u2019re bringing this awesome research to the public.", - "bio": "- Citizen science coordinator for the Human Computation Institute, focused on crowdsourcing Alzheimer\u2019s research \r\n - Met Janet Chapman at MozFest last year and worked with her to create Crowd2Map", - "image": "images/people/egle-marija-ramanauskaite_1489453206.jpg", - "partnership_logo": "", - "twitter_url": "https://twitter.com/seplute", - "linkedin_url": "https://www.linkedin.com/in/eglemarija", - "interview_url": null, - "featured": true, - "publish_after": "2017-04-05T21:29:58.985Z", - "expires": null, - "order": 20, - "internet_health_issues": [ - 3, - 5 - ] - } - }, - { - "model": "people.person", - "pk": 22, - "fields": { - "name": "Jen Caltrider", - "role": "Staff", - "location": "Shawnee, Colorado, USA", - "quote": "I love the internet and all it has to offer and want everyone in the world to be able to access it and feel safe to be themselves online. This is what gets me fired up every day.", - "bio": "- I studied to get my master's degree in Artificial Intelligence but hated writing code (OK, I was terrible at it). So I ended up combining my love of storytelling and all things nerdy and went to work at CNN as their first ever technology producer. \r\n- I moved to Colorado and fell in love with the mountains and with the camping mantra, \"Leave it Better Than You Found It.\" That's what motivated me to move from journalism to advocacy work. I still get to tell stories, I'm just telling them for good now.\r\n- I have many long conversations with my two pups, Husker and Beulah, and my kitty Stumpy about how it's a real shame Neal Stephenson's classic cyberpunk novel Snow Crash hasn't yet been made into an Oscar-worthy film.", - "image": "images/people/jen-caltrider_1489515728.jpg", - "partnership_logo": "", - "twitter_url": "https://twitter.com/caltrider", - "linkedin_url": "", - "interview_url": null, - "featured": false, - "publish_after": "2017-04-05T21:29:58.985Z", - "expires": null, - "order": 9, - "internet_health_issues": [ - 5 - ] - } - }, - { - "model": "people.person", - "pk": 23, - "fields": { - "name": "Gideon Thomas", - "role": "Staff", - "location": "Toronto, Canada", - "quote": "", - "bio": "- Worked at Seneca College's CDOT as a developer on Mozilla's Thimble which opened the pathway for me to work for Mozilla.\r\n - Enjoy developing open-source technology solutions that make it easy for people to learn about and participate in creating the open web.\r\n - Occasionally like to co-facilitate events that address social issues.", - "image": "images/people/gideon-thomas_1489515856.jpg", - "partnership_logo": "", - "twitter_url": "", - "linkedin_url": "https://www.linkedin.com/in/r-gideon-thomas-26362865/", - "interview_url": null, - "featured": false, - "publish_after": "2017-04-05T21:29:58.985Z", - "expires": null, - "order": 19, - "internet_health_issues": [ - 4, - 5 - ] - } - }, - { - "model": "people.person", - "pk": 24, - "fields": { - "name": "David Humphrey", - "role": "Software Development and Education Partner", - "location": "Toronto, Canada", - "quote": "I teach how to participate in collaborative projects. I set up a bike lane, so we\u2019re on the same road as Mozilla, but we\u2019re off to the side.", - "bio": "- Developer and open source expert\r\n - Professor at Seneca College\u2019s School of Information and Communications Technology\r\n - Since 2004, David and Mozilla have involved hundreds of students in research projects \u2014 developing new technologies and standards for the web", - "image": "images/people/david-humphrey_1489530355.jpg", - "partnership_logo": "images/people/david-humphrey_partnership_1489603424.svg", - "twitter_url": "https://twitter.com/humphd", - "linkedin_url": "", - "interview_url": null, - "featured": true, - "publish_after": "2017-04-05T21:29:58.985Z", - "expires": null, - "order": 30, - "internet_health_issues": [ - 3 - ] - } - }, - { - "model": "people.person", - "pk": 25, - "fields": { - "name": "Achintya Rao", - "role": "Mozilla Science Lab Contributor", - "location": "Geneva, Switzerland", - "quote": "I now have a virtual support structure \u2014 people I can ping and ask, \u201cHey, what do I do here?\u201d Or, \u201cHave you faced this?", - "bio": "- Communications Officer, CMS Experiment at CERN \r\n - ChD Student, UWE Science Communication Unit \r\n - Mentors two Mozilla Open Science Lab projects", - "image": "images/people/achintya-rao_1489524959.jpg", - "partnership_logo": "", - "twitter_url": "https://twitter.com/RaoOfPhysics", - "linkedin_url": "", - "interview_url": null, - "featured": true, - "publish_after": "2017-04-05T21:29:58.985Z", - "expires": null, - "order": 26, - "internet_health_issues": [ - 3 - ] - } - }, - { - "model": "people.person", - "pk": 26, - "fields": { - "name": "Hera Hussain", - "role": "MozFest volunteer, then Keynote Speaker", - "location": "London, United Kingdom", - "quote": "No matter how dangerous it is for young women to be online, they still want to get online. Their social activities are there. Now there are so many things you can only do online.", - "bio": "- Community & Partnerships Manager, OpenCorporates \r\n - Founder of Chayn, a global volunteer-led digital network empowering women against violence and oppression \r\n - Works with investigative journalists and NGOs running investigations using open company data", - "image": "images/people/hera-hussain_1489525157.jpg", - "partnership_logo": "", - "twitter_url": "https://twitter.com/herahussain", - "linkedin_url": "https://www.linkedin.com/in/herahussain", - "interview_url": null, - "featured": true, - "publish_after": "2017-04-05T21:29:58.985Z", - "expires": null, - "order": 14, - "internet_health_issues": [ - 1, - 5 - ] - } - }, - { - "model": "people.person", - "pk": 27, - "fields": { - "name": "Chrystian Rodriguez", - "role": "Staff", - "location": "New York, NY, USA", - "quote": "", - "bio": "", - "image": "images/people/chrystian-rodriguez_1489533510.jpg", - "partnership_logo": "", - "twitter_url": "https://twitter.com/xtianberrisoup", - "linkedin_url": "", - "interview_url": null, - "featured": false, - "publish_after": "2017-04-05T21:29:58.985Z", - "expires": null, - "order": 10, - "internet_health_issues": [ - 1, - 2, - 4, - 5 - ] - } - }, - { - "model": "people.person", - "pk": 28, - "fields": { - "name": "Roy Lamond", - "role": "Web Literacy and Digital Inclusion Partner", - "location": "Ottawa, Canada", - "quote": "", - "bio": "", - "image": "images/people/roy-lamond_1489533866.jpg", - "partnership_logo": "", - "twitter_url": "https://twitter.com/roylamond", - "linkedin_url": "", - "interview_url": null, - "featured": false, - "publish_after": "2017-04-05T21:29:58.985Z", - "expires": null, - "order": 27, - "internet_health_issues": [ - 3, - 4, - 5 - ] - } - }, - { - "model": "people.person", - "pk": 29, - "fields": { - "name": "Melissa Mark-Viverito", - "role": "Hive NYC Partner", - "location": "New York, NY, USA", - "quote": "Technology has the power to transform lives, and we must work to bring that opportunity to people of all backgrounds.", - "bio": "", - "image": "images/people/melissa-mark-viverito_1489533980.jpg", - "partnership_logo": "", - "twitter_url": "https://twitter.com/MMViverito", - "linkedin_url": "", - "interview_url": null, - "featured": false, - "publish_after": "2017-04-05T21:29:58.985Z", - "expires": null, - "order": 28, - "internet_health_issues": [ - 5 - ] - } - }, - { - "model": "people.person", - "pk": 30, - "fields": { - "name": "Christie Bahlai", - "role": "Mozilla Science Fellow", - "location": "East Lansing, Michigan, USA", - "quote": "During my fellowship I developed an open science and reproducible research course \u2014 my students' work was then highlighted in Science Magazine.", - "bio": "", - "image": "images/people/christie-bahlai_1489534389.jpg", - "partnership_logo": "", - "twitter_url": "https://twitter.com/cbahlai", - "linkedin_url": "", - "interview_url": null, - "featured": false, - "publish_after": "2017-04-05T21:29:58.985Z", - "expires": null, - "order": 24, - "internet_health_issues": [ - 3 - ] - } - }, - { - "model": "people.person", - "pk": 31, - "fields": { - "name": "Emily Long", - "role": "HiveNYC", - "location": "New York, NY, USA", - "quote": "Working with others is what really helps us grow as an organization. It gives us more projects and more room to experiment.", - "bio": "", - "image": "images/people/emily-long_1489535248.jpg", - "partnership_logo": "", - "twitter_url": "https://twitter.com/emlong", - "linkedin_url": "https://www.linkedin.com/in/emilymlong", - "interview_url": null, - "featured": false, - "publish_after": "2017-04-05T21:29:58.985Z", - "expires": null, - "order": 3, - "internet_health_issues": [ - 4, - 5 - ] - } - }, - { - "model": "people.person", - "pk": 32, - "fields": { - "name": "Duncan Washington", - "role": "Digital Skills Observatory contributor", - "location": "Nairobi, Kenya", - "quote": "Mozilla Clubs use local solutions on the ground to make an impact in society.", - "bio": "", - "image": "images/people/duncan-washington_1489535400.jpg", - "partnership_logo": "", - "twitter_url": "https://twitter.com/danthepoet", - "linkedin_url": "https://www.linkedin.com/in/duncan-washington-abbba717/", - "interview_url": null, - "featured": false, - "publish_after": "2017-04-05T21:29:58.985Z", - "expires": null, - "order": 4, - "internet_health_issues": [ - 5 - ] - } - }, - { - "model": "people.person", - "pk": 33, - "fields": { - "name": "Ariam Mogos", - "role": "HiveNYC", - "location": "Brooklyn, NY, USA", - "quote": "Mozilla has facilitated fantastic partnerships. Instead of running siloed programs we're really collaborating.", - "bio": "", - "image": "images/people/ariam-mogos_1489535496.jpg", - "partnership_logo": "", - "twitter_url": "https://twitter.com/aamogos", - "linkedin_url": "https://www.linkedin.com/in/ariammogos/", - "interview_url": null, - "featured": false, - "publish_after": "2017-04-05T21:29:58.985Z", - "expires": null, - "order": 6, - "internet_health_issues": [ - 4, - 5 - ] - } - }, - { - "model": "people.person", - "pk": 34, - "fields": { - "name": "Hillary Kolos", - "role": "HiveNYC", - "location": "Bronx, NY, USA", - "quote": "I really trust the people I work with in the Hive. That means that I can be more critical and more supportive.", - "bio": "", - "image": "images/people/hillary-kolos_1489535572.jpg", - "partnership_logo": "", - "twitter_url": "", - "linkedin_url": "https://www.linkedin.com/in/hillary-kolos-71b67a11/", - "interview_url": null, - "featured": false, - "publish_after": "2017-04-05T21:29:58.985Z", - "expires": null, - "order": 7, - "internet_health_issues": [ - 4, - 5 - ] - } - }, - { - "model": "people.person", - "pk": 35, - "fields": { - "name": "Daniel Lucio", - "role": "Gigabit Cities Partner", - "location": "Austin, TX, USA", - "quote": "", - "bio": "", - "image": "images/people/daniel-lucio_1489596584.jpg", - "partnership_logo": "images/people/daniel-lucio_partnership_1489596585.png", - "twitter_url": "https://twitter.com/danielrynelucio", - "linkedin_url": "", - "interview_url": null, - "featured": false, - "publish_after": "2017-04-05T21:29:58.985Z", - "expires": null, - "order": 15, - "internet_health_issues": [ - 4, - 5 - ] - } - }, - { - "model": "people.person", - "pk": 38, - "fields": { - "name": "Alan", - "role": "Staff", - "location": "Portland, ME", - "quote": "", - "bio": "", - "image": "images/people/alan_1498141017.jpg", - "partnership_logo": "", - "twitter_url": "", - "linkedin_url": "", - "interview_url": "", - "featured": false, - "publish_after": "2017-06-23T21:09:01Z", - "expires": null, - "order": 32, - "internet_health_issues": [ - 3 - ] - } - }, - { - "model": "people.person", - "pk": 46, - "fields": { - "name": "pomax", - "role": "pomax", - "location": "poamx", - "quote": "", - "bio": "", - "image": "images/people/pomax_1498251741.jpg", - "partnership_logo": "", - "twitter_url": "", - "linkedin_url": "", - "interview_url": "", - "featured": false, - "publish_after": "2017-06-23T21:02:07Z", - "expires": null, - "order": 33, - "internet_health_issues": [ - 3 - ] - } - }, - { - "model": "people.affiliation", - "pk": 2, - "fields": { - "name": "Executive Director, European Digital Rights (EDRi)", - "person": 1 - } - }, - { - "model": "people.affiliation", - "pk": 58, - "fields": { - "name": "Postdoctoral researcher at the Center for Reproducible Neuroscience and the Department of Psychology at Stanford University", - "person": 17 - } - }, - { - "model": "people.affiliation", - "pk": 59, - "fields": { - "name": "Senior Policy Advisor, European Digital Rights (EDRi)", - "person": 9 - } - }, - { - "model": "people.affiliation", - "pk": 60, - "fields": { - "name": "Editor, Internet Health Report, Mozilla", - "person": 4 - } - }, - { - "model": "people.affiliation", - "pk": 61, - "fields": { - "name": "Director of Technology Projects, New America's Open Technology Institute", - "person": 11 - } - }, - { - "model": "people.affiliation", - "pk": 62, - "fields": { - "name": "Vice President of Transition Technology & Innovation Programs for the USO", - "person": 8 - } - }, - { - "model": "people.affiliation", - "pk": 64, - "fields": { - "name": "Founder and CEO, Concinnity Risks", - "person": 12 - } - }, - { - "model": "people.affiliation", - "pk": 65, - "fields": { - "name": "Senior Risk Researcher at Cambridge Centre for Risk Studies", - "person": 12 - } - }, - { - "model": "people.affiliation", - "pk": 66, - "fields": { - "name": "Portfolio Strategist, Hive Chicago, Mozilla", - "person": 6 - } - }, - { - "model": "people.affiliation", - "pk": 67, - "fields": { - "name": "Co-founder and CTO of Lucy Parsons Labs", - "person": 13 - } - }, - { - "model": "people.affiliation", - "pk": 68, - "fields": { - "name": "Co-organizer for Cryptoparty Chicago", - "person": 13 - } - }, - { - "model": "people.affiliation", - "pk": 69, - "fields": { - "name": "Localization Project Manager, Mozilla", - "person": 5 - } - }, - { - "model": "people.affiliation", - "pk": 70, - "fields": { - "name": "Policy and Advocacy Assistant, IFLA", - "person": 10 - } - }, - { - "model": "people.affiliation", - "pk": 71, - "fields": { - "name": "Science communicator for the CMS Collaboration at CERN\u2019s Large Hadron Collider", - "person": 25 - } - }, - { - "model": "people.affiliation", - "pk": 72, - "fields": { - "name": "PhD candidate, University of the West of England", - "person": 25 - } - }, - { - "model": "people.affiliation", - "pk": 73, - "fields": { - "name": "Neuroimaging Researcher, University of Cambridge", - "person": 14 - } - }, - { - "model": "people.affiliation", - "pk": 74, - "fields": { - "name": "Founder and lead developer of the STEMM Role Models project", - "person": 14 - } - }, - { - "model": "people.affiliation", - "pk": 75, - "fields": { - "name": "Bioinformatics PhD student at Queen Mary University of London", - "person": 15 - } - }, - { - "model": "people.affiliation", - "pk": 76, - "fields": { - "name": "Node.js web developer", - "person": 15 - } - }, - { - "model": "people.affiliation", - "pk": 77, - "fields": { - "name": "Citizen Science Coordinator, Human Computation Institute", - "person": 21 - } - }, - { - "model": "people.affiliation", - "pk": 78, - "fields": { - "name": "Co-Founder, Crowd2Map Tanzania", - "person": 21 - } - }, - { - "model": "people.affiliation", - "pk": 79, - "fields": { - "name": "Neuroscience PhD, Oregon Health & Science University", - "person": 16 - } - }, - { - "model": "people.affiliation", - "pk": 80, - "fields": { - "name": "Founding member of Women in Science Portland", - "person": 16 - } - }, - { - "model": "people.affiliation", - "pk": 83, - "fields": { - "name": "Software Developer, Mozilla", - "person": 23 - } - }, - { - "model": "people.affiliation", - "pk": 84, - "fields": { - "name": "Network Manager, Hive NYC, Mozilla", - "person": 27 - } - }, - { - "model": "people.affiliation", - "pk": 85, - "fields": { - "name": "Digital Skills Observatory contributor", - "person": 18 - } - }, - { - "model": "people.affiliation", - "pk": 86, - "fields": { - "name": "VP, Program Development, Digital Opportunity Trust", - "person": 28 - } - }, - { - "model": "people.affiliation", - "pk": 87, - "fields": { - "name": "Speaker, New York City Council", - "person": 29 - } - }, - { - "model": "people.affiliation", - "pk": 88, - "fields": { - "name": "Head of the Department of Information Systems, University of the Western Cape", - "person": 19 - } - }, - { - "model": "people.affiliation", - "pk": 89, - "fields": { - "name": "Professor, Seneca College", - "person": 24 - } - }, - { - "model": "people.affiliation", - "pk": 90, - "fields": { - "name": "Ecologist, Zipkin Lab, Department of Integrative Biology, Michigan State university.", - "person": 30 - } - }, - { - "model": "people.affiliation", - "pk": 91, - "fields": { - "name": "Associate Scientist, Kellogg Biological Station Long Term Ecological Research Site (NSF-funded)", - "person": 30 - } - }, - { - "model": "people.affiliation", - "pk": 92, - "fields": { - "name": "Director of Communications & Development, The LAMP", - "person": 31 - } - }, - { - "model": "people.affiliation", - "pk": 93, - "fields": { - "name": "Manager of Digital Programming, New York Hall of Science", - "person": 20 - } - }, - { - "model": "people.affiliation", - "pk": 94, - "fields": { - "name": "Deputy Research Director and Data Analyst, Digital Divide Data", - "person": 32 - } - }, - { - "model": "people.affiliation", - "pk": 95, - "fields": { - "name": "Research Analyst & Project Lead, Digital Skills Observatory", - "person": 32 - } - }, - { - "model": "people.affiliation", - "pk": 96, - "fields": { - "name": "Education Innovation Specialist, UNICEF", - "person": 33 - } - }, - { - "model": "people.affiliation", - "pk": 97, - "fields": { - "name": "Founder + Global Project Lead, Nairobi Play Project", - "person": 33 - } - }, - { - "model": "people.affiliation", - "pk": 98, - "fields": { - "name": "Global Campaigner, Mozilla", - "person": 22 - } - }, - { - "model": "people.affiliation", - "pk": 99, - "fields": { - "name": "Director of Digital Programming, DreamYard Project", - "person": 34 - } - }, - { - "model": "people.affiliation", - "pk": 100, - "fields": { - "name": "Community Impact Manager, Google Fiber", - "person": 35 - } - }, - { - "model": "people.affiliation", - "pk": 101, - "fields": { - "name": "Community & Partnerships Manager, Open Corporates", - "person": 26 - } - }, - { - "model": "people.affiliation", - "pk": 102, - "fields": { - "name": "Founder, Chayn", - "person": 26 - } - }, - { - "model": "people.affiliation", - "pk": 103, - "fields": { - "name": "Co-Founder, EmpowerHack", - "person": 26 - } - }, - { - "model": "news.news", - "pk": 1, - "fields": { - "headline": "The Internet Is Sick", - "outlet": "MIT Technology Review", - "date": "2017-01-19", - "link": "https://www.technologyreview.com/s/603392/mozilla/", - "excerpt": "", - "author": "Tom Simonite", - "glyph": "images/news/the-internet-is-sick_1490306060.svg", - "featured": false, - "publish_after": "2017-04-21T13:37:56Z", - "expires": null, - "is_video": false, - "thumbnail": "" - } - }, - { - "model": "news.news", - "pk": 2, - "fields": { - "headline": "Finding Inspiration for Art in the Betrayal of Privacy", - "outlet": "New York Times", - "date": "2016-12-27", - "link": "https://www.nytimes.com/2016/12/27/magazine/finding-inspiration-for-art-in-the-betrayal-of-privacy.html", - "excerpt": "", - "author": "Jenna Wortham", - "glyph": "images/news/finding-inspiration-for-art-in-the-betrayal-of-privacy_1490306216.svg", - "featured": false, - "publish_after": "2017-04-21T13:38:21Z", - "expires": null, - "is_video": false, - "thumbnail": "" - } - }, - { - "model": "news.news", - "pk": 3, - "fields": { - "headline": "Mozilla's art installation warns about how companies are using your data", - "outlet": "CNBC", - "date": "2016-12-13", - "link": "http://www.cnbc.com/2016/12/13/mozillas-the-glass-room-warns-about-how-companies-are-using-your-data.html", - "excerpt": "", - "author": "Michelle Castillo", - "glyph": "images/news/mozilla-s-art-installation-warns-about-how-companies-are-using-your-data_1491846701.svg", - "featured": false, - "publish_after": "2017-04-21T13:38:35Z", - "expires": null, - "is_video": false, - "thumbnail": "" - } - }, - { - "model": "news.news", - "pk": 4, - "fields": { - "headline": "Visit the internet's dark side at this demented apple store", - "outlet": "Fast Company", - "date": "2016-12-01", - "link": "https://www.fastcodesign.com/3066104/visit-the-internets-dark-side-at-this-demented-apple-store", - "excerpt": "", - "author": "Mark Wilson", - "glyph": "images/news/visit-the-internet-s-dark-side-at-this-demented-apple-store_1490306555.svg", - "featured": false, - "publish_after": "2017-04-21T13:38:56Z", - "expires": null, - "is_video": false, - "thumbnail": "images/news/visit-the-internet-s-dark-side-at-this-demented-apple-store_thumbnail_1505768982.jpg" - } - }, - { - "model": "news.news", - "pk": 5, - "fields": { - "headline": "There's No Escaping Big Data in 'The Glass Room'", - "outlet": "WNYC", - "date": "2016-12-12", - "link": "http://www.wnyc.org/story/theres-no-escaping-big-data-glass-room/", - "excerpt": "", - "author": "WNYC News", - "glyph": "images/news/there-s-no-escaping-big-data-in-the-glass-room_1490309068.svg", - "featured": false, - "publish_after": "2017-04-21T13:38:41Z", - "expires": null, - "is_video": false, - "thumbnail": "" - } - }, - { - "model": "news.news", - "pk": 6, - "fields": { - "headline": "Wie steht es um die Gesundheit des Internets?", - "outlet": "t3n", - "date": "2016-11-01", - "link": "http://t3n.de/news/mozilla-festival-internet-gesundheit-761360/", - "excerpt": "", - "author": "Kim Rixecker", - "glyph": "images/news/what-about-the-health-of-the-internet_1491846626.svg", - "featured": false, - "publish_after": "2017-04-21T13:39:19Z", - "expires": null, - "is_video": false, - "thumbnail": "" - } - }, - { - "model": "news.news", - "pk": 7, - "fields": { - "headline": "Mozilla planta cara a los \u2018trolls\u2019", - "outlet": "El Pa\u00eds", - "date": "2016-11-03", - "link": "http://tecnologia.elpais.com/tecnologia/2016/10/31/actualidad/1477905484_625075.html", - "excerpt": "", - "author": "Jos\u00e9 Mendiola Zuriarrain", - "glyph": "images/news/mozilla-stands-up-to-the-trolls_1490309367.svg", - "featured": false, - "publish_after": "2017-04-21T13:39:12Z", - "expires": null, - "is_video": false, - "thumbnail": "" - } - }, - { - "model": "news.news", - "pk": 8, - "fields": { - "headline": "The Rise of Digital Empires", - "outlet": "The New Statesman", - "date": "2016-09-01", - "link": "http://tech.newstatesman.com/guest-opinion/digital-empires", - "excerpt": "", - "author": "Mark Surman", - "glyph": "images/news/the-rise-of-digital-empires_1491846584.svg", - "featured": false, - "publish_after": "2017-04-21T13:40:59Z", - "expires": null, - "is_video": false, - "thumbnail": "" - } - }, - { - "model": "news.news", - "pk": 9, - "fields": { - "headline": "10-Minute Digital Privacy Tuneup", - "outlet": "Consumer Reports", - "date": "2016-09-20", - "link": "http://www.consumerreports.org/privacy/the-consumer-reports-10-minute-digital-privacy-tuneup/", - "excerpt": "", - "author": "Consumer Reports", - "glyph": "images/news/10-minute-digital-privacy-tuneup_1490309594.svg", - "featured": false, - "publish_after": "2017-04-21T13:39:42Z", - "expires": null, - "is_video": false, - "thumbnail": "" - } - }, - { - "model": "news.news", - "pk": 10, - "fields": { - "headline": "Take a selfie as a form of political protest? Yes you can", - "outlet": "CNET", - "date": "2016-09-27", - "link": "https://www.cnet.com/news/mozilla-post-crimes-app-european-union-protest-selfie/", - "excerpt": "", - "author": "Patrick Holland", - "glyph": "images/news/take-a-selfie-as-a-form-of-political-protest-yes-you-can_1490309670.svg", - "featured": false, - "publish_after": "2017-04-21T13:39:25Z", - "expires": null, - "is_video": false, - "thumbnail": "" - } - }, - { - "model": "news.news", - "pk": 11, - "fields": { - "headline": "Let's fix EU copyright law, for innovation and creativity online", - "outlet": "EU Observer", - "date": "2016-08-25", - "link": "https://euobserver.com/opinion/134752", - "excerpt": "", - "author": "Katharina Borchert", - "glyph": "images/news/let-s-fix-eu-copyright-law-for-innovation-and-creativity-online_1490311914.svg", - "featured": false, - "publish_after": "2017-04-20T13:40:53Z", - "expires": null, - "is_video": false, - "thumbnail": "" - } - }, - { - "model": "news.news", - "pk": 12, - "fields": { - "headline": "Mozilla breathes petition-of-fire at EU copyright laws", - "outlet": "The Register", - "date": "2016-08-26", - "link": "http://www.theregister.co.uk/2016/08/26/mozilla_eu_copyright_protest/", - "excerpt": "", - "author": "Simon Sharwood", - "glyph": "images/news/mozilla-breathes-petition-of-fire-at-eu-copyright-laws_1490311974.svg", - "featured": false, - "publish_after": "2017-04-21T13:41:10Z", - "expires": null, - "is_video": false, - "thumbnail": "" - } - }, - { - "model": "news.news", - "pk": 13, - "fields": { - "headline": "Mozilla's new game uses emoji to teach you about encryption", - "outlet": "Mashable", - "date": "2016-06-29", - "link": "http://mashable.com/2016/06/29/mozilla-codemoji-encryption/#q8yR_JjM98qy", - "excerpt": "", - "author": "Karissa Bell", - "glyph": "images/news/mozilla-s-new-game-uses-emoji-to-teach-you-about-encryption_1490312037.svg", - "featured": false, - "publish_after": "2017-04-21T13:41:53Z", - "expires": null, - "is_video": false, - "thumbnail": "" - } - }, - { - "model": "news.news", - "pk": 14, - "fields": { - "headline": "Mozilla made a game to teach you the basics of encryption", - "outlet": "Engadget", - "date": "2016-06-28", - "link": "https://www.engadget.com/2016/06/28/mozilla-encryption-game/", - "excerpt": "", - "author": "Jon Fingas", - "glyph": "images/news/mozilla-made-a-game-to-teach-you-the-basics-of-encryption_1490312089.svg", - "featured": false, - "publish_after": "2017-04-20T13:40:00Z", - "expires": null, - "is_video": false, - "thumbnail": "" - } - }, - { - "model": "news.news", - "pk": 15, - "fields": { - "headline": "This encryption tool can make you smile", - "outlet": "WIRED Germany", - "date": "2016-06-29", - "link": "https://www.wired.de/collection/tech/dieses-verschluesselungs-tool-laesst-eure-texte-laecheln", - "excerpt": "", - "author": "WIRED Editorial", - "glyph": "images/news/this-encryption-tool-can-make-you-smile_1490312144.svg", - "featured": false, - "publish_after": "2017-04-20T13:40:24Z", - "expires": null, - "is_video": false, - "thumbnail": "" - } - }, - { - "model": "news.news", - "pk": 16, - "fields": { - "headline": "Web literacy among the underprivileged in Kolkata", - "outlet": "Times of India", - "date": "2016-06-27", - "link": "http://timesofindia.indiatimes.com/city/kolkata/Web-literacy-among-the-underprivileged-in-Kolkata/articleshow/52933377.cms", - "excerpt": "", - "author": "Jhimli Mukherjee Pandey", - "glyph": "images/news/web-literacy-among-the-underprivileged-in-kolkata_1490312194.svg", - "featured": false, - "publish_after": "2017-04-20T13:39:21Z", - "expires": null, - "is_video": false, - "thumbnail": "" - } - }, - { - "model": "news.news", - "pk": 17, - "fields": { - "headline": "Mozilla expands its National Gigabit Project to Austin", - "outlet": "512 Tech", - "date": "2016-05-17", - "link": "http://www.512tech.com/technology/mozilla-expands-its-national-gigabit-project-austin/0wo6pcOmcpRqDKrPypDfbP/", - "excerpt": "", - "author": "Lori Hawkins", - "glyph": "images/news/mozilla-expands-its-national-gigabit-project-to-austin_1491846474.svg", - "featured": false, - "publish_after": "2017-04-20T13:39:17Z", - "expires": null, - "is_video": false, - "thumbnail": "" - } - }, - { - "model": "news.news", - "pk": 18, - "fields": { - "headline": "Mozilla's Web Literacy Map Teaches the Essential Web Skills Everyone Should Know", - "outlet": "Lifehacker", - "date": "2016-04-21", - "link": "http://lifehacker.com/mozillas-web-literacy-map-teaches-the-essential-web-ski-1772260465", - "excerpt": "", - "author": "Melanie Pinola", - "glyph": "images/news/mozilla-s-web-literacy-map-teaches-the-essential-web-skills-everyone-should-know_1490312301.svg", - "featured": false, - "publish_after": "2017-04-20T13:37:36Z", - "expires": null, - "is_video": false, - "thumbnail": "" - } - }, - { - "model": "news.news", - "pk": 19, - "fields": { - "headline": "Mozilla Foundation Backs Apple In Encryption Case With Federal Government", - "outlet": "NPR", - "date": "2016-02-19", - "link": "http://www.npr.org/2016/02/19/467318811/mozilla-foundation-backs-apple-in-encryption-case-with-federal-government", - "excerpt": "", - "author": "NPR Transcript", - "glyph": "images/news/mozilla-foundation-backs-apple-in-encryption-case-with-federal-government_1490312354.svg", - "featured": false, - "publish_after": "2017-04-20T13:37:12Z", - "expires": null, - "is_video": false, - "thumbnail": "" - } - }, - { - "model": "news.news", - "pk": 20, - "fields": { - "headline": "Mozilla campaign encourages people to understand encryption", - "outlet": "CBC", - "date": "2016-02-23", - "link": "http://www.cbc.ca/news/technology/mozilla-campaign-encourages-people-to-understand-encryption-1.3460109", - "excerpt": "", - "author": "Dan Misener", - "glyph": "images/news/mozilla-campaign-encourages-people-to-understand-encryption_1490312403.svg", - "featured": false, - "publish_after": "2017-04-20T13:37:22Z", - "expires": null, - "is_video": false, - "thumbnail": "" - } - }, - { - "model": "news.news", - "pk": 21, - "fields": { - "headline": "Mozilla chief: FBI snooping at Apple 'back door' makes you less safe", - "outlet": "CNN", - "date": "2016-02-18", - "link": "http://www.cnn.com/2016/02/18/opinions/apple-encryption-backdoor-fbi-surman/index.html", - "excerpt": "", - "author": "Mark Surman", - "glyph": "images/news/mozilla-chief-fbi-snooping-at-apple-back-door-makes-you-less-safe_1490312456.svg", - "featured": false, - "publish_after": "2017-04-20T13:37:07Z", - "expires": null, - "is_video": false, - "thumbnail": "" - } - }, - { - "model": "news.news", - "pk": 23, - "fields": { - "headline": "Digital Citizens, Let\u2019s Talk About Internet Health", - "outlet": "Mozilla Internet Citizen", - "date": "2017-01-19", - "link": "https://medium.com/mozilla-internet-citizen/digital-citizens-lets-talk-about-internet-health-767860769e7f#.y2fdf3oc7", - "excerpt": "", - "author": "Mark Surman", - "glyph": "images/news/digital-citizens-lets-talk-about-internet-health_1490312529.svg", - "featured": false, - "publish_after": "2017-04-21T13:37:48Z", - "expires": null, - "is_video": false, - "thumbnail": "" - } - }, - { - "model": "news.news", - "pk": 24, - "fields": { - "headline": "Living Inside the Computer: Building Responsible IoT", - "outlet": "Mozilla Internet Citizen", - "date": "2017-01-05", - "link": "https://medium.com/mozilla-internet-citizen/living-inside-the-computer-mozilla-is-calling-for-responsible-iot-6cd57b146705#.d8zrn3tsg", - "excerpt": "", - "author": "Mark Surman", - "glyph": "images/news/living-inside-the-computer-building-responsible-iot_1490312626.svg", - "featured": false, - "publish_after": "2017-04-21T13:38:14Z", - "expires": null, - "is_video": false, - "thumbnail": "" - } - }, - { - "model": "news.news", - "pk": 25, - "fields": { - "headline": "Learning and the future of IoT", - "outlet": "Read, Write, Participate", - "date": "2017-01-06", - "link": "https://medium.com/read-write-participate/learning-and-the-future-of-iot-d5a338fc33a5#.4dlfpx58o", - "excerpt": "", - "author": "Chad Sansing", - "glyph": "images/news/learning-and-the-future-of-iot_1490312709.svg", - "featured": false, - "publish_after": "2017-04-21T13:38:03Z", - "expires": null, - "is_video": false, - "thumbnail": "" - } - }, - { - "model": "news.news", - "pk": 26, - "fields": { - "headline": "Welcome to The Glass Room", - "outlet": "Mozilla Internet Citizen", - "date": "2016-12-01", - "link": "https://medium.com/mozilla-internet-citizen/welcome-to-the-glass-room-667c4a933784#.z9yk2815y", - "excerpt": "", - "author": "Kevin Zawacki", - "glyph": "images/news/welcome-to-the-glass-room_1490312781.svg", - "featured": false, - "publish_after": "2017-04-21T13:38:48Z", - "expires": null, - "is_video": false, - "thumbnail": "" - } - }, - { - "model": "news.news", - "pk": 27, - "fields": { - "headline": "Teaching the Web, with Art as Curriculum", - "outlet": "Read, Write, Participate", - "date": "2016-12-14", - "link": "https://medium.com/read-write-participate/teaching-the-web-with-art-as-curriculum-c1d1c86fb12a#.wtvj5k4xu", - "excerpt": "", - "author": "Mozilla", - "glyph": "images/news/teaching-the-web-with-art-as-curriculum_1490312877.svg", - "featured": false, - "publish_after": "2017-04-21T13:38:27Z", - "expires": null, - "is_video": false, - "thumbnail": "" - } - }, - { - "model": "news.news", - "pk": 28, - "fields": { - "headline": "Women + Web = ", - "outlet": "Read, Write, Participate", - "date": "2016-11-14", - "link": "https://medium.com/read-write-participate/women-web-strong-7e50f123311e#.3fgz2yr91", - "excerpt": "", - "author": "Amira Dhalla", - "glyph": "images/news/women-web-strong_1490312944.svg", - "featured": false, - "publish_after": "2017-04-21T13:39:05Z", - "expires": null, - "is_video": false, - "thumbnail": "" - } - }, - { - "model": "news.news", - "pk": 33, - "fields": { - "headline": "How We\u2019re Training Women in Africa to Teach the Web", - "outlet": "Read, Write, Participate", - "date": "2016-07-25", - "link": "https://medium.com/read-write-participate/mozilla-club-leadership-training-in-nairobi-and-cape-town-cbb9ad2a3f38#.8632npaeu", - "excerpt": "", - "author": "Amira Dhalla", - "glyph": "images/news/how-were-training-women-in-africa-to-teach-the-web_1490313280.svg", - "featured": false, - "publish_after": "2017-04-20T13:40:29Z", - "expires": null, - "is_video": false, - "thumbnail": "" - } - }, - { - "model": "news.news", - "pk": 34, - "fields": { - "headline": "Why Developing Open Science Software Matters", - "outlet": "Read, Write, Participate", - "date": "2016-07-25", - "link": "https://medium.com/read-write-participate/mozilla-fellows-for-science-why-developing-open-science-software-matters-d7bbbd55da80#.z9bbb7i30", - "excerpt": "", - "author": "Abigail Cabunoc Mayes", - "glyph": "images/news/why-developing-open-science-software-matters_1490313333.svg", - "featured": false, - "publish_after": "2017-04-21T13:40:53Z", - "expires": null, - "is_video": false, - "thumbnail": "" - } - }, - { - "model": "news.news", - "pk": 35, - "fields": { - "headline": "Translating the Web into Xhosa (and Zulu)", - "outlet": "Read, Write, Participate", - "date": "2016-07-25", - "link": "https://medium.com/read-write-participate/translating-the-web-into-xhosa-and-zulu-d061348c50b4#.csri3v8m9", - "excerpt": "", - "author": "Mozilla", - "glyph": "images/news/translating-the-web-into-xhosa-and-zulu_1490313380.svg", - "featured": false, - "publish_after": "2017-04-21T13:40:47Z", - "expires": null, - "is_video": false, - "thumbnail": "" - } - }, - { - "model": "news.news", - "pk": 36, - "fields": { - "headline": "Teaching the Web in Kenya\u2019s High Schools", - "outlet": "Read, Write, Participate", - "date": "2016-07-25", - "link": "https://medium.com/read-write-participate/teaching-the-web-in-kenyas-high-schools-4a4ed519485f#.rmikbftq7", - "excerpt": "", - "author": "Mozilla", - "glyph": "images/news/teaching-the-web-in-kenyas-high-schools_1490313425.svg", - "featured": false, - "publish_after": "2017-04-20T13:40:43Z", - "expires": null, - "is_video": false, - "thumbnail": "" - } - }, - { - "model": "news.news", - "pk": 37, - "fields": { - "headline": "The South Africa township where women learn tech", - "outlet": "BBC", - "date": "2017-03-15", - "link": "http://www.bbc.com/news/world-africa-39273651", - "excerpt": "Far more men than women access the internet in the developing world, and the UN and the Mozilla Foundaton are trying to redress the balance.", - "author": "BBC", - "glyph": "images/news/the-south-africa-township-where-women-learn-tech_1491846244.svg", - "featured": true, - "publish_after": "2017-04-21T13:37:42Z", - "expires": null, - "is_video": false, - "thumbnail": "" - } - }, - { - "model": "news.news", - "pk": 38, - "fields": { - "headline": "The road to real results for online learning in developing countries", - "outlet": "DevEx", - "date": "2017-04-03", - "link": "https://www.devex.com/news/the-road-to-real-results-for-online-learning-in-developing-countries-89884", - "excerpt": "", - "author": "Catherine Cheney", - "glyph": "images/news/the-road-to-real-results-for-online-learning-in-developing-countries_1491846399.svg", - "featured": true, - "publish_after": "2017-04-21T13:37:22Z", - "expires": null, - "is_video": false, - "thumbnail": "" - } - }, - { - "model": "news.news", - "pk": 39, - "fields": { - "headline": "Eugene receives tech honor and money to encourage Internet projects", - "outlet": "The Register-Guard", - "date": "2017-03-15", - "link": "http://registerguard.com/rg/news/local/35378104-75/eugene-receives-tech-honor-and-money-to-fuel-internet-projects.html.csp", - "excerpt": "", - "author": "Sherri Buri McDonald", - "glyph": "images/news/eugene-receives-tech-honor-and-money-to-encourage-internet-projects_1491846171.svg", - "featured": false, - "publish_after": "2017-04-21T13:37:36Z", - "expires": null, - "is_video": false, - "thumbnail": "" - } - }, - { - "model": "news.news", - "pk": 40, - "fields": { - "headline": "Mozilla: \u2018IoT will be the first big battle of 2017,\u2019 calls for responsible IoT", - "outlet": "Network World", - "date": "2017-01-05", - "link": "http://www.networkworld.com/article/3154938/security/mozilla-iot-will-be-the-first-big-battle-of-2017-calls-for-responsible-iot.html", - "excerpt": "", - "author": "Ms. Smith", - "glyph": "images/news/mozilla-iot-will-be-the-first-big-battle-of-2017-calls-for-responsible-iot_1491846080.svg", - "featured": false, - "publish_after": "2017-04-21T13:38:09Z", - "expires": null, - "is_video": false, - "thumbnail": "" - } - }, - { - "model": "news.news", - "pk": 41, - "fields": { - "headline": "Facebook, Mozilla, Craig Newmark, others launch $14 million fund to support news integrity", - "outlet": "VentureBeat", - "date": "2017-04-02", - "link": "https://venturebeat.com/2017/04/02/facebook-mozilla-craig-newmark-others-launch-14-million-fund-to-support-news-integrity/", - "excerpt": "", - "author": "Ken Yeung", - "glyph": "images/news/facebook-mozilla-craig-newmark-others-launch-14-million-fund-to-support-news-integrity_1491846311.svg", - "featured": true, - "publish_after": "2017-04-21T13:37:30Z", - "expires": null, - "is_video": false, - "thumbnail": "" - } - }, - { - "model": "news.news", - "pk": 42, - "fields": { - "headline": "Worried About Your Online Privacy? Mozilla\u2019s Executive Director Has Tips for You", - "outlet": "Slate", - "date": "2017-04-03", - "link": "http://www.slate.com/blogs/future_tense/2017/04/03/worried_about_your_digital_privacy_mozilla_s_executive_director_has_tips.html", - "excerpt": "", - "author": "Mark Surman", - "glyph": "images/news/worried-about-your-online-privacy-mozillas-executive-director-has-tips-for-you_1491846367.svg", - "featured": true, - "publish_after": "2017-04-21T13:37:07Z", - "expires": null, - "is_video": false, - "thumbnail": "" - } - }, - { - "model": "news.news", - "pk": 43, - "fields": { - "headline": "Internet health as a social issue", - "outlet": "CBC", - "date": "2017-04-09", - "link": "http://www.cbc.ca/radio/spark/internet-health-as-a-social-issue-1.4053202", - "excerpt": "", - "author": "Nora Young", - "glyph": "images/news/internet-health-as-a-social-issue_1491835177.svg", - "featured": true, - "publish_after": "2017-04-21T13:36:05Z", - "expires": null, - "is_video": false, - "thumbnail": "" - } - }, - { - "model": "news.news", - "pk": 44, - "fields": { - "headline": "Au Kenya, le Net pour le meilleur mais aussi pour le pire", - "outlet": "Le Monde", - "date": "2017-04-06", - "link": "http://www.lemonde.fr/pixels/article/2017/04/06/au-kenya-le-net-pour-le-meilleur-mais-aussi-pour-le-pire_5107052_4408996.html", - "excerpt": "", - "author": "Damien Leloup", - "glyph": "images/news/au-kenya-le-net-pour-le-meilleur-mais-aussi-pour-le-pire_1491938408.svg", - "featured": false, - "publish_after": "2017-04-21T13:36:15Z", - "expires": null, - "is_video": false, - "thumbnail": "" - } - }, - { - "model": "news.news", - "pk": 45, - "fields": { - "headline": "How mobile apps are growing the African tech sector", - "outlet": "CNN", - "date": "2016-08-08", - "link": "http://www.cnn.com/videos/world/2016/08/08/marketplace-africa-mozilla-foundation-spc-b.cnn", - "excerpt": "", - "author": "CNN Africa", - "glyph": "images/news/how-mobile-apps-are-growing-the-african-tech-sector_1492030161.svg", - "featured": false, - "publish_after": "2017-04-20T13:40:49Z", - "expires": null, - "is_video": false, - "thumbnail": "" - } - }, - { - "model": "news.news", - "pk": 46, - "fields": { - "headline": "How Can South Africa Kickstart Its Tech Industry?", - "outlet": "The Atlantic", - "date": "2016-05-05", - "link": "https://www.theatlantic.com/education/archive/2016/05/why-south-africas-tech-industry-still-needs-room-to-grow/481335/", - "excerpt": "", - "author": "Rebecca Gibian and Diana Crandall", - "glyph": "", - "featured": false, - "publish_after": "2017-04-20T13:37:57Z", - "expires": null, - "is_video": false, - "thumbnail": "" - } - }, - { - "model": "news.news", - "pk": 47, - "fields": { - "headline": "Why Web Literacy Matters, Too", - "outlet": "Bright", - "date": "2015-06-16", - "link": "https://brightreads.com/why-web-literacy-matters-too-eedfd902ab07", - "excerpt": "", - "author": "Mark Surman", - "glyph": "", - "featured": false, - "publish_after": "2017-04-20T13:35:59Z", - "expires": null, - "is_video": false, - "thumbnail": "" - } - }, - { - "model": "news.news", - "pk": 48, - "fields": { - "headline": "The woman whose phone 'misdiagnosed HIV'", - "outlet": "BBC", - "date": "2017-04-17", - "link": "http://www.bbc.com/news/technology-39371100", - "excerpt": "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis HSDHJasgdha SHDHjasgdhga SHBHashdgahsd", - "author": "Jane Wakefield", - "glyph": "images/news/the-woman-whose-phone-misdiagnosed-hiv_1492475903.svg", - "featured": false, - "publish_after": "2017-04-21T13:35:50Z", - "expires": null, - "is_video": false, - "thumbnail": "images/news/the-woman-whose-phone-misdiagnosed-hiv_thumbnail_1507152335.jpg" - } - }, - { - "model": "news.news", - "pk": 49, - "fields": { - "headline": "Unlocking the potential of technologies", - "outlet": "BBC", - "date": "2017-04-27", - "link": "http://www.bbc.com/news/in-pictures-39630389", - "excerpt": "", - "author": "BBC", - "glyph": "", - "featured": false, - "publish_after": "2017-05-01T16:45:57Z", - "expires": null, - "is_video": false, - "thumbnail": "" - } - }, - { - "model": "landingpage.signup", - "pk": 1, - "fields": { - "title": "Internet Health basic form", - "header": "Keep me updated", - "description": "

What's next? Read the report and send us your feedback. Stay tuned for the next version. Let’s get the world talking about Internet health.

", - "newsletter": "mozilla-leadership-network" - } - }, - { - "model": "landingpage.signup", - "pk": 2, - "fields": { - "title": "Fellowship basic form", - "header": "Get connected", - "description": "

Mozilla will periodically update you about important people, projects, and opportunities in our Network so you can connect yourself to the Movement for Internet health.

", - "newsletter": "mozilla-leadership-network" - } - }, - { - "model": "landingpage.signup", - "pk": 3, - "fields": { - "title": "Leadership Training", - "header": "Stay Connected", - "description": "

We'll send you updates with opportunities to add valuable skills to your leadership toolkit, and find like-minded people and projects across the Network.

", - "newsletter": "mozilla-leadership-network" - } - }, - { - "model": "landingpage.signup", - "pk": 4, - "fields": { - "title": "Default Form", - "header": "Get connected", - "description": "

Mozilla will periodically update you about important people, projects, and opportunities in our Network so you can connect yourself to the Movement for Internet health.

", - "newsletter": "mozilla-leadership-network" - } - }, - { - "model": "landingpage.signup", - "pk": 5, - "fields": { - "title": "MITI", - "header": "Get updates by email", - "description": "

Find out about future MITI news, events and research

", - "newsletter": "miti" - } - }, - { - "model": "landingpage.landingpage", - "pk": 4, - "fields": { - "header": "Fellowships that Empower Leaders", - "content": "

At Mozilla, we’re committed to providing research funding, mentorship, and project-based learning opportunities for community leaders who want to contribute to an open and inclusive web throughout art, science, media, security, policy and advocacy domains.

\n

We’ve hosted a range of fellows in past cohorts, from neuroscientists working on institutional policy in Portland and San Francisco, to trans-Atlantic privacy and security hackers developing research materials and trainings that protect journalists and communication on the open web. Read more about our current cohorts advancing open data, the open web, and tech policy.

\n

Here are some of our supporting organizations:

\n

", - "signup": 2 - } - }, - { - "model": "landingpage.landingpage", - "pk": 6, - "fields": { - "header": "Introducing the Internet Health Report", - "content": "

Mozilla’s Internet Health Report is an open source initiative that combines research from multiple sources to document what’s healthy and unhealthy.

\n

\n

Is the Internet getting healthier?

\n

The Internet is an ecosystem that billions of people depend on. A living entity, shaped by our actions. We’re connected, and we can each make a difference.

\n

Is the web thriving? Under threat? We believe these are timely and essential questions.

\n

Version 0.1 of Mozilla's Internet Health Report identifies five key Internet health markers and offers a brief prognosis for each in 2017.

\n

\n

Internet Health Report

", - "signup": 1 - } - }, - { - "model": "landingpage.landingpage", - "pk": 5, - "fields": { - "header": "Leadership Training", - "content": "

The skills you need to build a healthy web.

\n

Open Leadership 101 is your introduction to “working open.” Learn the basics of participation, collaboration, and sharing on community-driven projects. Discover what working open can do for your project, and explore open projects from across the Network. Think of this free, hour-long online course as your launchpad into the Leadership Network.

\n

\n

\"\"

\n

Start Your Training

", - "signup": 4 - } - }, - { - "model": "landingpage.landingpage", - "pk": 9, - "fields": { - "header": "Network 50", - "content": "

50 People Who Made the Internet a Better Place in 2016

\n

\n

Mozilla’s mission is keeping the Internet healthy—ensuring the web is a global public resource, open and accessible to all. It’s an essential mission, but also a daunting one, one that Mozilla can’t achieve alone. That is why we’re committed to fueling the broader Internet health network: individuals and organizations around the globe working on topics like online privacy and security, open innovation, decentralization, digital inclusion and web literacy. Working together, this network can have an outsized, positive impact on Internet health.

\n

We are amazed and inspired by the fantastic contributions of these network members and wanted to recognize members whose contributions have been critical to this mssions; Network50 is our attempt to do so. It is an accolade for network members who have done outstanding Internet health work over the past 18 months, with the winners representing the diversity of the network.

\n

They speak different languages, work in different fields, and belong to different organizations but they are all committed to a better web and to the health of the internet. These are the people behind recent victories in the realms of public policy, open science, digital inclusion, ethical technology and other critical areas.

\n

To meet the full Network50, please click on their names below (alphabetical, by first name). And join Mozilla in thanking these individuals for their outstanding work.

\n

Will we see your name on this list next year?

\n

\n\n

\n

\n
\n

Amel Ghouila

\n

Amel Ghouila is a Bioinformatician at Institut Pasteur de Tunis, an Open Science advocate and a Regional Ambassador for Technovation, the international competition for girls between 10 and 18 years old interested in developing mobile applications to solve a community problem. She has been active in the internet health movement as a Study Group Lead. She is a member of our first cohort of \"Network50.”

\n

Amel is an outstanding network member, contributor, and connector. She leads a Study Group in Tunis, and has brought in other Study Group leads to expand the Open Science mission. She is involved with H3ABioNet, a Pan-African Bioinformatics network comprising 32 Bioinformatics research groups that focuses on developing Bioinformatics capacity within Africa. She hosted a Global Sprint site at the Institute de Pasteur, helping bring more scientists into the Open Science movement. She has been a willing and eager mentor to many others, and a strong advocate for the Open movement.

\n

\n
\n

Alex Wafula

\n

Alex Wafula is a software professional and a community activist. He has been active in the internet health movement as a Mozilla Rep, Firefox Student Ambassador, and researcher. He is a member of our first cohort of \"Network50.”

\n

Alex has been a leader of the Kenyan and then the East African community for many years and continues to evolve and grow as a facilitative leader who supports others to succeed. Most recently, he was an outstanding contributor to the recent Digital Skills Observatory program. As part of that project, he helped design, develop, and execute 4 digital skills workshops and an accompanying Android app, helping engage the community in a consistent and substantial manner. He has a strong history of contribution to the Internet health movement as a Mozilla Rep, a Firefox Student Ambassador, a Wikimedia Editor and also as a Wikimedia Kenya Board Member.

\n

\n
\n

David Bild

\n

David Bild works as the Coordinator of Teen and Young Adult Programs at the Chicago Academy of Sciences/Peggy Notebaert Nature Museum. He has been active in the internet health movement as a Hive Chicago member and advisor. He is a member of our first cohort of \"Network50.”

\n

David is one of the most active, prolific and collaborative members of Hive Chicago, and has led, supported, connected, spread, and shared a dozen or more projects in that community. David works in the open, using open source tools, to create participatory, inclusive, and interest-driven programs for youth in Chicago; as an example, his Hive Mapping Cooperative project focused on enabling teens and educators to collect, visualize, and share media-rich spatial data using free and open source mapping, data collection, and data sharing tools. In recognition of his contributions, he was nominated by his peers to serve an 18-month term on the Hive Chicago Advisory Committee. He has also been a regular attendee and session leader at MozFest and a collaborator across hubs.

\n

\n
\n

Kim Wilkens

\n

Kim Wilkens is an educator and Founder of Tech-Girls, a volunteer-based, not-for-profit that works with parents, educators, and partners to provide training, resources and relationships needed to spark girls interest in STEM. As part of the internet health movement, she has been an active participant in Mozilla Learning activities, and as a MozFest volunteer. She is a member of our first cohort of \"Network50\".

\n

Kim is an award-winning local organizer, advocate for web literacy and women-in-tech, and an educator who regularly develops new web literacy activities, advancing the mission Internet health through her many programs. As an example, Kim created her own after-school program to teach web literacy to girls who have typically been considered outsiders in tech, organized a local SPARK hackathon for youth and collaborated on MozFest 2016 to create  Learning Hub space titled \"Demystify the Web!\". She has been an active and consistent contributor to curriculum, messaging and events over multiple years. Events like SPARK and organizations like Tech-Girls are testaments to her success in helping others learn, make, and organize.

\n

\n
\n

Shreyas Narayanan Kutty

\n

Shreyas Narayanan Kutty is a committed Internet health advocate and contributor. He has been active in the internet health movement as a Club Captain, Mozilla Rep, MozFest volunteer and a Club Regional Coordinator. He is a member of our first cohort of \"Network50.”

\n

As an active collaborator in developing the strategy, and growing the community, Shreyas has been key to the growth of Mozilla Clubs program since before its inception. He has mobilized and energized his local community in India, and as Regional Coordinator has trained and mentored 10+ Mozilla Club Captains. He is a collaborator and network builder; in his final year at university, Shreyas secured the cooperation of Wikimedia and Google Developer Group, to organize a Maker Party event that drew over 700 participants. He has also been a key volunteer at Mozilla Festival and other events. He has a strong history of contribution to the Internet health movement as a part of the internet health movement, and also as a volunteer for the Open Source Initiative.

\n

\n
\n

Ariam Mogos

\n

Ariam Mogos works as the Learning Lead for UNICEF's Office of Innovation. She has been active in the internet health movement as a Hive NYC member and MozFest participant. She is a member of our first cohort of \"Network50.”

\n

Ariam Mogos is a dedicated youth development advocate, a social entrepreneur and a highly respected educator and learning technologist. She has been an active member of Hive NYC for several years, both as an organizational representative and as an individual member. In her previous position at Global Kids, she integrated web literacy into her program curricula, reaching thousands of students in public schools throughout NYC. The Young Innovators Squad program that she started mentors young people on how to share their technical skills and experiences with their peers. Outside of NYC, she has designed maker spaces and community-based coding programs for girls and urban refugees in Sierra Leone, Kenya, and South Africa. The Internet health movement is stronger because of her efforts on multiple fronts.

\n

\n
\n

Brian Bot

\n

Brian Bot works as a Principal Scientist at Sage Bionetworks. He has been a part of the internet health movement as an Open Science participant. He is a member of our first cohort of \"Network50.”

\n

Brian Bot is an outstanding community member with a firm foundation in open science initiatives and mobile development. At Sage Bionetworks, he is leading research on participatory biomedical research studies, with the objective of furthering our understanding of the application of open source practices in various settings. His work aims to re-envision how scientists can ensure reproducibility of their research results and communicate complex science to one another and to the public at large. He is an exceptionally active network member, advocating for open science best practices through his work with Mozilla and outside.

\n

\n
\n

Noah Swartz

\n

Noah Swartz works as Staff Technologist at the Electronic Frontier Foundation. He has a long history of involvement with the internet health movement as a MozFest facilitator, and privacy advocate. He is a member of our first cohort of \"Network50.”

\n

Noah Swartz is an avid supporter and developer of and for the open internet, a free software/culture advocate, and an untiring partner and advocate for web privacy. Over the years, Noah has facilitated various sessions at MozFest to help others better understand the importance of privacy and the nefarious tools used by those who are tracking and collecting data on users. His work with Privacy Lab, in partnership with Mozilla, is an example that underscores his community-building efforts, through which he mentors, inspires, and helps others succeed. The Privacy Lab has successfully grown the privacy-oriented web community and has exposed many people to the ideas, concerns, and trade-offs involved with online privacy. He has a long-standing involvement in the Internet health movement, including his current work at Electronic Frontier Foundation, and his prior work as a free software activist at the MIT Media Lab..

\n

\n
\n

Rita Geladze

\n

Rita Geladze is the Founder of Educators Camp, a network of educators dedicated to providing exceptional professional development services, youth-driven curriculum design, and capacity building workshops. She has been active in the internet health movement as Hive NYC member and is part of our first cohort of \"Network50.”

\n

Rita Geladze has contributed as a key Hive NYC leader in many ways over the past few years - from facilitating small group discussions to leading workshops and developing web literacy curriculum. She cares deeply about online privacy and web literacy and has been a dedicated advocate and educator in pushing Mozilla's priorities and activities. Rita has also facilitated digital literacy workshops for NYC youth and remains a phenomenal partner and facilitator of analog and creative ways to embrace and teach web literacy skills.

\n

\n
\n

Baratang Miya

\n

Baratang Miya is the Founder and CEO, GirlHype - Women Who Code - a not-for-profit that provides programming and app development training for girls and young women. She has been active in the internet health movement as a Regional Coordinator. She is a member of our first cohort of \"Network50.”

\n

Baratang is a key leader of the Mozilla Clubs for Women and Girls program. A self-taught coder, she has been sharing her skills and experiences with women and girls through her leadership of Mozilla Clubs and her own organization, GirlHype, which she founded 12 years ago. As a Regional Coordinator, she oversees execution of 5 clubs in Cape Town, South Africa. Her success has been amplified by her keen awareness of the challenges of making Mozilla programs and content relevant to people with little access - as in those living in the townships in and around Cape Town. Although she focuses on getting women into STEM, She understands that this is about building women's self-efficacy and confidence, to work in tech or beyond.

\n

\n
\n

Gina Grant

\n

Gina Grant is an educator and Senior Manager of Digital Engagement at the Chicago Architecture Foundation. She has been active in the internet health movement as an invaluable Hive Chicago member. She is a member of our first cohort of \"Network50.”

\n

Gina has been an active and passionate advocate for Hive work in Chicago for many years. In her current role at the Chicago Architecture Foundation (CAF), she has supported CAF's efforts to openly share their educational resources for use and reuse by others. In her work with CAF and its DiscoverDesign.org platform, Gina routinely helps Chicago youth and internet health movement members use the design process to succeed as novice designers. Gina has been a key player in local efforts to improve interoperability between learning platforms to create a broader and more inclusive learning ecosystem. Her work with developing and sharing Minecraft themed challenges and activities for youth in Chicago has been a great way for young people to learn how to deal with issues of the built environment and civic engagement.

\n

\n
\n

Meghan Hausman

\n

C. Meghan Hausman is a STEM education advocate and currently works as the Extension Program Coordinator for Northeastern Illinois University's Center for College Access and Success, promoting making and makerspaces while coordinating professional development for teachers as well as programming for youth. She has been active in the internet health movement as a Hive Chicago member, and is a member of our first cohort of \"Network50.”

\n

Meghan has been one of the most active contributors to Hive Chicago over the last many years, leading the development of Hive-funded projects, hosting meetups, and making significant and ongoing contributions. Meghan's efforts provide practical examples of creating citywide spaces for open innovation and broadening digital inclusion. She has helped build the strength of our peer professional learning community, by creating a space for professional affinity groups to form around shared problems of practices. Her contributions to the Hive-funded mobile maker space project Maker Mob has taken Hive's work to new audiences, inspiring engagement and participation in making at locations as diverse as block parties and farmers markets.

\n

\n
\n

Duncan Washington

\n

Duncan Washington is a technology professional, researcher, and digital inclusion activist. He has been active in the internet health movement as a Research Analyst and Project Lead, and is a member of our first cohort of \"Network50.”

\n

The Digital Skills Observatory is a critical project, not only for Mozilla but for the digital inclusion movement, and the insights it yields will shape how donors, governments, and foundations think about this critical work. The tremendous progress made on this project would not have been possible without the active leadership, coordination, organization, critical thinking, and technical skills of Duncan. His dedication to the success and impact of the project and his openness to understanding new ideas (and reconfiguring old ones) is an invaluable asset. Duncan has been able to bring not only technical research experience but also a deep team-oriented methodology to the project. His contributions have helped deliver high-quality digital skills training, as well as produce and publicize world-class research documentation that will contribute to open practices.

\n

\n
\n

Madeleine Bonsma-Fisher

\n

Madeleine Bonsma-Fisher is an Open Science advocate and currently a Ph.D. Student at the University of Toronto. She has been active in the internet health movement as an outstanding Study Group Lead within the Science Lab. She is a member of our first cohort of \"Network50.”

\n

Madeleine has been an exceptional leader in the Open Science movement, and her work exemplifies working in the open for the benefit of others. She has been involved with multiple Mozilla Science Lab activities, teaching a session at the first Working Open Workshop and serving as a member of the inaugural Open Leadership Cohort, and a mentor for the Open Leadership Training. She started and nurtured one of the most actively growing Study groups for the past two years - UofTCoders at the University of Toronto. Her coaching and mentorship have been invaluable to other members of the Open Science communities, helping them succeed with their Open Science projects.

\n

\n
\n

Meredith Summs

\n

Meredith Summs is an informal educator, instructional technology specialist, a curriculum developer for the Internet health movement, and currently works as the Associate Director, Learning Design at Mouse. She has been active in the internet health movement as a Hive NYC member for over five years. She is a member of our first cohort of \"Network50.”

\n

For the past several years, Meredith has been an active and engaged Hive NYC member, an ally at Mouse and contributor of curriculum on how to connect fun offline activities with web literacy skills needed on the web. She has taught circuitry, web literacy, human-centered design, assistive & adaptive tech, IT and game design. She has developed high-quality web literacy curriculum and training through her work with Mouse, with a focus on connecting fun, offline activities with web literacy skills. She helped develop Kraken the Code, one of the most popular Web Literacy Basics activities and one that has been translated into more than 10 languages. She has also shared her expertise with digital badging, and provided valuable input as part of the update to the Web Literacy Map v2.0.

\n

\n
\n

Rafael Rosa

\n

Rafael Rosa is Vice President of Programs for the Student Conservation Association and was previously the Vice President of Education at the Chicago Academy of Sciences. He has been active in the internet health movement as a Hive Chicago member, and a past advisory committee member. He is a member of our first cohort of \"Network50.”

\n

Rafael has been a member of Hive Chicago since its inception. He has been instrumental in leading education initiatives that intersect with nature and technology. He has co-led many large city-wide collaborations and was nominated by his peers to serve on our 6-member Advisory Committee. Through his work in the committee, he has led discussions and projects that challenge the ways institutions and organizations engage with under-served communities. In this role, he also mentors new member organizations in the network and provides strategic guidance to Hive leadership. He has been instrumental in updating Hive's mission to clearly align our work with the promise of the Internet for learning.

\n

\n
\n

Tina Verbo

\n

Tina (Kristina) Verbo is a software professional, an active member of the Philippines technical community, and a member of our first cohort of \"Network50.” She has been active in the internet health movement as a Club Captain, Firefox Student Ambassador, Mozfest facilitator, Mozilla Rep and a Regional Coordinator.

\n

Tina Verbo has been a long-standing contributor both in the Philippines and globally; she served as a Firefox Student Ambassador starting with the launch of the program, has been involved in the Mozilla Philippines Community as a Mozilla Rep, and serves as a Regional Coordinator for the Mozilla Clubs program. As a Regional Coordinator, she oversees the execution of 11 clubs in her region and advocates for web literacy through workshops, websites, communication channels and more. She has created vital resources on running clubs in schools, in the community and for women. She has translated our materials into her local language helping adapt the program to her local context. Her work gives us a perspective on how MLN resources and materials apply to another language and another culture.

\n

\n
\n

Anthony Negron

\n

Anthony Negron works as the Manager of Digital Programming at the new York Hall of Science (NYHS), helping research, develop and implement innovative digital programming both at NYHS and in partnership with other institutions. He has been active in the internet health movement as a Hive NYC member and joins our first cohort of \"Network50.”

\n

Anthony is one of the original and longest-serving members of the Hive NYC Learning Network, and is deeply committed to the network's values and principles of working openly and collaboratively. As an educator, Anthony is committed to providing quality web literacy experiences to young people throughout NYC, in a variety of settings. He has formed partnerships and contributed his time to several Hive institutions, helping them create their own digital media programs. As a STEM education advocate, Anthony has been instrumental in bringing knowledge to Hive NYC as an active collaborator, thought partner, and community expert.

\n

\n
\n

Anelda van der Walt

\n

Anelda van der Walt is a bioinformatician, a researcher, and entrepreneur. She leads Talarify, an eResearch consulting firm, and worked previously as an eResearch Analyst at the University of Cape Town. She has been active in the internet health movement as a Study Group Lead within the Science Lab. She is a member of our first cohort of \"Network50.”

\n

Anelda is a trailblazer for open science in her native South Africa, and more generally, across Africa. She is an excellent advocate, and an outstanding contributor for diversity, digital inclusion, open access and open science. She has been a Study Group Lead herself and is great connector and resource to other study group leads. She is very passionate about teaching and promoting openness in research and works to help researchers learn and understand how to make their work more open. She moves forward our web literacy mission through curriculum development and delivery of learning materials to audiences that wouldn't normally have access to such materials.

\n

\n
\n

Geoff Millener

\n

Geoff Millener is the Innovation and Technology Programs Manager at the Public Education Foundation Chattanooga, a strong Community Partner, a Mozilla Alum, a Hive Chattanooga member, and a member of our first cohort of \"Network50.”

\n

Geoff is an effective community builder and an advocate for innovation and openness in Learning. He has effectively helped translate the Open Web, Open Leadership principles and Mozilla's larger work to a local context and to an audience of formal educators. His work within the 4K streaming project has been useful in rallying teachers to explore this new arena of technology and collectively work on a curriculum that can be shared across the school district. As a past gigabit team staff member, he has a full understanding of our work and the context of the community and leverages both to support the work as it continues beyond his formal involvement. He has been a stalwart leader in connecting teachers with our effort (and the Internet health movement) and has shown up to volunteer repeatedly over the years.

\n

\n
\n

Ani Martinez

\n

Ani Martinez works as the Community Manager for the Remake Learning Network in the greater Pittsburgh region and beyond. She has been active in the internet health movement as a Hive Pittsburgh member, Club Captain, and MozFest volunteer. She is a member of our first cohort of \"Network50”.

\n

Ani is an experienced educator with a focus on tech, advocacy, and inclusion, committed to creating a network of accessible, hands-on problem solvers and educators. She has been a regular, consistent, and enthusiastic contributor to the Internet health movement and Mozilla projects through multiple avenues including Mozilla Clubs, Hive Pittsburgh, and MozFest. Ani has developed communities teaching the web in Pittsburgh, delivers high-quality programs in her local learning spaces and inspires other educators in our networks. She understands her own community, knows how to leverage what Mozilla and the Internet health movement can bring to her community, and has been a friendly and constructive critic for improvement.

\n

\n
\n

Anna Krystalli

\n

Anna Krystalli is an Open Science advocate based in Sheffield and is currently a freelance Research Data Scientist with a background in Ecology. She has been active in the internet health movement as a Project Lead and a MozFest Volunteer and Session Leader. She is a member of our first cohort of \"Network50.”

\n

Anna has been a dedicated and involved member of Mozilla’s Open Science activities and network. She was an active participant in many activities in the network, including Global Sprint, the Working Open Workshop, and the first Open Leadership Cohort, serving as a lead mentor. She planned and led a session at MozFest 2016, and has also delivered on programs through various workshops, including a symposium on reproducible research in behavioural ecology. She helped deliver open science hack days including the OpenCon Berlin Reproducibility Hack. She has catalyzed openness by persuading peers, students and collaborators to adopt open practices. Her work advances the Internet health movement through her contributions towards Open Innovation and Decentralization.

\n

\n
\n

Babitha George

\n

Babitha George is a researcher, a Principal of Quicksand Design Studio, a co-founder of the UnBox Festival and an advocate for social equality and development. She has been active in the internet health movement as a team leader, researcher and IoT program facilitator. She is a member of our first cohort of \"Network50.”

\n

Babitha is a key collaborator and thought partner on the topic of decentralization and digital inclusion, especially within the Global South. She has been a leading light in bringing complex, nuanced, design research into the Internet health movement. She has shown herself to be an excellent leader in the curation of research and in facilitating groups of individuals to have meaningful discussions around Open IoT. She was instrumental in at least three IoT events last year; she hosted the first event in Ahmedabad, India, led the team that conducted user research on privacy and the connected home for the second event, and co-edited the book publication at the third event. She also researched the role of local manufacturing and alternative forms of making as a path to community resilience and decentralization.

\n

\n
\n

Faith Luvuno Zuma

\n

Faith Luvuno Zuma is a researcher and curriculum designer in Kenya. She has been active in the internet health movement as an Open Researcher, and is a member of our first cohort of \"Network50.”

\n

Faith was an invaluable contributor to the Digital Skills Observatory. She contributed to creating 5 different research interventions (curriculum, lesson plans and software prototypes), ensuring the success of the project. She wrangled community members, managed logistics, created and iterated on digital skills content and subsequent reports, and accompanied the research team to collect field data. Her contributions - as a role model, project manager, community organizer, mentor, and leader - have helped ensure timely completion of all deliverables.

\n

\n
\n

Fatma Guerfali

\n

Fatma Guerfali is an Assistant Professor at Institut Pasteur de Tunis and an Open Science advocate. She has been active in the internet health movement as a Study Group Lead. She is a member of our first cohort of \"Network50.”

\n

Fatma is an invaluable network member and community builder. She leads a Study Group in Tunis, and as an Open Leadership Cohort member, is actively mentoring others to work and lead in the open. She is involved with H3ABioNet, a Pan-African Bioinformatics network comprising 32 Bioinformatics research groups, that is developing bioinformatics capacity within Africa. Her contributions have helped others in her community, particularly girls and young women, learn the skills they need to participate digitally, and her efforts have been critical in opening research practices to communities that do not have regular access to teaching resources.

\n

\n
\n

Geraldo Barros

\n

Geraldo Barros works as a front-end developer, is a committed young leader in the Internet health movement and is an active contributor to digital inclusion. He has been active in the internet health movement as a Club Captain, Regional Coordinator, and Mozilla Rep. He is a member of our first cohort of \"Network50.”

\n

Geraldo has been an active contributor to the Internet health movement for the last few years. He has successfully launched a Mozilla Club, helped grow many other Mozilla Clubs, serves as a Regional Coordinator for Mozilla Campus Clubs and also is involved as a Mozilla Rep. He is also engaged in the free and open source community in Brazil, and serves as a WoMakersCode leader. He has created a wide variety of curriculum assets that help other clubs and translated and localized other materials into Portuguese to make them more accessible to other club leaders. He has also invested in creating a more inclusive web by helping female leaders in his community and has created spaces for them to learn. His work is empowering more volunteers around Brazil to take the lead and push the Internet health mission forward.

\n

\n
\n

Germania Solorzano

\n

Germania Solorzano works for The Center for College Access and Success (formerly The Chicago Teachers' Center). She was an adjunct faculty member of Columbia College Chicago and taught for over 10 years in the Fiction Writing Department. She has been active in the internet health movement as a Hive Chicago member and advisory committee member and is a member of our first cohort of \"Network50.”

\n

Germania is a Hive Chicago contributor whose programs for youth and educators exemplify a commitment to learning by doing.  She builds active collaborations with peers in the network, shares best practices, and disseminates these learnings through educator outreach programs like the Make, Take, Teach Fair, an event that she helped develop as part of the working group she led. She has also served the network as an Advisory Committee member, guiding the operations of the network and helping plan the next phase of growth. She is dedicated to working in the open and creating spaces in which people can openly collaborate and solve problems.

\n

\n
\n

Aaron Deacon

\n

Aaron Deacon works as the Managing Director of Kansas City Digital Drive and is involved in multiple projects in Kansas City to grow and connect the technology community and also advance innovation and support the entrepreneurship ecosystem. He has been active in the internet health movement in Kansas City and a MozFest volunteer and presenter. He is a member of our first cohort of \"Network50.”

\n

Aaron has been an essential partner - as an individual and as a representative of his organization - in helping advance digital innovation and inclusion in Kansas City, through joint events, outreach, and numerous other ways. He has been a vital partner in supporting outreach, advising on local messaging, providing technical consultation and helping bring additional partners and people to the network, thus growing the Mozilla and the Internet health community in Kansas City. He has also presented at MozFest, and served as an honorary member of the external selection committee for the Gigabit Fund.

\n

\n
\n

Hildah Nyakwaka

\n

Hildah Nyakwaka is a student at the University of Nairobi and an untiring contributor to the East African technology community. She has been active in the internet health movement as a Regional Coordinator. She is a member of our first cohort of \"Network50.”

\n

Hildah is a key contributor to Mozilla’s efforts to extend web literacy to women and girls, and a key driver of the Mozilla Clubs for Women and Girls. In her role as a Regional Coordinator in Kenya, she oversees executive strategy in successfully running 10 clubs in Nairobi and building a local network that supports the education and empowerment of women in her community. Her clubs have enabled women and girls learn the web for the first time or build upon their previous skills to become web literate.  She is an invaluable mentor to the club captains she guides, and helps them succeed through mentorship and constructive feedback. Her contributions to the Internet health movement extend beyond Mozilla, particularly through Jamlab, a co-creation community made of passionate young people who are intent on using the Internet to co-create ideas and bring them alive.

\n

\n
\n

Max Franz

\n

Max Franz is a software engineer, specializing in user-interface design, who currently works at the University of Toronto. He is an open research advocate, within his organization and in the wider community. He has been active in the internet health movement as an Open Project Lead and a MozFest volunteer. He is a member of our first cohort of \"Network50.”

\n

Max has been a huge contributor to Open Science through his participation in many open research and working open initiatives.  He has helped many others in the Mozilla communities understand and adopt open working principles through his contributions and presentations at Global Sprint 2015, Global Sprint 2016 and MozFest 2015/16. In all his interactions, he has shown himself to be eager to learn things, help others succeed and take on challenges while building out his technical and leadership skills.  Over the course of the past years, Max has emerged as a leader not only on his project, Cytoscape.js, but also in the broader community, helping to continually evolve our common understanding of open source practices in science.

\n

\n
\n

Chris Foote

\n

Chris Foote (Spike) is a professional Electronic Engineer with a passion for science and technology. He is an advocate for open technology, as well as technology for development, and has volunteered with a number of global organizations such as CrisisCommons, CrisisMappers, and OpenStreetMap (OSM). He has been active in the internet health movement as a MozFest volunteer for many years, and is a member of our first cohort of \"Network50.”

\n

Spike has led and coordinated the volunteer program at MozFest for the last 4 years. He has worked hard to build a program where new volunteers feel welcomed and also understand why the Internet health movement is critical and how Mozilla contributes to the movement. He works hard to ensure the volunteers’ experience at the event is meaningful and worthwhile, taking the time to acknowledge people’s skills and interests. He also tirelessly campaigns to ensure MozFest volunteers get involved in other areas of contributing to the movement. He is a real community builder, mentoring, making connections, building collaborations, putting others first and always looking for new methods to make the process and relationships easier and long-lasting.

\n

\n
\n

David Ross

\n

David Ross is an open source and open data advocate, and an entrepreneur in the wearable tech space, building his startup using open principles. He has been active in the internet health movement as a Club Captain and MozFest volunteer. He is a member of our first cohort of \"Network50.”

\n

David is probably one of the biggest advocates for working in the open, reorganizing his whole business plan to ensure his startup is open. He has served as a MozFest volunteer for many years, helping spread the Internet health mission further. He is a committed learner, and integrates himself widely across many communities and meet-ups, always keeping a focus on the open-web mission. As a Mozilla Club Captain, David coordinates and teaches at web literacy events in London. He is invited to speak at tech events on issues of online privacy and security, using that platform to effectively disseminate a wider understanding of these key issues. Currently, as an Open Project Lead, he is helping further improve our understanding of open practices, and how to propagate them.

\n

\n
\n

Gina Tesoriero

\n

Gina Tesoriero is a networked education activist and an advocate for web literacy and digital inclusion. She currently works as a Special Education Teacher at the new York City Department of Education. She has been active in the internet health movement as a Hive NYC member, Club Captain, and MozFest volunteer. She is a member of our first cohort of \"Network50.”

\n

\n
\n

Nathalie Rayter

\n

Nathalie Rayter is an exemplary community builder and educator. She works as the STEM Teen Programs Manager at the Adler Planetarium, creating equitable opportunities for engaging youth people in science and technology. She has been active in the internet health movement as a Hive Chicago member and served as a member of its Advisory Committee in 2016. She is a member of our first cohort of \"Network50.”

\n

Nathalie is a constant innovator and a tireless advocate for inclusive youth programs. She has led, supported, implemented, spread and shared a dozen projects funded by the Hive. Nathalie has developed programs at the Planetarium that mobilize her department to be intentional about the diversity of their participants, innovative in the experiential learning they provide and caring authentically for the youth they serve. She was instrumental in the development and production of the Maker Mob - a traveling maker party made of museums and organizations providing free activities at community events. In her current role as an Advisory Committee member, she has ensured our decisions are in the best interests of the community of educators in the network.

\n

\n
\n

Greg McVerry

\n

Greg McVerry is an Ed-Tech entrepreneur, teacher, and digital inclusion advocate. He works as an Associate Professor of Education at Southern Connecticut State University. He has been active in the internet health movement as a Club Captain and a technical contributor. He is a member of our first cohort of \"Network50.”

\n

Greg drives the Internet health mission forward through his contributions as a participation lead, Mozilla Club Captain, curriculum tester, and Thimble champion. As a teacher, Greg naturally thinks about how our tools and curriculum will be received by learners. His thoughtful feedback about how Thimble is used in learning contexts helped us make important decisions about the user experience, the feature set, and the curricular content. He has been an active tester of our curriculum and has made valuable contributions, helping to increase the overall quality. He has taken many of the principles mentioned above into an Ed-Tech startup he founded to create technologies that develop the instructional capacity of teachers. Finally, Greg is one of the most active network members in Github, demonstrating a strong commitment to working and learning in the open.

\n

\n
\n

Harry Smith

\n

Harry Smith is an outstanding youth leader in our network, a committed volunteer and a student in Lancaster, UK. He has been active in the internet health movement as a MozFest volunteer. He is a member of our first cohort of \"Network50.”

\n

Harry is one of our youngest community members and despite his youth, has already been a contributor for many years. His work is invaluable in creating connections between youth and science - an area that generally doesn’t get enough attention. He was an active participant in the Campus Campaign as well as Mozilla Study Groups. He helped deliver the Youth Zone Program at MozFest in 2015, teaching young people how to read, write and participate online. As a long-time MozFest volunteer, he has contributed to the success of the festival over the years. He is a passionate youth advocate, and his encouragement is leading other young people to become contributors to the Internet health movement, tools and programs.

\n

\n
\n

Ian O'Byrne

\n

Ian O'Byrne is an educator, researcher, and entrepreneur. His research examines the literacy practices of individuals as they read, write, and communicate in online and hybrid spaces. He is currently an Assistant Professor of Literacy Education at the College of Charleston. He is a member of our first cohort of \"Network50.”

\n

Ian has been an active and engaged contributor on digital inclusion, web literacy, and open credentialing issues. He has actively contributed on evolving Mozilla’s Web Literacy work in education settings. He was also critical to creating and updating the Web Literacy Map and paper, which serves as the foundation for global digital inclusion efforts. For the Web Literacy Map 2.0 launched most recently, he collaborated and contributed content, research, and writing to the web literacy white paper and the structure of the new map.  Finally, he has been a key thought partner around the use of Digital Badges for Web Literacy.

\n

\n
\n

Charles Canario

\n

Charles Canario works at The James Baldwin School as a college coach and is an educator and a digital equity advocate. He has been active in the internet health movement as a Hive NYC member and is part of our first cohort of \"Network50.”

\n

As a young mentor and facilitator, Charles has been an exceptional leader within Hive NYC, initially in his role as a youth leader at Hive member organization Global Action Project, and most recently as an independent community member.  He brings a strong social justice lens to the Internet health movement, always pushing Mozilla to think deeper about its efforts towards diversity, inclusion, and equity.  Over the past year, he has worked closely with Hive NYC staff to lead online privacy and web literacy activities at community events throughout the city.  Charles has also contributed collaboratively on a new online privacy curriculum that is being developed specifically towards communities that aren't always reached in the technology field, such as immigrant and undocumented communities, youth of color, and young people from under-resourced schools.

\n

\n
\n

Vladan Joler

\n

Vladan Joler is a social justice advocate, activist, and a professor of new media at the University of Novi Sad and founder of Share Foundation, an organization that is dedicated to protecting the rights of Internet citizens. He is a member of our first cohort of \"Network50.”

\n

Vladan is a collaborator and thought partner on the topic of privacy and security as well as decentralization decentralization, especially through alternative forms of networks, and how it relates to the Internet of Things. He participated in the first Mozilla-organized IoT event and developed a stream of research and prototyping around privacy. He then furthered these explorations by leading a participant group at follow-up events. His work has generated actionable insights about anonymity and modes of controlling connectivity, ranging from the Dark Temple to the Wayback Privacy Machine. He regularly publishes reflections on privacy and internet activism that contribute to our common understanding of advocacy, such as essays on Facebook’s algorithms and alternative forms of networks in Cuba. He is also developing curriculum and a university partnership that could contribute to growing new leaders in this space.

\n

\n
\n

Dennis Ndegwa

\n

Dennis Ndegwa is a technology professional, researcher and open data advocate. He is currently an Open Data Fellow at the ICT Authority, Government of Kenya. He has been active in the internet health movement as a Mozilla Rep and as an Open Researcher. He is a member of our first cohort of \"Network50.”

\n

Dennis is an integral part of the Mozilla community in East Africa, having served as a Mozilla Rep for some time, and now as a researcher with the Digital Skills Observatory - a project that aims to find out how much equipping low-income earners (in Kenya) with digital skills will assist in improving their lives. He has been a critical reason for the success of the DSO project, helping design and develop 4 digital skills workshops and then bringing teams together to execute these workshops. He works closely with, leads, and learns from a community of practitioners and volunteers, and has learned to do this work in an open, transparent and thorough manner.

\n

\n
\n

Eva Constantaras

\n

Eva Constantaras is a journalist with Internews, specializing in investigative data journalism, specially as a tool to enhance transparency. She has been active in the internet health movement and a played an active role in the delivery of MozFest 2016. She is a member of our first cohort of \"Network50.”

\n

Eva is an open-journalist, open practices advocate and an ardent supporter and a member of the open news network; she is also building the European open news network through support, advocacy and mentoring. Eva conducts trainings around the world and seeks out ways to connect the international community of media technologists. She also models open practices - never shying away from challenging situations or offering tough, critical feedback. Eva valuable in improving our work with the international journalism community, and has been crucial to expanding the relevance of MozFest to this community. She has invited and recruited several international journalists to the event, and has helped prototype and develop sessions last year and this year.

\n

\n
\n

Su Adams

\n

Su Adams is an entrepreneur, freelance educator, and a digital inclusion activist. She has been active in the Mozilla community as a Mozilla Clubs Regional Coordinator and MozFest contributor. She is a member of our first cohort of \"Network50.”

\n

Su is always challenging the education norms, culture, and processes, pushing for them to be more open - and work in the open. She worked hard to bring the badging culture to school, and the curriculum. She has served as a Regional Coordinator for the last two years, on-boarding new club captains and providing continued support to ensure the ongoing success of clubs. She has been a long-time volunteer at MozFest, and was instrumental in designing a learning space at MozFest called Demystify the Web, providing opportunities for support, sharing, and learning about tools and methods for both new and existing educators. Su is a deeply committed contributor to the Open Movement as a mentor for CoderDojo and #a11yhacks.

\n

\n
\n

Faye Tandog

\n

Faye Tandog is a software professional and an active member of the Philippines technical community. She has been active in the Mozilla community in a variety of roles over the years. She is a member of our first cohort of \"Network50.”

\n

Faye has been a long-standing contributor to the Mozilla community both in the Philippines and globally. She has served as a Firefox Student Ambassador, as a leader of the Women and Mozilla initiative in the Philippines, and as a Mozilla Rep, receiving worldwide recognition repeatedly for her outstanding contributions in that role. She also served as an adviser to the global FSA program and is now a member of the worldwide Campus Advisory Committee for Mozilla Campus Clubs. As part of the mentorship program, under the Open Project, she's working to create curriculum and resources collaboratively to train student leaders. She is a leader in the Digital Inclusion and Web Literacy space generally, having served as a facilitator of MakerSpace Manila. The Internet health movement is stronger because of the commitment and efforts of young leaders like her.

\n

\n
\n

Amy Lee

\n

Amy Lee is a microbiologist, bioinformatician, and an Open Science advocate, currently working as a researcher analyzing large genomic data to understand immunity and infection at the University of British Columbia. She has been active in the internet health movement as a Study Group Lead. She is a member of our first cohort of \"Network50.”

\n

Amy has been critical to the success of our Mozilla Science Lab, building and leading the first Study Group. Amy's passion for supporting peer-to-peer learning really set the Science Lab in motion - helping model how local leadership can carry the mission forward. As the first Study Group Lead, Amy had to evolve a model of how study groups would operate, and what these groups can expect from the Study Group Lead. She has developed and delivered high-quality programs and curriculum, built a community and is now helping, inspiring and mentoring others to succeed. She has also advanced our working open mission by developing curriculum and participating in events that show others how to work openly.  She's been a dedicated supporter and collaborator, across the Study Group program, Open Science Leadership Summit, and the main MozFest stage.

\n

\n
\n

Priyanka Nag

\n

Priyanka Nag is a technology professional, open source advocate and an integral member of the Mozilla India community. She has been active in the internet health movement in a variety of roles over the years. She is a member of our first cohort of \"Network50.”

\n

Priyanka is a long-term contributor to the Internet health and Open Source movement in India, and has a long history of contribution, at Mozilla and also with the Wikimedia Foundation. Within Mozilla, she has been actively engaged as a MozFest volunteer. Over the years as a MozFest advocate she has brought many people from the Mozilla Global community to MozFest to learn about our issues, organize and stimulate their own communities to engage with issues that are critical to an open, accessible, and transparent web. Priyanka has been a great resource to new contributors, helping them connect with people, tools and resources within Mozilla and beyond.

\n

\n
\n

Caitlin Stanton

\n

Caitlin Stanton is an entrepreneur, a young digital activist and a freshman at Cornell University. She has been active in the internet health movement as a partner and learning advocate. She is a member of our first cohort of \"Network50.”

\n

Caitlin co-founded def hacks(), a 24 hour hackathon designed for high school students, by high school students, with her co-founder Emily Redler, as a method for helping young people learn to code in a supportive environment while gaining access and mentorship from professionals in digital fields. She approached Mozilla as a partner to bring more knowledge about why open practices matter to hackathon participants. She grew def hacks() to several new cities, including new York, San Francisco, Seattle, Boston, and London, after its first year and then mentored others to take the reigns as she entered college last fall. Her commitment to digital activism is also illustrated by her leadership roles with the PixieHacks hackathon and Women in Computing at Cornell. Through her assorted contributions, she has demonstrated outstanding commitment to supporting her peers as they seek to learn and develop their coding, creativity and collaboration skills.

\n

\n
\n

Randy Macdonald

\n

Randy Macdonald is a teacher and networked education activist. He currently works as a Program Manager at the Technology Association of Oregon Foundation. He has been active in the internet health movement as a Mozilla Club Captain. He is a member of our first cohort of \"Network50.”

\n

Randy demonstrates a clear commitment to the Internet health through efforts to teach young people to read, write, and participate on the web. He currently directs an initiative that provides STEM-based after school programs for youth in Oregon. He also trains others to teach computational and design-based thinking skills for solving community problems using mobile technology. He has been an active participant in web literacy leaders training and in integrating badges in afterschool and informal learning environments. His work with high school-age youth has contributed greatly to our common understanding of out-of-school time programming and digital credentials. He is launching 10 Mozilla Clubs focused on teaching web literacy skills to youth throughout Oregon, and as a Regional Coordinator aims to expand the program beyond his local community.

\n

\n
\n

Georgia Bullen

\n

Georgia Bullen is a civic innovator and open technology advocate. She currently works as the Director of Tech Projects at new America's Open Technology Institute. She has been active in the internet health movement as a MozFest volunteer, a mentor with the Open Web Fellowship program, and a collaborator in the fight to protect Net Neutrality worldwide. She is a member of our first cohort of \"Network50.”

\n

Georgia is a strong advocate for open data practices and transparency, and is deeply engaged in the global open internet fight. She has been a long-term activist in the Internet health movement, and Mozilla, both through her work with OTI and as an individual who seems to have her finger on all the pulses around open internet issues. She's very passionate about issues like copyright, net neutrality and community engagement to ensure fair access to a high-quality internet experience. As a mentor for one of our Open Web Fellows, she both guided the fellow's project at MeasurementLab, and help the fellow navigate the confusing world of internet policy and advocacy. She's an advocate for women in technology, and works to connect people to raise the profile of their work, and make the whole bigger than the sum of its parts.

\n

\n
\n

William Duyck (FuzzyFox)

\n

William Duyck (FuzzyFox) is a technologist who, in his own words, ‘wants to make the web a better place for the average user, to help them on their journeys to web literacy and participatory culture, and make great tools to support them in their everyday lives.’ He has been active in the internet health movement as a Mozilla Rep, an intern and a MozFest volunteer. He is a member of our first cohort of \"Network50.”

\n

FuzzyFox has been an advocate for all things open since he was 14 years old. For many years, he has volunteered his time and helped make MozFest a success every year. He's been an active community member, presenting and sharing his work with others at conferences such as FOSDEM. As a Mozilla Rep, he supports existing and future local community efforts and programs, and also recruits, supports and mentors future Mozilla Reps. He worked with Mozilla as an intern and during that time, led many train-the-trainer events and also supported different after school web literacy programs. After his internship, he went back to school to finish up his degree, to drive the open source community forward for years to come.

\n

\n
\n

Paul Oh

\n

Paul Oh is an educator, a frequent blogger and long-distance collaborator who is used to open forms of production and sharing, especially in his technology and community-building work. He currently works as the Senior Director at Teaching Channel. He has been active in the internet health movement as the co-producer of the Mozilla Curriculum Workshop webcast. He is a member of our first cohort of \"Network50.”

\n

Paul is a long-time champion of web literacy. He pushed the National Writing Project (NWP), during his work there, to champion web literacy and online composition as key forms of knowledge and production for the network. He inspires teachers to be more open in their teaching and learning. Most importantly, he strives to develop diverse and inclusive communities of practice wherever he works and, especially in his current and past role, helped manage widely distributed networks of practice that decentralized power into the hands of innovative teachers and their students. His work is dedicated to surfacing others' processes and successes in hope of helping educators replicate each other's best work.

\n

\n
\n

Mmaki Jantjies

\n

Mmaki Jantjies works as the Head of the Department, Information Systems at the University of the Western Cape, and is a committed advocate and contributor to technology-for-development. She has been active in the internet health movement asa Regional Coordinator. She is a member of our first cohort of \"Network50.”

\n

Mmaki is an experienced teacher and technology professor and serves the network as the Regional Coordinator of the Mozilla Clubs for Women and Girls Program in Cape Town South Africa. In that role, she is helping coordinate five clubs in one province and starting new clubs in two other provinces. The clubs she organizes enables female students at the University of Western Cape to teach web literacy to girls in local high schools and develop their leadership skills. Her work increases digital literacy and also helps girls and women in her community develop the required agency to implement the change they dream of and visualize.

\n

", - "signup": 4 - } - }, - { - "model": "landingpage.landingpage", - "pk": 8, - "fields": { - "header": "Share your Feedback", - "content": "

", - "signup": null - } - }, - { - "model": "landingpage.landingpage", - "pk": 11, - "fields": { - "header": "Tech Policy Fellowship", - "content": "

Mozilla Tech Policy Fellowship

\n

The Mozilla Tech Policy Fellowship brings together tech policy experts from around the world to participate in policy efforts to improve the health of the Internet. Find more details about the fellowship here.

\n

Tech Policy Fellows

\n

\n\n

\n

\n
\n

Alan Davidson

\n

\"Alan

\n

Alan Davidson will work to produce a census of major Internet policy risks and will engage in advocacy and educational strategy to minimize those risks. Alan is also a Fellow at New America in Washington, D.C. Until January 2017, he served as the first Director of Digital Economy at the U.S. Department of Commerce and a Senior Advisor to the Secretary of Commerce. Prior to joining the department, Davidson was the director of the Open Technology Institute at New America. Earlier, Davidson opened Google’s Washington policy office in 2005 and led the company’s public policy and government relations efforts in North and South America. He was previously Associate Director of the Center for Democracy and Technology. Alan has a bachelor’s degree in mathematics and computer science and a master’s degree in technology and policy from the Massachusetts Institute of Technology (MIT). He is a graduate of Yale Law School.

\n

\n
\n

Amina Fazlullah

\n

\"Amina

\n
Image courtesy of New America
\n

Amina Fazlullah will work to promote policies that support broadband connectivity in rural and vulnerable communities in the United States. Amina joins the fellowship from her most recent role as Policy Advisor to the National Digital Inclusion Alliance where she led efforts to develop policies that support broadband deployment, digital inclusion, and digital equity efforts across the United States. Amina has worked on a broad range of Internet policy issues including Universal Service, consumer protection, antitrust, net neutrality, spectrum policy and children's online privacy. She has testified before Congress, the Federal Communications Commission, the Department of Commerce, and Federal Trade Commission. Amina was formerly the Benton Foundation's Director of Policy in Washington, D.C., where she worked to further government policies to address communication needs of vulnerable communities. Before that, Amina worked with the U.S. Public Interest Research Group, for the Honorable Chief Judge James M. Rosenbaum of the U.S. District Court of Minnesota, and at the Federal Communications Commission. She is graduate of the University of Minnesota Law School and Pennsylvania State University.

\n

\n
\n

Camille Fischer

\n

\"Camille

\n

Camille Fischer will be working to promote individual rights to privacy, security, and free speech on the Internet. In the last year of the Obama Administration, Camille led the National Economic Council’s approach to consumers’ economic and civil rights on the Internet and in emerging technologies. She represented consumers’ voices in discussions with other federal agencies regarding law enforcement access to data, including encryption and international law enforcement agreements. She has run commercial privacy and security campaigns, like the BuySecure Initiative to increase consumers’ financial security, and also worked to promote an economic voice within national security policy and to advocate for due process protections within surveillance and digital access reform. Before entering the government as a Presidential Management Fellow, Camille graduated from Georgetown University Law Center where she wrote state legislation for the privacy-protective commercial use of facial recognition technology. Camille is also an amateur photographer in D.C.

\n

\n
\n

Caroline Holland

\n

\"Caroline

\n

Caroline Holland will be working to to promote a healthy internet by exploring current competition issues related to the Internet ecosystem. Caroline served most recently as Chief Counsel for Competition Policy and Intergovernmental Relations at the U.S. Department of Justice Antitrust Division. In that role, she was involved in several high-profile matters while overseeing the Division’s competition policy and advocacy efforts, interagency policy initiatives, and congressional relations. Caroline previously served as Chief Counsel and Staff Director of the Senate Antitrust Subcommittee where she advised the committee chairmen on a wide variety of competition issues related to telecommunications, technology, and intellectual property. Before taking on this role, she was a counsel on the Senate Judiciary Committee and an attorney in private practice focusing on public policy and regulatory work. Caroline holds a J.D. from Georgetown University Law Center and a B.A. in Public Policy from Trinity College in Hartford, Connecticut. Between college and law school, Caroline served in the Antitrust Division as an honors paralegal and as Clerk of the Senate Antitrust Subcommittee.

\n

\n
\n

Linet Kwamboka

\n

\"Linet

\n

Linet Kwamboka will work on understanding the policies that guide data collection and dissemination in East Africa (Kenya, Uganda, Tanzania and Rwanda). Through this, she aims to publish policy recommendations on existing policies, proposed policy amendments, and a report outlining her findings. Linet is the Founder and CEO of DataScience LTD, which builds information systems to generate and use data to discover intelligent insights about people, products, and services for resource allocation and decision making. She was previously the Kenya Open Data Initiative Project Coordinator for the Government of Kenya at the Kenya ICT Authority. Linet is also a director of the World Data Lab–Africa, working to make data personal, tangible and actionable to help citizens make better informed choices about their lives. She also consults with the UNDP in the Strengthening Electoral Processes in Kenya Project, offering support to the Independent Electoral Boundaries Commission in information systems and technology. She has worked at the World Bank as a GIS and Technology Consultant and was a Software Engineering Fellow at Carnegie Mellon University, Pittsburgh. Her background is in computer science, data analysis, and Geographical Information Systems. Linet is a recognized unsung hero by the American Embassy in Kenya in her efforts to encourage more women into technology and computing, has been a finalist in the Bloomberg award of global open data champions and is a member of the Open Data Institute Global Open Data Leaders’ Network.

\n

\n
\n

Terah Lyons

\n

\"Terah

\n

Terah Lyons will work on advancing policy and governance around the future of machine intelligence, with a specific focus on coordination in international governance of AI. Her work targets questions related to the responsible development and deployment of AI and machine learning, including how society can minimize the risks of AI while maximizing its benefits, and what AI development and advanced automation means for humankind across cultural and political boundaries. Terah is a former Policy Advisor to the U.S. Chief Technology Officer in the White House Office of Science and Technology Policy (OSTP). She most recently led a policy portfolio in the Obama Administration focused on machine intelligence, including AI, robotics, and intelligent transportation systems. In her work at OSTP, Terah helped establish and direct the White House Future of Artificial Intelligence Initiative, oversaw robotics policy and regulatory matters, led the Administration’s work from the White House on civil and commercial unmanned aircraft systems/drone integration into the U.S. airspace system, and advised on Federal automated vehicles policy. She also advised on issues related to diversity and inclusion in the technology industry and entrepreneurial ecosystem. Prior to her work at the White House, Terah was a Fellow with the Harvard School of Engineering and Applied Sciences based in Cape Town, South Africa. She is a graduate of Harvard University, where she currently sits on the Board of Directors of the Harvard Alumni Association.

\n

\n
\n

Marilia Monteiro

\n

\"Marilia

\n

Marilia Monteiro will be analyzing consumer protection and competition policy to contribute to the development of sustainable public policies and innovation. From 2013-15, she was Policy Manager at the Brazilian Ministry of Justice’s Consumer Office coordinating public policies for the consumer protection in digital markets and law enforcement actions targeting ISP and Internet application. She has researched the intersection between innovation technologies and society in different areas: current democratic innovations in Latin America regarding e-participation at the Wissenschaftszentrum Berlin für Sozialforschung and the development of public policies on health privacy and data protection at the \"Privacy Brazil\" project with the Internet Lab in partnership with Ford Foundation in Brazil. She is a board member at Coding Rights, a Brazilian-born, women-led, think-and-do tank and active in Internet Governance fora. Marilia holds a Master in Public Policy from the Hertie School of Governance in Berlin focusing on policy analysis, a bachelor in Law from Fundação Getulio Vargas School of Law in Rio de Janeiro and specialises in digital rights.

\n

\n
\n

Jason Schultz

\n

\"Jason

\n

Jason Schultz will analyze the impacts and effects of new technologies such as artificial intelligence/machine learning and the Internet of Things through the lenses of consumer protection, civil liberties, innovation, and competition. His research aims to help policymakers navigate these important legal concerns while still allowing for open innovation and for competition to thrive. Jason is a Professor of Clinical Law, Director of NYU's Technology Law & Policy Clinic, and Co-Director of the Engelberg Center on Innovation Law & Policy. His clinical projects, research, and writing primarily focus on the ongoing struggles to balance traditional areas of law such as intellectual property, consumer protection, and privacy with the public interest in free expression, access to knowledge, civil rights, and innovation in light of new technologies and the challenges they pose. During the 2016-2017 academic year, Jason was on leave at the White House Office of Science and Technology Policy, where he served as Senior Advisor on Innovation and Intellectual Property to former U.S. Chief Technology Officer Megan Smith. With Aaron Perzanowski, he is the author of The End of Ownership: Personal Property in the Digital Economy (MIT Press 2016), which argues for retaining consumer property rights in a marketplace that increasingly threatens them. Prior to joining NYU, Jason was an Assistant Clinical Professor of Law and Director of the Samuelson Law, Technology & Public Policy Clinic at the UC Berkeley School of Law (Boalt Hall). Before joining Boalt Hall, he was a Senior Staff Attorney at the Electronic Frontier Foundation and before that practiced intellectual property law at the firm of Fish & Richardson, PC. He also served as a clerk to the Honorable D. Lowell Jensen of the Northern District of California. He is a member of the American Law Institute.

\n

\n
\n

Gigi Sohn

\n

\"Gigi

\n

Gigi Sohn will be working to promote an open Internet in the United States. She is one of the nation’s leading public advocates for open, affordable, and democratic communications networks. Gigi is also a Distinguished Fellow at the Georgetown Law Institute for Technology Law & Policy and an Open Society Foundations Leadership in Government Fellow. For nearly 30 years, Gigi has worked across the United States to defend and preserve the fundamental competition and innovation policies that have made broadband Internet access more ubiquitous, competitive, affordable, open, and protective of user privacy. Most recently, Gigi was Counselor to the former Chairman of the U.S. Federal Communications Commission, Tom Wheeler, who she advised on a wide range of Internet, telecommunications and media issues. Gigi was named by the Daily Dot in 2015 as one of the “Heroes Who Saved the Internet” in recognition of her role in the FCC’s adoption of the strongest-ever net neutrality rules. Gigi co-founded and served as CEO of Public Knowledge, the leading communications policy advocacy organization. She was previously a Project Specialist in the Ford Foundation’s Media, Arts and Culture unit and Executive Director of the Media Access Project, the first public interest law firm in the communications space. Gigi holds a B.S. in Broadcasting and Film, Summa Cum Laude, from the Boston University College of Communication and a J.D. from the University of Pennsylvania Law School.

\n

\n
\n

Cori Zarek

\n

\"Cori

\n

Cori Zarek is the Senior Fellow leading the Tech Policy Fellows team and serving as a liaison with the Mozilla Foundation. Her work as a fellow will focus on the intersection of tech policy and transparency. Before joining Mozilla, Cori was Deputy U.S. Chief Technology Officer at the White House where she led the team's work to build a more digital, open, and collaborative government. Cori also coordinated U.S. involvement with the global Open Government Partnership, a 75-country initiative driving greater transparency and accountability around the world. Previously, she was an attorney at the U.S. National Archives, working on open government and freedom of information policy. Before joining the U.S. government, Cori was the Freedom of Information Director at The Reporters Committee for Freedom of the Press where she assisted journalists with legal issues, and she also practiced for a Washington law firm. Cori received her B.A. from the University of Iowa where she was editor of the student-run newspaper, The Daily Iowan. Cori also received her J.D. from the University of Iowa where she wrote for the Iowa Law Review and The Des Moines Register. She was inducted into the Freedom of Information Hall of Fame in 2016. Cori is also the President of the D.C. Open Government Coalition and teaches a media law class at American University.

", - "signup": null - } - }, - { - "model": "landingpage.landingpage", - "pk": 1, - "fields": { - "header": "Landing page placeholder", - "content": "

WAIT STOP

\n

Don't edit this page. It's a placeholder. Go back and click on the plus icon next to \"Opportunities\" in the list to edit other sub-pages.

", - "signup": 1 - } - }, - { - "model": "landingpage.landingpage", - "pk": 13, - "fields": { - "header": "Mozilla Information Trust Initiative", - "content": "

We are investing in people, programs, and projects that disrupt misinformation online.

\n

Mozilla is working to surface new ideas that seek to address misinformation, cognitive bias, “belief echos,” and algorithmic “filter bubbles.” The initiative will launch efforts in four areas: products, research, visualization, and literacy. If you would like to help with this initiative, or receive updates as we announce the specifics, just use the sign-up form on the right.

\n\n

Why Mozilla

\n

The spread of misinformation violates nearly every tenet of the Mozilla Manifesto, our guiding doctrine. Mozilla has a long history of putting community and principles first, and devoting resources to urgent issues—our Firefox browser is just one example. Mozilla is committed to building tolerance rather than hate, and building technology that can protect individuals and the web.

\n

So we’re drawing on the unique depth and breadth of the Mozilla Network—from journalists and technologists to policymakers and scientists—to build functional products, research, and community-based solutions.

\n

Specifically, we’re advancing work in these areas:

\n\n\n\n\n\n\n\n
\"browser\n

\n

Product

\n
\n

Mozilla’s Open Innovation team will work with like-minded technologists and artists to develop technology that combats misinformation.

\n

Mozilla will partner with global media organizations to do this, and also double down on our existing product work in the space, like Pocket, Focus, and Coral. Coral is a Mozilla project that builds open-source tools to make digital journalism more inclusive and more engaging.

\n\n\n\n\n\n\n\n
\"user\n

\n

Literacy

\n
\n

We can’t solve misinformation with technology alone—we also need to educate and empower Internet users, as well as those leading innovative literacy initiatives.

\n

Mozilla will develop a web literacy curriculum that addresses misinformation, and will continue investing in existing projects like the Mission: Information teaching kit.

\n\n\n\n\n\n\n\n
\"research\n

\n

Research

\n
\n

Misinformation in the digital age is a relatively new phenomenon. To solve such a thorny problem, we first need to fully understand it.

\n

Later this year, Mozilla will be releasing original research on how misinformation impacts users’ experiences online. We will be drawing on a dataset of user-level browsing data gathered during the 2016 U.S. elections.

\n\n\n\n\n\n\n\n
\"light\n

\n

Creative interventions

\n
\n

Mozilla will field and fund pitches from technologists and artists who are combatting misinformation using various mediums, including virtual reality and augmented reality. It’s an opportunity to apply emerging technology to one of today’s most pressing issues.

\n

 

", - "signup": 5 - } - }, - { - "model": "highlights.highlight", - "pk": 1, - "fields": { - "title": "MozFest 2017 Call for Proposals", - "description": "MozFest is the world's leading festival for the open Internet movement. It will be held October 27-29, 2017 at Ravensbourne College, London. Anyone may submit a proposal for MozFest 2017. MozFest sessions cover a wide range of topics, but share two important qualities: they are interactive and inclusive.", - "link_label": "Submit a proposal", - "link_url": "https://mozillafestival.org/", - "image": "images/highlights/mozfest-2017-call-for-proposals_1500050486.jpg", - "footer": "", - "publish_after": "2017-07-13T18:05:30Z", - "expires": null, - "order": 4 - } - }, - { - "model": "highlights.highlight", - "pk": 2, - "fields": { - "title": "Fellowships that Empower Leaders", - "description": "We provide funding and exciting project-based opportunities to professionals doing game-changing work at the intersection of media, science, security, advocacy, and technology.", - "link_label": "Be a fellow", - "link_url": "https://network.mozilla.org/opportunity/fellowships", - "image": "", - "footer": "", - "publish_after": "2017-07-13T18:07:14Z", - "expires": null, - "order": 2 - } - }, - { - "model": "highlights.highlight", - "pk": 3, - "fields": { - "title": "Internet Health Report", - "description": "Is the Internet getting healthier? Is it under threat? Do we all have a voice on the web? Mozilla’s Internet Health Report is an open source initiative that combines research from multiple sources to document what’s healthy and unhealthy.", - "link_label": "Read the report", - "link_url": "https://network.mozilla.org/opportunity/internet-health-report", - "image": "images/highlights/a-third_1497994010.jpg", - "footer": "", - "publish_after": "2017-07-13T18:07:42Z", - "expires": null, - "order": 3 - } - }, - { - "model": "highlights.highlight", - "pk": 4, - "fields": { - "title": "Leadership Training for Collaboration", - "description": "Learn the basics of participation, collaboration, and sharing on community-driven projects. Discover what working open can do for your project.", - "link_label": "Be a leader", - "link_url": "https://network.mozilla.org/opportunity/training/", - "image": "images/highlights/leadership-training-for-collaboration_1502989220.jpg", - "footer": "", - "publish_after": "2017-08-17T10:00:17Z", - "expires": null, - "order": 1 - } - }, - { - "model": "milestones.milestone", - "pk": 1, - "fields": { - "headline": "Global Sprint", - "photo": "images/milestones/global-sprint_1501699483.png", - "start_date": "2017-08-17", - "end_date": "2017-08-22", - "description": "Testing this thing. Yep! Yep!", - "link_url": "http://mozillapulse.org", - "link_label": "random link" - } - }, - { - "model": "milestones.milestone", - "pk": 2, - "fields": { - "headline": "An old event", - "photo": "images/milestones/an-old-event_1501877607.jpg", - "start_date": "2017-08-01", - "end_date": "2017-08-02", - "description": "Description of old event", - "link_url": "https://mozilla.org", - "link_label": "Some link label" - } - }, - { - "model": "auth.permission", - "fields": { - "name": "Can add log entry", - "content_type": [ - "admin", - "logentry" - ], - "codename": "add_logentry" - } - }, - { - "model": "auth.permission", - "fields": { - "name": "Can change log entry", - "content_type": [ - "admin", - "logentry" - ], - "codename": "change_logentry" - } - }, - { - "model": "auth.permission", - "fields": { - "name": "Can delete log entry", - "content_type": [ - "admin", - "logentry" - ], - "codename": "delete_logentry" - } - }, - { - "model": "auth.permission", - "fields": { - "name": "Can add user", - "content_type": [ - "auth", - "user" - ], - "codename": "add_user" - } - }, - { - "model": "auth.permission", - "fields": { - "name": "Can change user", - "content_type": [ - "auth", - "user" - ], - "codename": "change_user" - } - }, - { - "model": "auth.permission", - "fields": { - "name": "Can delete user", - "content_type": [ - "auth", - "user" - ], - "codename": "delete_user" - } - }, - { - "model": "auth.permission", - "fields": { - "name": "Can add group", - "content_type": [ - "auth", - "group" - ], - "codename": "add_group" - } - }, - { - "model": "auth.permission", - "fields": { - "name": "Can change group", - "content_type": [ - "auth", - "group" - ], - "codename": "change_group" - } - }, - { - "model": "auth.permission", - "fields": { - "name": "Can delete group", - "content_type": [ - "auth", - "group" - ], - "codename": "delete_group" - } - }, - { - "model": "auth.permission", - "fields": { - "name": "Can add permission", - "content_type": [ - "auth", - "permission" - ], - "codename": "add_permission" - } - }, - { - "model": "auth.permission", - "fields": { - "name": "Can change permission", - "content_type": [ - "auth", - "permission" - ], - "codename": "change_permission" - } - }, - { - "model": "auth.permission", - "fields": { - "name": "Can delete permission", - "content_type": [ - "auth", - "permission" - ], - "codename": "delete_permission" - } - }, - { - "model": "auth.permission", - "fields": { - "name": "Can add content type", - "content_type": [ - "contenttypes", - "contenttype" - ], - "codename": "add_contenttype" - } - }, - { - "model": "auth.permission", - "fields": { - "name": "Can change content type", - "content_type": [ - "contenttypes", - "contenttype" - ], - "codename": "change_contenttype" - } - }, - { - "model": "auth.permission", - "fields": { - "name": "Can delete content type", - "content_type": [ - "contenttypes", - "contenttype" - ], - "codename": "delete_contenttype" - } - }, - { - "model": "auth.permission", - "fields": { - "name": "Can add session", - "content_type": [ - "sessions", - "session" - ], - "codename": "add_session" - } - }, - { - "model": "auth.permission", - "fields": { - "name": "Can change session", - "content_type": [ - "sessions", - "session" - ], - "codename": "change_session" - } - }, - { - "model": "auth.permission", - "fields": { - "name": "Can delete session", - "content_type": [ - "sessions", - "session" - ], - "codename": "delete_session" - } - }, - { - "model": "auth.permission", - "fields": { - "name": "Can add internet health issue", - "content_type": [ - "people", - "internethealthissue" - ], - "codename": "add_internethealthissue" - } - }, - { - "model": "auth.permission", - "fields": { - "name": "Can change internet health issue", - "content_type": [ - "people", - "internethealthissue" - ], - "codename": "change_internethealthissue" - } - }, - { - "model": "auth.permission", - "fields": { - "name": "Can delete internet health issue", - "content_type": [ - "people", - "internethealthissue" - ], - "codename": "delete_internethealthissue" - } - }, - { - "model": "auth.permission", - "fields": { - "name": "Can add affiliation", - "content_type": [ - "people", - "affiliation" - ], - "codename": "add_affiliation" - } - }, - { - "model": "auth.permission", - "fields": { - "name": "Can change affiliation", - "content_type": [ - "people", - "affiliation" - ], - "codename": "change_affiliation" - } - }, - { - "model": "auth.permission", - "fields": { - "name": "Can delete affiliation", - "content_type": [ - "people", - "affiliation" - ], - "codename": "delete_affiliation" - } - }, - { - "model": "auth.permission", - "fields": { - "name": "Can add person", - "content_type": [ - "people", - "person" - ], - "codename": "add_person" - } - }, - { - "model": "auth.permission", - "fields": { - "name": "Can change person", - "content_type": [ - "people", - "person" - ], - "codename": "change_person" - } - }, - { - "model": "auth.permission", - "fields": { - "name": "Can delete person", - "content_type": [ - "people", - "person" - ], - "codename": "delete_person" - } - }, - { - "model": "auth.permission", - "fields": { - "name": "Can add opportunity", - "content_type": [ - "opportunities", - "opportunity" - ], - "codename": "add_opportunity" - } - }, - { - "model": "auth.permission", - "fields": { - "name": "Can change opportunity", - "content_type": [ - "opportunities", - "opportunity" - ], - "codename": "change_opportunity" - } - }, - { - "model": "auth.permission", - "fields": { - "name": "Can delete opportunity", - "content_type": [ - "opportunities", - "opportunity" - ], - "codename": "delete_opportunity" - } - }, - { - "model": "auth.permission", - "fields": { - "name": "Can add news", - "content_type": [ - "news", - "news" - ], - "codename": "add_news" - } - }, - { - "model": "auth.permission", - "fields": { - "name": "Can change news", - "content_type": [ - "news", - "news" - ], - "codename": "change_news" - } - }, - { - "model": "auth.permission", - "fields": { - "name": "Can delete news", - "content_type": [ - "news", - "news" - ], - "codename": "delete_news" - } - }, - { - "model": "auth.permission", - "fields": { - "name": "Can add site", - "content_type": [ - "sites", - "site" - ], - "codename": "add_site" - } - }, - { - "model": "auth.permission", - "fields": { - "name": "Can change site", - "content_type": [ - "sites", - "site" - ], - "codename": "change_site" - } - }, - { - "model": "auth.permission", - "fields": { - "name": "Can delete site", - "content_type": [ - "sites", - "site" - ], - "codename": "delete_site" - } - }, - { - "model": "auth.permission", - "fields": { - "name": "Can add redirect", - "content_type": [ - "redirects", - "redirect" - ], - "codename": "add_redirect" - } - }, - { - "model": "auth.permission", - "fields": { - "name": "Can change redirect", - "content_type": [ - "redirects", - "redirect" - ], - "codename": "change_redirect" - } - }, - { - "model": "auth.permission", - "fields": { - "name": "Can delete redirect", - "content_type": [ - "redirects", - "redirect" - ], - "codename": "delete_redirect" - } - }, - { - "model": "auth.permission", - "fields": { - "name": "Can add Setting", - "content_type": [ - "conf", - "setting" - ], - "codename": "add_setting" - } - }, - { - "model": "auth.permission", - "fields": { - "name": "Can change Setting", - "content_type": [ - "conf", - "setting" - ], - "codename": "change_setting" - } - }, - { - "model": "auth.permission", - "fields": { - "name": "Can delete Setting", - "content_type": [ - "conf", - "setting" - ], - "codename": "delete_setting" - } - }, - { - "model": "auth.permission", - "fields": { - "name": "Can add Site permission", - "content_type": [ - "core", - "sitepermission" - ], - "codename": "add_sitepermission" - } - }, - { - "model": "auth.permission", - "fields": { - "name": "Can change Site permission", - "content_type": [ - "core", - "sitepermission" - ], - "codename": "change_sitepermission" - } - }, - { - "model": "auth.permission", - "fields": { - "name": "Can delete Site permission", - "content_type": [ - "core", - "sitepermission" - ], - "codename": "delete_sitepermission" - } - }, - { - "model": "auth.permission", - "fields": { - "name": "Can add Keyword", - "content_type": [ - "generic", - "keyword" - ], - "codename": "add_keyword" - } - }, - { - "model": "auth.permission", - "fields": { - "name": "Can change Keyword", - "content_type": [ - "generic", - "keyword" - ], - "codename": "change_keyword" - } - }, - { - "model": "auth.permission", - "fields": { - "name": "Can delete Keyword", - "content_type": [ - "generic", - "keyword" - ], - "codename": "delete_keyword" - } - }, - { - "model": "auth.permission", - "fields": { - "name": "Can add assigned keyword", - "content_type": [ - "generic", - "assignedkeyword" - ], - "codename": "add_assignedkeyword" - } - }, - { - "model": "auth.permission", - "fields": { - "name": "Can change assigned keyword", - "content_type": [ - "generic", - "assignedkeyword" - ], - "codename": "change_assignedkeyword" - } - }, - { - "model": "auth.permission", - "fields": { - "name": "Can delete assigned keyword", - "content_type": [ - "generic", - "assignedkeyword" - ], - "codename": "delete_assignedkeyword" - } - }, - { - "model": "auth.permission", - "fields": { - "name": "Can add Rating", - "content_type": [ - "generic", - "rating" - ], - "codename": "add_rating" - } - }, - { - "model": "auth.permission", - "fields": { - "name": "Can change Rating", - "content_type": [ - "generic", - "rating" - ], - "codename": "change_rating" - } - }, - { - "model": "auth.permission", - "fields": { - "name": "Can delete Rating", - "content_type": [ - "generic", - "rating" - ], - "codename": "delete_rating" - } - }, - { - "model": "auth.permission", - "fields": { - "name": "Can add Comment", - "content_type": [ - "generic", - "threadedcomment" - ], - "codename": "add_threadedcomment" - } - }, - { - "model": "auth.permission", - "fields": { - "name": "Can change Comment", - "content_type": [ - "generic", - "threadedcomment" - ], - "codename": "change_threadedcomment" - } - }, - { - "model": "auth.permission", - "fields": { - "name": "Can delete Comment", - "content_type": [ - "generic", - "threadedcomment" - ], - "codename": "delete_threadedcomment" - } - }, - { - "model": "auth.permission", - "fields": { - "name": "Can add Page", - "content_type": [ - "pages", - "page" - ], - "codename": "add_page" - } - }, - { - "model": "auth.permission", - "fields": { - "name": "Can change Page", - "content_type": [ - "pages", - "page" - ], - "codename": "change_page" - } - }, - { - "model": "auth.permission", - "fields": { - "name": "Can delete Page", - "content_type": [ - "pages", - "page" - ], - "codename": "delete_page" - } - }, - { - "model": "auth.permission", - "fields": { - "name": "Can add Rich text page", - "content_type": [ - "pages", - "richtextpage" - ], - "codename": "add_richtextpage" - } - }, - { - "model": "auth.permission", - "fields": { - "name": "Can change Rich text page", - "content_type": [ - "pages", - "richtextpage" - ], - "codename": "change_richtextpage" - } - }, - { - "model": "auth.permission", - "fields": { - "name": "Can delete Rich text page", - "content_type": [ - "pages", - "richtextpage" - ], - "codename": "delete_richtextpage" - } - }, - { - "model": "auth.permission", - "fields": { - "name": "Can add Link", - "content_type": [ - "pages", - "link" - ], - "codename": "add_link" - } - }, - { - "model": "auth.permission", - "fields": { - "name": "Can change Link", - "content_type": [ - "pages", - "link" - ], - "codename": "change_link" - } - }, - { - "model": "auth.permission", - "fields": { - "name": "Can delete Link", - "content_type": [ - "pages", - "link" - ], - "codename": "delete_link" - } - }, - { - "model": "auth.permission", - "fields": { - "name": "Can add Form", - "content_type": [ - "forms", - "form" - ], - "codename": "add_form" - } - }, - { - "model": "auth.permission", - "fields": { - "name": "Can change Form", - "content_type": [ - "forms", - "form" - ], - "codename": "change_form" - } - }, - { - "model": "auth.permission", - "fields": { - "name": "Can delete Form", - "content_type": [ - "forms", - "form" - ], - "codename": "delete_form" - } - }, - { - "model": "auth.permission", - "fields": { - "name": "Can add Field", - "content_type": [ - "forms", - "field" - ], - "codename": "add_field" - } - }, - { - "model": "auth.permission", - "fields": { - "name": "Can change Field", - "content_type": [ - "forms", - "field" - ], - "codename": "change_field" - } - }, - { - "model": "auth.permission", - "fields": { - "name": "Can delete Field", - "content_type": [ - "forms", - "field" - ], - "codename": "delete_field" - } - }, - { - "model": "auth.permission", - "fields": { - "name": "Can add Form entry", - "content_type": [ - "forms", - "formentry" - ], - "codename": "add_formentry" - } - }, - { - "model": "auth.permission", - "fields": { - "name": "Can change Form entry", - "content_type": [ - "forms", - "formentry" - ], - "codename": "change_formentry" - } - }, - { - "model": "auth.permission", - "fields": { - "name": "Can delete Form entry", - "content_type": [ - "forms", - "formentry" - ], - "codename": "delete_formentry" - } - }, - { - "model": "auth.permission", - "fields": { - "name": "Can add Form field entry", - "content_type": [ - "forms", - "fieldentry" - ], - "codename": "add_fieldentry" - } - }, - { - "model": "auth.permission", - "fields": { - "name": "Can change Form field entry", - "content_type": [ - "forms", - "fieldentry" - ], - "codename": "change_fieldentry" - } - }, - { - "model": "auth.permission", - "fields": { - "name": "Can delete Form field entry", - "content_type": [ - "forms", - "fieldentry" - ], - "codename": "delete_fieldentry" - } - }, - { - "model": "auth.permission", - "fields": { - "name": "Can add comment", - "content_type": [ - "django_comments", - "comment" - ], - "codename": "add_comment" - } - }, - { - "model": "auth.permission", - "fields": { - "name": "Can change comment", - "content_type": [ - "django_comments", - "comment" - ], - "codename": "change_comment" - } - }, - { - "model": "auth.permission", - "fields": { - "name": "Can delete comment", - "content_type": [ - "django_comments", - "comment" - ], - "codename": "delete_comment" - } - }, - { - "model": "auth.permission", - "fields": { - "name": "Can moderate comments", - "content_type": [ - "django_comments", - "comment" - ], - "codename": "can_moderate" - } - }, - { - "model": "auth.permission", - "fields": { - "name": "Can add comment flag", - "content_type": [ - "django_comments", - "commentflag" - ], - "codename": "add_commentflag" - } - }, - { - "model": "auth.permission", - "fields": { - "name": "Can change comment flag", - "content_type": [ - "django_comments", - "commentflag" - ], - "codename": "change_commentflag" - } - }, - { - "model": "auth.permission", - "fields": { - "name": "Can delete comment flag", - "content_type": [ - "django_comments", - "commentflag" - ], - "codename": "delete_commentflag" - } - }, - { - "model": "auth.permission", - "fields": { - "name": "Can add feature", - "content_type": [ - "features", - "feature" - ], - "codename": "add_feature" - } - }, - { - "model": "auth.permission", - "fields": { - "name": "Can change feature", - "content_type": [ - "features", - "feature" - ], - "codename": "change_feature" - } - }, - { - "model": "auth.permission", - "fields": { - "name": "Can delete feature", - "content_type": [ - "features", - "feature" - ], - "codename": "delete_feature" - } - }, - { - "model": "auth.permission", - "fields": { - "name": "Can add signup", - "content_type": [ - "landingpage", - "signup" - ], - "codename": "add_signup" - } - }, - { - "model": "auth.permission", - "fields": { - "name": "Can change signup", - "content_type": [ - "landingpage", - "signup" - ], - "codename": "change_signup" - } - }, - { - "model": "auth.permission", - "fields": { - "name": "Can delete signup", - "content_type": [ - "landingpage", - "signup" - ], - "codename": "delete_signup" - } - }, - { - "model": "auth.permission", - "fields": { - "name": "Can add landing page", - "content_type": [ - "landingpage", - "landingpage" - ], - "codename": "add_landingpage" - } - }, - { - "model": "auth.permission", - "fields": { - "name": "Can change landing page", - "content_type": [ - "landingpage", - "landingpage" - ], - "codename": "change_landingpage" - } - }, - { - "model": "auth.permission", - "fields": { - "name": "Can delete landing page", - "content_type": [ - "landingpage", - "landingpage" - ], - "codename": "delete_landingpage" - } - }, - { - "model": "auth.permission", - "fields": { - "name": "Can add nonce", - "content_type": [ - "social_django", - "nonce" - ], - "codename": "add_nonce" - } - }, - { - "model": "auth.permission", - "fields": { - "name": "Can change nonce", - "content_type": [ - "social_django", - "nonce" - ], - "codename": "change_nonce" - } - }, - { - "model": "auth.permission", - "fields": { - "name": "Can delete nonce", - "content_type": [ - "social_django", - "nonce" - ], - "codename": "delete_nonce" - } - }, - { - "model": "auth.permission", - "fields": { - "name": "Can add code", - "content_type": [ - "social_django", - "code" - ], - "codename": "add_code" - } - }, - { - "model": "auth.permission", - "fields": { - "name": "Can change code", - "content_type": [ - "social_django", - "code" - ], - "codename": "change_code" - } - }, - { - "model": "auth.permission", - "fields": { - "name": "Can delete code", - "content_type": [ - "social_django", - "code" - ], - "codename": "delete_code" - } - }, - { - "model": "auth.permission", - "fields": { - "name": "Can add user social auth", - "content_type": [ - "social_django", - "usersocialauth" - ], - "codename": "add_usersocialauth" - } - }, - { - "model": "auth.permission", - "fields": { - "name": "Can change user social auth", - "content_type": [ - "social_django", - "usersocialauth" - ], - "codename": "change_usersocialauth" - } - }, - { - "model": "auth.permission", - "fields": { - "name": "Can delete user social auth", - "content_type": [ - "social_django", - "usersocialauth" - ], - "codename": "delete_usersocialauth" - } - }, - { - "model": "auth.permission", - "fields": { - "name": "Can add association", - "content_type": [ - "social_django", - "association" - ], - "codename": "add_association" - } - }, - { - "model": "auth.permission", - "fields": { - "name": "Can change association", - "content_type": [ - "social_django", - "association" - ], - "codename": "change_association" - } - }, - { - "model": "auth.permission", - "fields": { - "name": "Can delete association", - "content_type": [ - "social_django", - "association" - ], - "codename": "delete_association" - } - }, - { - "model": "auth.permission", - "fields": { - "name": "Can add partial", - "content_type": [ - "social_django", - "partial" - ], - "codename": "add_partial" - } - }, - { - "model": "auth.permission", - "fields": { - "name": "Can change partial", - "content_type": [ - "social_django", - "partial" - ], - "codename": "change_partial" - } - }, - { - "model": "auth.permission", - "fields": { - "name": "Can delete partial", - "content_type": [ - "social_django", - "partial" - ], - "codename": "delete_partial" - } - }, - { - "model": "auth.permission", - "fields": { - "name": "Can add creator", - "content_type": [ - "creators", - "creator" - ], - "codename": "add_creator" - } - }, - { - "model": "auth.permission", - "fields": { - "name": "Can change creator", - "content_type": [ - "creators", - "creator" - ], - "codename": "change_creator" - } - }, - { - "model": "auth.permission", - "fields": { - "name": "Can delete creator", - "content_type": [ - "creators", - "creator" - ], - "codename": "delete_creator" - } - }, - { - "model": "auth.permission", - "fields": { - "name": "Can add entry", - "content_type": [ - "entries", - "entry" - ], - "codename": "add_entry" - } - }, - { - "model": "auth.permission", - "fields": { - "name": "Can change entry", - "content_type": [ - "entries", - "entry" - ], - "codename": "change_entry" - } - }, - { - "model": "auth.permission", - "fields": { - "name": "Can delete entry", - "content_type": [ - "entries", - "entry" - ], - "codename": "delete_entry" - } - }, - { - "model": "auth.permission", - "fields": { - "name": "Can add issue", - "content_type": [ - "issues", - "issue" - ], - "codename": "add_issue" - } - }, - { - "model": "auth.permission", - "fields": { - "name": "Can change issue", - "content_type": [ - "issues", - "issue" - ], - "codename": "change_issue" - } - }, - { - "model": "auth.permission", - "fields": { - "name": "Can delete issue", - "content_type": [ - "issues", - "issue" - ], - "codename": "delete_issue" - } - }, - { - "model": "auth.permission", - "fields": { - "name": "Can add tag", - "content_type": [ - "tags", - "tag" - ], - "codename": "add_tag" - } - }, - { - "model": "auth.permission", - "fields": { - "name": "Can change tag", - "content_type": [ - "tags", - "tag" - ], - "codename": "change_tag" - } - }, - { - "model": "auth.permission", - "fields": { - "name": "Can delete tag", - "content_type": [ - "tags", - "tag" - ], - "codename": "delete_tag" - } - }, - { - "model": "auth.permission", - "fields": { - "name": "Can add User profile", - "content_type": [ - "userprofile", - "userprofile" - ], - "codename": "add_userprofile" - } - }, - { - "model": "auth.permission", - "fields": { - "name": "Can change User profile", - "content_type": [ - "userprofile", - "userprofile" - ], - "codename": "change_userprofile" - } - }, - { - "model": "auth.permission", - "fields": { - "name": "Can delete User profile", - "content_type": [ - "userprofile", - "userprofile" - ], - "codename": "delete_userprofile" - } - }, - { - "model": "auth.permission", - "fields": { - "name": "Can add user bookmark", - "content_type": [ - "userprofile", - "userbookmark" - ], - "codename": "add_userbookmark" - } - }, - { - "model": "auth.permission", - "fields": { - "name": "Can change user bookmark", - "content_type": [ - "userprofile", - "userbookmark" - ], - "codename": "change_userbookmark" - } - }, - { - "model": "auth.permission", - "fields": { - "name": "Can delete user bookmark", - "content_type": [ - "userprofile", - "userbookmark" - ], - "codename": "delete_userbookmark" - } - }, - { - "model": "auth.permission", - "fields": { - "name": "Can add highlight", - "content_type": [ - "highlights", - "highlight" - ], - "codename": "add_highlight" - } - }, - { - "model": "auth.permission", - "fields": { - "name": "Can change highlight", - "content_type": [ - "highlights", - "highlight" - ], - "codename": "change_highlight" - } - }, - { - "model": "auth.permission", - "fields": { - "name": "Can delete highlight", - "content_type": [ - "highlights", - "highlight" - ], - "codename": "delete_highlight" - } - }, - { - "model": "auth.permission", - "fields": { - "name": "Can add milestone", - "content_type": [ - "milestones", - "milestone" - ], - "codename": "add_milestone" - } - }, - { - "model": "auth.permission", - "fields": { - "name": "Can change milestone", - "content_type": [ - "milestones", - "milestone" - ], - "codename": "change_milestone" - } - }, - { - "model": "auth.permission", - "fields": { - "name": "Can delete milestone", - "content_type": [ - "milestones", - "milestone" - ], - "codename": "delete_milestone" - } - }, - { - "model": "auth.permission", - "fields": { - "name": "Can add featured highlight", - "content_type": [ - "homepage", - "homepagehighlights" - ], - "codename": "add_homepagehighlights" - } - }, - { - "model": "auth.permission", - "fields": { - "name": "Can change featured highlight", - "content_type": [ - "homepage", - "homepagehighlights" - ], - "codename": "change_homepagehighlights" - } - }, - { - "model": "auth.permission", - "fields": { - "name": "Can delete featured highlight", - "content_type": [ - "homepage", - "homepagehighlights" - ], - "codename": "delete_homepagehighlights" - } - }, - { - "model": "auth.permission", - "fields": { - "name": "Can add featured network leader", - "content_type": [ - "homepage", - "homepageleaders" - ], - "codename": "add_homepageleaders" - } - }, - { - "model": "auth.permission", - "fields": { - "name": "Can change featured network leader", - "content_type": [ - "homepage", - "homepageleaders" - ], - "codename": "change_homepageleaders" - } - }, - { - "model": "auth.permission", - "fields": { - "name": "Can delete featured network leader", - "content_type": [ - "homepage", - "homepageleaders" - ], - "codename": "delete_homepageleaders" - } - }, - { - "model": "auth.permission", - "fields": { - "name": "Can add featured news item", - "content_type": [ - "homepage", - "homepagenews" - ], - "codename": "add_homepagenews" - } - }, - { - "model": "auth.permission", - "fields": { - "name": "Can change featured news item", - "content_type": [ - "homepage", - "homepagenews" - ], - "codename": "change_homepagenews" - } - }, - { - "model": "auth.permission", - "fields": { - "name": "Can delete featured news item", - "content_type": [ - "homepage", - "homepagenews" - ], - "codename": "delete_homepagenews" - } - }, - { - "model": "auth.permission", - "fields": { - "name": "Can add homepage", - "content_type": [ - "homepage", - "homepage" - ], - "codename": "add_homepage" - } - }, - { - "model": "auth.permission", - "fields": { - "name": "Can change homepage", - "content_type": [ - "homepage", - "homepage" - ], - "codename": "change_homepage" - } - }, - { - "model": "auth.permission", - "fields": { - "name": "Can delete homepage", - "content_type": [ - "homepage", - "homepage" - ], - "codename": "delete_homepage" - } - }, - { - "model": "auth.group", - "fields": { - "name": "Producer", - "permissions": [ - [ - "add_feature", - "features", - "feature" - ], - [ - "change_feature", - "features", - "feature" - ], - [ - "add_highlight", - "highlights", - "highlight" - ], - [ - "change_highlight", - "highlights", - "highlight" - ], - [ - "change_homepage", - "homepage", - "homepage" - ], - [ - "change_homepagehighlights", - "homepage", - "homepagehighlights" - ], - [ - "change_homepageleaders", - "homepage", - "homepageleaders" - ], - [ - "change_homepagenews", - "homepage", - "homepagenews" - ], - [ - "add_landingpage", - "landingpage", - "landingpage" - ], - [ - "change_landingpage", - "landingpage", - "landingpage" - ], - [ - "add_milestone", - "milestones", - "milestone" - ], - [ - "change_milestone", - "milestones", - "milestone" - ], - [ - "add_news", - "news", - "news" - ], - [ - "change_news", - "news", - "news" - ], - [ - "add_link", - "pages", - "link" - ], - [ - "change_link", - "pages", - "link" - ], - [ - "add_page", - "pages", - "page" - ], - [ - "change_page", - "pages", - "page" - ], - [ - "add_richtextpage", - "pages", - "richtextpage" - ], - [ - "change_richtextpage", - "pages", - "richtextpage" - ], - [ - "add_affiliation", - "people", - "affiliation" - ], - [ - "change_affiliation", - "people", - "affiliation" - ], - [ - "delete_affiliation", - "people", - "affiliation" - ], - [ - "add_person", - "people", - "person" - ], - [ - "change_person", - "people", - "person" - ] - ] - } - }, - { - "model": "auth.group", - "fields": { - "name": "Admin", - "permissions": [ - [ - "add_logentry", - "admin", - "logentry" - ], - [ - "change_logentry", - "admin", - "logentry" - ], - [ - "add_user", - "auth", - "user" - ], - [ - "change_user", - "auth", - "user" - ], - [ - "add_contenttype", - "contenttypes", - "contenttype" - ], - [ - "change_contenttype", - "contenttypes", - "contenttype" - ], - [ - "delete_contenttype", - "contenttypes", - "contenttype" - ], - [ - "add_feature", - "features", - "feature" - ], - [ - "change_feature", - "features", - "feature" - ], - [ - "delete_feature", - "features", - "feature" - ], - [ - "add_landingpage", - "landingpage", - "landingpage" - ], - [ - "change_landingpage", - "landingpage", - "landingpage" - ], - [ - "delete_landingpage", - "landingpage", - "landingpage" - ], - [ - "add_signup", - "landingpage", - "signup" - ], - [ - "change_signup", - "landingpage", - "signup" - ], - [ - "delete_signup", - "landingpage", - "signup" - ], - [ - "add_news", - "news", - "news" - ], - [ - "change_news", - "news", - "news" - ], - [ - "delete_news", - "news", - "news" - ], - [ - "add_opportunity", - "opportunities", - "opportunity" - ], - [ - "change_opportunity", - "opportunities", - "opportunity" - ], - [ - "delete_opportunity", - "opportunities", - "opportunity" - ], - [ - "add_page", - "pages", - "page" - ], - [ - "change_page", - "pages", - "page" - ], - [ - "delete_page", - "pages", - "page" - ], - [ - "add_affiliation", - "people", - "affiliation" - ], - [ - "change_affiliation", - "people", - "affiliation" - ], - [ - "delete_affiliation", - "people", - "affiliation" - ], - [ - "add_internethealthissue", - "people", - "internethealthissue" - ], - [ - "change_internethealthissue", - "people", - "internethealthissue" - ], - [ - "delete_internethealthissue", - "people", - "internethealthissue" - ], - [ - "add_person", - "people", - "person" - ], - [ - "change_person", - "people", - "person" - ], - [ - "delete_person", - "people", - "person" - ], - [ - "add_session", - "sessions", - "session" - ], - [ - "change_session", - "sessions", - "session" - ], - [ - "delete_session", - "sessions", - "session" - ] - ] - } - }, - { - "model": "auth.group", - "fields": { - "name": "Author", - "permissions": [ - [ - "add_landingpage", - "landingpage", - "landingpage" - ], - [ - "change_landingpage", - "landingpage", - "landingpage" - ], - [ - "add_page", - "pages", - "page" - ], - [ - "change_page", - "pages", - "page" - ] - ] - } - }, - { - "model": "auth.group", - "fields": { - "name": "Editor", - "permissions": [ - [ - "add_highlight", - "highlights", - "highlight" - ], - [ - "change_highlight", - "highlights", - "highlight" - ], - [ - "delete_highlight", - "highlights", - "highlight" - ], - [ - "add_landingpage", - "landingpage", - "landingpage" - ], - [ - "change_landingpage", - "landingpage", - "landingpage" - ], - [ - "add_milestone", - "milestones", - "milestone" - ], - [ - "change_milestone", - "milestones", - "milestone" - ], - [ - "add_news", - "news", - "news" - ], - [ - "change_news", - "news", - "news" - ], - [ - "add_page", - "pages", - "page" - ], - [ - "change_page", - "pages", - "page" - ], - [ - "add_affiliation", - "people", - "affiliation" - ], - [ - "change_affiliation", - "people", - "affiliation" - ], - [ - "add_person", - "people", - "person" - ], - [ - "change_person", - "people", - "person" - ] - ] - } - }, - { - "model": "auth.user", - "pk": 5, - "fields": { - "password": "pbkdf2_sha256$30000$ivSct9l4EFFr$iTajIDfgfiQm+52pAYh2F7qEuN/gkRypjoB0a7xOZ/E=", - "last_login": null, - "is_superuser": true, - "username": "testuser", - "first_name": "", - "last_name": "", - "email": "", - "is_staff": true, - "is_active": true, - "date_joined": "2017-09-22T20:16:43.999Z", - "groups": [], - "user_permissions": [] - } - } -] diff --git a/network-api/networkapi/highlights/factory.py b/network-api/networkapi/highlights/factory.py new file mode 100644 index 00000000000..4a8044e5e8b --- /dev/null +++ b/network-api/networkapi/highlights/factory.py @@ -0,0 +1,69 @@ +from datetime import timezone + +from factory import ( + DjangoModelFactory, + Faker, + Trait, + LazyAttribute, + post_generation, +) + +from networkapi.utility.faker_providers import ImageProvider +from networkapi.highlights.models import Highlight + +Faker.add_provider(ImageProvider) + + +class HighlightFactory(DjangoModelFactory): + class Meta: + model = Highlight + exclude = ( + 'title_sentence', + 'link_label_words', + 'footer_sentence', + ) + + class Params: + unpublished = Trait( + publish_after=Faker( + 'future_datetime', + end_date='+30d', + tzinfo=timezone.utc + ) + ) + has_expiry = Trait( + expires=Faker( + 'future_datetime', + end_date='+30d', + tzinfo=timezone.utc + ) + ) + expired = Trait( + expires=Faker( + 'past_datetime', + start_date='-30d', + tzinfo=timezone.utc + ) + ) + + title = LazyAttribute(lambda o: o.title_sentence.rstrip('.')) + description = Faker('paragraph', nb_sentences=5, variable_nb_sentences=True) + link_label = LazyAttribute(lambda o: ' '.join(o.link_label_words)) + footer = LazyAttribute(lambda o: o.footer_sentence.rstrip('.')) + link_url = Faker('uri') + publish_after = Faker( + 'past_datetime', + start_date='-30d', + tzinfo=timezone.utc + ) + expires = None + order = 0 + + # LazyAttribute helper values + title_sentence = Faker('sentence', nb_words=4) + link_label_words = Faker('words', nb=3) + footer_sentence = Faker('sentence', nb_words=5) + + @post_generation + def image_name(self, create, extracted, **kwargs): + self.image.name = Faker('generic_image').generate({}) diff --git a/network-api/networkapi/highlights/tests.py b/network-api/networkapi/highlights/tests.py deleted file mode 100644 index c4ee46c0d28..00000000000 --- a/network-api/networkapi/highlights/tests.py +++ /dev/null @@ -1,61 +0,0 @@ -from django.test import TestCase -import factory -import datetime -import json -from faker import Factory as FakerFactory -from networkapi.highlights.models import Highlight - - -faker = FakerFactory.create() - - -class HighlightFactory(factory.DjangoModelFactory): - - title = factory.LazyAttribute( - lambda o: 'title '+' '.join(faker.words(nb=1)) - ) - description = factory.LazyAttribute( - lambda o: 'description '+''.join(faker.sentence(nb_words=20)) - ) - link_url = 'http://example.org/image.png' - link_label = factory.LazyAttribute( - lambda o: faker.words(nb=2) - ) - publish_after = datetime.datetime.now() - - class Meta: - model = Highlight - - -def setup_highlights(test): - """ - Generate some highlights - """ - - test.highlights = [HighlightFactory() for i in range(2)] - for highlight in test.highlights: - highlight.save() - - -class TestHighlightView(TestCase): - """ - Test Highlights endpoints - """ - - def test_view_highlights(self): - """ - Make sure highlights view works - """ - setup_highlights(self) - highlights = self.client.get('/api/highlights/') - highlights_json = json.loads(str(highlights.content, 'utf-8')) - self.assertEqual(highlights.status_code, 200) - self.assertEqual(len(highlights_json), 2) - - def test_view_highlight(self): - """ - Make sure single highlight route works - """ - setup_highlights(self) - highlight = self.client.get('/api/highlights/1/') - self.assertEqual(highlight.status_code, 200) diff --git a/network-api/networkapi/highlights/tests/__init__.py b/network-api/networkapi/highlights/tests/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/network-api/networkapi/highlights/tests/tests_factory.py b/network-api/networkapi/highlights/tests/tests_factory.py new file mode 100644 index 00000000000..870a6366023 --- /dev/null +++ b/network-api/networkapi/highlights/tests/tests_factory.py @@ -0,0 +1,69 @@ +from datetime import datetime, timezone +from django.test import TestCase + +from networkapi.highlights.factory import HighlightFactory + + +class TestHighlightFactory(TestCase): + """ + Test HighlightFactory constructor + """ + + def test_highlight_creation(self): + """ + Creation a Highlight with HighlightFactory should not raise an + exception + """ + + HighlightFactory() + + def test_highlight_default_publish_date(self): + """ + By Default, a highlight should have been published + """ + + highlight = HighlightFactory() + now = datetime.now(tz=timezone.utc) + + self.assertLess(highlight.publish_after, now) + + def test_highlight_unpublished_param(self): + """ + The unpublished kwargs should set publish_after date to sometime in + the future + """ + + highlight = HighlightFactory(unpublished=True) + now = datetime.now(tz=timezone.utc) + + self.assertGreater(highlight.publish_after, now) + + def test_highlight_default_expiry(self): + """ + By Default, a highlight should not have an expiry date + """ + + highlight = HighlightFactory() + + self.assertIsNone(highlight.expires) + + def test_highlight_has_expiry_param(self): + """ + The has_expiry kwargs should set the expires date to sometime in + the future + """ + + highlight = HighlightFactory(has_expiry=True) + now = datetime.now(tz=timezone.utc) + + self.assertGreater(highlight.expires, now) + + def test_highlight_expired_param(self): + """ + The expired kwargs should set the expires date to sometime in the past + """ + + highlight = HighlightFactory(expired=True) + now = datetime.now(tz=timezone.utc) + + self.assertLess(highlight.expires, now) diff --git a/network-api/networkapi/highlights/tests/tests_views.py b/network-api/networkapi/highlights/tests/tests_views.py new file mode 100644 index 00000000000..86c53866ec9 --- /dev/null +++ b/network-api/networkapi/highlights/tests/tests_views.py @@ -0,0 +1,95 @@ +import json + +from django.test import TestCase +from rest_framework.test import APIRequestFactory +from networkapi.highlights.factory import HighlightFactory +from networkapi.highlights.views import HighlightListView, HighlightView + + +class TestHighlightView(TestCase): + """ + Test HighlightView class + """ + + def setUp(self): + self.factory = APIRequestFactory() + + def test_view_highlight(self): + """ + Make sure single highlight view returns a 200 status code + """ + + pk = HighlightFactory().id + + request = self.factory.get('/api/highlights/{}'.format(pk)) + response = HighlightView.as_view()(request, pk=pk) + + self.assertEqual(response.status_code, 200) + + def test_view_unpublished_highlight(self): + """ + Make sure that an unpublished highlight isn't accessible + """ + + pk = HighlightFactory(unpublished=True).id + + request = self.factory.get('/api/highlights/{}'.format(pk)) + response = HighlightView.as_view()(request, pk=pk) + + self.assertEqual(response.status_code, 404) + + def test_view_expired_highlight(self): + """ + Make sure that an expired highlight isn't accessible + """ + + pk = HighlightFactory(expired=True) + + request = self.factory.get('/api/highlights/{}'.format(pk)) + response = HighlightView.as_view()(request, pk=pk) + + self.assertEqual(response.status_code, 404) + + +class TestHighlightListView(TestCase): + """ + Test HighlightListView class + """ + + def setUp(self): + """ + Generate some highlights + """ + + self.factory = APIRequestFactory() + + # Generate two default highlights + self.highlights = [HighlightFactory() for i in range(2)] + + # Generate some highlights with specific traits + self.highlights.append(HighlightFactory(has_expiry=True)) + self.highlights.append(HighlightFactory(has_expiry=True, unpublished=True)) + self.highlights.append(HighlightFactory(unpublished=True)) + self.highlights.append(HighlightFactory(expired=True)) + + def test_view_highlights_list_view(self): + """ + Make sure highlights view returns a 200 status code + """ + + request = self.factory.get('/api/highlights/') + response = HighlightListView.as_view()(request) + + self.assertEqual(response.status_code, 200) + + def test_view_highlights_list_view_length(self): + """ + Make sure highlights view returns only the three published records + """ + + request = self.factory.get('/api/highlights/') + response = HighlightListView.as_view()(request) + response.render() + response_json = json.loads(response.content) + + self.assertEqual(len(response_json), 3) diff --git a/network-api/networkapi/homepage/factory.py b/network-api/networkapi/homepage/factory.py new file mode 100644 index 00000000000..9092968062d --- /dev/null +++ b/network-api/networkapi/homepage/factory.py @@ -0,0 +1,40 @@ +from factory import DjangoModelFactory, SubFactory + +from networkapi.homepage.models import ( + Homepage, + HomepageLeaders, + HomepageNews, + HomepageHighlights, +) +from networkapi.highlights.factory import HighlightFactory +from networkapi.news.factory import NewsFactory +from networkapi.people.factory import PersonFactory + + +class HomepageFactory(DjangoModelFactory): + class Meta: + model = Homepage + + +class HomepageLeadersFactory(DjangoModelFactory): + class Meta: + model = HomepageLeaders + + leader = SubFactory(PersonFactory) + homepage = SubFactory(HomepageFactory) + + +class HomepageNewsFactory(DjangoModelFactory): + class Meta: + model = HomepageNews + + news = SubFactory(NewsFactory) + homepage = SubFactory(HomepageFactory) + + +class HomepageHighlightsFactory(DjangoModelFactory): + class Meta: + model = HomepageHighlights + + highlights = SubFactory(HighlightFactory) + homepage = SubFactory(HomepageFactory) diff --git a/network-api/networkapi/homepage/tests.py b/network-api/networkapi/homepage/tests.py deleted file mode 100644 index e55d6890979..00000000000 --- a/network-api/networkapi/homepage/tests.py +++ /dev/null @@ -1,3 +0,0 @@ -from django.test import TestCase # noqa: F401 - -# Create your tests here. diff --git a/network-api/networkapi/homepage/tests/__init__.py b/network-api/networkapi/homepage/tests/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/network-api/networkapi/homepage/tests/tests_factory.py b/network-api/networkapi/homepage/tests/tests_factory.py new file mode 100644 index 00000000000..7e2ece9434a --- /dev/null +++ b/network-api/networkapi/homepage/tests/tests_factory.py @@ -0,0 +1,161 @@ +from django.test import TestCase + +from networkapi.homepage.factory import ( + HomepageFactory, + HomepageLeadersFactory, + HomepageNewsFactory, + HomepageHighlightsFactory, +) +from networkapi.homepage.models import ( + Homepage, + HomepageLeaders, + HomepageNews, + HomepageHighlights, +) +from networkapi.people.models import Person +from networkapi.news.models import News +from networkapi.highlights.models import Highlight + + +class TestHomepageFactory(TestCase): + """ + Test HomepageFactory + """ + + def test_homepage_creation(self): + """ + HomepageFactory.create() should not raise an exception + """ + + HomepageFactory.create() + + def test_homepage_return_value(self): + """ + HomepageFactory.create() should return an instance of Homepage + """ + + homepage_inst = HomepageFactory.create() + + self.assertIsInstance(homepage_inst, Homepage) + + +class TestHomepageLeadersFactory(TestCase): + """ + Test HomepageLeadersFactory + """ + + def test_homepage_leaders_creation(self): + """ + HomepageLeadersFactory.create() should not raise an exception + """ + + HomepageLeadersFactory.create() + + def test_homepage_leaders_return_value(self): + """ + HomepageLeadersFactory.create() should return an instance of HomepageLeaders + """ + + homepage_leader = HomepageLeadersFactory.create() + + self.assertIsInstance(homepage_leader, HomepageLeaders) + + def test_homepage_leaders_has_homepage(self): + """ + HomepageLeadersFactory.create() should have a related Homepage model + """ + + homepage_leader = HomepageLeadersFactory.create() + + self.assertIsInstance(homepage_leader.homepage, Homepage) + + def test_homepage_leaders_has_person(self): + """ + HomepageLeadersFactory.create() should have a related Person model + """ + + homepage_leader = HomepageLeadersFactory.create() + + self.assertIsInstance(homepage_leader.leader, Person) + + +class TestHomepageNewsFactory(TestCase): + """ + Test HomepageNewsFactory + """ + + def test_homepage_news_creation(self): + """ + HomepageNewsFactory.create() should not raise an exception + """ + + HomepageNewsFactory.create() + + def test_homepage_news_return_value(self): + """ + HomepageNewsFactory.create() should not raise an exception + """ + + homepage_news = HomepageNewsFactory.create() + + self.assertIsInstance(homepage_news, HomepageNews) + + def test_homepage_news_has_homepage(self): + """ + HomepageNewsFactory.create() should generate an instance with + a related Homepage model + """ + + homepage_news = HomepageNewsFactory.create() + + self.assertIsInstance(homepage_news.homepage, Homepage) + + def test_homepage_news_has_person(self): + """ + HomepageNewsFactory.create() should have a related News model + """ + + homepage_news = HomepageNewsFactory.create() + + self.assertIsInstance(homepage_news.news, News) + + +class TestHomepageHighlightsFactory(TestCase): + """ + Test HomepageHighlightsFactory + """ + + def test_homepage_highlights_creation(self): + """ + HomepageHighlightsFactory.create() should not raise an exception + """ + + HomepageHighlightsFactory.create() + + def test_homepage_highlights_return_value(self): + """ + HomepageHighlightsFactory.create() should return an instance of HomepageHighlights + """ + + homepage_highlight = HomepageHighlightsFactory.create() + + self.assertIsInstance(homepage_highlight, HomepageHighlights) + + def test_homepage_highlights_has_homepage(self): + """ + HomepageHighlightsFactory.create() should generate an instance with + a related Homepage model + """ + + homepage_highlight = HomepageHighlightsFactory.create() + + self.assertIsInstance(homepage_highlight.homepage, Homepage) + + def test_homepage_highlights_has_highlight(self): + """ + HomepageHighlightsFactory.create() should have a related Highlight model + """ + + homepage_highlight = HomepageHighlightsFactory.create() + + self.assertIsInstance(homepage_highlight.highlights, Highlight) diff --git a/network-api/networkapi/homepage/tests/tests_views.py b/network-api/networkapi/homepage/tests/tests_views.py new file mode 100644 index 00000000000..3ba8cd86f6e --- /dev/null +++ b/network-api/networkapi/homepage/tests/tests_views.py @@ -0,0 +1,67 @@ +from datetime import datetime, timedelta, timezone + +from django.test import TestCase +from unittest import expectedFailure +from rest_framework.test import APIRequestFactory +from networkapi.homepage.views import HomepageView +from networkapi.homepage.factory import ( + HomepageFactory, + HomepageLeadersFactory, + HomepageNewsFactory, + HomepageHighlightsFactory, +) + + +class TestHomepageView(TestCase): + """ + Test HomepageView class + """ + + def setUp(self): + self.factory = APIRequestFactory() + + def test_homepage_view_response_code(self): + """ + Make sure the homepage returns a 200 status code + """ + + homepage = HomepageFactory() + HomepageLeadersFactory(homepage=homepage) + HomepageNewsFactory(homepage=homepage) + HomepageHighlightsFactory(homepage=homepage) + + request = self.factory.get('/api/homepage/') + response = HomepageView.as_view()(request) + + self.assertEqual(response.status_code, 200) + + def test_homepage_view_404(self): + """ + Make sure HomepageView returns a 404 if there's no Homepage + """ + + request = self.factory.get('/api/homepage/') + response = HomepageView.as_view()(request) + + self.assertEqual(response.status_code, 404) + + @expectedFailure + def test_homepage_view_expired_leader(self): + """ + Make sure an expired, featured person doesn't show up in the view + + Not sure if this should work - it seems expired Person records aren't filtered for this view + """ + + homepage = HomepageFactory() + expire_date = datetime.now(tz=timezone.utc) - timedelta(days=1) + + HomepageLeadersFactory( + homepage=homepage, + leader__expires=expire_date + ) + + request = self.factory.get('/api/homepage/') + response = HomepageView.as_view()(request) + + self.assertEqual(len(response.data['leaders']), 0) diff --git a/network-api/networkapi/landingpage/factory.py b/network-api/networkapi/landingpage/factory.py new file mode 100644 index 00000000000..a54ecffaf2a --- /dev/null +++ b/network-api/networkapi/landingpage/factory.py @@ -0,0 +1,59 @@ +from datetime import timezone + +from slugify import slugify +from factory import ( + DjangoModelFactory, + LazyAttribute, + Faker, + Trait, +) + +from networkapi.landingpage.models import LandingPage, Signup + +sentence_faker = Faker('sentence', nb_words=3, variable_nb_words=False) +past_datetime_faker = Faker('past_datetime', start_date='-30d', tzinfo=timezone.utc) + + +class SignupFactory(DjangoModelFactory): + class Meta: + model = Signup + exclude = ( + 'title_text', + 'header_text', + 'newsletter_text', + ) + + title = LazyAttribute(lambda o: o.title_text.rstrip('.')) + header = LazyAttribute(lambda o: o.header_text.rstrip('.')) + newsletter = LazyAttribute(lambda o: o.newsletter_text.rstrip('.')) + description = Faker('paragraph', nb_sentences=5, variable_nb_sentences=True) + + # LazyAttribute helper values + title_text = sentence_faker + header_text = sentence_faker + newsletter_text = sentence_faker + + +class LandingPageFactory(DjangoModelFactory): + class Meta: + model = LandingPage + exclude = ( + 'title_text', + 'header_text', + ) + + class Params: + has_expired = Trait( + expiry_date=past_datetime_faker + ) + + header = LazyAttribute(lambda o: o.header_text.rstrip('.')) + content = Faker('paragraph', nb_sentences=15, variable_nb_sentences=True) + signup = None + title = LazyAttribute(lambda o: o.title_text.rstrip('.')) + slug = LazyAttribute(lambda o: slugify(o.title_text)) + publish_date = past_datetime_faker + + # LazyAttribute helper values + title_text = sentence_faker + header_text = sentence_faker diff --git a/network-api/networkapi/landingpage/tests/__init__.py b/network-api/networkapi/landingpage/tests/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/network-api/networkapi/landingpage/tests/tests_factory.py b/network-api/networkapi/landingpage/tests/tests_factory.py new file mode 100644 index 00000000000..bbfa7be1f0f --- /dev/null +++ b/network-api/networkapi/landingpage/tests/tests_factory.py @@ -0,0 +1,67 @@ +from datetime import datetime, timezone +from django.test import TestCase + +from networkapi.landingpage.factory import SignupFactory, LandingPageFactory +from networkapi.landingpage.models import Signup, LandingPage + + +class TestSignupFactory(TestCase): + """ + Test SignupFactory + """ + + def test_signup_creation(self): + """ + SignupFactory.create() should not raise an exception + """ + + SignupFactory.create() + + def test_signup_return_value(self): + """ + SignupFactory.create() should return an instance of a Signup + """ + + self.assertIsInstance(SignupFactory.create(), Signup) + + +class TestLandingPageFactory(TestCase): + """ + Test LandingPageFactory + """ + + def test_landingpage_creation(self): + """ + LandingPageFactory.create() should not raise an exception + """ + + LandingPageFactory.create() + + def test_landingpage_return_value(self): + """ + LandingPageFactory.create() should return an instance of LandingPage + """ + + landing_page = LandingPageFactory.create() + + self.assertIsInstance(landing_page, LandingPage) + + def test_set_landing_page_parent(self): + """ + LandingPageFactory.create() should let you set another LandingPage as a parent + """ + + parent_page = LandingPageFactory.create() + has_parent = LandingPageFactory(parent=parent_page) + + self.assertIsInstance(has_parent.parent, LandingPage) + self.assertEqual(has_parent.parent, parent_page) + + def test_landingpage_expired(self): + """ + LandingPageFactory.create() can generate pages that have already expired + """ + + page = LandingPageFactory(has_expired=True) + + self.assertLess(page.expiry_date, datetime.now(tz=timezone.utc)) diff --git a/network-api/networkapi/management/commands/flush_models.py b/network-api/networkapi/management/commands/flush_models.py new file mode 100644 index 00000000000..ecdc1b6d7ae --- /dev/null +++ b/network-api/networkapi/management/commands/flush_models.py @@ -0,0 +1,50 @@ +from django.core.management.base import BaseCommand + +# Models +from networkapi.highlights.models import Highlight +from networkapi.landingpage.models import LandingPage, Signup +from networkapi.milestones.models import Milestone +from networkapi.news.models import News +from networkapi.people.models import ( + Person, + Affiliation, + InternetHealthIssue, +) +from networkapi.homepage.models import Homepage + + +class Command(BaseCommand): + help = 'Flush the models from the database' + + def handle(self, *args, **options): + + self.stdout.write('Flushing models from the database...') + + self.stdout.write('Dropping Homepage objects..') + Homepage.objects.all().delete() + + self.stdout.write('Dropping LandingPage objects...') + LandingPage.objects.all().delete() + + self.stdout.write('Dropping Signup objects...') + Signup.objects.all().delete() + + self.stdout.write('Dropping Highlight objects...') + Highlight.objects.all().delete() + + self.stdout.write('Dropping News objects...') + News.objects.all().delete() + + self.stdout.write('Dropping Milestone objects...') + Milestone.objects.all().delete() + + self.stdout.write('Dropping Person objects...') + Person.objects.all().delete() + + self.stdout.write('Dropping InternetHealthIssue objects...') + InternetHealthIssue.objects.all().delete() + + self.stdout.write('Dropping Affiliation objects...') + Affiliation.objects.all().delete() + + self.stdout.write(self.style.SUCCESS('Done!')) diff --git a/network-api/networkapi/management/commands/heroku_release.py b/network-api/networkapi/management/commands/heroku_release.py index 681eda51706..029cbd828b4 100644 --- a/network-api/networkapi/management/commands/heroku_release.py +++ b/network-api/networkapi/management/commands/heroku_release.py @@ -4,13 +4,13 @@ class Command(BaseCommand): - help = 'migrate the database if needed, and optionally seed' \ - 'the database using networkapi/fixtures/test_data.json' + help = 'migrate the database if needed, and' \ + 'generate a full set of fake model data' def handle(self, *args, **options): call_command('migrate') - if settings.LOAD_FIXTURE: + if settings.EXECUTE_FAKE_DATA: call_command('update_site_domain') - call_command('loaddata', './networkapi/fixtures/test_data.json') + call_command('load_fake_data', '--delete') diff --git a/network-api/networkapi/management/commands/load_fake_data.py b/network-api/networkapi/management/commands/load_fake_data.py new file mode 100644 index 00000000000..f40a65d0bda --- /dev/null +++ b/network-api/networkapi/management/commands/load_fake_data.py @@ -0,0 +1,120 @@ +import factory +from random import randint + +from django.core.management.base import BaseCommand +from django.core.management import call_command + +# Factories +from networkapi.highlights.factory import HighlightFactory +from networkapi.landingpage.factory import LandingPageFactory, SignupFactory +from networkapi.milestones.factory import MilestoneFactory +from networkapi.news.factory import NewsFactory +from networkapi.people.factory import ( + PersonFactory, + AffiliationFactory, + InternetHealthIssueFactory, +) +from networkapi.homepage.factory import ( + HomepageFactory, + HomepageNewsFactory, + HomepageLeadersFactory, + HomepageHighlightsFactory, +) + +internet_health_issues = [ + 'Digital Inclusion', + 'Web Literacy', + 'Open Innovation', + 'Decentralization', + 'Online Privacy and Security', +] + + +class Command(BaseCommand): + help = 'Generate fake data for local development and testing purposes' \ + 'and load it into the database' + + def add_arguments(self, parser): + parser.add_argument( + '--delete', + action='store_true', + dest='delete', + help='Delete previous highlights, homepage, landing page, milestones, news and people from the database', + ) + + parser.add_argument( + '--seed', + action='store', + dest='seed', + help='A seed value to pass to Faker before generating data', + ) + + def handle(self, *args, **options): + + if options['delete']: + call_command('flush_models') + + # Seed Faker with the provided seed value or a pseudorandom int between 0 and five million + if options['seed']: + seed = options['seed'] + else: + seed = randint(0, 5000000) + + self.stdout.write('Seeding Faker with: {}'.format(seed)) + faker = factory.faker.Faker._get_faker(locale='en-US') + faker.random.seed(seed) + + self.stdout.write('Generating LandingPage objects') + opportunity = LandingPageFactory.create(title='opportunity', content='This is placeholder') + [LandingPageFactory.create(parent=opportunity) for i in range(5)] + + self.stdout.write('Generating LandingPage objects with Signup CTAs') + [LandingPageFactory.create(parent=opportunity, signup=SignupFactory.create()) for i in range(5)] + + self.stdout.write('Generating Homepage') + homepage = HomepageFactory.create() + + self.stdout.write('Generating HomepageNews, HomepageHighlights, and HomepageLeaders objects') + [HomepageNewsFactory.create(homepage=homepage) for i in range(4)] + [HomepageHighlightsFactory.create(homepage=homepage) for i in range(4)] + [HomepageLeadersFactory.create(homepage=homepage) for i in range(4)] + + self.stdout.write('Generating Highlight objects') + [HighlightFactory.create() for i in range(10)] + + self.stdout.write('Generating Milestone objects') + [MilestoneFactory.create() for i in range(10)] + + self.stdout.write('Generating News objects') + [NewsFactory.create() for i in range(10)] + + self.stdout.write('Generating five InternetHealthIssue objects') + issue_objects = [] + for issue in internet_health_issues: + issue_objects.append(InternetHealthIssueFactory(name=issue)) + + self.stdout.write('Generating Person and Affiliation objects') + for i in range(10): + person = PersonFactory.create(internet_health_issues=issue_objects) + + for j in range(3): + AffiliationFactory.create(person=person) + + self.stdout.write('Generating unpublished, expired, and expiring highlights') + [HighlightFactory.create(unpublished=True) for i in range(4)] + [HighlightFactory.create(expired=True) for i in range(4)] + [HighlightFactory.create(has_expiry=True) for i in range(4)] + + self.stdout.write('Generating unpublished, expired, and expiring News') + [NewsFactory.create(unpublished=True) for i in range(4)] + [NewsFactory.create(expired=True) for i in range(4)] + [NewsFactory.create(has_expiry=True) for i in range(4)] + [NewsFactory.create(is_video=True) for i in range(4)] + + self.stdout.write('Generating featured, unpublished, expired, and expiring People') + [PersonFactory.create(is_featured=True) for i in range(4)] + [PersonFactory.create(unpublished=True) for i in range(4)] + [PersonFactory.create(has_expiry=True) for i in range(4)] + [PersonFactory.create(expired=True) for i in range(4)] + + self.stdout.write(self.style.SUCCESS('Done!')) diff --git a/network-api/networkapi/milestones/factory.py b/network-api/networkapi/milestones/factory.py new file mode 100644 index 00000000000..76c14588f1b --- /dev/null +++ b/network-api/networkapi/milestones/factory.py @@ -0,0 +1,42 @@ +from datetime import timedelta +from random import randrange + +from factory import ( + Faker, + DjangoModelFactory, + LazyAttribute, + post_generation +) + +from networkapi.utility.faker_providers import ImageProvider +from networkapi.milestones.models import Milestone + +Faker.add_provider(ImageProvider) + + +class MilestoneFactory(DjangoModelFactory): + + class Meta: + model = Milestone + exclude = ( + 'headline_sentence', + 'link_label_sentence', + 'milestone_length', + ) + + # Model Attributes + headline = LazyAttribute(lambda o: o.headline_sentence.rstrip('.')) + description = Faker('paragraph', nb_sentences=4, variable_nb_sentences=True) + link_label = LazyAttribute(lambda o: o.link_label_sentence.rstrip('.')) + link_url = Faker('url') + start_date = Faker('date_time_between', start_date='-30d', end_date='+30d') + end_date = LazyAttribute(lambda o: o.start_date + timedelta(days=o.milestone_length)) + + # LazyAttribute helper values + headline_sentence = Faker('sentence', nb_words=4) + link_label_sentence = Faker('sentence', nb_words=4) + milestone_length = LazyAttribute(lambda o: randrange(30)) + + @post_generation + def photo_name(self, create, extracted, **kwargs): + self.photo.name = Faker('generic_image').generate({}) diff --git a/network-api/networkapi/milestones/tests/__init__.py b/network-api/networkapi/milestones/tests/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/network-api/networkapi/milestones/tests/tests_factory.py b/network-api/networkapi/milestones/tests/tests_factory.py new file mode 100644 index 00000000000..c7863b875bc --- /dev/null +++ b/network-api/networkapi/milestones/tests/tests_factory.py @@ -0,0 +1,35 @@ +from django.test import TestCase + +from networkapi.milestones.factory import MilestoneFactory +from networkapi.milestones.models import Milestone + + +class TestMilestoneFactory(TestCase): + """ + Test the MilestoneFactory constructor + """ + + def test_milestone_creation(self): + """ + MilestoneFactory should not throw when creating a Milestone model + """ + + MilestoneFactory.create() + + def test_milestone_return_value(self): + """ + MilestoneFactory should return a Milestone instance + """ + + milestone = MilestoneFactory.create() + + self.assertIsInstance(milestone, Milestone) + + def test_post_generation(self): + """ + MilestoneFactory should generate a photo.name attribute in the post_generation stage + """ + + milestone = MilestoneFactory.create() + + self.assertIsNotNone(milestone.photo.name) diff --git a/network-api/networkapi/milestones/tests/tests_views.py b/network-api/networkapi/milestones/tests/tests_views.py new file mode 100644 index 00000000000..21993982be5 --- /dev/null +++ b/network-api/networkapi/milestones/tests/tests_views.py @@ -0,0 +1,56 @@ +import json + +from django.test import TestCase +from rest_framework.test import APIRequestFactory + +from networkapi.milestones.factory import MilestoneFactory +from networkapi.milestones.views import MilestoneView, MilestoneListView + + +class TestSingleMilestoneViews(TestCase): + + def setUp(self): + self.factory = APIRequestFactory() + + def test_milestone_view(self): + """ + Make sure single milestone view returns a 200 status code + """ + + pk = MilestoneFactory.create().id + + request = self.factory.get('/api/milestones/{}'.format(pk)) + response = MilestoneView.as_view()(request, pk=pk) + + self.assertEqual(response.status_code, 200) + + +class TestMultipleMilestonesView(TestCase): + + def setUp(self): + self.factory = APIRequestFactory() + + # Create multiple milestones + [MilestoneFactory.create() for i in range(4)] + + def test_milestone_list_view(self): + """ + Make sure milestone list view returns a 200 status code + """ + + request = self.factory.get('/api/milestones') + response = MilestoneListView.as_view()(request) + + self.assertEqual(response.status_code, 200) + + def test_milestone_list_view_length(self): + """ + Make sure milestone list view return the right amount of milestones + """ + + request = self.factory.get('/api/milestones') + response = MilestoneListView.as_view()(request) + response.render() + response_json = json.loads(response.content) + + self.assertEqual(len(response_json), 4) diff --git a/network-api/networkapi/news/factory.py b/network-api/networkapi/news/factory.py new file mode 100644 index 00000000000..b3a02a19735 --- /dev/null +++ b/network-api/networkapi/news/factory.py @@ -0,0 +1,55 @@ +from datetime import timezone + +from factory import ( + DjangoModelFactory, + Faker, + post_generation, + Trait, + LazyAttribute, +) + +from networkapi.utility.faker_providers import ImageProvider +from networkapi.news.models import News + +Faker.add_provider(ImageProvider) + + +class NewsFactory(DjangoModelFactory): + + class Meta: + model = News + exclude = ( + 'headline_sentence', + ) + + class Params: + is_featured = Trait( + featured=True + ) + unpublished = Trait( + publish_after=Faker('future_datetime', end_date='+30d', tzinfo=timezone.utc) + ) + has_expiry = Trait( + expires=Faker('future_datetime', end_date='+30d', tzinfo=timezone.utc) + ) + expired = Trait( + expires=Faker('past_datetime', start_date='-30d', tzinfo=timezone.utc) + ) + video = Trait( + is_video=True + ) + + headline = LazyAttribute(lambda o: o.headline_sentence.rstrip('.')) + outlet = Faker('company') + date = Faker('past_date', start_date='-30d') + link = Faker('url') + excerpt = Faker('paragraph', nb_sentences=3, variable_nb_sentences=True) + author = Faker('name') + publish_after = Faker('past_datetime', start_date='-30d', tzinfo=timezone.utc) + + # LazyAttribute helper value + headline_sentence = Faker('sentence', nb_words=4) + + @post_generation + def set_thumbnail(self, create, extracted, **kwargs): + self.thumbnail.name = Faker('generic_image').generate({}) diff --git a/network-api/networkapi/news/tests.py b/network-api/networkapi/news/tests.py deleted file mode 100644 index d7e40de9f30..00000000000 --- a/network-api/networkapi/news/tests.py +++ /dev/null @@ -1,5 +0,0 @@ -from django.test import TestCase - - -class TestNewsView(TestCase): - pass diff --git a/network-api/networkapi/news/tests/__init__.py b/network-api/networkapi/news/tests/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/network-api/networkapi/news/tests/tests_factory.py b/network-api/networkapi/news/tests/tests_factory.py new file mode 100644 index 00000000000..4794327f050 --- /dev/null +++ b/network-api/networkapi/news/tests/tests_factory.py @@ -0,0 +1,72 @@ +from datetime import datetime, timezone +from django.test import TestCase + +from networkapi.news.factory import NewsFactory +from networkapi.news.models import News + + +class TestNewsFactory(TestCase): + """ + Test NewsFactory constructor + """ + + def test_news_creation(self): + """ + NewsFactory should not raise an exception + """ + + NewsFactory.create() + + def test_news_return_value(self): + """ + NewsFactory should return an instance of News + """ + + news = NewsFactory.create() + + self.assertIsInstance(news, News) + + def test_news_is_featured_param(self): + """ + The is_featured kwargs should set featured to True + """ + + news = NewsFactory.create(is_featured=True) + + self.assertEqual(news.featured, True) + + def test_news_unpublished_param(self): + """ + The unpublished kwargs should set publish_after date to sometime in the future + """ + + news = NewsFactory.create(unpublished=True) + + self.assertGreater(news.publish_after, datetime.now(tz=timezone.utc)) + + def test_news_has_expiry_param(self): + """ + The has_expiry kwarg should set the expires date to sometime in the future + """ + + news = NewsFactory.create(has_expiry=True) + + self.assertGreater(news.expires, datetime.now(tz=timezone.utc)) + + def test_news_expired_param(self): + """ + The expired kwarg should set the expires date to sometime in the past + """ + + news = NewsFactory.create(expired=True) + + self.assertLess(news.expires, datetime.now(tz=timezone.utc)) + + def test_news_video_param(self): + """ + The video kwargs should set is_video to True + """ + + news = NewsFactory.create(video=True) + + self.assertEqual(news.is_video, True) diff --git a/network-api/networkapi/news/tests/tests_views.py b/network-api/networkapi/news/tests/tests_views.py new file mode 100644 index 00000000000..55106148958 --- /dev/null +++ b/network-api/networkapi/news/tests/tests_views.py @@ -0,0 +1,90 @@ +import json + +from django.test import TestCase +from rest_framework.test import APIRequestFactory + +from networkapi.news.factory import NewsFactory +from networkapi.news.views import NewsListView, NewsView + + +class TestNewsView(TestCase): + + def setUp(self): + self.factory = APIRequestFactory() + + def test_view_one_news(self): + """ + Make sure single news view returns a 200 status code + """ + + pk = NewsFactory.create().id + + request = self.factory.get('/api/news/{}'.format(pk)) + response = NewsView.as_view()(request, pk=pk) + + self.assertEqual(response.status_code, 200) + + def test_view_unpublished_news(self): + """ + Make sure that an unpublished news isn't accessible + """ + + pk = NewsFactory.create(unpublished=True).id + + request = self.factory.get('/api/news/{}'.format(pk)) + response = NewsView.as_view()(request, pk=pk) + + self.assertEqual(response.status_code, 404) + + def test_view_expired_news(self): + """ + Make sure that an expired news isn't accessible + """ + + pk = NewsFactory.create(expired=True).id + + request = self.factory.get('/api/news/{}'.format(pk)) + response = NewsView.as_view()(request, pk=pk) + + self.assertEqual(response.status_code, 404) + + +class TestNewsListView(TestCase): + + def setUp(self): + """ + Create some news + """ + + self.factory = APIRequestFactory() + + # Generate default news + [NewsFactory.create() for i in range(4)] + + # Generate news with different traits + NewsFactory.create(has_expiry=True) + NewsFactory.create(has_expiry=True, unpublished=True) + NewsFactory.create(unpublished=True) + NewsFactory.create(expired=True) + + def test_news_list_view(self): + """ + Make sure list news view returns a 200 status code + """ + + request = self.factory.get('/api/news/') + response = NewsListView.as_view()(request) + + self.assertEqual(response.status_code, 200) + + def test_news_list_view_length(self): + """ + Make sure list news view returns only the 4 published news + """ + + request = self.factory.get('/api/news/') + response = NewsListView.as_view()(request) + response.render() + response_json = json.loads(response.content) + + self.assertEqual(len(response_json), 5) diff --git a/network-api/networkapi/people/factory.py b/network-api/networkapi/people/factory.py new file mode 100644 index 00000000000..27504a757a0 --- /dev/null +++ b/network-api/networkapi/people/factory.py @@ -0,0 +1,105 @@ +from datetime import timezone + +from factory import ( + DjangoModelFactory, + Faker, + post_generation, + SubFactory, + Trait, + LazyAttribute, +) + +from networkapi.utility.faker_providers import ImageProvider +from networkapi.people.models import InternetHealthIssue, Person, Affiliation + +Faker.add_provider(ImageProvider) + + +class InternetHealthIssueFactory(DjangoModelFactory): + class Meta: + model = InternetHealthIssue + exclude = ('name_sentence',) + + name = LazyAttribute(lambda o: o.name_sentence.rstrip('.')) + + # LazyAttribute helper value + name_sentence = Faker('sentence', nb_words=5, variable_nb_words=True) + + +class PersonFactory(DjangoModelFactory): + class Meta: + model = Person + + class Params: + is_featured = Trait( + featured=True + ) + unpublished = Trait( + publish_after=Faker( + 'future_datetime', + end_date='+30d', + tzinfo=timezone.utc, + ) + ) + has_expiry = Trait( + expires=Faker( + 'future_datetime', + end_date='+30d', + tzinfo=timezone.utc, + ) + ) + expired = Trait( + expires=Faker( + 'past_datetime', + start_date='-30d', + tzinfo=timezone.utc, + ) + ) + + name = Faker('name') + role = Faker('job') + location = Faker('country') + quote = Faker('paragraph', nb_sentences=3, variable_nb_sentences=True) + bio = Faker('paragraph', nb_sentences=2, variable_nb_sentences=True) + twitter_url = Faker('url') + linkedin_url = Faker('url') + interview_url = Faker('url') + publish_after = Faker( + 'past_datetime', + start_date='-30d', + tzinfo=timezone.utc, + ) + featured = False + + # Methods to run after the model has been generated + @post_generation + def set_images(self, create, extracted, **kwargs): + self.image.name = Faker('people_image').generate({}) + self.partnership_logo.name = Faker('generic_image').generate({}) + + @post_generation + def internet_health_issues(self, create, extracted, **kwargs): + """ + After model generation, Relate any internet health issues from the + internet_health_issues kwarg to the new instance. + """ + + if not create: + return + + if extracted: + issue_set = [] + + for issue in extracted: + if isinstance(issue, InternetHealthIssue): + issue_set.append(issue) + + self.internet_health_issues.set(issue_set) + + +class AffiliationFactory(DjangoModelFactory): + class Meta: + model = Affiliation + + name = Faker('company') + person = SubFactory(PersonFactory) diff --git a/network-api/networkapi/people/tests.py b/network-api/networkapi/people/tests.py deleted file mode 100644 index e55d6890979..00000000000 --- a/network-api/networkapi/people/tests.py +++ /dev/null @@ -1,3 +0,0 @@ -from django.test import TestCase # noqa: F401 - -# Create your tests here. diff --git a/network-api/networkapi/people/tests/__init__.py b/network-api/networkapi/people/tests/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/network-api/networkapi/people/tests/tests_factory.py b/network-api/networkapi/people/tests/tests_factory.py new file mode 100644 index 00000000000..7b9f46a68c1 --- /dev/null +++ b/network-api/networkapi/people/tests/tests_factory.py @@ -0,0 +1,119 @@ +from datetime import datetime, timezone +from django.test import TestCase + +from networkapi.people.factory import ( + InternetHealthIssueFactory, + PersonFactory, + AffiliationFactory, +) + +from networkapi.people.models import ( + InternetHealthIssue, + Person, + Affiliation +) + + +class TestPersonFactory(TestCase): + """ + Test PersonFactory + """ + + def test_person_creation(self): + """ + PersonFactory should not raise and exception when generating a model instance + """ + + PersonFactory.create() + + def test_person_return_value(self): + """ + PersonFactory should return an instance of Person + """ + + person = PersonFactory.create() + + self.assertIsInstance(person, Person) + + def test_person_featured_param(self): + """ + The is_featured kwarg should set featured to True + """ + + person = PersonFactory.create(is_featured=True) + + self.assertEqual(person.featured, True) + + def test_person_unpublished_param(self): + """ + The unpublished kwarg should set the publish_after date to sometime + in the future + """ + + person = PersonFactory.create(unpublished=True) + + self.assertGreater(person.publish_after, datetime.now(tz=timezone.utc)) + + def test_person_has_expiry_param(self): + """ + The has_expiry kwarg should set the expires date to sometime in the + future + """ + + person = PersonFactory.create(has_expiry=True) + + self.assertGreater(person.expires, datetime.now(tz=timezone.utc)) + + def test_person_expired_param(self): + """ + The expired kwarg should set the expires date to sometime in the + past + """ + + person = PersonFactory.create(expired=True) + + self.assertLess(person.expires, datetime.now(tz=timezone.utc)) + + +class TestInternetHealthIssueFactory(TestCase): + """ + Test InternetHealthIssueFactory + """ + + def test_internet_health_issue_creation(self): + """ + InternetHealthIssueFactory should not raise an exception + """ + + InternetHealthIssueFactory.create() + + def test_internet_health_issue_return_value(self): + """ + InternetHealthIssueFactory should return an instance of InternetHealthIssue + """ + + issue = InternetHealthIssueFactory.create() + + self.assertIsInstance(issue, InternetHealthIssue) + + +class TestAffiliationFactory(TestCase): + """ + Test AffiliationFactory + """ + + def test_affiliation_creation(self): + """ + AffiliationFactory should not raise an exception + """ + + AffiliationFactory.create() + + def test_affiliation_return_value(self): + """ + AffiliationFactory should return an instance of Affiliation + """ + + affiliation = AffiliationFactory.create() + + self.assertIsInstance(affiliation, Affiliation) diff --git a/network-api/networkapi/settings.py b/network-api/networkapi/settings.py index 04d3d75f02e..0bbc1c5fec4 100644 --- a/network-api/networkapi/settings.py +++ b/network-api/networkapi/settings.py @@ -35,7 +35,7 @@ DJANGO_LOG_LEVEL=(str, 'INFO'), FILEBROWSER_DEBUG=(bool, False), FILEBROWSER_DIRECTORY=(str, ''), - LOAD_FIXTURE=(bool, False), + EXECUTE_FAKE_DATA=(bool, False), NETWORK_SITE_URL=(str, ''), PULSE_API_DOMAIN=(str, ''), PULSE_DOMAIN=(str, ''), @@ -67,8 +67,8 @@ # SECURITY WARNING: don't run with debug turned on in production! DEBUG = FILEBROWSER_DEBUG = env('DEBUG') -# This should only be needed in Heroku review apps -LOAD_FIXTURE = env('LOAD_FIXTURE') +# This should only be set to True in Heroku review apps +EXECUTE_FAKE_DATA = env('EXECUTE_FAKE_DATA') # Force permanent redirects to the domain specified in TARGET_DOMAIN DOMAIN_REDIRECT_MIDDLWARE_ENABLED = env('DOMAIN_REDIRECT_MIDDLWARE_ENABLED') diff --git a/network-api/networkapi/utility/faker_providers.py b/network-api/networkapi/utility/faker_providers.py new file mode 100644 index 00000000000..0c784496e82 --- /dev/null +++ b/network-api/networkapi/utility/faker_providers.py @@ -0,0 +1,42 @@ +from faker.providers import BaseProvider + + +class ImageProvider(BaseProvider): + """ + A custom Faker Provider for relative image urls, for use with factory_boy + + >>> from factory import Faker + >>> from networkapi.utility.faker_providers import ImageProvider + >>> fake - Faker() + >>> Faker.add_provider(ImageProvider) + """ + + base_path = 'images/placeholders/' + + generic_images = ( + 'generic/tigerparrot.jpg', + 'generic/photographer.jpg', + 'generic/windfarm.jpg', + 'generic/hotair.jpg', + 'generic/computerandcoffee.jpg', + ) + + headshot_images = ( + 'people/woman.jpg', + 'people/man.jpg', + 'people/dino.jpg', + ) + + def generic_image(self): + """ + returns a path to one of the predefined generic placeholder images + """ + + return '{}{}'.format(self.base_path, self.random_element(self.generic_images)) + + def people_image(self): + """ + returns a path to one of the predefined people placeholder images + """ + + return '{}{}'.format(self.base_path, self.random_element(self.headshot_images)) diff --git a/requirements.txt b/requirements.txt index b4b9d26094f..eb3644c0784 100644 --- a/requirements.txt +++ b/requirements.txt @@ -44,5 +44,7 @@ requests==2.13.0 # Testing flake8==2.5.4 -factory_boy==2.8.1 -fake-factory==0.5.7 +factory_boy==2.9.2 +faker==0.8.10 +coverage==4.4.2 +python-coveralls==2.9.1