diff --git a/.gitignore b/.gitignore index b62ada9a..03632ed6 100644 --- a/.gitignore +++ b/.gitignore @@ -1,25 +1,25 @@ -# coverage +# Coverage testing files. .coverage /htmlcov -# database +# SQLite database file. *.sqlite3 -# enviornment +# Environment files. .env docker.env -# ide +# IDE configuration files. /.idea -# npm folder +# Node development dependencies. /node_modules -# python +# Python files. *.pyc -# static build files +# App static file folders. /*/static -# media folder +# Django media root folder. /media diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 9e331cd1..035bcb85 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -13,11 +13,10 @@ ## Contributions -Contributions are accepted and encouraged via GitHub -[Issues](https://github.com/cdubz/babybuddy/issues) and -[Pull Requests](https://github.com/cdubz/babybuddy/pulls). Maintainers and users -may also be found at [babybuddy/Lobby](https://gitter.im/babybuddy/Lobby) on -Gitter. +Contributions are accepted and encouraged via GitHub [Issues](https://github.com/cdubz/babybuddy/issues) +and [Pull Requests](https://github.com/cdubz/babybuddy/pulls). Maintainers and +users may also be found at [babybuddy/Lobby](https://gitter.im/babybuddy/Lobby) +on Gitter. ### Pull request process @@ -26,7 +25,7 @@ Gitter. 1. Run `gulp lint` and `gulp test` (see [Gulp Commands](#gulp-commands)) and ensure that all tests pass. 1. If changes are made to assets: build, collect and commit the `/static` - folder (see [Pre-commit Hook](#pre-commit-hook)). + folder (see [`gulp collectstatic`](#collectstatic)). 1. Open a [new pull request](https://github.com/cdubz/babybuddy/compare) against the `master` branch. @@ -38,37 +37,55 @@ and we will do our best to provide feedback and support potential contributors. #### POEditor Baby Buddy is set up as a project on [POEditor](https://poeditor.com/). -Interested contibutors can -[join translation of Baby Buddy](https://poeditor.com/join/project/QwQqrpTIzn) +Interested contributors can [join translation of Baby Buddy](https://poeditor.com/join/project/QwQqrpTIzn) for access to a simple, web-based frontend for adding/editing translation files to the project. #### Manual -Baby Buddy has support for translation/localization to any language. A general -translation process will look something like this: +Baby Buddy has support for translation/localization. A manual translation +process will look something like this: 1. Set up a development environment (see [Development](#development) below). -1. Run `gulp makemessages -l xx` where `xx` is a specific locale code (e.g. "fr" -for French or "es" for Spanish). This create a new translation file at -`locale/xx/LC_MESSAGES/django.po`, or update one if it exits. -1. Open the created/updated `django.po` file and update the header template with -license and contact info. + +1. Run `gulp makemessages -l xx` where `xx` is a specific locale code in the +[ISO 639-1 format](https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes) (e.g. +"fr" for French or "es" for Spanish). This create a new translation file at +`locale/xx/LC_MESSAGES/django.po`, or updates one if it exists. + +1. Open the created/updated `django.po` file and update the header template +with license and contact info. + 1. Start translating! Each translatable string will have a `msgid` value with the string in English and a corresponding (empty) `msgstr` value where a translated string can be filled in. + 1. Once all strings have been translated, run `gulp compilemessages -l xx` to compile an optimized translation file (`locale/xx/LC_MESSAGES/django.mo`). + 1. To expose the new translation as a user setting, add the locale code to the `LANGUAGES` array in the base settings file (`babybuddy/settings/base.py`). + +1. Check (in `node_modules/plotly.js/dist/`)if Plotly offers a translation for +the language. If it does: + + 1. Add the Plotly translation file path to [`gulpfile.config.js`](gulpfile.config.js) in + `extrasConfig.plotlyLocales`. + + 1. Add a `script` tag for the file in [`reports/templates/reports/report_base.html`](reports/templates/reports/report_base.html) + in the `javascript` block (this files will have many existing languages to + use as reference). + + 1. Build, collect, and commit the `/static` folder. + 1. Run the development server, log in, and update the user language to test the newly translated strings. -Once the translation is complete, commit the new files and changes to a fork and -[create a pull request](#pull-request-process) for review. +Once the translation is complete, commit the new files and changes to a fork +and [create a pull request](#pull-request-process) for review. For more information on the Django translation process, see Django's -documentation section: [Translation](https://docs.djangoproject.com/en/dev/topics/i18n/translation/). +documentation section: [Translation](https://docs.djangoproject.com/en/3.0/topics/i18n/translation/). ## Development @@ -164,9 +181,18 @@ the `babybuddy/static` folder, so generally `gulp build` should be run before this command for production deployments. Gulp also passes along non-overlapping arguments for this command, e.g. `--no-input`. +Before executing this command, ensure that + +- `DEBUG` is set to it's default (`False`). +- `STATICFILES_STORAGE` is set to it's default. +- `SECRET_KEY` is set to (anything). + +See the [`development.py` settings file](babybuddy/settings/development.py) for +additional information. + #### `compilemessages` -Executes Django's `compilemessages` management task. See [django-admin compilemessages](https://docs.djangoproject.com/en/dev/ref/django-admin/#compilemessages) +Executes Django's `compilemessages` management task. See [django-admin compilemessages](https://docs.djangoproject.com/en/3.0/ref/django-admin/#compilemessages) for more details about other options and functionality of this command. #### `coverage` @@ -192,7 +218,7 @@ Executes Python and SASS linting for all relevant source files. #### `makemessages` -Executes Django's `makemessages` management task. See [django-admin makemessages](https://docs.djangoproject.com/en/dev/ref/django-admin/#makemessages) +Executes Django's `makemessages` management task. See [django-admin makemessages](https://docs.djangoproject.com/en/3.0/ref/django-admin/#makemessages) for more details about other options and functionality of this command. When working on a single translation, the `-l` flag is useful to make message for only that language, e.g. `gulp makemessages -l fr` to make only a French @@ -236,29 +262,3 @@ Executes Baby Buddy's suite of tests. Gulp also passes along non-overlapping arguments for this command, however individual tests cannot be run with this command. `python manage.py test` can be used for individual test execution. - -### Pre-commit Hook - -A [pre-commit hook](https://git-scm.com/docs/githooks#_pre_commit) is -recommended for all commits in order to make sure that static assets are -correctly committed. Here is an example working script for bash: - -``` -#!/bin/bash - -if [ $(git diff --cached --name-only | grep static_src -c) -ne 0 ] -then - gulp clean && gulp build && gulp collectstatic - if [ $? -ne 0 ]; then exit $?; fi - git add ./static -fi - -gulp lint && gulp test - -exit $? -``` - -This script will build and add static assets to the commit only if changes have -been made to files in a `static_src` directory of the project. It will always -run the `gulp lint` and `gulp test` commands. If any of these processes result -in an error, the commit will be rejected. diff --git a/LICENSE b/LICENSE index 352afb93..25eead2a 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ BSD 2-Clause License -Copyright (c) 2017, Baby Buddy's Contributors +Copyright (c) 2017 - 2020, Baby Buddy's Contributors All rights reserved. Redistribution and use in source and binary forms, with or without diff --git a/README.md b/README.md index f4f37a2c..daf22d61 100644 --- a/README.md +++ b/README.md @@ -5,9 +5,9 @@ [![License](https://img.shields.io/badge/License-BSD%202--Clause-orange.svg)](https://opensource.org/licenses/BSD-2-Clause) [![Gitter](https://img.shields.io/gitter/room/nwjs/nw.js.svg)](https://gitter.im/babybuddy/Lobby) -A buddy for babies! Helps caregivers track sleep, feedings, diaper changes, and -tummy time to learn about and predict baby's needs without (*as much*) guess -work. +A buddy for babies! Helps caregivers track sleep, feedings, diaper changes, +tummy time and more to learn about and predict baby's needs without (*as much*) +guess work. ![Baby Buddy desktop view](screenshot.png) @@ -50,7 +50,7 @@ variables - see [Configuration](#configuration) for detailed information. A basic [Elastic Beanstalk](https://aws.amazon.com/elasticbeanstalk/) configuration is provided in `.ebextensions/babybuddy.config`. The steps -below are a rough guide to deployment. See [Working with Python](http://docs.aws.amazon.com/elasticbeanstalk/latest/dg/create-deploy-python-apps.html) +below are a rough guide to deployment. See [Working with Python](https://docs.aws.amazon.com/elasticbeanstalk/latest/dg/create-deploy-python-apps.html) for detailed information. 1. Clone/download the Baby Buddy repo @@ -78,12 +78,12 @@ redeploy the app (e.g. if there are errors or settings are changed). ### Docker -A Docker deployment requires [Docker](http://docker.com/) and -[Docker Compose](https://docs.docker.com/compose/overview/) to create two -containers - one for the database and one for the application. +A Docker deployment requires [Docker](https://www.docker.com/) and +[Docker Compose](https://docs.docker.com/compose/) to create two containers - +one for the database and one for the application. 1. Copy the `docker.env.example` to `docker.env` and set the `ALLOWED_HOSTS` and -`SECRET_KEY` variables within +`SECRET_KEY` variables cp docker.env.example docker.env editor docker.env @@ -101,7 +101,7 @@ containers - one for the database and one for the application. The app should now be locally available at [http://127.0.0.1:8000](http://127.0.0.1:8000). See -[Get Started, Part 6: Deploy your app](https://docs.docker.com/get-started/part6/) +[Docker's "Get Started" documentation](https://docs.docker.com/get-started/) for detailed information about deployment methods with Docker. ### Heroku @@ -276,15 +276,15 @@ This option may be set to a single host or comma-separated list of hosts (without spaces). This should *always* be set to a specific host or hosts in production deployments. -See also: [Django's documentation on the ALLOWED_HOSTS setting](https://docs.djangoproject.com/en/1.11/ref/settings/#allowed-hosts) +See also: [Django's documentation on the ALLOWED_HOSTS setting](https://docs.djangoproject.com/en/3.0/ref/settings/#allowed-hosts) ### `ALLOW_UPLOADS` *Default: True* Whether or not to allow uploads (e.g. of Child photos). For some deployments -(AWS, Heroku, Nanobox) this setting will default to False due to the lack of -available persistent storage. +(AWS, Heroku) this setting will default to False due to the lack of available +persistent storage. ### `AWS_ACCESS_KEY_ID` @@ -310,8 +310,7 @@ See also: [`AWS_STORAGE_BUCKET_NAME`](#aws_storage_bucket_name) If you would like to use AWS S3 for storage on ephemeral storage platforms like Heroku you will need to create a bucket and add it's name. See django-storages' -[Amazon S3 documentation] -(http://django-storages.readthedocs.io/en/latest/backends/amazon-S3.html). +[Amazon S3 documentation](https://django-storages.readthedocs.io/en/latest/backends/amazon-S3.html). ### `DEBUG` @@ -320,21 +319,21 @@ Heroku you will need to create a bucket and add it's name. See django-storages' When in debug mode, Baby Buddy will print much more detailed error information for exceptions. This setting should be *False* in production deployments. -See also [Django's documentation on the DEBUG setting](https://docs.djangoproject.com/en/1.11/ref/settings/#debug). +See also [Django's documentation on the DEBUG setting](https://docs.djangoproject.com/en/3.0/ref/settings/#debug). ### `NAP_START_MAX` *Default: 18:00* The maximum *start* time (in the instance's time zone) before which a sleep -entry is consider a nap. Expects the format %H:%M. +entry is consider a nap. Expects the 24-hour format %H:%M. ### `NAP_START_MIN` *Default: 06:00* The minimum *start* time (in the instance's time zone) after which a sleep -entry is considered a nap. Expects the format %H:%M. +entry is considered a nap. Expects the 24-hour format %H:%M. ### `SECRET_KEY` @@ -343,7 +342,7 @@ entry is considered a nap. Expects the format %H:%M. A random, unique string must be set as the "secret key" before Baby Buddy can be deployed and run. -See also [Django's documentation on the SECRET_KEY setting](https://docs.djangoproject.com/en/1.11/ref/settings/#secret-key). +See also [Django's documentation on the SECRET_KEY setting](https://docs.djangoproject.com/en/3.0/ref/settings/#secret-key). ### `TIME_ZONE` @@ -354,9 +353,13 @@ for all possible values. ## Languages -Baby Buddy includes translation support as of v1.2.2. Language can be set on a per-user basis from the user settings page (`/user/settings/`). See [CONTRIBUTING.md](CONTRIBUTING.md#translation) for information about how to create/update translations. +Baby Buddy includes translation support as of v1.2.2. Language can be set on a +per-user basis from the user settings page (`/user/settings/`). See +[CONTRIBUTING.md](CONTRIBUTING.md#translation) for information about how to +create/update translations. ### Available languages + :us: English (U.S.) *(base)* :fr: French @@ -371,7 +374,7 @@ Baby Buddy includes translation support as of v1.2.2. Language can be set on a p ## API -Baby Buddy uses the [Django REST Framework](http://www.django-rest-framework.org/) +Baby Buddy uses the [Django REST Framework](https://www.django-rest-framework.org/) (DRF) to provide a REST API. The only requirement for (most) requests is that the `Authorization` header is @@ -393,8 +396,8 @@ Currently, the following endpoints are available for `GET`, `OPTIONS`, and ### Authentication -By default, the [TokenAuthentication](http://www.django-rest-framework.org/api-guide/authentication/#tokenauthentication) -and [SessionAuthentication](http://www.django-rest-framework.org/api-guide/authentication/#sessionauthentication) +By default, the [TokenAuthentication](https://www.django-rest-framework.org/api-guide/authentication/#tokenauthentication) +and [SessionAuthentication](https://www.django-rest-framework.org/api-guide/authentication/#sessionauthentication) classes are enabled. Session authentication covers local API requests made by the application itself. Token authentication allows external requests to be made. @@ -505,10 +508,10 @@ formats. Returns JSON data in the response body describing the added/updated instance or error details if errors exist. Errors are keyed by either the field in error or -the general string "non_field_errors" (usually when validation incorporates +the general string `non_field_errors` (usually when validation involves multiple fields). ## Contributing Contributions are welcome! See [CONTRIBUTING.md](CONTRIBUTING.md) for detailed -information about how to develop and contribute to Baby Buddy. +information about how to contribute to Baby Buddy. diff --git a/babybuddy/settings/base.py b/babybuddy/settings/base.py index a912d19c..baf7331e 100644 --- a/babybuddy/settings/base.py +++ b/babybuddy/settings/base.py @@ -25,7 +25,7 @@ DEBUG = os.environ.get('DEBUG', False) # Applications -# https://docs.djangoproject.com/en/1.11/ref/applications/ +# https://docs.djangoproject.com/en/3.0/ref/applications/ INSTALLED_APPS = [ 'api', @@ -50,7 +50,7 @@ INSTALLED_APPS = [ ] # Middleware -# https://docs.djangoproject.com/en/1.11/ref/middleware/ +# https://docs.djangoproject.com/en/3.0/ref/middleware/ MIDDLEWARE = [ 'django.middleware.security.SecurityMiddleware', @@ -66,13 +66,13 @@ MIDDLEWARE = [ # URL dispatcher -# https://docs.djangoproject.com/en/1.11/topics/http/urls/ +# https://docs.djangoproject.com/en/3.0/topics/http/urls/ ROOT_URLCONF = 'babybuddy.urls' # Templates -# https://docs.djangoproject.com/en/1.11/ref/templates/upgrading/#the-templates-settings +# https://docs.djangoproject.com/en/3.0/ref/settings/#std:setting-TEMPLATES TEMPLATES = [ { @@ -92,13 +92,13 @@ TEMPLATES = [ # WGSI -# https://docs.djangoproject.com/en/1.11/howto/deployment/wsgi/ +# https://docs.djangoproject.com/en/3.0/howto/deployment/wsgi/ WSGI_APPLICATION = 'babybuddy.wsgi.application' # Authentication -# https://docs.djangoproject.com/en/1.11/topics/auth/default/ +# https://docs.djangoproject.com/en/3.0/topics/auth/default/ LOGIN_REDIRECT_URL = '/' @@ -108,7 +108,7 @@ LOGOUT_REDIRECT_URL = '/login/' # Internationalization -# https://docs.djangoproject.com/en/1.11/topics/i18n/ +# https://docs.djangoproject.com/en/3.0/topics/i18n/ LANGUAGE_CODE = 'en' @@ -135,7 +135,8 @@ LANGUAGES = [ # Static files (CSS, JavaScript, Images) -# https://docs.djangoproject.com/en/1.11/howto/static-files/ +# https://docs.djangoproject.com/en/3.0/howto/static-files/ +# http://whitenoise.evans.io/en/stable/django.html STATICFILES_STORAGE = 'whitenoise.storage.CompressedManifestStaticFilesStorage' @@ -152,7 +153,7 @@ WHITENOISE_ROOT = os.path.join(BASE_DIR, 'static', 'babybuddy', 'root') # Media files (User uploaded content) -# https://docs.djangoproject.com/en/2.0/topics/files/ +# https://docs.djangoproject.com/en/3.0/topics/files/ MEDIA_ROOT = os.path.join(BASE_DIR, 'media') @@ -170,7 +171,7 @@ if AWS_STORAGE_BUCKET_NAME: # Django Rest Framework -# http://www.django-rest-framework.org/# +# https://www.django-rest-framework.org/ REST_FRAMEWORK = { 'DEFAULT_AUTHENTICATION_CLASSES': [ diff --git a/babybuddy/settings/development.py b/babybuddy/settings/development.py index fda3479f..2ef9185c 100644 --- a/babybuddy/settings/development.py +++ b/babybuddy/settings/development.py @@ -1,14 +1,14 @@ from .base import * # Quick-start development settings - unsuitable for production -# See https://docs.djangoproject.com/en/1.11/howto/deployment/checklist/ +# https://docs.djangoproject.com/en/3.0/howto/deployment/checklist/ SECRET_KEY = 'CHANGE ME' DEBUG = True # Database -# https://docs.djangoproject.com/en/1.11/ref/settings/#databases +# https://docs.djangoproject.com/en/3.0/ref/settings/#databases DATABASES = { 'default': { @@ -19,7 +19,7 @@ DATABASES = { # Static files (CSS, JavaScript, Images) -# https://docs.djangoproject.com/en/1.11/howto/static-files/ +# https://docs.djangoproject.com/en/3.0/howto/static-files/ # # Comment out STATICFILES_STORAGE and uncomment DEBUG = False to test with # production static files. @@ -29,7 +29,7 @@ STATICFILES_STORAGE = 'django.contrib.staticfiles.storage.StaticFilesStorage' # Django Rest Framework -# http://www.django-rest-framework.org/# +# https://www.django-rest-framework.org/ REST_FRAMEWORK['DEFAULT_RENDERER_CLASSES'] = ( 'rest_framework.renderers.JSONRenderer', diff --git a/babybuddy/settings/docker.py b/babybuddy/settings/docker.py index 1bd5d569..fc9d7d06 100644 --- a/babybuddy/settings/docker.py +++ b/babybuddy/settings/docker.py @@ -2,7 +2,7 @@ from .base import * # Database -# https://docs.djangoproject.com/en/1.11/ref/settings/#databases +# https://docs.djangoproject.com/en/3.0/ref/settings/#databases DATABASES = { 'default': { diff --git a/babybuddy/settings/eb.py b/babybuddy/settings/eb.py index 61af383c..38eb7312 100644 --- a/babybuddy/settings/eb.py +++ b/babybuddy/settings/eb.py @@ -5,7 +5,7 @@ BABY_BUDDY['ALLOW_UPLOADS'] = os.environ.get('ALLOW_UPLOADS', False) # Database -# https://docs.djangoproject.com/en/1.11/ref/settings/#databases +# https://docs.djangoproject.com/en/3.0/ref/settings/#databases DATABASES = { 'default': { diff --git a/babybuddy/settings/heroku.py b/babybuddy/settings/heroku.py index 82e3ca53..c5acde69 100644 --- a/babybuddy/settings/heroku.py +++ b/babybuddy/settings/heroku.py @@ -7,7 +7,7 @@ BABY_BUDDY['ALLOW_UPLOADS'] = os.environ.get('ALLOW_UPLOADS', False) # Database -# https://docs.djangoproject.com/en/1.11/ref/settings/#databases +# https://docs.djangoproject.com/en/3.0/ref/settings/#databases DATABASES = { 'default': dj_database_url.config(conn_max_age=500) @@ -15,6 +15,8 @@ DATABASES = { # Email +# https://docs.djangoproject.com/en/3.0/topics/email/ +# https://devcenter.heroku.com/articles/sendgrid#python SENDGRID_USERNAME = os.environ.get('SENDGRID_USERNAME', None) # noqa: F405 SENDGRID_PASSWORD = os.environ.get('SENDGRID_PASSWORD', None) # noqa: F405 diff --git a/babybuddy/settings/nanobox.py b/babybuddy/settings/nanobox.py deleted file mode 100644 index 798abf67..00000000 --- a/babybuddy/settings/nanobox.py +++ /dev/null @@ -1,16 +0,0 @@ -from .base import * - - -# Database -# https://docs.djangoproject.com/en/1.11/ref/settings/#databases - -DATABASES = { - 'default': { - 'ENGINE': 'django.db.backends.postgresql_psycopg2', - 'NAME': 'gonano', - 'USER': os.environ.get('DATA_DB_USER'), - 'PASSWORD': os.environ.get('DATA_DB_PASS'), - 'HOST': os.environ.get('DATA_DB_HOST'), - 'PORT': '', - } -} diff --git a/babybuddy/settings/production.example.py b/babybuddy/settings/production.example.py index 5c0c2459..928ae4c3 100644 --- a/babybuddy/settings/production.example.py +++ b/babybuddy/settings/production.example.py @@ -9,7 +9,7 @@ ALLOWED_HOSTS = [''] # Database -# https://docs.djangoproject.com/en/1.11/ref/settings/#databases +# https://docs.djangoproject.com/en/3.0/ref/settings/#databases DATABASES = { 'default': { @@ -19,6 +19,7 @@ DATABASES = { } -# Static files +# Media files +# https://docs.djangoproject.com/en/3.0/topics/files/ MEDIA_ROOT = os.path.join(BASE_DIR, '../data/media') diff --git a/babybuddy/settings/travis.py b/babybuddy/settings/travis.py index e4c41e17..b7850624 100644 --- a/babybuddy/settings/travis.py +++ b/babybuddy/settings/travis.py @@ -4,13 +4,13 @@ SECRET_KEY = 'TRAVISCIWHYNOT' # Static files (CSS, JavaScript, Images) -# https://docs.djangoproject.com/en/1.11/howto/static-files/ +# https://docs.djangoproject.com/en/3.0/howto/static-files/ STATICFILES_STORAGE = 'django.contrib.staticfiles.storage.StaticFilesStorage' # Database -# https://docs.djangoproject.com/en/1.11/ref/settings/#databases +# https://docs.djangoproject.com/en/3.0/ref/settings/#databases DATABASES = { 'default': {