This page shows all of the active project grants that were awarded.
13 |
14 | {% for project in grant_projects %}
15 |
16 |
12 |
13 |
14 |
15 | {% if messages %}
16 | {% for message in messages %}
17 |
{{ message }}
19 | {% endfor %}
20 | {% endif %}
21 |
22 |
{% block head_title %}{% endblock %}
23 |
24 |
25 | {% block panel_content %}{% endblock %}
26 |
27 |
28 |
29 | {% endblock %}
30 |
--------------------------------------------------------------------------------
/open_humans/templates/partials/activity-info-short-bs4.html:
--------------------------------------------------------------------------------
1 |
2 |
Managed by:
3 |
4 | {{ project.leader }}
5 | {% if project.organization %}
6 | {{ project.organization}}
7 | {% endif %}
8 |
9 |
--------------------------------------------------------------------------------
/open_humans/templates/partials/activity-management-join-add-button.html:
--------------------------------------------------------------------------------
1 |
8 | {{ connect_prefix|add:activity.connect_verb|title }} {{ activity.verbose_name }}
9 |
10 |
--------------------------------------------------------------------------------
/open_humans/templates/partials/activity-management-sharing-opportunities.html:
--------------------------------------------------------------------------------
1 | {% load utilities %}
2 |
3 |
4 |
5 |
Sharing Opportunities
6 |
7 |
8 | Data from this data source can be shared with the following projects:
9 |
10 |
11 |
12 | {% for requesting_activity in requesting_activities %}
13 |
14 |
15 | {{ requesting_activity.name }}:
16 |
17 |
18 | {{ requesting_activity.authorized_members }}
19 | member{{ requesting_activity.authorized_members|pluralize }}
20 |
21 | {% project_is_connected requesting_activity user as connected %}
22 | {% if connected %}
23 | (joined)
24 | {% endif %}
25 |
26 | {% endfor %}
27 |
28 |
--------------------------------------------------------------------------------
/open_humans/templates/partials/activity-panel-needs.html:
--------------------------------------------------------------------------------
1 | {% load static %}
2 | {% load utilities %}
3 | {# the "needs" panel on an activity page #}
4 |
5 |
--------------------------------------------------------------------------------
/open_humans/templates/partials/activity-panel-news.html:
--------------------------------------------------------------------------------
1 | {% load static %}
2 | {% load utilities %}
3 | {# the "news" panel on an activity page #}
4 |
5 |
--------------------------------------------------------------------------------
/open_humans/templates/partials/activity-permissions-bs4.html:
--------------------------------------------------------------------------------
1 | {% if requests_permissions %}
2 |
3 |
4 | Requested permissions:
5 |
6 |
7 | {% for source_project in project.requested_sources.all %}
8 |
9 | {{ source_project.name }}
10 | {% endfor %}
11 | {% if project.request_username_access %}
12 | Username
13 | {% endif %}
14 |
15 |
16 | {% endif %}
17 | {% if project.returned_data_description %}
18 |
19 |
20 | Uploaded data:
21 |
22 |
23 | {{ project.returned_data_description }}
24 |
25 |
26 | {% endif %}
27 |
--------------------------------------------------------------------------------
/open_humans/templates/partials/connection-activity.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | {{ source.verbose_name }}
4 |
5 |
6 |
7 |
8 |
9 |
10 | {% if not user_data.is_connected %}
11 |
12 |
13 | Are you a {{ source.verbose_name }} user?
14 |
15 |
16 |
21 |
22 |
23 | {% else %}
24 |
25 |
26 | Perform a new data import?
27 |
28 |
29 |
30 |
37 |
38 |
39 |
40 | {% endif %}
41 |
42 |
43 |
--------------------------------------------------------------------------------
/open_humans/templates/partials/my-member-data-source.html:
--------------------------------------------------------------------------------
1 | {% load data_import %}
2 | {% load utilities %}
3 |
4 |
5 | {% source_is_public project.id_label as is_public %}
6 | {% include 'partials/public-sharing-button.html' %}
7 |
8 |
9 | {{ project.name }}
10 |
11 |
12 |
13 | {% if data_files %}
14 |
15 |
16 |
17 | File
18 | Size
19 | Downloads
20 | Description
21 |
22 |
23 |
24 | {% for data_file in data_files|dictsort:'basename' %}
25 |
26 |
27 | {{ data_file.basename }}
28 | [Download ]
29 |
30 |
31 |
32 | {{ data_file.size|filesizeformat }}
33 |
34 |
35 |
36 | {{ data_file.access_logs.count }}
37 |
38 |
39 |
40 | {{ data_file.description }}
41 |
42 |
43 | {% endfor %} {# data_file in data_files #}
44 |
45 | {% else %}
46 |
There are not currently any files associated with this source.
47 | {% endif %}
48 |
--------------------------------------------------------------------------------
/open_humans/templates/partials/project-grants-blurb.html:
--------------------------------------------------------------------------------
1 |
Project Grants
2 |
3 |
4 | Do you have an idea for a project that will help grow the Open Humans
5 | ecosystem?
6 |
7 |
8 | You might qualify for a grant of up to $5000 supporting your work!
9 |
10 |
Learn more about project grants
12 |
13 |
--------------------------------------------------------------------------------
/open_humans/templates/partials/project-in-development.html:
--------------------------------------------------------------------------------
1 |
2 |
Project In Development
3 |
4 | This project that has not been reviewed and
5 | approved by Open Humans staff.
6 |
7 |
8 | This project is in development.
9 | Only join if you know & trust the coordinator, and have
10 | been invited to join for testing purposes.
11 |
12 |
13 |
--------------------------------------------------------------------------------
/open_humans/templates/partials/source-in-development.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | This source is in development. Your data will help us develop
4 | data processing! After this is in place, we'll produce files from your data.
5 | Please email
6 | support@openhumans.org
7 | with suggestions or issues.
8 |
9 |
10 |
--------------------------------------------------------------------------------
/open_humans/templates/partials/upload-activity.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | {{ source.verbose_name }}
4 |
5 |
6 |
7 |
8 |
9 |
10 | {% if not user_data.is_connected %}
11 |
12 |
13 | Are you a {{ source.verbose_name }} user?
14 |
15 |
16 |
21 |
22 |
23 | {% else %}
24 |
25 |
26 | Update your {{ source.verbose_name }} data?
27 |
28 |
29 |
42 |
43 |
44 | {% endif %}
45 |
46 |
47 |
--------------------------------------------------------------------------------
/open_humans/templates/partials/visible-public-sharing.html:
--------------------------------------------------------------------------------
1 |
2 | {% if show_toggle_visible_button %}
3 |
22 | {% endif %} {# if show_toggle_visible_button #}
23 |
24 |
--------------------------------------------------------------------------------
/open_humans/templates/scopes/scope-container.html:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenHumans/open-humans/51c6bdb666d6d8ee0cbe227c606584d3f1556969/open_humans/templates/scopes/scope-container.html
--------------------------------------------------------------------------------
/open_humans/templates/socialaccount/authentication_error.html:
--------------------------------------------------------------------------------
1 | {% extends "panel.html" %}
2 |
3 | {% load i18n %}
4 |
5 | {% block head_title %}{% trans "Social Network Login Failure" %}{% endblock %}
6 |
7 | {% block panel_content %}
8 |
{% trans "Social Network Login Failure" %}
9 |
10 |
{% trans "An error occurred while attempting to login via your social network account." %}
11 |
12 | {% comment %}
13 |
14 | Auth error: {{ auth_error }}
15 | Provider: {{ auth_error.provider }}
16 | Code: {{ auth_error.code }}
17 | Exception: {{ auth_error.exception }}
18 |
19 | {% endcomment %}
20 | {% endblock %}
21 |
--------------------------------------------------------------------------------
/open_humans/templates/socialaccount/login_cancelled.html:
--------------------------------------------------------------------------------
1 | {% extends "panel.html" %}
2 |
3 | {% load i18n %}
4 |
5 | {% block head_title %}{% trans "Login Cancelled" %}{% endblock %}
6 |
7 | {% block panel_content %}
8 |
9 |
{% trans "Login Cancelled" %}
10 |
11 | {% url 'account_login' as login_url %}
12 |
13 |
{% blocktrans %}You decided to cancel logging in to our site using one of your existing accounts. If this was a mistake, please proceed to sign in .{% endblocktrans %}
14 |
15 | {% endblock %}
16 |
--------------------------------------------------------------------------------
/open_humans/templates/socialaccount/messages/account_connected.txt:
--------------------------------------------------------------------------------
1 | {% load i18n %}
2 | {% blocktrans %}The social account has been connected.{% endblocktrans %}
3 |
--------------------------------------------------------------------------------
/open_humans/templates/socialaccount/messages/account_connected_other.txt:
--------------------------------------------------------------------------------
1 | {% load i18n %}
2 | {% blocktrans %}The social account is already connected to a different account.{% endblocktrans %}
3 |
--------------------------------------------------------------------------------
/open_humans/templates/socialaccount/messages/account_disconnected.txt:
--------------------------------------------------------------------------------
1 | {% load i18n %}
2 | {% blocktrans %}The social account has been disconnected.{% endblocktrans %}
3 |
--------------------------------------------------------------------------------
/open_humans/templates/socialaccount/snippets/login_extra.html:
--------------------------------------------------------------------------------
1 | {% load socialaccount %}
2 |
--------------------------------------------------------------------------------
/open_humans/templates/socialaccount/snippets/provider_list.html:
--------------------------------------------------------------------------------
1 | {% load socialaccount %}
2 |
3 | {% get_providers as socialaccount_providers %}
4 |
5 | {% for provider in socialaccount_providers %}
6 | {% if provider.id == "openid" %}
7 | {% for brand in provider.get_brands %}
8 |
9 | {{brand.name}}
13 |
14 | {% endfor %}
15 | {% endif %}
16 |
17 | {{provider.name}}
19 |
20 | {% endfor %}
21 |
--------------------------------------------------------------------------------
/open_humans/templatetags/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenHumans/open-humans/51c6bdb666d6d8ee0cbe227c606584d3f1556969/open_humans/templatetags/__init__.py
--------------------------------------------------------------------------------
/open_humans/wsgi.py:
--------------------------------------------------------------------------------
1 | """
2 | WSGI config for open_humans project.
3 |
4 | It exposes the WSGI callable as a module-level variable named ``application``.
5 |
6 | For more information on this file, see
7 | https://docs.djangoproject.com/en/dev/howto/deployment/wsgi/
8 | """
9 |
10 | import logging
11 | import os
12 |
13 | os.environ.setdefault("DJANGO_SETTINGS_MODULE", "open_humans.settings")
14 |
15 | # pylint: disable=wrong-import-position
16 | from django.conf import settings # noqa
17 | from django.core.cache.backends.memcached import BaseMemcachedCache # noqa
18 | from django.core.wsgi import get_wsgi_application # noqa
19 |
20 | logger = logging.getLogger(__name__)
21 |
22 | logger.info("WSGI application starting")
23 |
24 | logger.info("DEBUG: %s", settings.DEBUG)
25 | logger.info("OAUTH2_DEBUG: %s", settings.OAUTH2_DEBUG)
26 | logger.info("LOG_EVERYTHING: %s", settings.LOG_EVERYTHING)
27 |
28 | # Fix django closing connection to MemCachier after every request (#11331)
29 | BaseMemcachedCache.close = lambda self, **kwargs: None
30 |
31 | application = get_wsgi_application()
32 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "open-humans",
3 | "version": "1.0.0",
4 | "license": "MIT",
5 | "description": "Open Humans",
6 | "main": "gulpfile.js",
7 | "author": "Personal Genomes Org",
8 | "repository": {
9 | "type": "git",
10 | "url": "https://github.com/OpenHumans/open-humans.git"
11 | },
12 | "engines": {
13 | "node": "6.x",
14 | "npm": "3.x"
15 | },
16 | "dependencies": {
17 | "autoprefixer": "^6.4.1",
18 | "bootstrap": "^3.3.7",
19 | "browserify": "^13.1.0",
20 | "drmonty-garlicjs": "^1.2.3",
21 | "gulp": "^4.0.2",
22 | "gulp-cssnano": "^2.1.2",
23 | "gulp-eslint": "^3.0.1",
24 | "gulp-jscs": "^4.0.0",
25 | "gulp-load-plugins": "^1.3.0",
26 | "gulp-postcss": "^6.2.0",
27 | "gulp-shell": "^0.5.2",
28 | "gulp-sourcemaps": "^1.6.0",
29 | "gulp-uglify": "^2.0.0",
30 | "gulp-util": "^3.0.7",
31 | "js-cookie": "^2.1.3",
32 | "js-yaml": "^3.6.1",
33 | "lodash": "^4.16.0",
34 | "markdown": "^0.5.0",
35 | "postcss-color-function": "^2.0.1",
36 | "postcss-reporter": "^1.4.1",
37 | "precss": "^1.4.0",
38 | "pretty-hrtime": "^1.0.2",
39 | "rimraf": "^2.5.4",
40 | "select2": "^4.0.5",
41 | "through2": "^2.0.1",
42 | "vinyl-buffer": "^1.0.0",
43 | "watchify": "^3.7.0",
44 | "webshim": "^1.15.10"
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/private_sharing/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenHumans/open-humans/51c6bdb666d6d8ee0cbe227c606584d3f1556969/private_sharing/__init__.py
--------------------------------------------------------------------------------
/private_sharing/admin.py:
--------------------------------------------------------------------------------
1 | from django.contrib import admin
2 |
3 | from . import models
4 |
5 |
6 | class DataRequestProjectMemberAdmin(admin.ModelAdmin):
7 | """
8 | Display and make the 'created' field read-only in the admin interface.
9 | """
10 |
11 | readonly_fields = ("created",)
12 | search_fields = ("member__user__username", "project_member_id", "project__name")
13 | raw_id_fields = ("member",)
14 |
15 |
16 | class DataRequestProjectAdmin(admin.ModelAdmin):
17 | """
18 | set the coordinator field to be raw_id
19 | """
20 |
21 | raw_id_fields = ("coordinator",)
22 |
23 |
24 | admin.site.register(models.ProjectDataFile)
25 | admin.site.register(models.DataRequestProject, DataRequestProjectAdmin)
26 | admin.site.register(models.OAuth2DataRequestProject, DataRequestProjectAdmin)
27 | admin.site.register(models.OnSiteDataRequestProject, DataRequestProjectAdmin)
28 | admin.site.register(models.DataRequestProjectMember, DataRequestProjectMemberAdmin)
29 | admin.site.register(models.FeaturedProject)
30 |
--------------------------------------------------------------------------------
/private_sharing/api_filter_backends.py:
--------------------------------------------------------------------------------
1 | from rest_framework.filters import BaseFilterBackend
2 |
3 |
4 | class ProjectFilterBackend(BaseFilterBackend):
5 | """
6 | Filter that only allows users to see their own objects.
7 | """
8 |
9 | def filter_queryset(self, request, queryset, view):
10 | return queryset.filter(project=request.auth)
11 |
--------------------------------------------------------------------------------
/private_sharing/api_permissions.py:
--------------------------------------------------------------------------------
1 | from rest_framework.permissions import BasePermission
2 |
3 |
4 | class HasValidProjectToken(BasePermission):
5 | """
6 | Return True if the request has a valid project token.
7 | """
8 |
9 | def has_permission(self, request, view):
10 | return bool(request.auth)
11 |
--------------------------------------------------------------------------------
/private_sharing/api_urls.py:
--------------------------------------------------------------------------------
1 | from django.urls import path
2 |
3 | from rest_framework.urlpatterns import format_suffix_patterns
4 |
5 | from . import api_views
6 |
7 | urlpatterns = [
8 | path("project/", api_views.ProjectDataView.as_view()),
9 | path("project/members/", api_views.ProjectMemberDataView.as_view()),
10 | path(
11 | "project/exchange-member/",
12 | api_views.ProjectMemberExchangeView.as_view(),
13 | name="exchange-member",
14 | ),
15 | path("project/message/", api_views.ProjectMessageView.as_view()),
16 | path("project/remove-members/", api_views.ProjectRemoveMemberView.as_view()),
17 | # Views for managing uploaded data files
18 | path("project/files/upload/", api_views.ProjectFileUploadView.as_view()),
19 | path("project/files/delete/", api_views.ProjectFileDeleteView.as_view()),
20 | path(
21 | "project/files/upload/direct/", api_views.ProjectFileDirectUploadView.as_view()
22 | ),
23 | path(
24 | "project/files/upload/complete/",
25 | api_views.ProjectFileDirectUploadCompletionView.as_view(),
26 | ),
27 | ]
28 |
29 | urlpatterns = format_suffix_patterns(urlpatterns)
30 |
--------------------------------------------------------------------------------
/private_sharing/migrations/0002_add_project_data_file.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # Generated by Django 1.10 on 2016-08-01 23:15
3 |
4 | import django.contrib.postgres.fields
5 | from django.db import migrations, models
6 | import django.db.models.deletion
7 |
8 |
9 | class Migration(migrations.Migration):
10 |
11 | initial = True
12 |
13 | dependencies = [
14 | ('private_sharing', '0001_squashed_0034_auto_20160727_2138'),
15 | ('data_import', '0001_squashed_0020_auto_20160729_1632'),
16 | ]
17 |
18 | operations = [
19 |
20 | migrations.CreateModel(
21 | name='ProjectDataFile',
22 | fields=[
23 | ('parent', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, related_name='parent_project_data_file', serialize=False, to='data_import.DataFile')),
24 | ('direct_sharing_project', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='private_sharing.DataRequestProject')),
25 | ],
26 | bases=('data_import.datafile',),
27 | ),
28 | ]
29 |
--------------------------------------------------------------------------------
/private_sharing/migrations/0004_projectdatafile_completed.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # Generated by Django 1.9.9 on 2016-09-26 17:16
3 |
4 | from django.db import migrations, models
5 |
6 |
7 | class Migration(migrations.Migration):
8 |
9 | dependencies = [
10 | ('private_sharing', '0003_auto_20160909_0427'),
11 | ]
12 |
13 | operations = [
14 | migrations.AddField(
15 | model_name='projectdatafile',
16 | name='completed',
17 | field=models.BooleanField(default=False),
18 | ),
19 | ]
20 |
--------------------------------------------------------------------------------
/private_sharing/migrations/0005_auto_20160926_1717.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # Generated by Django 1.9.9 on 2016-09-26 17:17
3 |
4 | from django.db import migrations
5 |
6 |
7 | def migrate_completed(apps, *args):
8 | ProjectDataFile = apps.get_model('private_sharing', 'ProjectDataFile')
9 |
10 | ProjectDataFile.objects.all().update(completed=True)
11 |
12 |
13 | class Migration(migrations.Migration):
14 |
15 | dependencies = [
16 | ('private_sharing', '0004_projectdatafile_completed'),
17 | ]
18 |
19 | operations = [
20 | migrations.RunPython(migrate_completed),
21 | ]
22 |
--------------------------------------------------------------------------------
/private_sharing/migrations/0006_auto_20161102_1932.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # Generated by Django 1.9.9 on 2016-11-02 19:32
3 |
4 | from django.db import migrations, models
5 |
6 |
7 | class Migration(migrations.Migration):
8 |
9 | dependencies = [
10 | ('private_sharing', '0005_auto_20160926_1717'),
11 | ]
12 |
13 | operations = [
14 | migrations.AlterField(
15 | model_name='datarequestproject',
16 | name='info_url',
17 | field=models.URLField(blank=True, verbose_name='URL for general information about your project'),
18 | ),
19 | ]
20 |
--------------------------------------------------------------------------------
/private_sharing/migrations/0008_featuredproject.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # Generated by Django 1.9.9 on 2018-01-05 01:20
3 |
4 | from django.db import migrations, models
5 | import django.db.models.deletion
6 |
7 |
8 | class Migration(migrations.Migration):
9 |
10 | dependencies = [
11 | ('private_sharing', '0007_auto_20171220_2038'),
12 | ]
13 |
14 | operations = [
15 | migrations.CreateModel(
16 | name='FeaturedProject',
17 | fields=[
18 | ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
19 | ('description', models.TextField(blank=True)),
20 | ('project', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='private_sharing.DataRequestProject')),
21 | ],
22 | ),
23 | ]
24 |
--------------------------------------------------------------------------------
/private_sharing/migrations/0009_auto_20180317_2209.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # Generated by Django 1.9.9 on 2018-03-17 22:09
3 |
4 | from django.db import migrations, models
5 |
6 |
7 | class Migration(migrations.Migration):
8 |
9 | dependencies = [
10 | ('private_sharing', '0008_featuredproject'),
11 | ]
12 |
13 | operations = [
14 | migrations.AddField(
15 | model_name='datarequestproject',
16 | name='all_sources_access',
17 | field=models.BooleanField(default=False),
18 | ),
19 | migrations.AddField(
20 | model_name='datarequestprojectmember',
21 | name='all_sources_shared',
22 | field=models.BooleanField(default=False),
23 | ),
24 | ]
25 |
--------------------------------------------------------------------------------
/private_sharing/migrations/0010_datarequestprojectmember_visible.py:
--------------------------------------------------------------------------------
1 | # Generated by Django 2.0.7 on 2018-08-15 21:54
2 |
3 | from django.db import migrations, models
4 |
5 |
6 | class Migration(migrations.Migration):
7 |
8 | dependencies = [
9 | ('private_sharing', '0009_auto_20180317_2209'),
10 | ]
11 |
12 | operations = [
13 | migrations.AddField(
14 | model_name='datarequestprojectmember',
15 | name='visible',
16 | field=models.BooleanField(default=True),
17 | ),
18 | ]
19 |
--------------------------------------------------------------------------------
/private_sharing/migrations/0012_datarequestproject_approval_history.py:
--------------------------------------------------------------------------------
1 | # Generated by Django 2.1.3 on 2019-01-11 20:38
2 |
3 | import django.contrib.postgres.fields
4 | from django.db import migrations, models
5 |
6 |
7 | class Migration(migrations.Migration):
8 |
9 | dependencies = [
10 | ('private_sharing', '0011_auto_20180912_2206'),
11 | ]
12 |
13 | operations = [
14 | migrations.AddField(
15 | model_name='datarequestproject',
16 | name='approval_history',
17 | field=django.contrib.postgres.fields.ArrayField(base_field=django.contrib.postgres.fields.ArrayField(base_field=models.CharField(max_length=32), size=2), default=list, editable=False, size=None),
18 | ),
19 | ]
20 |
--------------------------------------------------------------------------------
/private_sharing/migrations/0013_auto_20190121_2142.py:
--------------------------------------------------------------------------------
1 | # Generated by Django 2.1.3 on 2019-01-21 21:42
2 |
3 | from django.db import migrations, models
4 |
5 |
6 | class Migration(migrations.Migration):
7 |
8 | dependencies = [
9 | ('private_sharing', '0012_datarequestproject_approval_history'),
10 | ]
11 |
12 | operations = [
13 | migrations.AddField(
14 | model_name='datarequestproject',
15 | name='add_data',
16 | field=models.BooleanField(default=False, help_text='If your project collects data, choose "Add data" here. If you choose "Add data", you will need to provide a "Returned data description" below.', verbose_name='Add data'),
17 | ),
18 | migrations.AddField(
19 | model_name='datarequestproject',
20 | name='explore_share',
21 | field=models.BooleanField(default=False, help_text='If your project performs analysis on data, choose "Explore & share".', verbose_name='Explore & share'),
22 | ),
23 | migrations.AlterField(
24 | model_name='datarequestproject',
25 | name='returned_data_description',
26 | field=models.CharField(blank=True, help_text='Leave this blank if your project doesn\'t plan to add or return new data for your members. If your project is set to be displayed under "Add data", then you must provide this information.', max_length=140, verbose_name='Description of data you plan to upload to member accounts (140 characters max)'),
27 | ),
28 | ]
29 |
--------------------------------------------------------------------------------
/private_sharing/migrations/0014_datarequestproject_no_public_data.py:
--------------------------------------------------------------------------------
1 | # Generated by Django 2.1.3 on 2019-01-21 22:11
2 |
3 | from django.db import migrations, models
4 |
5 |
6 | class Migration(migrations.Migration):
7 |
8 | dependencies = [
9 | ('private_sharing', '0013_auto_20190121_2142'),
10 | ]
11 |
12 | operations = [
13 | migrations.AddField(
14 | model_name='datarequestproject',
15 | name='no_public_data',
16 | field=models.BooleanField(default=False),
17 | ),
18 | ]
19 |
--------------------------------------------------------------------------------
/private_sharing/migrations/0015_auto_20190124_1849.py:
--------------------------------------------------------------------------------
1 | # Generated by Django 2.1.5 on 2019-01-24 18:49
2 |
3 | from django.db import migrations
4 |
5 |
6 | class Migration(migrations.Migration):
7 |
8 | dependencies = [
9 | ('private_sharing', '0014_datarequestproject_no_public_data'),
10 | ]
11 |
12 | operations = [
13 | migrations.RemoveField(
14 | model_name='datarequestproject',
15 | name='request_message_permission',
16 | ),
17 | migrations.RemoveField(
18 | model_name='datarequestprojectmember',
19 | name='message_permission',
20 | ),
21 | ]
22 |
--------------------------------------------------------------------------------
/private_sharing/migrations/0016_auto_20190128_2111.py:
--------------------------------------------------------------------------------
1 | # Generated by Django 2.1.5 on 2019-01-28 21:11
2 |
3 | import django.contrib.postgres.fields
4 | from django.db import migrations, models
5 |
6 |
7 | class Migration(migrations.Migration):
8 |
9 | dependencies = [
10 | ('private_sharing', '0015_auto_20190124_1849'),
11 | ]
12 |
13 | operations = [
14 | migrations.AddField(
15 | model_name='datarequestprojectmember',
16 | name='last_authorized',
17 | field=django.contrib.postgres.fields.ArrayField(base_field=django.contrib.postgres.fields.ArrayField(base_field=models.CharField(max_length=32), size=2), default=list, editable=False, size=None),
18 | ),
19 | migrations.AddField(
20 | model_name='datarequestprojectmember',
21 | name='last_joined',
22 | field=django.contrib.postgres.fields.ArrayField(base_field=django.contrib.postgres.fields.ArrayField(base_field=models.CharField(max_length=32), size=2), default=list, editable=False, size=None),
23 | ),
24 | ]
25 |
--------------------------------------------------------------------------------
/private_sharing/migrations/0017_auto_20190212_0511.py:
--------------------------------------------------------------------------------
1 | # Generated by Django 2.1.5 on 2019-02-12 05:11
2 |
3 | import django.contrib.postgres.fields
4 | from django.db import migrations, models
5 |
6 |
7 | class Migration(migrations.Migration):
8 |
9 | dependencies = [
10 | ('private_sharing', '0016_auto_20190128_2111'),
11 | ]
12 |
13 | operations = [
14 | migrations.AlterModelOptions(
15 | name='datarequestproject',
16 | options={'ordering': ['name']},
17 | ),
18 | migrations.AddField(
19 | model_name='datarequestproject',
20 | name='requested_sources',
21 | field=models.ManyToManyField(related_name='requesting_projects', to='private_sharing.DataRequestProject'),
22 | ),
23 | migrations.AddField(
24 | model_name='datarequestprojectmember',
25 | name='granted_sources',
26 | field=models.ManyToManyField(to='private_sharing.DataRequestProject'),
27 | ),
28 | migrations.AlterField(
29 | model_name='datarequestproject',
30 | name='request_sources_access',
31 | field=django.contrib.postgres.fields.ArrayField(base_field=models.CharField(max_length=100), blank=True, default=list, help_text='List of sources this project is requesting access to on Open Humans.', size=None),
32 | ),
33 | ]
34 |
--------------------------------------------------------------------------------
/private_sharing/migrations/0018_oauth2datarequestproject_terms_url.py:
--------------------------------------------------------------------------------
1 | # Generated by Django 2.1.5 on 2019-02-12 21:15
2 |
3 | from django.db import migrations, models
4 |
5 |
6 | class Migration(migrations.Migration):
7 |
8 | dependencies = [
9 | ('private_sharing', '0017_auto_20190212_0511'),
10 | ]
11 |
12 | operations = [
13 | migrations.AddField(
14 | model_name='oauth2datarequestproject',
15 | name='terms_url',
16 | field=models.URLField(default='', help_text='The URL for your "terms of use" policy.', verbose_name='Terms of Use URL'),
17 | preserve_default=False,
18 | ),
19 | ]
20 |
--------------------------------------------------------------------------------
/private_sharing/migrations/0019_auto_20190214_1915.py:
--------------------------------------------------------------------------------
1 | # Generated by Django 2.1.7 on 2019-02-14 19:15
2 |
3 | from django.db import migrations, models
4 |
5 |
6 | class Migration(migrations.Migration):
7 |
8 | dependencies = [
9 | ('private_sharing', '0018_oauth2datarequestproject_terms_url'),
10 | ]
11 |
12 | operations = [
13 | migrations.AlterField(
14 | model_name='oauth2datarequestproject',
15 | name='deauth_webhook',
16 | field=models.URLField(blank=True, default='', help_text="The URL to send a POST to when a member\n requests data erasure. This request will be in the form\n of JSON,\n { 'project_member_id': '12345678', 'erasure_requested': True}", max_length=256, verbose_name='Deauthorization Webhook URL'),
17 | ),
18 | migrations.AlterField(
19 | model_name='oauth2datarequestproject',
20 | name='terms_url',
21 | field=models.URLField(help_text='The URL for your "terms of use" (or "terms of service").', verbose_name='Terms of Use URL'),
22 | ),
23 | ]
24 |
--------------------------------------------------------------------------------
/private_sharing/migrations/0020_auto_20190222_0036.py:
--------------------------------------------------------------------------------
1 | # Generated by Django 2.1.7 on 2019-02-22 00:36
2 |
3 | from django.db import migrations
4 |
5 |
6 | class Migration(migrations.Migration):
7 |
8 | dependencies = [("private_sharing", "0019_auto_20190214_1915")]
9 |
10 | operations = [
11 | migrations.RemoveField(
12 | model_name="datarequestproject", name="request_sources_access"
13 | ),
14 | migrations.RemoveField(
15 | model_name="datarequestprojectmember", name="sources_shared"
16 | ),
17 | ]
18 |
--------------------------------------------------------------------------------
/private_sharing/migrations/0021_auto_20190412_1908.py:
--------------------------------------------------------------------------------
1 | # Generated by Django 2.2 on 2019-04-12 19:08
2 |
3 | from django.db import migrations, models
4 |
5 |
6 | class Migration(migrations.Migration):
7 |
8 | dependencies = [
9 | ("data_import", "0019_datatype"),
10 | ("private_sharing", "0020_auto_20190222_0036"),
11 | ]
12 |
13 | operations = [
14 | migrations.AddField(
15 | model_name="datarequestproject",
16 | name="auto_add_datatypes",
17 | field=models.BooleanField(default=False),
18 | ),
19 | migrations.AddField(
20 | model_name="datarequestproject",
21 | name="registered_datatypes",
22 | field=models.ManyToManyField(to="data_import.DataType"),
23 | ),
24 | migrations.AddField(
25 | model_name="projectdatafile",
26 | name="datatypes",
27 | field=models.ManyToManyField(to="data_import.DataType"),
28 | ),
29 | ]
30 |
--------------------------------------------------------------------------------
/private_sharing/migrations/0022_auto_20190507_1843.py:
--------------------------------------------------------------------------------
1 | # Generated by Django 2.2.1 on 2019-05-07 18:43
2 |
3 | from django.db import migrations, models
4 | import django.db.models.deletion
5 |
6 |
7 | class Migration(migrations.Migration):
8 |
9 | dependencies = [("private_sharing", "0021_auto_20190412_1908")]
10 |
11 | operations = [
12 | migrations.AlterField(
13 | model_name="projectdatafile",
14 | name="direct_sharing_project",
15 | field=models.ForeignKey(
16 | on_delete=django.db.models.deletion.PROTECT,
17 | to="private_sharing.DataRequestProject",
18 | ),
19 | )
20 | ]
21 |
--------------------------------------------------------------------------------
/private_sharing/migrations/0023_auto_20190528_1826.py:
--------------------------------------------------------------------------------
1 | # Generated by Django 2.2.1 on 2019-05-28 18:26
2 |
3 | from django.db import migrations
4 |
5 |
6 | class Migration(migrations.Migration):
7 |
8 | dependencies = [
9 | ("open_humans", "0014_member_password_reset_redirect"),
10 | ("private_sharing", "0022_auto_20190507_1843"),
11 | ]
12 |
13 | operations = [
14 | migrations.AlterUniqueTogether(
15 | name="datarequestprojectmember", unique_together={("member", "project")}
16 | )
17 | ]
18 |
--------------------------------------------------------------------------------
/private_sharing/migrations/0024_auto_20190716_0504.py:
--------------------------------------------------------------------------------
1 | # Generated by Django 2.2.3 on 2019-07-16 05:04
2 |
3 | from django.db import migrations, models
4 |
5 |
6 | class Migration(migrations.Migration):
7 |
8 | dependencies = [("private_sharing", "0023_auto_20190528_1826")]
9 |
10 | operations = [
11 | migrations.AlterField(
12 | model_name="datarequestproject",
13 | name="registered_datatypes",
14 | field=models.ManyToManyField(
15 | blank=True, related_name="source_projects", to="data_import.DataType"
16 | ),
17 | ),
18 | migrations.AlterField(
19 | model_name="datarequestproject",
20 | name="requested_sources",
21 | field=models.ManyToManyField(
22 | blank=True,
23 | related_name="requesting_projects",
24 | to="private_sharing.DataRequestProject",
25 | ),
26 | ),
27 | ]
28 |
--------------------------------------------------------------------------------
/private_sharing/migrations/0025_datarequestproject_any_datatypes.py:
--------------------------------------------------------------------------------
1 | # Generated by Django 2.2.3 on 2019-11-04 22:58
2 |
3 | from django.db import migrations, models
4 |
5 |
6 | class Migration(migrations.Migration):
7 |
8 | dependencies = [("private_sharing", "0024_auto_20190716_0504")]
9 |
10 | operations = [
11 | migrations.AddField(
12 | model_name="datarequestproject",
13 | name="any_datatypes",
14 | field=models.BooleanField(default=False),
15 | )
16 | ]
17 |
--------------------------------------------------------------------------------
/private_sharing/migrations/0026_auto_20191202_2105.py:
--------------------------------------------------------------------------------
1 | # Generated by Django 2.2.7 on 2019-12-02 21:05
2 |
3 | from django.db import migrations, models
4 |
5 |
6 | class Migration(migrations.Migration):
7 |
8 | dependencies = [("private_sharing", "0025_datarequestproject_any_datatypes")]
9 |
10 | operations = [
11 | migrations.AddField(
12 | model_name="datarequestproject",
13 | name="review_url",
14 | field=models.URLField(
15 | blank=True, verbose_name="URL for project approval review"
16 | ),
17 | ),
18 | migrations.AlterField(
19 | model_name="datarequestprojectmember",
20 | name="granted_sources",
21 | field=models.ManyToManyField(
22 | related_name="granted_sources", to="private_sharing.DataRequestProject"
23 | ),
24 | ),
25 | ]
26 |
--------------------------------------------------------------------------------
/private_sharing/migrations/0027_oauth2datarequestproject_webhook_secret.py:
--------------------------------------------------------------------------------
1 | # Generated by Django 2.2.10 on 2020-07-01 21:05
2 |
3 | import django.core.validators
4 | from django.db import migrations, models
5 |
6 |
7 | class Migration(migrations.Migration):
8 |
9 | dependencies = [("private_sharing", "0026_auto_20191202_2105")]
10 |
11 | operations = [
12 | migrations.AddField(
13 | model_name="oauth2datarequestproject",
14 | name="webhook_secret",
15 | field=models.CharField(
16 | blank=True,
17 | help_text="If entered, this string will be used to provide a hash verifying Open Humans as the sender.",
18 | max_length=64,
19 | validators=[
20 | django.core.validators.RegexValidator(regex="[\x00-\x7f]*"),
21 | django.core.validators.MinLengthValidator(16),
22 | ],
23 | ),
24 | )
25 | ]
26 |
--------------------------------------------------------------------------------
/private_sharing/migrations/0028_datarequestproject_jogl_page.py:
--------------------------------------------------------------------------------
1 | # Generated by Django 2.2.10 on 2020-07-16 22:52
2 |
3 | from django.db import migrations, models
4 |
5 |
6 | class Migration(migrations.Migration):
7 |
8 | dependencies = [("private_sharing", "0027_oauth2datarequestproject_webhook_secret")]
9 |
10 | operations = [
11 | migrations.AddField(
12 | model_name="datarequestproject",
13 | name="jogl_page",
14 | field=models.URLField(
15 | blank=True, help_text="JOGL project page URL (optional)"
16 | ),
17 | )
18 | ]
19 |
--------------------------------------------------------------------------------
/private_sharing/migrations/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenHumans/open-humans/51c6bdb666d6d8ee0cbe227c606584d3f1556969/private_sharing/migrations/__init__.py
--------------------------------------------------------------------------------
/private_sharing/static/images/badge.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenHumans/open-humans/51c6bdb666d6d8ee0cbe227c606584d3f1556969/private_sharing/static/images/badge.png
--------------------------------------------------------------------------------
/private_sharing/templates/direct-sharing/layout.html:
--------------------------------------------------------------------------------
1 | {% extends 'base.html' %}
2 |
3 | {% load static %}
4 |
5 | {% block head_title %}Direct sharing{% endblock %}
6 |
7 | {% block main %}
8 |
9 |
10 |
11 |
12 | {% include 'direct-sharing/navigation-items.html' %}
13 |
14 |
15 |
16 |
17 |
18 | {% include 'direct-sharing/navigation-items.html' %}
19 |
20 |
21 |
22 |
23 |
24 | {% block content %}{% endblock %}
25 |
26 |
27 | {% endblock %}
28 |
--------------------------------------------------------------------------------
/private_sharing/templates/direct-sharing/oauth2-data-access.html:
--------------------------------------------------------------------------------
1 | {% extends 'direct-sharing/layout.html' %}
2 |
3 | {% block content %}
4 |
OAuth2 data access
5 |
6 |
7 | Once a member authorizes data sharing, you'll be able to immediately access
8 | that data via our API.
9 |
10 |
11 |
12 | Topics:
13 |
14 |
25 |
26 | {% include 'direct-sharing/partials/data-access.html' with oauth2_project=True %}
27 |
28 | {% include 'direct-sharing/partials/project-info.html' with oauth2_project=True %}
29 |
30 | {% endblock %}
31 |
--------------------------------------------------------------------------------
/private_sharing/templates/direct-sharing/oauth2-data-upload.html:
--------------------------------------------------------------------------------
1 | {% extends 'direct-sharing/layout.html' %}
2 |
3 | {% block content %}
4 |
OAuth2 Data Upload
5 |
6 | {% include 'direct-sharing/partials/data-upload.html' with oauth2_project=True %}
7 |
8 | {% endblock %}
9 |
--------------------------------------------------------------------------------
/private_sharing/templates/direct-sharing/oauth2-features.html:
--------------------------------------------------------------------------------
1 | {% extends 'direct-sharing/layout.html' %}
2 |
3 | {% block content %}
4 |
OAuth2 features
5 |
6 | When is an "OAuth2" project appropriate?
7 |
8 |
9 | "OAuth2 authorization" may be appropriate if...
10 |
11 |
12 | {% include 'direct-sharing/partials/oauth2-appropriate-if.html' %}
13 |
14 |
Features
15 |
16 | Here's a summary of main features:
17 |
18 |
19 | {% include 'direct-sharing/partials/features.html' with oauth2_project=True %}
20 |
21 | {% endblock %}
22 |
--------------------------------------------------------------------------------
/private_sharing/templates/direct-sharing/oauth2-member-removal.html:
--------------------------------------------------------------------------------
1 | {% extends 'direct-sharing/layout.html' %}
2 |
3 | {% block content %}
4 |
5 |
OAuth2 member removal
6 |
7 |
8 | Topics:
9 |
10 |
27 |
28 | {% include 'direct-sharing/partials/member-removal.html' with oauth2_project=True %}
29 |
30 | {% endblock %}
31 |
--------------------------------------------------------------------------------
/private_sharing/templates/direct-sharing/oauth2-messages.html:
--------------------------------------------------------------------------------
1 | {% extends 'direct-sharing/layout.html' %}
2 |
3 | {% block content %}
4 |
5 |
OAuth2 messages
6 |
7 |
8 | Topics:
9 |
10 |
27 |
28 | {% include 'direct-sharing/partials/messages.html' with oauth2_project=True %}
29 |
30 | {% endblock %}
31 |
--------------------------------------------------------------------------------
/private_sharing/templates/direct-sharing/on-site-data-access.html:
--------------------------------------------------------------------------------
1 | {% extends 'direct-sharing/layout.html' %}
2 |
3 | {% block content %}
4 |
On-site data access
5 |
6 |
7 | Once a member authorizes data sharing, you'll be able to immediately access
8 | that data via our API.
9 |
10 |
11 |
12 | Topics:
13 |
14 |
28 |
29 | {% include 'direct-sharing/partials/data-access.html' with on_site_project=True %}
30 |
31 | {% include 'direct-sharing/partials/project-info.html' with on_site_project=True %}
32 |
33 | {% endblock %}
34 |
--------------------------------------------------------------------------------
/private_sharing/templates/direct-sharing/on-site-data-upload.html:
--------------------------------------------------------------------------------
1 | {% extends 'direct-sharing/layout.html' %}
2 |
3 | {% block content %}
4 |
On-site Data Upload
5 |
6 | {% include 'direct-sharing/partials/data-upload.html' with on_site_project=True %}
7 |
8 | {% endblock %}
9 |
--------------------------------------------------------------------------------
/private_sharing/templates/direct-sharing/on-site-features.html:
--------------------------------------------------------------------------------
1 | {% extends 'direct-sharing/layout.html' %}
2 |
3 | {% block content %}
4 |
On-site features
5 |
6 | When is an "on-site" project appropriate?
7 |
8 |
9 | "On-site authorization" may be appropriate if...
10 |
11 |
12 | You just want something simple.
13 | You have limited technical resources.
14 | You are NOT running an accounts-based website or phone app.
15 |
16 |
17 |
Features
18 |
19 | Here's a summary of main features:
20 |
21 |
22 | {% include 'direct-sharing/partials/features.html' with on_site_project=True %}
23 |
24 | {% endblock %}
25 |
--------------------------------------------------------------------------------
/private_sharing/templates/direct-sharing/on-site-member-removal.html:
--------------------------------------------------------------------------------
1 | {% extends 'direct-sharing/layout.html' %}
2 |
3 | {% block content %}
4 |
5 |
On-site member removal
6 |
7 |
8 | Topics:
9 |
10 |
24 |
25 | {% include 'direct-sharing/partials/member-removal.html' with on_site_project=True %}
26 |
27 | {% endblock %}
28 |
--------------------------------------------------------------------------------
/private_sharing/templates/direct-sharing/on-site-messages.html:
--------------------------------------------------------------------------------
1 | {% extends 'direct-sharing/layout.html' %}
2 |
3 | {% block content %}
4 |
5 |
On-site messages
6 |
7 |
8 | Topics:
9 |
10 |
24 |
25 | {% include 'direct-sharing/partials/messages.html' with on_site_project=True %}
26 |
27 | {% endblock %}
28 |
--------------------------------------------------------------------------------
/private_sharing/templates/direct-sharing/on-site-setup.html:
--------------------------------------------------------------------------------
1 | {% extends 'direct-sharing/layout.html' %}
2 |
3 | {% block content %}
4 |
On-site setup
5 |
6 |
7 | Topics:
8 |
9 |
20 |
21 | {% include 'direct-sharing/partials/setup.html' with on_site_project=True %}
22 |
23 | {% endblock %}
24 |
--------------------------------------------------------------------------------
/private_sharing/templates/direct-sharing/partials/about-master-token.html:
--------------------------------------------------------------------------------
1 |
2 | Each project has a "master access token" used for API calls.
3 | This token is a password for your project.
4 |
5 |
6 |
7 | To find the token, your
8 | project management page and click on your project's name. The master
9 | access token should be listed in your project's details.
10 |
11 |
12 |
13 | Keep this token PRIVATE.
14 |
15 |
16 |
17 | Do NOT publicly share this token.
18 | Do NOT share this token in an unsecured manner.
19 | NEVER put this token into a git repository.
20 |
21 |
22 |
23 | This token is used to authorize the following:
24 |
25 |
26 | API access to any private data shared with your project
27 | sending messages to project members via API
28 | uploading data for project members via API
29 |
30 |
31 |
32 | If you ever believe the security of this token may have been compromised,
33 | contact us at support@openhumans.org and we'll reset it to a new
34 | value.
35 |
36 |
37 |
38 | When using this token in programs, we recommend you do NOT store it.
39 | You should enter the token each time you run your software.
40 |
41 |
42 |
43 | If you want to have fully automated API transactions with Open Humans, you
44 | should use OAuth2 endpoints with user-specific access tokens.
45 |
46 |
--------------------------------------------------------------------------------
/private_sharing/templates/direct-sharing/partials/oauth2-appropriate-if.html:
--------------------------------------------------------------------------------
1 |
2 | You're running an accounts-based website or phone app.
3 | You have a pre-existing project.
4 | You're technically inclined.
5 |
6 |
--------------------------------------------------------------------------------
/private_sharing/templates/direct-sharing/partials/on-site-appropriate-if.html:
--------------------------------------------------------------------------------
1 |
2 | You just want something simple.
3 | You have limited technical resources.
4 | You're NOT running a phone app or website with accounts.
5 |
6 |
--------------------------------------------------------------------------------
/private_sharing/templates/direct-sharing/partials/project-info.html:
--------------------------------------------------------------------------------
1 |
API data access: Project information
2 |
3 |
4 | {% if oauth2_project %}OAuth2 and master access tokens can also both{% else %}
5 | Master access tokens can also{% endif %} be used to retrieve information about
6 | the project they are related to.
7 |
8 |
9 |
10 | To use this endpoint, send a secure GET request (using 'https') to the following
11 | URL with the 'access_token' parameter set to access token:
12 |
13 |
14 | https://www.openhumans.org/api/direct-sharing/project/?access_token=<ACCESS_TOKEN>
15 |
16 |
17 |
18 | This returns JSON-formatted data related to the project itself.
19 |
20 |
--------------------------------------------------------------------------------
/private_sharing/templates/email/notify-withdrawal.html:
--------------------------------------------------------------------------------
1 |
2 | Hello,
3 |
4 |
5 |
6 | This email is to inform you that a member, {{ project.project_member.project_member_id }},
7 | has withdrawn their participation from your project.
8 |
9 |
10 | For your convenience, we maintain a list of project members that have requested
11 | withdrawal. It can be found at {{ withdrawn_url }}.
12 |
13 | {% if erasure_requested %}
14 |
15 | In addition, they have requested erasure of their data. We have
16 | deleted the data on our end, and hereby request that you do the same.
17 |
18 | {% endif %}
19 |
20 | Questions? Email us at
21 | support@openhumans.org .
22 |
23 |
24 | Thank you for being a member of our community!
25 |
26 |
27 |
28 | The Open Humans Team
29 |
30 |
31 |
32 | (0) {{ withdrawn_data }}
33 |
34 |
--------------------------------------------------------------------------------
/private_sharing/templates/email/notify-withdrawal.txt:
--------------------------------------------------------------------------------
1 | Hello,
2 |
3 | This email is to inform you that a member, {{ project.project_member.project_member_id }},
4 | has withdrawn their participation from your project.
5 |
6 | For your convenience, we maintain a list of project members that have requested
7 | withdrawal. It can be found at {{ withdrawn_url }}.
8 |
9 | {% if erasure_requested %}
10 | In addition, they have requested erasure of their data. We have
11 | deleted the data on our end, and hereby request that you do the same.
12 |
13 | {% endif %}
14 | Questions? Email us at support@openhumans.org
15 |
16 | Thank you for being a member of our community!
17 |
18 | The Open Humans Team
19 |
--------------------------------------------------------------------------------
/private_sharing/templates/email/project-message.txt:
--------------------------------------------------------------------------------
1 | {{ message }}
2 |
3 | -------------------------------------------------------------------------------
4 |
5 | This email was sent by Open Humans project "{{ project }}" to "{{ username }}".
6 | It has been automatically delivered. The project has not been given your email
7 | address. You have no obligation to reply to this email or take any other action
8 | that might disclose your identity. Open Humans did not review nor retain a copy
9 | of this message’s contents and is not responsible for material sent by this
10 | project. You should retain a copy of this message if you may need it in the
11 | future.
12 |
13 | If you wish to respond using your Project Member ID (i.e. not reveal your
14 | personal email) you can use this form:
15 | <{{ project_message_form }}>
16 |
17 | If you respond directly, the project will know your email address. Your email
18 | will go directly to the project's email address, this communication is not
19 | managed by Open Humans.
20 |
21 | When you authorized this project, you granted permission for it to send you
22 | messages. You may deauthorize this project by visiting the project management
23 | page: <{{ activity_management_url }}>.
24 |
25 | Please report abuses of messaging to Open Humans at
.
26 |
--------------------------------------------------------------------------------
/private_sharing/templates/private_sharing/authorize-inactive.html:
--------------------------------------------------------------------------------
1 | {% extends 'panel.html' %}
2 |
3 | {% block head_title %}
4 | Authorization not possible
5 | {% endblock %}
6 |
7 | {% block panel_content %}
8 |
9 | Unfortunately, this project is not currently active.
10 |
11 |
12 | {% endblock %}
13 |
--------------------------------------------------------------------------------
/private_sharing/templates/private_sharing/authorize-oauth2.html:
--------------------------------------------------------------------------------
1 | {% extends 'private_sharing/authorize-base.html' %}
2 |
3 | {% block form_content %}
4 |
37 | {% endblock %}
38 |
--------------------------------------------------------------------------------
/private_sharing/templates/private_sharing/authorize-on-site.html:
--------------------------------------------------------------------------------
1 | {% extends 'private_sharing/authorize-base.html' %}
2 |
3 | {% block form_content %}
4 |
8 |
9 |
15 |
16 |
17 |
18 |
20 | Hide membership
21 |
22 | If hidden, the project's badge will not appear on your public
23 | profile.
24 |
25 |
26 |
27 |
28 |
29 |
30 |
33 |
34 |
37 |
38 | {% endblock %}
39 |
--------------------------------------------------------------------------------
/private_sharing/templates/private_sharing/create-project.html:
--------------------------------------------------------------------------------
1 | {% extends 'panel.html' %}
2 |
3 | {% load bootstrap_tags %}
4 | {% load static %}
5 |
6 | {% block head_title %}Create a project{% endblock %}
7 |
8 | {% block panel_content %}
9 |
10 | The information you enter below initializes your project. It can all be
11 | edited later! Once initialized, you can start testing and improving your
12 | project.
13 |
14 |
38 | {% endblock %}
39 |
--------------------------------------------------------------------------------
/private_sharing/templates/private_sharing/join-on-site.html:
--------------------------------------------------------------------------------
1 | {% extends 'panel.html' %}
2 |
3 | {% load utilities %}
4 |
5 | {% block head_title %}Join '{{ object.name }}'{% endblock %}
6 |
7 | {% block panel_content %}
8 | {% if not object.approved %}
9 | {% include 'partials/project-in-development.html' %}
10 | {% endif %}
11 | {% if object.project_type == 'activity' %}
12 |
13 | Not a research study. This project is an activity, not a
14 | research study. As such, it has not been through the ethical review process a
15 | human subjects research study would normally undergo. The text below should
16 | describe how this activity plans to interact with you and/or your data.
17 |
18 | {% endif %}
19 |
20 |
21 |
22 | {{ object.consent_text|markdown }}
23 |
24 |
25 |
26 |
39 | {% endblock %}
40 |
--------------------------------------------------------------------------------
/private_sharing/templates/private_sharing/leave-project.html:
--------------------------------------------------------------------------------
1 | {% extends 'panel.html' %}
2 |
3 | {% load utilities %}
4 | {% load private_sharing %}
5 |
6 | {% block head_title %}Confirm removal{% endblock %}
7 |
8 | {% block panel_content %}
9 |
10 |
11 |
Are you sure you want to leave the project
12 | '{{ object.project.name }}' ?
13 |
14 |
15 |
16 |
37 | {% endblock %}
38 |
--------------------------------------------------------------------------------
/private_sharing/templates/private_sharing/message-project-members.html:
--------------------------------------------------------------------------------
1 | {% extends 'panel.html' %}
2 |
3 | {% load bootstrap_tags %}
4 | {% load static %}
5 |
6 | {% block head_title %}Message project members{% endblock %}
7 |
8 | {% block panel_content %}
9 |
10 | Project: {{object.name}}
11 |
12 |
13 | Use the form below to message members of your project.
14 |
15 |
16 |
17 |
28 |
29 | {% endblock %}
30 |
--------------------------------------------------------------------------------
/private_sharing/templates/private_sharing/project-withdrawn-members-view.html:
--------------------------------------------------------------------------------
1 | {% extends 'base.html' %}
2 |
3 | {% load utilities %}
4 |
5 | {% block head_title %}Withdrawn project members{% endblock %}
6 |
7 | {% block main %}
8 |
9 | Members project members
10 |
11 | Below you can find a listing of the project members that have left the
12 | project, and whether they have requested erasure of their data from
13 | "{{ object.name }}".
14 |
15 |
16 |
17 |
18 |
19 |
20 | Project Member ID
21 | Erasure Requested
22 |
23 |
24 |
25 |
26 |
27 | {% for project_member in object_list %}
28 |
29 |
30 |
31 | {{ project_member.project_member_id }}
32 |
33 |
34 | {% template_bool project_member.erasure_requested %}
35 |
36 |
37 |
38 | {% endfor %}
39 |
40 |
41 |
42 |
43 |
44 | {% endblock %}
45 |
--------------------------------------------------------------------------------
/private_sharing/templates/private_sharing/remove-project-members.html:
--------------------------------------------------------------------------------
1 | {% extends 'panel.html' %}
2 |
3 | {% load bootstrap_tags %}
4 | {% load static %}
5 |
6 | {% block head_title %}{{ aoeueoa }}Remove project members{% endblock %}
7 |
8 | {% block panel_content %}
9 |
10 |
Project: {{object.name}}
11 |
12 |
13 | CAUTION: this action cannot be reversed by you!
14 | You can use the form below to remove members from your project.
15 |
16 |
17 |
18 |
29 |
30 | {% endblock %}
31 |
--------------------------------------------------------------------------------
/private_sharing/templates/private_sharing/update-project.html:
--------------------------------------------------------------------------------
1 | {% extends 'panel.html' %}
2 |
3 | {% load bootstrap_tags %}
4 | {% load static %}
5 |
6 | {% block head_title %}Update a project{% endblock %}
7 |
8 | {% block panel_content %}
9 |
10 | Use the form below to edit the information about your project.
11 |
12 |
13 |
14 |
24 |
25 | {% endblock %}
26 |
--------------------------------------------------------------------------------
/private_sharing/templatetags/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenHumans/open-humans/51c6bdb666d6d8ee0cbe227c606584d3f1556969/private_sharing/templatetags/__init__.py
--------------------------------------------------------------------------------
/private_sharing/templatetags/private_sharing.py:
--------------------------------------------------------------------------------
1 | from django import template
2 | from django.utils.safestring import mark_safe
3 |
4 | from private_sharing.models import DataRequestProject
5 |
6 | register = template.Library()
7 |
8 |
9 | @register.simple_tag()
10 | def erasure_requested_checkbox(object):
11 | """
12 | If a Data Request Project supports member data erasure, then return the
13 | html to produce a checkbox to request this.
14 | """
15 | html = """
16 |
17 |
18 |
19 |
20 | Request that {0} deletes my data
21 |
22 |
23 | """
24 | erasure_supported = object.project.erasure_supported
25 | if erasure_supported == True:
26 | return mark_safe(str(html).format(object.project.name))
27 | else:
28 | return ""
29 |
--------------------------------------------------------------------------------
/public_data/__init__.py:
--------------------------------------------------------------------------------
1 | default_app_config = "public_data.apps.PublicDataConfig"
2 |
--------------------------------------------------------------------------------
/public_data/admin.py:
--------------------------------------------------------------------------------
1 | # from django.contrib import admin
2 |
3 | # Register your models here.
4 |
--------------------------------------------------------------------------------
/public_data/apps.py:
--------------------------------------------------------------------------------
1 | from django.apps import AppConfig
2 |
3 |
4 | class PublicDataConfig(AppConfig):
5 | """
6 | Configure the public data application.
7 | """
8 |
9 | name = "public_data"
10 | verbose_name = "Public Data"
11 |
12 | def ready(self):
13 | # Make sure our signal handlers get hooked up
14 |
15 | # pylint: disable=unused-variable
16 | import public_data.signals # noqa
17 |
--------------------------------------------------------------------------------
/public_data/migrations/0002_auto_20171213_1947.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # Generated by Django 1.9.9 on 2017-12-13 19:47
3 |
4 | from django.db import migrations
5 |
6 |
7 | class Migration(migrations.Migration):
8 |
9 | dependencies = [
10 | ('public_data', '0001_squashed_0004_auto_20151230_0050'),
11 | ]
12 |
13 | operations = [
14 | migrations.RemoveField(
15 | model_name='participant',
16 | name='enrollment_date',
17 | ),
18 | migrations.RemoveField(
19 | model_name='participant',
20 | name='signature',
21 | ),
22 | ]
23 |
--------------------------------------------------------------------------------
/public_data/migrations/0003_auto_20190508_2341.py:
--------------------------------------------------------------------------------
1 | # Generated by Django 2.2.1 on 2019-05-08 23:41
2 |
3 | from django.db import migrations, models
4 | import django.db.models.deletion
5 |
6 |
7 | class Migration(migrations.Migration):
8 |
9 | dependencies = [
10 | ("private_sharing", "0022_auto_20190507_1843"),
11 | ("public_data", "0002_auto_20171213_1947"),
12 | ]
13 |
14 | operations = [
15 | migrations.AddField(
16 | model_name="publicdataaccess",
17 | name="project_membership",
18 | field=models.OneToOneField(
19 | null=True,
20 | on_delete=django.db.models.deletion.CASCADE,
21 | to="private_sharing.DataRequestProjectMember",
22 | ),
23 | ),
24 | migrations.AlterField(
25 | model_name="publicdataaccess",
26 | name="data_source",
27 | field=models.CharField(max_length=100, null=True),
28 | ),
29 | ]
30 |
--------------------------------------------------------------------------------
/public_data/migrations/0005_auto_20190508_2342.py:
--------------------------------------------------------------------------------
1 | # Generated by Django 2.2.1 on 2019-05-08 23:42
2 |
3 | from django.db import migrations, models
4 | import django.db.models.deletion
5 |
6 |
7 | class Migration(migrations.Migration):
8 |
9 | dependencies = [("public_data", "0004_migrate_data_20190508")]
10 |
11 | operations = [
12 | migrations.RemoveField(model_name="publicdataaccess", name="data_source"),
13 | migrations.AlterField(
14 | model_name="publicdataaccess",
15 | name="project_membership",
16 | field=models.OneToOneField(
17 | on_delete=django.db.models.deletion.CASCADE,
18 | to="private_sharing.DataRequestProjectMember",
19 | ),
20 | ),
21 | ]
22 |
--------------------------------------------------------------------------------
/public_data/migrations/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenHumans/open-humans/51c6bdb666d6d8ee0cbe227c606584d3f1556969/public_data/migrations/__init__.py
--------------------------------------------------------------------------------
/public_data/signals.py:
--------------------------------------------------------------------------------
1 | from django.db.models.signals import post_save
2 | from django.dispatch import receiver
3 |
4 | from .models import Participant
5 |
6 |
7 | @receiver(post_save, sender=Participant)
8 | def post_save_cb(sender, instance, created, raw, update_fields, **kwargs):
9 | """
10 | Set all PublicDataAccess objects' is_public to false when a user leaves the
11 | public sharing study.
12 | """
13 | # If the model was updated but not created or udpated as part of a fixture
14 | if raw or created:
15 | return
16 |
17 | if not instance.enrolled:
18 | for public_data_access in instance.publicdataaccess_set.all():
19 | public_data_access.is_public = False
20 | public_data_access.save(update_fields=["is_public"])
21 |
--------------------------------------------------------------------------------
/public_data/static/docs/Consent_Document_20141212_(stamped).pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenHumans/open-humans/51c6bdb666d6d8ee0cbe227c606584d3f1556969/public_data/static/docs/Consent_Document_20141212_(stamped).pdf
--------------------------------------------------------------------------------
/public_data/static/docs/Consent_Document_20160128_(stamped).pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenHumans/open-humans/51c6bdb666d6d8ee0cbe227c606584d3f1556969/public_data/static/docs/Consent_Document_20160128_(stamped).pdf
--------------------------------------------------------------------------------
/public_data/static/docs/Research_Protocol_20141212.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenHumans/open-humans/51c6bdb666d6d8ee0cbe227c606584d3f1556969/public_data/static/docs/Research_Protocol_20141212.pdf
--------------------------------------------------------------------------------
/public_data/static/docs/Research_Protocol_20160128.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenHumans/open-humans/51c6bdb666d6d8ee0cbe227c606584d3f1556969/public_data/static/docs/Research_Protocol_20160128.pdf
--------------------------------------------------------------------------------
/public_data/static/images/public-data-sharing-badge.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenHumans/open-humans/51c6bdb666d6d8ee0cbe227c606584d3f1556969/public_data/static/images/public-data-sharing-badge.png
--------------------------------------------------------------------------------
/public_data/templates/public_data/withdraw.html:
--------------------------------------------------------------------------------
1 | {% extends 'base.html' %}
2 |
3 | {% block main %}
4 |
5 | By deactivating the "public data sharing" feature you will also mark all of
6 | your data files as private.
7 |
8 |
9 |
14 | {% endblock main %}
15 |
--------------------------------------------------------------------------------
/public_data/urls.py:
--------------------------------------------------------------------------------
1 | from django.urls import path
2 | from django.views.decorators.http import require_POST
3 |
4 | from .views import (
5 | ActivateOverviewView,
6 | ConsentView,
7 | HomeView,
8 | QuizView,
9 | ToggleSharingView,
10 | WithdrawView,
11 | )
12 |
13 | app_name = "public-data"
14 |
15 | urlpatterns = [
16 | path("", HomeView.as_view(), name="home"),
17 | # Enrollment process pages. User must be logged in to access.
18 | path(
19 | "activate-1-overview/", ActivateOverviewView.as_view(), name="enroll-overview"
20 | ),
21 | path("activate-2-information/", ConsentView.as_view(), name="enroll-information"),
22 | path("activate-3-quiz/", QuizView.as_view(), name="enroll-quiz"),
23 | path(
24 | "activate-4-complete/",
25 | require_POST(ConsentView.as_view()),
26 | name="enroll-signature",
27 | ),
28 | # Withdraw from the public data study
29 | path("deactivate/", WithdrawView.as_view(), name="deactivate"),
30 | # Data management
31 | path("toggle-sharing/", ToggleSharingView.as_view(), name="toggle-sharing"),
32 | ]
33 |
--------------------------------------------------------------------------------
/requirements.in:
--------------------------------------------------------------------------------
1 | -e git+https://github.com/beaugunderson/django-storages-s3upload.git#egg=django-storages-s3upload
2 |
3 | # 20200507 Added to enable Apple OAuth from a feature PR in progress.
4 | -e git+https://github.com/gedankenstuecke/django-allauth.git@c9aa44fb22771b00f70ed68d1030aad44bbe9ae2#egg=django-allauth
5 |
6 | ansicolors
7 | arrow
8 | beautifulsoup4
9 | bleach
10 | boto3==1.12
11 | brotlipy
12 | celery==5.4.0
13 | cffi==1.16.0
14 | dj-database-url
15 | Django==3.2
16 | #django-allauth
17 | django-appconf
18 | django-autoslug
19 | django-bmemcached
20 | django-bootstrap-pagination
21 | django-cors-headers
22 | django-debug-toolbar
23 | django-extensions
24 | django-filter
25 | django-forms-bootstrap
26 | django-heroku
27 | django-ipware
28 | django-oauth-toolkit
29 | django-recaptcha
30 | django-storages==1.9.1
31 | django-waffle==0.20.0
32 | django_coverage_plugin
33 | djangorestframework
34 | factory-boy
35 | feedparser
36 | gevent
37 | gunicorn
38 | Jinja2
39 | jsonfield # can't remove this because migrations depend on it presently
40 | mailchimp
41 | Markdown
42 | mock
43 | Pillow # for sorl-thumbnail
44 | psycopg2==2.9.9
45 | pyparsing
46 | PyJWT
47 | raven
48 | redis
49 | requests
50 | selenium
51 | sorl-thumbnail
52 | termcolor
53 |
54 | # modules we control
55 | django-gulp
56 | django-hash-filter2
57 | env-tools
58 |
--------------------------------------------------------------------------------
/runtime.txt:
--------------------------------------------------------------------------------
1 | python-3.10.14
2 |
--------------------------------------------------------------------------------
/scripts/benchmark.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | ENV="staging"
4 | # ENV="www"
5 |
6 | ab -c 10 -t 300 -s 30 "https://$ENV.openhumans.org/member/beau/"
7 |
8 | echo "https://$ENV.openhumans.org/members/" > urls.txt
9 | echo "https://$ENV.openhumans.org/member/beau/" >> urls.txt
10 | echo "https://$ENV.openhumans.org/" >> urls.txt
11 |
12 | siege --file urls.txt --quiet --internet --time 5m
13 |
--------------------------------------------------------------------------------
/scripts/dump-production.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | COMMAND="./manage.py dumpdata --natural-foreign --natural-primary -e admin -e contenttypes -e auth.Permission -e auth.Group -e sessions --indent=2"
4 |
5 | production run "$COMMAND"
6 |
--------------------------------------------------------------------------------
/scripts/migrate_s3.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # pylint: disable=wrong-import-order
3 |
4 | import boto3
5 | import os
6 | import re
7 |
8 | from env_tools import apply_env
9 |
10 | apply_env()
11 |
12 | import django # noqa
13 |
14 | os.environ.setdefault("DJANGO_SETTINGS_MODULE", "open_humans.settings")
15 |
16 | django.setup()
17 |
18 | from data_import.models import DataFile # noqa
19 | from data_import.utils import get_upload_path # noqa
20 |
21 | BUCKET_NAME = "open-humans-production"
22 |
23 | s3 = boto3.resource("s3")
24 |
25 | bucket = s3.Bucket(BUCKET_NAME)
26 |
27 | for key in bucket.objects.all():
28 | if not re.match(r"^member/", key.key):
29 | continue
30 |
31 | if "profile-images" in key.key:
32 | continue
33 |
34 | try:
35 | data_file = DataFile.objects.get(file=key.key)
36 | except DataFile.DoesNotExist:
37 | print("Does not exist: {}".format(key.key))
38 |
39 | continue
40 | except DataFile.MultipleObjectsReturned:
41 | print("Multiple objects: {}".format(key.key))
42 |
43 | continue
44 |
45 | file_name = os.path.basename(key.key)
46 |
47 | new_key = get_upload_path(data_file, file_name)
48 |
49 | print(key.key)
50 | print(" {}".format(file_name))
51 | print(" {}".format(new_key))
52 | print("")
53 |
54 | s3.Object(BUCKET_NAME, new_key).copy_from(
55 | CopySource="{0}/{1}".format(BUCKET_NAME, key.key)
56 | )
57 |
58 | data_file.file = new_key
59 | data_file.save()
60 |
61 | key.delete()
62 |
--------------------------------------------------------------------------------
/static/css/_footer.css:
--------------------------------------------------------------------------------
1 | /* Sticky footer styles
2 | -------------------------------------------------- */
3 | $footer-height: 60px;
4 | $footer-border-color: $navbar-border-color;
5 | $footer-border-thickness: $navbar-border-thickness;
6 |
7 | html {
8 | position: relative;
9 | min-height: 100%;
10 | }
11 |
12 | body {
13 | /* Margin bottom by footer height */
14 | margin-bottom: $footer-height;
15 | }
16 |
17 | .footer {
18 | position: absolute;
19 | bottom: 0;
20 | width: 100%;
21 | /* Set the fixed height of the footer here */
22 | height: $footer-height;
23 | background-color: #ffffff;
24 | border-color: $footer-border-color;
25 | border-width: $footer-border-thickness 0 0;
26 | border-style: solid;
27 | }
28 |
29 | .footer > .container-fluid,
30 | .footer > .container {
31 | padding: 15px;
32 | }
33 |
--------------------------------------------------------------------------------
/static/css/_global-variables.css:
--------------------------------------------------------------------------------
1 | /* Colors
2 | -------------------------------------------------- */
3 | $oh-teal: #4ac1c8;
4 | $oh-teal-dark: #009fa8;
5 | $oh-teal-verydark: #008c94;
6 | $oh-teal-verylight: #e6f9fa;
7 |
8 | $oh-orange: #ff9161;
9 | $oh-orange-verylight: #fff1eb;
10 | $oh-orange-dark: #f7763e;
11 |
12 | $oh-gray-verydark: #4d4d4d;
13 |
14 | $oh-background-image: '/static/images/get2014_background.jpg';
15 |
16 | /* Navbar styles
17 | -------------------------------------------------- */
18 | $navbar-height: 50px;
19 | $navbar-border-thickness: 0px;
20 | $navbar-background-color: #ffffff;
21 | $navbar-background-color-active: $oh-teal-verylight;
22 | $navbar-border-color: $fff;
23 | $navbar-color: $oh-teal-dark;
24 | $navbar-color-focus-hover: $oh-teal-verydark;
25 | $navbar-color-active: $oh-teal-verydark;
26 |
27 |
28 | /* Fonts
29 | -------------------------------------------------- */
30 | $user-input-font: 'Merriweather', 'Palatino Linotype', 'Book Antiqua', Palatino, serif;
31 | $heading-font: 'Montserrat', sans-serif;
32 | $main-font: 'Montserrat', sans-serif;
33 |
--------------------------------------------------------------------------------
/static/css/_pages-members.css:
--------------------------------------------------------------------------------
1 | .member-profile-img {
2 | width: 30px;
3 | height: 30px;
4 | }
5 |
--------------------------------------------------------------------------------
/static/css/_text.css:
--------------------------------------------------------------------------------
1 | /* Text, links, and header styles
2 | -------------------------------------------------- */
3 | h1, h2, h3, h4, h5, h6,
4 | .h1, .h2, .h3, .h4, .h5, .h6 {
5 | font-family: $heading-font;
6 | font-weight: 300;
7 | color: $oh-gray-verydark;
8 | }
9 |
10 | body {
11 | font-family: $main-font;
12 | }
13 |
14 | a {
15 | color: $oh-teal-dark;
16 |
17 | &:hover, &:focus {
18 | color: $oh-teal-verydark;
19 | }
20 | }
21 |
22 | h6.section-header {
23 | margin-top: 15px;
24 | margin-bottom: 0;
25 | }
26 |
27 | hr.section-header {
28 | margin-top: 0;
29 | margin-bottom: 10px;
30 | }
31 |
32 | .profile-text {
33 | font-family: $user-input-font;
34 |
35 | h1, .h1, h2, .h2, h3, .h3, h4, .h4, h5, .h5, h6, .h6 {
36 | font-family: $user-input-font;
37 | }
38 |
39 | h1, .h1, h2, .h2, h3, .h3 {
40 | margin-top: 10px;
41 | margin-bottom: 5px;
42 | font-weight: 700;
43 | }
44 |
45 | h1, .h1 {
46 | font-size: 24px;
47 | }
48 |
49 | h2, .h2 {
50 | font-size: 21px;
51 | }
52 |
53 | h3, .h3 {
54 | font-size: 18px;
55 | }
56 |
57 | h4, .h5 {
58 | font-size: 15px;
59 | }
60 |
61 | h5, .h5 {
62 | font-size: 12px;
63 | }
64 |
65 | h6, .h6 {
66 | font-size: 9px;
67 | }
68 | }
69 |
70 | .bigger-text {
71 | font-size: 18px;
72 | }
73 |
--------------------------------------------------------------------------------
/static/css/main.css:
--------------------------------------------------------------------------------
1 | @import '_global-variables.css';
2 | @import '_navbar.css';
3 | @import '_buttons.css';
4 | @import '_text.css';
5 | @import '_footer.css';
6 | @import '_divs.css';
7 | @import '_pages.css';
8 |
9 | /* The blurred background image shown on every page */
10 | #blurred-people-background {
11 | width: 100%;
12 | height: 100%;
13 | z-index: -1;
14 | position: absolute;
15 | background-size: cover;
16 | background-position: center;
17 | /* The actual image URL is specified in a template block */
18 | }
19 |
20 | /* TODO: Move somewhere appropriate */
21 | .profile-image {
22 | width: 30%;
23 | margin-left: 2%;
24 | float: right;
25 | max-width: 250px;
26 | }
27 |
28 | /* Messages
29 | -------------------------------------------------- */
30 | .message {
31 | margin: 15px 0;
32 | padding: 15px;
33 | background-color: #ddf9ff;
34 | border-style: solid;
35 | border-color: $oh-indigo-muted;
36 | border-width: 2px;
37 | border-radius: 6px;
38 |
39 | &.error {
40 | background-color: #ffeeee;
41 | border-color: #cc0000;
42 | font-weight: 800;
43 | }
44 |
45 | &.success {
46 | background-color: #d9ffee;
47 | border-color: #00aa22;
48 | }
49 | }
50 |
51 | /* Site-wide modals
52 | -------------------------------------------------- */
53 | #signup-modal {
54 | overflow: scroll;
55 | }
56 |
--------------------------------------------------------------------------------
/static/images/FB-F.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenHumans/open-humans/51c6bdb666d6d8ee0cbe227c606584d3f1556969/static/images/FB-F.png
--------------------------------------------------------------------------------
/static/images/FB-f-Logo__blue_29.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenHumans/open-humans/51c6bdb666d6d8ee0cbe227c606584d3f1556969/static/images/FB-f-Logo__blue_29.png
--------------------------------------------------------------------------------
/static/images/Mad-Ball.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenHumans/open-humans/51c6bdb666d6d8ee0cbe227c606584d3f1556969/static/images/Mad-Ball.jpg
--------------------------------------------------------------------------------
/static/images/apple-logo-white-large-3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenHumans/open-humans/51c6bdb666d6d8ee0cbe227c606584d3f1556969/static/images/apple-logo-white-large-3x.png
--------------------------------------------------------------------------------
/static/images/bastian-greshake-tzovaras.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenHumans/open-humans/51c6bdb666d6d8ee0cbe227c606584d3f1556969/static/images/bastian-greshake-tzovaras.jpg
--------------------------------------------------------------------------------
/static/images/connect-data.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenHumans/open-humans/51c6bdb666d6d8ee0cbe227c606584d3f1556969/static/images/connect-data.png
--------------------------------------------------------------------------------
/static/images/default-badge.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenHumans/open-humans/51c6bdb666d6d8ee0cbe227c606584d3f1556969/static/images/default-badge.png
--------------------------------------------------------------------------------
/static/images/email-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenHumans/open-humans/51c6bdb666d6d8ee0cbe227c606584d3f1556969/static/images/email-icon.png
--------------------------------------------------------------------------------
/static/images/get2014_background.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenHumans/open-humans/51c6bdb666d6d8ee0cbe227c606584d3f1556969/static/images/get2014_background.jpg
--------------------------------------------------------------------------------
/static/images/google-logo-g.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenHumans/open-humans/51c6bdb666d6d8ee0cbe227c606584d3f1556969/static/images/google-logo-g.png
--------------------------------------------------------------------------------
/static/images/knight-logo-300.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenHumans/open-humans/51c6bdb666d6d8ee0cbe227c606584d3f1556969/static/images/knight-logo-300.jpg
--------------------------------------------------------------------------------
/static/images/mdulaney.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenHumans/open-humans/51c6bdb666d6d8ee0cbe227c606584d3f1556969/static/images/mdulaney.jpg
--------------------------------------------------------------------------------
/static/images/oh-connect-study.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenHumans/open-humans/51c6bdb666d6d8ee0cbe227c606584d3f1556969/static/images/oh-connect-study.png
--------------------------------------------------------------------------------
/static/images/oh-public-data.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenHumans/open-humans/51c6bdb666d6d8ee0cbe227c606584d3f1556969/static/images/oh-public-data.png
--------------------------------------------------------------------------------
/static/images/oh-research-help.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenHumans/open-humans/51c6bdb666d6d8ee0cbe227c606584d3f1556969/static/images/oh-research-help.png
--------------------------------------------------------------------------------
/static/images/oh-research-partner.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenHumans/open-humans/51c6bdb666d6d8ee0cbe227c606584d3f1556969/static/images/oh-research-partner.png
--------------------------------------------------------------------------------
/static/images/open-humans-logo-horizontal-80px.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenHumans/open-humans/51c6bdb666d6d8ee0cbe227c606584d3f1556969/static/images/open-humans-logo-horizontal-80px.png
--------------------------------------------------------------------------------
/static/images/open_humans_favicon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenHumans/open-humans/51c6bdb666d6d8ee0cbe227c606584d3f1556969/static/images/open_humans_favicon.png
--------------------------------------------------------------------------------
/static/images/open_humans_logo_only.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenHumans/open-humans/51c6bdb666d6d8ee0cbe227c606584d3f1556969/static/images/open_humans_logo_only.png
--------------------------------------------------------------------------------
/static/images/profile-placeholder.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenHumans/open-humans/51c6bdb666d6d8ee0cbe227c606584d3f1556969/static/images/profile-placeholder.png
--------------------------------------------------------------------------------
/static/images/project-1-draft.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenHumans/open-humans/51c6bdb666d6d8ee0cbe227c606584d3f1556969/static/images/project-1-draft.png
--------------------------------------------------------------------------------
/static/images/project-2-test.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenHumans/open-humans/51c6bdb666d6d8ee0cbe227c606584d3f1556969/static/images/project-2-test.png
--------------------------------------------------------------------------------
/static/images/project-3-try.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenHumans/open-humans/51c6bdb666d6d8ee0cbe227c606584d3f1556969/static/images/project-3-try.png
--------------------------------------------------------------------------------
/static/images/rwjf_logo1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenHumans/open-humans/51c6bdb666d6d8ee0cbe227c606584d3f1556969/static/images/rwjf_logo1.png
--------------------------------------------------------------------------------
/static/images/share-data.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenHumans/open-humans/51c6bdb666d6d8ee0cbe227c606584d3f1556969/static/images/share-data.png
--------------------------------------------------------------------------------
/static/images/twitter-xs-logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenHumans/open-humans/51c6bdb666d6d8ee0cbe227c606584d3f1556969/static/images/twitter-xs-logo.png
--------------------------------------------------------------------------------
/static/images/your-data-plus-you-sketch.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenHumans/open-humans/51c6bdb666d6d8ee0cbe227c606584d3f1556969/static/images/your-data-plus-you-sketch.jpg
--------------------------------------------------------------------------------
/static/js/about.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var navPills = require('./lib/nav-pills.js');
4 |
5 | navPills();
6 |
--------------------------------------------------------------------------------
/static/js/account-password-reset-token.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | $(function () {
4 | $('#id_password').attr('required', '');
5 | $('#id_password_confirm').attr('required', '');
6 |
7 | $('#id_password').attr('minlength', '8');
8 | $('#id_password_confirm').attr('minlength', '8');
9 |
10 | $('#id_password_confirm').attr('data-parsley-equalto', '#id_password');
11 | });
12 |
--------------------------------------------------------------------------------
/static/js/account-password.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | $(function () {
4 | $('#id_password_current').attr('required', '');
5 |
6 | $('#id_password_new').attr('required', '');
7 | $('#id_password_new_confirm').attr('required', '');
8 |
9 | $('#id_password_new').attr('minlength', '8');
10 | $('#id_password_new_confirm').attr('minlength', '8');
11 |
12 | $('#id_password_new_confirm').attr('data-parsley-equalto', '#id_password_new');
13 | });
14 |
--------------------------------------------------------------------------------
/static/js/activity-management.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var publicSharingToggle = require('./lib/public-sharing-toggle.js');
4 | var publicVisibleToggle = require('./lib/public-visible-toggle.js');
5 |
6 | $(function () {
7 | $('[data-toggle="popover"]').popover({html: true, trigger: 'focus'});
8 |
9 | publicSharingToggle();
10 |
11 | $('form.delete-selfie-file').on('click', 'input[type=submit]', function (e) {
12 | e.preventDefault();
13 |
14 | var $form = $(this).parent();
15 | var formUrl = $form.attr('action');
16 |
17 | var self = this;
18 |
19 | $.post(formUrl, $form.serialize(), function () {
20 | var $tr = $(self).parents('tr').eq(0);
21 |
22 | $tr.hide('slow', function () {
23 | $tr.remove();
24 | });
25 | }).fail(function () {
26 | // fall back to a regular form submission if AJAX doesn't work
27 | $form.submit();
28 | });
29 | });
30 | });
31 |
--------------------------------------------------------------------------------
/static/js/add-data.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | $(function () {
4 | $('[data-toggle="popover"]').popover({html: true, trigger: 'focus'});
5 |
6 | var $grid = $('.grid').isotope({
7 | itemSelector: '.item',
8 | layoutMode: 'masonry',
9 | masonry: {
10 | columnWidth: '.col-md-4',
11 | percentPosition: true
12 | }
13 | });
14 |
15 | $('.grid').imagesLoaded(function () {
16 | $('.grid').isotope('layout');
17 | });
18 |
19 | });
20 |
--------------------------------------------------------------------------------
/static/js/community-guidelines.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var navPills = require('./lib/nav-pills.js');
4 |
5 | navPills();
6 |
--------------------------------------------------------------------------------
/static/js/explore-share.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | $(function () {
4 | $('[data-toggle="popover"]').popover({html: true, trigger: 'focus'});
5 |
6 | var $grid = $('.grid').isotope({
7 | itemSelector: '.item',
8 | layoutMode: 'masonry',
9 | masonry: {
10 | columnWidth: '.col-md-4',
11 | percentPosition: true
12 | }
13 | });
14 |
15 | $('.grid').imagesLoaded(function () {
16 | $('.grid').isotope('layout');
17 | });
18 |
19 | });
20 |
--------------------------------------------------------------------------------
/static/js/home.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | function getHashFilter() {
4 | var matches = location.hash.match(/filter=([^&]+)/i);
5 | var filter = matches && matches[1];
6 |
7 | return (filter && decodeURIComponent(filter)) || '*';
8 | }
9 |
10 | $(function () {
11 | $('[data-toggle="popover"]').popover({html: true, trigger: 'focus'});
12 |
13 | var $grid = $('.grid').isotope({
14 | itemSelector: '.item',
15 | layoutMode: 'masonry',
16 | masonry: {
17 | columnWidth: '.col-md-4',
18 | percentPosition: true
19 | }
20 | });
21 |
22 | $('.grid').imagesLoaded(function () {
23 | $('.grid').isotope('layout');
24 | });
25 |
26 | function onHashchange() {
27 | var filter = getHashFilter();
28 |
29 | $('.filters button').removeClass('selected');
30 | $('.filters button[data-filter="' + filter + '"]').addClass('selected');
31 |
32 | $('.filter-empty').hide();
33 |
34 | $('.filter-description').hide();
35 | $('.filter-description[data-filter="' + filter + '"]').show();
36 |
37 | $grid.isotope({filter: filter});
38 |
39 | var filteredItems = $('.grid ' + filter);
40 |
41 | if (!filteredItems.length) {
42 | $('.filter-description').hide();
43 | $('.filter-empty[data-filter="' + getHashFilter() + '"]').show();
44 | }
45 | }
46 |
47 | $('.filters button').click(function () {
48 | location.hash = 'filter=' +
49 | encodeURIComponent($(this).attr('data-filter'));
50 | });
51 |
52 | $(window).on('hashchange', onHashchange);
53 |
54 | onHashchange();
55 | });
56 |
--------------------------------------------------------------------------------
/static/js/lib/enable-csrf.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var Cookies = require('js-cookie');
4 |
5 | function csrfSafeMethod(method) {
6 | // These HTTP methods do not require CSRF protection
7 | return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
8 | }
9 |
10 | module.exports = function ($) {
11 | var csrfToken = Cookies.get('csrftoken');
12 |
13 | $.ajaxSetup({
14 | beforeSend: function (xhr, settings) {
15 | if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
16 | xhr.setRequestHeader('X-CSRFToken', csrfToken);
17 | }
18 | }
19 | });
20 | };
21 |
--------------------------------------------------------------------------------
/static/js/lib/nav-pills.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | function updatePill() {
4 | var url = document.location.toString();
5 |
6 | if (url.match('#')) {
7 | $('.nav-pills a[href="#' + url.split('#')[1] + '"]').tab('show');
8 | }
9 | }
10 |
11 | module.exports = function () {
12 | $(function () {
13 | // Change the hash when a user clicks on a nav-pill link
14 | $('.nav-pills a, .table-of-contents a').on('click', function (e) {
15 | e.preventDefault();
16 |
17 | history.pushState({}, '', e.target.hash);
18 |
19 | updatePill();
20 | });
21 |
22 | // Show the correct page when the hash changes
23 | $(window).on('popstate', function () {
24 | updatePill();
25 | });
26 |
27 | updatePill();
28 | });
29 | };
30 |
--------------------------------------------------------------------------------
/static/js/lib/public-sharing-toggle.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | module.exports = function () {
4 | // AJAX toggling for public data sharing
5 | $('form.toggle-sharing').on('click', 'button[type=submit]', function (e) {
6 | e.preventDefault();
7 |
8 | var self = this;
9 | $(self).html("Updating...");
10 | $(self).prop("disabled", true);
11 |
12 | var $form = $(this).parent();
13 | var formUrl = $form.attr('action');
14 |
15 | var isPublic = $(this).siblings('input[name=public]').val() === 'True';
16 |
17 | var newState = isPublic ? 'False' : 'True';
18 | var newValue = isPublic ? 'Stop public sharing' : 'Share publicly';
19 |
20 | $.post(formUrl, $form.serialize(), function () {
21 | $(self).html(newValue);
22 | $(self).removeAttr('disabled')
23 | $(self).siblings('input[name=public]').val(newState);
24 | }).fail(function () {
25 | // fall back to a regular form submission if AJAX doesn't work
26 | $form.submit();
27 | });
28 | });
29 | };
30 |
--------------------------------------------------------------------------------
/static/js/lib/public-visible-toggle.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | module.exports = function () {
4 | // AJAX toggling for public data visibility
5 | $('form.toggle-visibility').on('click', 'button[type=submit]', function (e) {
6 | e.preventDefault();
7 |
8 | var self = this;
9 | $(self).html("Updating...");
10 | $(self).prop("disabled", true);
11 |
12 | var $form = $(this).parent();
13 | var formUrl = $form.attr('action');
14 |
15 | var isVisible = $(this).siblings('input[name=visible]').val() === 'True';
16 |
17 | var newState = isVisible ? 'False' : 'True';
18 | var newValue = isVisible ? 'Visible' : 'Hidden';
19 |
20 | $.post(formUrl, $form.serialize(), function () {
21 | $(self).html(newValue);
22 | $(self).removeAttr('disabled')
23 | $(self).siblings('input[name=visible]').val(newState);
24 | }).fail(function () {
25 | // fall back to a regular form submission if AJAX doesn't work
26 | $form.submit();
27 | });
28 | });
29 | };
30 |
--------------------------------------------------------------------------------
/static/js/member-detail.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | $(function () {
4 | $('[data-toggle="popover"]').popover({html: true, trigger: 'focus'});
5 | });
6 |
--------------------------------------------------------------------------------
/static/js/member-me-research-data.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var publicSharingToggle = require('./lib/public-sharing-toggle.js');
4 |
5 | $(function () {
6 | $('[data-toggle="popover"]').popover({html: true, trigger: 'focus'});
7 |
8 | publicSharingToggle();
9 |
10 | $('form.delete-selfie-file').on('click', 'input[type=submit]', function (e) {
11 | e.preventDefault();
12 |
13 | var $form = $(this).parent();
14 | var formUrl = $form.attr('action');
15 |
16 | var self = this;
17 |
18 | $.post(formUrl, $form.serialize(), function () {
19 | var $tr = $(self).parents('tr').eq(0);
20 |
21 | $tr.hide('slow', function () {
22 | $tr.remove();
23 | });
24 | }).fail(function () {
25 | // fall back to a regular form submission if AJAX doesn't work
26 | $form.submit();
27 | });
28 | });
29 | });
30 |
--------------------------------------------------------------------------------
/static/js/my-member-data-selfie.js:
--------------------------------------------------------------------------------
1 | /*global SELFIE_ACKNOWLEDGE_URL:true, SELFIE_SHOW_MODAL:true*/
2 |
3 | 'use strict';
4 |
5 | var enableCsrf = require('./lib/enable-csrf.js');
6 | var publicSharingToggle = require('./lib/public-sharing-toggle.js');
7 |
8 | enableCsrf($);
9 |
10 | $(function () {
11 | $('[data-toggle="popover"]').popover({html: true, trigger: 'focus'});
12 |
13 | publicSharingToggle();
14 |
15 | $('.delete-button').click(function (e) {
16 | e.preventDefault();
17 | });
18 |
19 | if (!SELFIE_SHOW_MODAL) {
20 | return;
21 | }
22 |
23 | $('#data-selfie-modal').modal({
24 | keyboard: false,
25 | backdrop: 'static'
26 | });
27 |
28 | $('#continue').click(function (e) {
29 | e.preventDefault();
30 |
31 | $('#data-selfie-modal').modal('hide');
32 |
33 | $.post(SELFIE_ACKNOWLEDGE_URL);
34 | });
35 | });
36 |
--------------------------------------------------------------------------------
/static/js/public-data-api.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | $(function () {
4 | var $sourceSearch = $('#source-search').select2({
5 | placeholder: 'Select an activity',
6 | theme: 'bootstrap'
7 | });
8 |
9 | $sourceSearch.on('select2:select', function () {
10 | var url = 'https://www.openhumans.org/api/public-data/?source=' +
11 | $sourceSearch.val();
12 |
13 | $('#source-url').html('' + url + ' ');
14 | });
15 | });
16 |
--------------------------------------------------------------------------------
/static/js/studies-connect.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | $(function () {
4 | $('[data-toggle="popover"]').popover({html: true});
5 | });
6 |
--------------------------------------------------------------------------------