diff --git a/.gitignore b/.gitignore
index 72364f9..62616a4 100644
--- a/.gitignore
+++ b/.gitignore
@@ -23,6 +23,15 @@ var/
*.egg-info/
.installed.cfg
*.egg
+envNeuro/
+.DS_Store
+bin/
+man/
+pip-selfcheck.json
+pyvenv.cfg
+share/
+
+
# PyInstaller
# Usually these files are written by a python script from a template
diff --git a/.travis.yml b/.travis.yml
new file mode 100644
index 0000000..90c9361
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,18 @@
+language: python
+python:
+- '2.7'
+- '3.5'
+before_install:
+- pip install -U pip setuptools
+- pip install six
+install:
+- pip install -r requirements.pip
+env:
+ global:
+ - secure: O0pOPi+1KGOJMaKqJB+09lRhIsXSNP7ycGn9jsJhvN6XljHBK+bgqWEriSNZ2y01l8GKy+fcnNuiMQLDIc4tQvFkxmYUhoBClkcx12Css1glS9cYpssmbav1YvazKdPL6Y/XdDTtA7na1ggPUaV3Ww4zcIazxOPifnR+Rc5YwGxFBsv0cVRGaAZ8Z7XeqitV7M1DxYa4i2O0hTWQEkw5d9BQH+kZxvervSIE4e4RrPvkopvsXd/Al1djTsJA3ZX0qvCyykuMwANj2ERes9ye2SvP5+etugdmeo267nsXasFN+FO2x+IZYWBNGL8Yl689pOuiGdmvvuP5pG1VYRi+cyk2nMZUC+aN0iuipocfLqJTjaZg7rjdjpRy22M/9eQbMBAUBKHSUkeaLDba+lpvbNiY6ybKQZlwd2pKQZSjHHsAa3lgBG3WduNSCGEKCsKmUgGBRn1c4h5yQFXcHjIRdqr9k21tbF6hCE/LJJoWJEY5XIJIqboitGvNcxWF3qtfau+koTYqH8ZufePOikkKvxiOpoK0bML1HViBdCvSFNB7ioYsLTqXaCN4RhXRUuFrU1O7k4wTZXoLLvyhIYIdnwjpXJX+7HgZq7ieIvAIYkB9rX199xK8cgKb/3WjMGZ7AEF1y4Tay8dRGcAsPu/MUBTSm/BzJvXB+Yy/SrqIXNk=
+script:
+ - cd neuropy
+ - ./manage.py test
+
+notifications:
+ email: false
\ No newline at end of file
diff --git a/README.md b/README.md
index e2699bd..b38de24 100644
--- a/README.md
+++ b/README.md
@@ -1,2 +1,147 @@
# NeuroPy
+[](https://travis-ci.org/NeuroPyPlanner/NeuroPy)
+
Personalized CBT-based priority planner
+
+## Creators:
+
+[Amos Bolder](https://github.com/amosboldor) | [Claire Gatenby](https://github.com/clair3st) | [Patrick Saunders](https://github.com/pasaunders) | [Sera Smith](https://github.com/serashioda)
+
+### URL: [HERE](http://ec2-52-14-126-118.us-east-2.compute.amazonaws.com/)
+
+### About the App:
+A personalized priority app to support a *Cognitive Behavioral Therapy* (CBT) approach to efficiently organize your day according to a struggle/disorder that is effectively treated by CBT. CBT is a goal-oriented pyschotherapy treatment, taking a hands-on approach to problem solving. Goal of CBT is to change the patterns of thinking or behavior that are behind a person's difficulties, modifying their feelings and therefore their thinking and behavior overtime.
+
+*Neuropy* Considers what the habit/disorder the user wants to treat with CBT, along with medication, it's half-life and peak periods. Also works around black-out periods on user's schedule by syncing with Google Calender, personal preference or most productive period of the day for user, and finally considers time commitments for each activity. Each "TO-DO" will be ranked considering these aspects and will be worked into periods of the day.
+
+##### version-0.1 (in active development)
+##### Keywords:
+
+No medical data is stored by NeuroPy
+
+##Getting Started
+
+Clone this repository into whatever directory you want to work from.
+```
+https://github.com/NeuroPyPlanner/NeuroPy.git
+```
+Assuming that you have access to Python 3 at the system level, start up a new virtual environment.
+```
+$ cd NeuroPy
+$ python3 -m venv ENV
+$ source ENV/bin/activate
+```
+Once your environment has been activated, make sure to install Django and all of this project's required packages.
+```
+(NeuroPy) $ pip install -r requirements.pip
+```
+Navigate to the project root, imagersite, and apply the migrations for the app.
+```
+(NeuroPy) $ cd imagersite
+
+(NeuroPy) $ ./manage.py migrate
+```
+Finally, run the server in order to server the app on localhost
+```
+(NeuroPy) $ ./manage.py runserver
+```
+Django will typically serve on port 8000, unless you specify otherwise. You can access the locally-served site at the address http://localhost:8000.
+
+
+##Current Models (outside of Django built-ins):
+
+This application allow users to store and organize photos.
+
+**The `Profile` model contains:**
+
+- The period which the user is up and active
+- The time of day when a user is best able to focus and work
+- The time of day when a user takes their medication
+- A __str__ method which returns the user's username.
+
+**The `Todo` model contains:**
+
+- Date
+- Ease of accomplishing the task
+- Duration of task
+- Owner of the task
+- Title of the task
+- Description
+- Priority level
+- A __str__ method which returns the task title
+
+**The `Medication` model contains:**
+
+- Name
+- Medication Type
+- Use (on or off label)
+- Half life
+- Ramp-up time
+- Peak Period
+- Start and end times for the easy, medium and peak energy periods
+ represented as a comma seperated set of integers where the first
+ integer represents the number of hours since the user took the
+ medicaion, and the second integer representing the number of extra
+ minutes.
+- A __str__ method which returns the medication's name
+
+##Current URL Routes
+
+- `/oauth2/` Google calendar request authorization
+- `/admin` Superuser admin page.
+- `/` Home page.
+- `/login` Login page.
+- `/logout` Logout route, no view.
+- `/accounts/register` Register a user form.
+- `/accounts/activate/complete/` Activation complete view.
+- `/accounts/register/complete/` Registration complete, email sent.
+- `/profile/` Links to the following routes:
+ - `/` Shows the user their profile data.
+ - `/edit/` Allows the user to edit their profile
+- `/profile/todo/ Links to the following routes:
+ - `/calendar/` Allows the user to view their schedule
+ - `/schedule/` Shows the user's to-do list ordered by priority and difficulty
+ - `/[todo_id]/edit/` Allows the user to edit their to-do items
+ - `/[todo_id]/` Detail view for an individula to-do item
+ - `/add/` Allows the user to create a new to-do item
+ - `/` Shows the user a summary of all their to-do items
+
+
+##Running Tests
+
+Running tests for the NeuroPy is fairly straightforward. Navigate to the same directory as the manage.py file and type:
+```
+(NeuroPy) $ coverage run manage.py test
+```
+This will show you which tests have failed, which tests have passed. If you'd like a report of the actual coverage of your tests, type
+```
+(NeuroPy) $ coverage report
+```
+This will read from the included .coverage file, with configuration set in the .coveragerc file. Currently the configuration will show which lines were missing from the test coverage.
+
+
+### USER STORIES:
+
+#### User Stories
+
+- As a user I want the app to use good CBT principles so that I can effectively manage my energy.
+- As a user I want the app to take my medications into account so that I can work at my highest-focus time of day.
+- As a user I want the app to take in my personal preferences into account so that I don’t work on easy tasks when I have energy and hard tasks when I’m tired.
+- As a user I want the app to preserve my preferences so that I can conveniently generate new schedules.
+- As a user I want to be able to input my personal preferences and data easily and accurately so that the app can prioritize my day effectively.
+- As a user I want my medical data to be secure so that I can avoid fraud and identity theft.
+- As a user I want to be able to quickly generate schedules with minimal clicks so that I don’t have to spend all my energy organizing.
+- As a user I want my newly generated schedule to be integrated into my google calendar with notifications.
+- As a user I want the app to take into account my sleep schedule so that I can work when I have the most energy.
+
+
+#### Developer Stories
+
+- As a developer I want readable and well documented code to make maintenance easier.
+- As a developer I want to practise test driven development in building my app and spotting bugs early on.
+- As a developer I want to avoid storing any medical data so that I don’t have to deal with HIPAA violations.
+- As a developer I want to store data of users in appropriate models, with logical relationships.
+- As a developer I want to build for one disorder before expanding so that I can build on a strong foundation.
+- As a developer I want a narrow open source license so that we retain plenty of rights to our work.
+- As a developer I want to write an algorithm that prioritises todos based on a user’s profile.
+- As a developer I want to integrate the google calendars with my app using an api.
diff --git a/neuropy/.coveragerc b/neuropy/.coveragerc
new file mode 100644
index 0000000..6f834f5
--- /dev/null
+++ b/neuropy/.coveragerc
@@ -0,0 +1,21 @@
+[run]
+omit =
+ */migrations/*,
+ */tests.py
+ manage.py
+ neuropy/wsgi.py
+ neuropy/urls.py
+ neuropy/views.py
+ */envNeuro/*
+ */apps.py
+ */admin.py
+ */__init__.py
+
+source =
+ neuropy
+ medication
+ todo
+ userprofile
+
+[report]
+show_missing = True
\ No newline at end of file
diff --git a/neuropy/manage.py b/neuropy/manage.py
new file mode 100755
index 0000000..19d8b1d
--- /dev/null
+++ b/neuropy/manage.py
@@ -0,0 +1,22 @@
+#!/usr/bin/env python
+import os
+import sys
+
+if __name__ == "__main__":
+ os.environ.setdefault("DJANGO_SETTINGS_MODULE", "neuropy.settings")
+ try:
+ from django.core.management import execute_from_command_line
+ except ImportError:
+ # The above import may fail for some other reason. Ensure that the
+ # issue is really that Django is missing to avoid masking other
+ # exceptions on Python 2.
+ try:
+ import django
+ except ImportError:
+ raise ImportError(
+ "Couldn't import Django. Are you sure it's installed and "
+ "available on your PYTHONPATH environment variable? Did you "
+ "forget to activate a virtual environment?"
+ )
+ raise
+ execute_from_command_line(sys.argv)
diff --git a/neuropy/medication/__init__.py b/neuropy/medication/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/neuropy/medication/admin.py b/neuropy/medication/admin.py
new file mode 100644
index 0000000..23c2c1f
--- /dev/null
+++ b/neuropy/medication/admin.py
@@ -0,0 +1,4 @@
+from django.contrib import admin
+from medication.models import Medication
+
+admin.site.register(Medication)
diff --git a/neuropy/medication/apps.py b/neuropy/medication/apps.py
new file mode 100644
index 0000000..e095071
--- /dev/null
+++ b/neuropy/medication/apps.py
@@ -0,0 +1,7 @@
+from __future__ import unicode_literals
+
+from django.apps import AppConfig
+
+
+class MedicationConfig(AppConfig):
+ name = 'medication'
diff --git a/neuropy/medication/fixtures/medication.json b/neuropy/medication/fixtures/medication.json
new file mode 100644
index 0000000..a68dcf3
--- /dev/null
+++ b/neuropy/medication/fixtures/medication.json
@@ -0,0 +1,112 @@
+[
+ {
+ "fields":{
+ "treating_dis":"ADD/ADHD",
+ "name":"CONCERTA",
+ "post_peak_medium_end":"12:00:00",
+ "post_peak_medium_start":"09:30:00",
+ "ramp_up":"03:30:00",
+ "half_life":"03:30:00",
+ "medium_end":"05:00:00",
+ "medium_start":"03:30:00",
+ "peak_period":"09:30:00",
+ "med_type":"stimulant",
+ "peak_end":"09:30:00",
+ "post_peak_easy_start":"12:00:00",
+ "post_peak_easy_end":"16:00:00",
+ "peak_start":"00:00:00",
+ "easy_start":"00:00:00",
+ "easy_end":"03:30:00"
+ },
+ "model":"medication.medication",
+ "pk":1
+ },
+ {
+ "fields":{
+ "treating_dis":"ADD/ADHD",
+ "name":"ADDERALL",
+ "post_peak_medium_end":"12:00:00",
+ "post_peak_medium_start":"09:30:00",
+ "ramp_up":"07:00:00",
+ "half_life":"10:00:00",
+ "medium_end":"05:00:00",
+ "medium_start":"03:30:00",
+ "peak_period":"09:30:00",
+ "med_type":"stimulant",
+ "peak_end":"09:30:00",
+ "post_peak_easy_start":"12:00:00",
+ "post_peak_easy_end":"16:00:00",
+ "peak_start":"00:00:00",
+ "easy_start":"00:00:00",
+ "easy_end":"03:30:00"
+ },
+ "model":"medication.medication",
+ "pk":2
+ },
+ {
+ "fields":{
+ "treating_dis":"ADD/ADHD",
+ "name":"Focalin",
+ "post_peak_medium_end":"12:00:00",
+ "post_peak_medium_start":"09:30:00",
+ "ramp_up":"06:30:00",
+ "half_life":"07:00:00",
+ "medium_end":"05:00:00",
+ "medium_start":"03:30:00",
+ "peak_period":"09:30:00",
+ "med_type":"stimulant",
+ "peak_end":"09:30:00",
+ "post_peak_easy_start":"12:00:00",
+ "post_peak_easy_end":"16:00:00",
+ "peak_start":"00:00:00",
+ "easy_start":"00:00:00",
+ "easy_end":"03:30:00"
+ },
+ "model":"medication.medication",
+ "pk":3
+ },
+ {
+ "fields":{
+ "treating_dis":"ADD/ADHD",
+ "name":"Ritalin LA",
+ "post_peak_medium_end":"12:00:00",
+ "post_peak_medium_start":"09:30:00",
+ "ramp_up":"07:00:00",
+ "half_life":"03:30:00",
+ "medium_end":"05:00:00",
+ "medium_start":"03:30:00",
+ "peak_period":"09:30:00",
+ "med_type":"stimulant",
+ "peak_end":"09:30:00",
+ "post_peak_easy_start":"12:00:00",
+ "post_peak_easy_end":"16:00:00",
+ "peak_start":"00:00:00",
+ "easy_start":"00:00:00",
+ "easy_end":"03:30:00"
+ },
+ "model":"medication.medication",
+ "pk":5
+ },
+ {
+ "fields":{
+ "treating_dis":"ADD/ADHD",
+ "name":"Vyvanse",
+ "post_peak_medium_end":"12:00:00",
+ "post_peak_medium_start":"09:30:00",
+ "ramp_up":"02:00:00",
+ "half_life":"11:00:00",
+ "medium_end":"05:00:00",
+ "medium_start":"03:30:00",
+ "peak_period":"09:30:00",
+ "med_type":"stimulant",
+ "peak_end":"09:30:00",
+ "post_peak_easy_start":"12:00:00",
+ "post_peak_easy_end":"16:00:00",
+ "peak_start":"00:00:00",
+ "easy_start":"00:00:00",
+ "easy_end":"03:30:00"
+ },
+ "model":"medication.medication",
+ "pk":6
+ }
+]
\ No newline at end of file
diff --git a/neuropy/medication/migrations/0001_initial.py b/neuropy/medication/migrations/0001_initial.py
new file mode 100644
index 0000000..972c277
--- /dev/null
+++ b/neuropy/medication/migrations/0001_initial.py
@@ -0,0 +1,40 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.10.5 on 2017-02-17 01:28
+from __future__ import unicode_literals
+
+import django.core.validators
+from django.db import migrations, models
+import re
+
+
+class Migration(migrations.Migration):
+
+ initial = True
+
+ dependencies = [
+ ]
+
+ operations = [
+ migrations.CreateModel(
+ name='Medication',
+ fields=[
+ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('name', models.CharField(default='CONCERTA', max_length=20)),
+ ('med_type', models.CharField(default='stimulant', max_length=20)),
+ ('treating_dis', models.CharField(default='ADD/ADHD', max_length=25)),
+ ('half_life', models.DurationField()),
+ ('ramp_up', models.DurationField()),
+ ('peak_period', models.DurationField()),
+ ('easy_start', models.CharField(max_length=50, validators=[django.core.validators.RegexValidator(re.compile('^\\d+(?:\\,\\d+)*\\Z', 32), code='invalid', message='Enter only digits separated by commas.')])),
+ ('easy_end', models.CharField(max_length=50, validators=[django.core.validators.RegexValidator(re.compile('^\\d+(?:\\,\\d+)*\\Z', 32), code='invalid', message='Enter only digits separated by commas.')])),
+ ('medium_start', models.CharField(max_length=50, validators=[django.core.validators.RegexValidator(re.compile('^\\d+(?:\\,\\d+)*\\Z', 32), code='invalid', message='Enter only digits separated by commas.')])),
+ ('medium_end', models.CharField(max_length=50, validators=[django.core.validators.RegexValidator(re.compile('^\\d+(?:\\,\\d+)*\\Z', 32), code='invalid', message='Enter only digits separated by commas.')])),
+ ('peak_start', models.CharField(max_length=50, validators=[django.core.validators.RegexValidator(re.compile('^\\d+(?:\\,\\d+)*\\Z', 32), code='invalid', message='Enter only digits separated by commas.')])),
+ ('peak_end', models.CharField(max_length=50, validators=[django.core.validators.RegexValidator(re.compile('^\\d+(?:\\,\\d+)*\\Z', 32), code='invalid', message='Enter only digits separated by commas.')])),
+ ('post_peak_medium_start', models.CharField(max_length=50, validators=[django.core.validators.RegexValidator(re.compile('^\\d+(?:\\,\\d+)*\\Z', 32), code='invalid', message='Enter only digits separated by commas.')])),
+ ('post_peak_medium_end', models.CharField(max_length=50, validators=[django.core.validators.RegexValidator(re.compile('^\\d+(?:\\,\\d+)*\\Z', 32), code='invalid', message='Enter only digits separated by commas.')])),
+ ('post_peak_easy_start', models.CharField(max_length=50, validators=[django.core.validators.RegexValidator(re.compile('^\\d+(?:\\,\\d+)*\\Z', 32), code='invalid', message='Enter only digits separated by commas.')])),
+ ('post_peak_easy_end', models.CharField(max_length=50, validators=[django.core.validators.RegexValidator(re.compile('^\\d+(?:\\,\\d+)*\\Z', 32), code='invalid', message='Enter only digits separated by commas.')])),
+ ],
+ ),
+ ]
diff --git a/neuropy/medication/migrations/0002_auto_20170216_1728.py b/neuropy/medication/migrations/0002_auto_20170216_1728.py
new file mode 100644
index 0000000..5af5f74
--- /dev/null
+++ b/neuropy/medication/migrations/0002_auto_20170216_1728.py
@@ -0,0 +1,25 @@
+"""."""
+
+# -*- coding: utf-8 -*-
+# Generated by Django 1.10.5 on 2017-02-14 00:12
+from __future__ import unicode_literals
+
+from django.db import migrations
+
+
+def load_medications_from_fixture(apps, schema_editor):
+ """."""
+ from django.core.management import call_command
+ call_command("loaddata", "medication")
+
+
+class Migration(migrations.Migration):
+ """."""
+
+ dependencies = [
+ ('medication', '0001_initial'),
+ ]
+
+ operations = [
+ migrations.RunPython(load_medications_from_fixture),
+ ]
diff --git a/neuropy/medication/migrations/__init__.py b/neuropy/medication/migrations/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/neuropy/medication/models.py b/neuropy/medication/models.py
new file mode 100644
index 0000000..a932bbc
--- /dev/null
+++ b/neuropy/medication/models.py
@@ -0,0 +1,35 @@
+"""Medication model- no user relation."""
+
+from __future__ import unicode_literals
+
+from django.db import models
+from django.utils.encoding import python_2_unicode_compatible
+from django.core.validators import validate_comma_separated_integer_list
+
+
+@python_2_unicode_compatible
+class Medication(models.Model):
+ """Medication instace class."""
+
+ name = models.CharField(
+ max_length=20,
+ default='CONCERTA')
+ med_type = models.CharField(max_length=20, default='stimulant')
+ treating_dis = models.CharField(max_length=25, default='ADD/ADHD')
+ half_life = models.DurationField()
+ ramp_up = models.DurationField()
+ peak_period = models.DurationField()
+ easy_start = models.CharField(validators=[validate_comma_separated_integer_list], max_length=50)
+ easy_end = models.CharField(validators=[validate_comma_separated_integer_list], max_length=50)
+ medium_start = models.CharField(validators=[validate_comma_separated_integer_list], max_length=50)
+ medium_end = models.CharField(validators=[validate_comma_separated_integer_list], max_length=50)
+ peak_start = models.CharField(validators=[validate_comma_separated_integer_list], max_length=50)
+ peak_end = models.CharField(validators=[validate_comma_separated_integer_list], max_length=50)
+ post_peak_medium_start = models.CharField(validators=[validate_comma_separated_integer_list], max_length=50)
+ post_peak_medium_end = models.CharField(validators=[validate_comma_separated_integer_list], max_length=50)
+ post_peak_easy_start = models.CharField(validators=[validate_comma_separated_integer_list], max_length=50)
+ post_peak_easy_end = models.CharField(validators=[validate_comma_separated_integer_list], max_length=50)
+
+ def __str__(self):
+ """String representation of Medication."""
+ return self.name
diff --git a/neuropy/medication/tests.py b/neuropy/medication/tests.py
new file mode 100644
index 0000000..780d698
--- /dev/null
+++ b/neuropy/medication/tests.py
@@ -0,0 +1,82 @@
+"""Tests for medication app."""
+
+from django.test import TestCase
+from medication.models import Medication
+import factory
+import datetime
+import dateutil
+
+class MedicationTestCase(TestCase):
+ """Test the Medication model."""
+
+ def setUp(self):
+ """Setup for medications."""
+ self.medications = [medication for medication in Medication.objects.all()]
+
+ def test_all_meds_are_present(self):
+ """Test top all ADHD medications are present."""
+ self.assertTrue(self.medications[0].name == 'CONCERTA')
+ self.assertTrue(self.medications[1].name == 'ADDERALL')
+ self.assertTrue(self.medications[2].name == 'Focalin')
+ self.assertTrue(self.medications[3].name == 'Ritalin LA')
+ self.assertTrue(self.medications[4].name == 'Vyvanse')
+
+ def test_medication1_info_is_correct(self):
+ """Test that a medication instance has a name."""
+ med1 = self.medications[0]
+ self.assertTrue(med1.name == "CONCERTA")
+ self.assertTrue(med1.med_type == 'stimulant')
+ self.assertTrue(med1.treating_dis == 'ADD/ADHD')
+ self.assertTrue(med1.half_life == datetime.timedelta(hours=3, minutes=30))
+ self.assertTrue(med1.ramp_up == datetime.timedelta(hours=3, minutes=30))
+
+ def test_treating_disorder_are_all_same(self):
+ """Test that a medication instance has a name."""
+ for medication in self.medications:
+ self.assertTrue(medication.treating_dis == "ADD/ADHD")
+
+ def test_med_type_are_all_same(self):
+ """Test medicatcion instance type."""
+ for medication in self.medications:
+ self.assertTrue(medication.med_type == "stimulant")
+
+ def test_no_dupelicate_medication(self):
+ """Test that there are no duplicates of a medication."""
+ seen_meds = []
+ for medication in self.medications:
+ if medication in seen_meds:
+ raise ValueError("Medication already exists")
+ else:
+ seen_meds.append(medication)
+ return seen_meds
+
+ def test_peak_start_is_before_peak_end(self):
+ """Test that peak start time is before peak end."""
+ for medication in self.medications:
+ self.assertTrue(medication.peak_start < medication.peak_end)
+
+ def test_medication_duration(self):
+ """Test medication peak duration is equal to diff between peak-end and start."""
+ for medication in self.medications:
+ peak_end = dateutil.parser.parse(medication.peak_end)
+ peak_start = dateutil.parser.parse(medication.peak_start)
+ peak_delta = peak_end - peak_start
+ peak_period = medication.peak_period
+ self.assertTrue(peak_delta == peak_period)
+
+ def test_change_data(self):
+ """Test Editing medication data."""
+ medication = self.medications[1]
+ medication = Medication.objects.get(id=medication.id)
+ medication.peak_period = datetime.timedelta(hours=10)
+ medication.save()
+ medication = Medication.objects.get(id=medication.id)
+ self.assertTrue(medication.peak_period == datetime.timedelta(hours=10))
+
+ def test_delete_med(self):
+ """Test fetching medication after delete throws an exception."""
+ medication = self.medications[1]
+ medication = Medication.objects.get(id=medication.id)
+ medication.delete()
+ with self.assertRaises(Medication.DoesNotExist):
+ Medication.objects.get(id=medication.id)
diff --git a/neuropy/medication/views.py b/neuropy/medication/views.py
new file mode 100644
index 0000000..91ea44a
--- /dev/null
+++ b/neuropy/medication/views.py
@@ -0,0 +1,3 @@
+from django.shortcuts import render
+
+# Create your views here.
diff --git a/neuropy/neuropy/__init__.py b/neuropy/neuropy/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/neuropy/neuropy/oauth.py b/neuropy/neuropy/oauth.py
new file mode 100644
index 0000000..b4d8bf0
--- /dev/null
+++ b/neuropy/neuropy/oauth.py
@@ -0,0 +1,29 @@
+"""Code for return auth."""
+from oauth2client.contrib.django_util.storage import DjangoORMStorage
+from django.contrib.auth.decorators import login_required
+from oauth2client.client import OAuth2WebServerFlow
+from userprofile.models import CredentialsModel
+from django.http import HttpResponseBadRequest
+from django.http import HttpResponseRedirect
+from oauth2client.contrib import xsrfutil
+from neuropy import settings
+
+FLOW = OAuth2WebServerFlow(
+ client_id=settings.GOOGLE_OAUTH2_CLIENT_ID,
+ client_secret=settings.GOOGLE_OAUTH2_CLIENT_SECRET,
+ scope='https://www.googleapis.com/auth/calendar',
+ redirect_uri='http://localhost:8000/oauth2callback',
+ prompt='consent'
+)
+
+
+@login_required
+def auth_return(request):
+ """Oauth return view."""
+ if not xsrfutil.validate_token(settings.SECRET_KEY, request.GET['state'],
+ request.user):
+ return HttpResponseBadRequest()
+ credential = FLOW.step2_exchange(request.GET['code'])
+ storage = DjangoORMStorage(CredentialsModel, 'user_id', request.user, 'credential')
+ storage.put(credential)
+ return HttpResponseRedirect("/")
diff --git a/neuropy/neuropy/settings.py b/neuropy/neuropy/settings.py
new file mode 100644
index 0000000..55b9f74
--- /dev/null
+++ b/neuropy/neuropy/settings.py
@@ -0,0 +1,148 @@
+"""
+Django settings for neuropy project.
+
+Generated by 'django-admin startproject' using Django 1.10.5.
+
+For more information on this file, see
+https://docs.djangoproject.com/en/1.10/topics/settings/
+
+For the full list of settings and their values, see
+https://docs.djangoproject.com/en/1.10/ref/settings/
+"""
+
+import os
+
+# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
+BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
+
+
+# Quick-start development settings - unsuitable for production
+# See https://docs.djangoproject.com/en/1.10/howto/deployment/checklist/
+
+# SECURITY WARNING: keep the secret key used in production secret!
+SECRET_KEY = 'y6o$5t_po!&22rrkc@-dewa4(us%g5k)fyrk-2ln)e!rlb#n^j'
+
+# SECURITY WARNING: don't run with debug turned on in production!
+DEBUG = True
+
+ALLOWED_HOSTS = []
+
+
+# Application definition
+
+INSTALLED_APPS = [
+ 'django.contrib.admin',
+ 'django.contrib.auth',
+ 'django.contrib.contenttypes',
+ 'django.contrib.sessions',
+ 'django.contrib.messages',
+ 'django.contrib.staticfiles',
+ 'medication',
+ 'neuropy',
+ 'userprofile',
+ 'todo',
+ 'bootstrap3',
+ 'oauth2client.contrib.django_util'
+]
+
+MIDDLEWARE = [
+ 'django.middleware.security.SecurityMiddleware',
+ 'django.contrib.sessions.middleware.SessionMiddleware',
+ 'django.middleware.common.CommonMiddleware',
+ 'django.middleware.csrf.CsrfViewMiddleware',
+ 'django.contrib.auth.middleware.AuthenticationMiddleware',
+ 'django.contrib.messages.middleware.MessageMiddleware',
+ 'django.middleware.clickjacking.XFrameOptionsMiddleware',
+]
+
+ROOT_URLCONF = 'neuropy.urls'
+
+TEMPLATES = [
+ {
+ 'BACKEND': 'django.template.backends.django.DjangoTemplates',
+ 'DIRS': [],
+ 'APP_DIRS': True,
+ 'OPTIONS': {
+ 'context_processors': [
+ 'django.template.context_processors.debug',
+ 'django.template.context_processors.request',
+ 'django.contrib.auth.context_processors.auth',
+ 'django.contrib.messages.context_processors.messages',
+ ],
+ },
+ },
+]
+
+WSGI_APPLICATION = 'neuropy.wsgi.application'
+
+
+# Database
+# https://docs.djangoproject.com/en/1.10/ref/settings/#databases
+
+DATABASES = {
+ 'default': {
+ 'ENGINE': 'django.db.backends.postgresql',
+ 'NAME': 'neuropy',
+ 'USER': os.environ.get("USER_NAME", ''),
+ 'PASSWORD': os.environ.get('DATABASE_PASSWORD', ''),
+ 'HOST': '127.0.0.1',
+ 'PORT': '5432',
+ 'TEST': {
+ 'NAME': 'test_neuropy'
+ }
+ }
+}
+
+
+# Password validation
+# https://docs.djangoproject.com/en/1.10/ref/settings/#auth-password-validators
+
+AUTH_PASSWORD_VALIDATORS = [
+ {
+ 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
+ },
+ {
+ 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
+ },
+ {
+ 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
+ },
+ {
+ 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
+ },
+]
+
+GOOGLE_OAUTH2_CLIENT_ID = os.environ.get('GOOGLE_CLIENT_ID', '')
+
+GOOGLE_OAUTH2_CLIENT_SECRET = os.environ.get('GOOGLE_CLIENT_SECRET', '')
+
+GOOGLE_OAUTH2_SCOPES = ('https://www.googleapis.com/auth/calendar',)
+
+GOOGLE_OAUTH2_STORAGE_MODEL = {
+ 'model': 'userprofile.models.CredentialsModel',
+ 'user_property': 'user_id',
+ 'credentials_property': 'credential',
+}
+
+
+# Internationalization
+# https://docs.djangoproject.com/en/1.10/topics/i18n/
+
+LANGUAGE_CODE = 'en-us'
+
+TIME_ZONE = 'America/Los_Angeles'
+
+USE_I18N = True
+
+USE_L10N = True
+
+USE_TZ = True
+
+
+# Static files (CSS, JavaScript, Images)
+# https://docs.djangoproject.com/en/1.10/howto/static-files/
+
+STATIC_URL = '/static/'
+ACCOUNT_ACTIVATION_DAYS = 7
+EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'
+LOGIN_REDIRECT_URL = '/'
diff --git a/neuropy/neuropy/static/neuropy/Amos.jpg b/neuropy/neuropy/static/neuropy/Amos.jpg
new file mode 100644
index 0000000..f47f131
Binary files /dev/null and b/neuropy/neuropy/static/neuropy/Amos.jpg differ
diff --git a/neuropy/neuropy/static/neuropy/Claire.jpg b/neuropy/neuropy/static/neuropy/Claire.jpg
new file mode 100644
index 0000000..130331f
Binary files /dev/null and b/neuropy/neuropy/static/neuropy/Claire.jpg differ
diff --git a/neuropy/neuropy/static/neuropy/cover.css b/neuropy/neuropy/static/neuropy/cover.css
new file mode 100755
index 0000000..d2df406
--- /dev/null
+++ b/neuropy/neuropy/static/neuropy/cover.css
@@ -0,0 +1,179 @@
+/*
+ * Globals
+ */
+
+@import url('https://fonts.googleapis.com/css?family=Open+Sans|Pacifico|Sansita');
+/*font-family: 'Pacifico', cursive;
+font-family: 'Open Sans Condensed', sans-serif;
+font-family: 'Open Sans', sans-serif;*/
+
+/* Links */
+a,
+a:focus,
+a:hover {
+ color: #fff;
+}
+
+/* Custom default button */
+.btn-default,
+.btn-default:hover,
+.btn-default:focus {
+ color: #333;
+ text-shadow: none; /* Prevent inheritance from `body` */
+ background-color: #fff;
+ border: 1px solid #fff;
+}
+
+
+/*
+ * Base structure
+ */
+
+html,
+body {
+ height: 100%;
+}
+body {
+ color: #fff;
+ text-align: center;
+ text-shadow: 0 1px 3px rgba(0,0,0,.5);
+ font-family: 'Open Sans', bold, sans-serif;
+ position: relative;
+ background-image:
+ linear-gradient(rgba(0, 0, 0, 0.3),
+ rgba(0, 0, 0, 0.3)), url('pexels-photo-109019.jpeg');
+ background-repeat: no-repeat;
+ background-attachment: fixed;
+ background-size: cover;
+}
+
+/* Extra markup and styles for table-esque vertical and horizontal centering */
+.site-wrapper {
+ display: table;
+ width: 100%;
+ height: 100%; /* For at least Firefox */
+ min-height: 100%;
+ -webkit-box-shadow: inset 0 0 100px rgba(0,0,0,.5);
+ box-shadow: inset 0 0 100px rgba(0,0,0,.5);
+}
+.site-wrapper-inner {
+ display: table-cell;
+ vertical-align: top;
+}
+.cover-container {
+ margin-right: auto;
+ margin-left: auto;
+}
+
+/* Padding for spacing */
+.inner {
+ padding: 30px;
+}
+
+
+/*
+ * Header
+ */
+.masthead-brand {
+ margin-top: 10px;
+ margin-bottom: 10px;
+}
+
+.masthead-nav > li {
+ display: inline-block;
+}
+.masthead-nav > li + li {
+ margin-left: 20px;
+}
+.masthead-nav > li > a {
+ padding-right: 0;
+ padding-left: 0;
+ font-size: 16px;
+ font-weight: bold;
+ color: #fff; /* IE8 proofing */
+ color: rgba(255,255,255,.75);
+ border-bottom: 2px solid transparent;
+}
+.masthead-nav > li > a:hover,
+.masthead-nav > li > a:focus {
+ background-color: transparent;
+ border-bottom-color: #a9a9a9;
+ border-bottom-color: rgba(255,255,255,.25);
+}
+.masthead-nav > .active > a,
+.masthead-nav > .active > a:hover,
+.masthead-nav > .active > a:focus {
+ color: #fff;
+ border-bottom-color: #fff;
+}
+
+@media (min-width: 768px) {
+ .masthead-brand {
+ float: left;
+ }
+ .masthead-nav {
+ float: right;
+ }
+}
+
+
+/*
+ * Cover
+ */
+
+.cover {
+ padding: 0 20px;
+}
+.cover .btn-lg {
+ padding: 10px 20px;
+ font-weight: bold;
+}
+
+.cover-heading {
+ font-family: 'Pacifico', cursive;
+}
+
+
+/*
+ * Footer
+ */
+
+.mastfoot {
+ color: #999; /* IE8 proofing */
+ color: rgba(255,255,255,.5);
+}
+
+
+/*
+ * Affix and center
+ */
+
+@media (min-width: 768px) {
+ /* Pull out the header and footer */
+ .masthead {
+ position: fixed;
+ top: 0;
+ }
+ .mastfoot {
+ position: fixed;
+ bottom: 0;
+ }
+ /* Start the vertical centering */
+ .site-wrapper-inner {
+ vertical-align: middle;
+ }
+ /* Handle the widths */
+ .masthead,
+ .mastfoot,
+ .cover-container {
+ width: 100%; /* Must be percentage or pixels for horizontal alignment */
+ }
+}
+
+@media (min-width: 992px) {
+ .masthead,
+ .mastfoot,
+ .cover-container {
+ width: 700px;
+ }
+}
diff --git a/neuropy/neuropy/static/neuropy/icon.png b/neuropy/neuropy/static/neuropy/icon.png
new file mode 100644
index 0000000..61024c3
Binary files /dev/null and b/neuropy/neuropy/static/neuropy/icon.png differ
diff --git a/neuropy/neuropy/static/neuropy/patrick.jpg b/neuropy/neuropy/static/neuropy/patrick.jpg
new file mode 100644
index 0000000..5d10718
Binary files /dev/null and b/neuropy/neuropy/static/neuropy/patrick.jpg differ
diff --git a/neuropy/neuropy/static/neuropy/pexels-photo-109019.jpeg b/neuropy/neuropy/static/neuropy/pexels-photo-109019.jpeg
new file mode 100644
index 0000000..3e2e8cd
Binary files /dev/null and b/neuropy/neuropy/static/neuropy/pexels-photo-109019.jpeg differ
diff --git a/neuropy/neuropy/static/neuropy/puzzle.png b/neuropy/neuropy/static/neuropy/puzzle.png
new file mode 100644
index 0000000..acdd7da
Binary files /dev/null and b/neuropy/neuropy/static/neuropy/puzzle.png differ
diff --git a/neuropy/neuropy/static/neuropy/sera.jpg b/neuropy/neuropy/static/neuropy/sera.jpg
new file mode 100644
index 0000000..d8c2737
Binary files /dev/null and b/neuropy/neuropy/static/neuropy/sera.jpg differ
diff --git a/neuropy/neuropy/static/neuropy/sticky-footer-navbar.css b/neuropy/neuropy/static/neuropy/sticky-footer-navbar.css
new file mode 100755
index 0000000..ca27d75
--- /dev/null
+++ b/neuropy/neuropy/static/neuropy/sticky-footer-navbar.css
@@ -0,0 +1,142 @@
+/* Sticky footer styles
+-------------------------------------------------- */
+@import url('https://fonts.googleapis.com/css?family=Open+Sans|Pacifico|Sansita');
+
+html {
+ position: relative;
+ min-height: 100%;
+
+}
+body {
+ /* Margin bottom by footer height */
+ margin-bottom: 60px;
+ font-family: 'Open Sans', bold, sans-serif;
+}
+.footer {
+ position: absolute;
+ bottom: 0;
+ width: 100%;
+ color: #fff;
+ /* Set the fixed height of the footer here */
+ height: 60px;
+ background-image:
+ linear-gradient(rgba(0, 0, 0, 0.3),
+ rgba(0, 0, 0, 0.3)), url('pexels-photo-109019.jpeg');
+ background-repeat: no-repeat;
+ background-size: cover;
+}
+nav {
+ background-image:
+ linear-gradient(rgba(0, 0, 0, 0.3),
+ rgba(0, 0, 0, 0.3)), url('pexels-photo-109019.jpeg');
+ background-repeat: no-repeat;
+ background-size: cover;
+ color: #fff;
+}
+.navbar-default .navbar-nav>li>a,
+.navbar-default .navbar-brand {
+ color: #fff;
+}
+
+.neuropy {
+ font-family: 'Pacifico', cursive;
+ font-size: 2em;
+}
+
+.name {
+ font-family: 'Pacifico', cursive;
+
+}
+
+.form-section {
+ margin-bottom: 25px;
+}
+
+h1 {
+ font-family: 'Sansita', sans-serif;
+}
+
+.uppercase {
+ text-transform: uppercase;
+}
+
+/* Custom page CSS
+-------------------------------------------------- */
+/* Not required for template or sticky footer method. */
+
+body > .container {
+ padding: 60px 15px 0;
+}
+.container .text-muted {
+ margin: 20px 0;
+}
+
+.footer > .container {
+ padding-right: 15px;
+ padding-left: 15px;
+ margin-top: 30px;
+}
+
+code {
+ font-size: 80%;
+}
+
+.terms {
+ width: 60%;
+ height: 300px;
+ border: 1px solid #ccc;
+ background: #f2f2f2;
+ padding: 6px;
+ overflow: auto;
+ margin-bottom: 30px;
+}
+
+.unstyled {
+ list-style: none;
+}
+
+.color1 {
+ background-color: rgba(164, 189, 252, 0.5);
+}
+
+.color2 {
+ background-color: rgba(122, 231, 191, 0.5);
+}
+
+.color3 {
+ background-color: rgba(219, 173, 255, 0.5);
+}
+
+.color4 {
+ background-color: rgba(255, 136, 124, 0.5);
+}
+
+.color5 {
+ background-color: rgba(251, 215, 91, 0.5);
+}
+
+.color6 {
+ background-color: rgba(255, 184, 120, 0.5);
+}
+
+.color7 {
+ background-color: rgba(70, 214, 219, 0.5);
+}
+
+.color8 {
+ background-color: rgba(225, 225, 225, 0.5);
+}
+
+.color9 {
+ background-color: rgba(84, 132, 237, 0.5);
+}
+
+.color10 {
+ background-color: rgba(81, 183, 73, 0.5);
+}
+
+.color11 {
+ background-color: rgba(220, 33, 39, 0.5);
+}
+
+
diff --git a/neuropy/neuropy/static/neuropy/white-icon.png b/neuropy/neuropy/static/neuropy/white-icon.png
new file mode 100644
index 0000000..fe3df4f
Binary files /dev/null and b/neuropy/neuropy/static/neuropy/white-icon.png differ
diff --git a/neuropy/neuropy/templates/neuropy/about.html b/neuropy/neuropy/templates/neuropy/about.html
new file mode 100644
index 0000000..18761a5
--- /dev/null
+++ b/neuropy/neuropy/templates/neuropy/about.html
@@ -0,0 +1,64 @@
+{% extends 'neuropy/layout.html' %}
+{% load static %}
+
+
+{% block content %}
+
+
+
+
About Neuropy
+
+
+
+
A personalized priority app to support a Cognitive Behavioral Therapy (CBT) approach to efficiently organize your day according to a struggle/disorder that is effectively treated by CBT. CBT is a goal-oriented pyschotherapy treatment, taking a hands-on approach to problem solving. Goal of CBT is to change the patterns of thinking or behavior that are behind a person's difficulties, modifying their feelings and therefore their thinking and behavior overtime.
+
+
Neuropy Considers what the habit/disorder the user wants to treat with CBT, along with medication, its efficacy, and peak periods. Also works around black-out periods on user's schedule by syncing with Google Calender, personal preference or most productive period of the day for user, and finally considers time commitments for each activity. Each "TO-DO" will be ranked considering these aspects and will be worked into periods of the day.
Hi, I am Sera. I was born and raised in Tokyo, Japan until Age 11. I then moved to Seattle where I stayed until graduating from University of Washington with a degree in Criminal Psychology and Classical Japanese. I am bilingual and have 2 Shiba Inu's. I was also a Shiba Inu breeder while living in NV after UW. I am a Python developer.
+
+
+
+
+
Amos Bolder
+
+
Hi, I am Amos I love to code. Python rules everything else drools. I am Python developer.
+
+
+
+
+
Claire Gatenby
+
+
I am a born and bred Australian who made the wild decision to quit my job and move to Seattle where I am learning how to code. I dream of using my past life as a scientist and my new skills as a developer to move into bioinformatics. I love cats, staying active, travelling, the outdoors and taking photos. I am Python developer.
+
+
+
+
+
Patrick Saunders
+
+
Hi, I am Patrick. I am a new, starry-eyed software developer. I am happiest when his tests are passing or at least when they’re failing in a predictable way. I'm excited about python but I'm also looking forward to expanding my set of languages.