Commit be8d80f4 authored by David Haynes's avatar David Haynes 🙆

Merge branch '2.2-dev' into 'master'

2.2

Closes #97, #91, #92, #90, #88, #99, #100, #78, #75, and #77

See merge request !50
parents ec5b0b71 06ec7ed1
Pipeline #3761 passed with stage
in 1 minute and 6 seconds
......@@ -13,5 +13,4 @@ whats_open/secret_key.py
whats_open/assets/
static/admin/
data
whats-open/api/migrations
.vscode
services:
- mysql:latest
- mysql:5.7
variables:
MYSQL_DATABASE: wopen
......@@ -10,10 +10,13 @@ types:
before_script:
- apt-get update -qy
- apt-get install -y mysql-client libmysqlclient-dev python-mysqldb libgdal1h libproj-dev proj-data proj-bin
- pip install -r requirements/test.txt
- apt-get install -y mysql-client default-libmysqlclient-dev python-mysqldb
gdal-bin libproj-dev proj-data proj-bin binutils
- cd whats-open/
- export WOPEN_SECRET_KEY=$(dd if=/dev/urandom count=100 | tr -dc "A-Za-z0-9" | fold -w 60 | head -n1 2>/dev/null)
- pip install pipenv
- pipenv install --system --deploy
- export WOPEN_SECRET_KEY=$(dd if=/dev/urandom count=100 | tr -dc "A-Za-z0-9"
| fold -w 60 | head -n1 2>/dev/null)
- export WOPEN_EMAIL_DOMAIN="@masonlive.gmu.edu"
- export WOPEN_DB_NAME="wopen"
- export WOPEN_DB_USER="root"
......@@ -21,21 +24,16 @@ before_script:
- export WOPEN_DB_HOST="mysql"
- export WOPEN_DB_PORT=3306
- export WOPEN_SUPERUSER=admin
- export WOPEN_ENV=dev
- python manage.py makemigrations
- python manage.py makemigrations api
- python manage.py migrate
- echo "from django.contrib.auth import get_user_model; User = get_user_model(); User.objects.create_superuser('root', 'root@srct.gmu.edu', 'root') " | python manage.py shell
- echo "from django.contrib.auth import get_user_model; User =
get_user_model(); User.objects.create_superuser('root',
'root@srct.gmu.edu', 'root') " | python manage.py shell
whats-open-py3.5:
image: library/python:3.5
whats-open-py3.7:
image: library/python:3.7
type: test
script:
- python manage.py test
whats-open-py3.6:
image: library/python:3.6
type: test
script:
# - if pip list --outdated --format=legacy | grep "Latest" | wc -l > 0; then echo "Please update your dependecies!" && pip list --outdated --format=legacy && exit 1; else exit 0; fi
- coverage run --source=api --omit=*migrations/*,*admin.py,*__init__.py,*.pyc manage.py test
- coverage html -i && grep pc_cov htmlcov/index.html | egrep -o "[0-9]+\%" | awk '{ print "covered " $1;}'
- echo "Done 😄"
......@@ -5,6 +5,30 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
## [2.2] - 2019-01-29
## Fixed
- Default owner now assigned automatically to the current logged in user / field hidden
- Path buggy schedule checking timezone utilization
- Schedules may now have N open times
## Added
- Admin action to bulk apply schedules to facilities
- Changed default image
- Alert model refactored to support URLs, subjects, and bodies
- Add front royal location as an option
## Removed
- Mason Korea support dropped
- Deprecated previous Alert model
- Drop label support
- Drop Sodoxo classifier
- Drop schedule promotion
- Drop schedule deletion
## [2.1.1] - 2017-01-13
## Fixed
......
......@@ -4,13 +4,13 @@ We would love for you to contribute to What's Open and help make it even better
than it is today! As a contributor, here are the guidelines we would like you to
follow:
- [Code of Conduct](#coc)
- [Question or Problem?](#question)
- [Issues and Bugs](#issue)
- [Feature Requests](#feature)
- [Submission Guidelines](#submit)
- [Coding Rules](#rules)
- [Commit Message Guidelines](#commit)
- [Code of Conduct](#coc)
- [Question or Problem?](#question)
- [Issues and Bugs](#issue)
- [Feature Requests](#feature)
- [Submission Guidelines](#submit)
- [Coding Rules](#rules)
- [Commit Message Guidelines](#commit)
## <a name="coc"></a> Code of Conduct
......@@ -32,13 +32,13 @@ better, you can [submit a Merge Request](#submit-pr) with a fix.
## <a name="feature"></a> Missing a Feature?
You can *request* a new feature by [submitting an issue](#submit-issue) to our
GitLab Repository. If you would like to *implement* a new feature, please ensure
You can _request_ a new feature by [submitting an issue](#submit-issue) to our
GitLab Repository. If you would like to _implement_ a new feature, please ensure
an issue already exists to be associated with your commits.
* For any **contribution**, first [open an issue](#submit-issue) and outline your proposal so that it can be
discussed. This will also allow us to better coordinate our efforts, prevent duplication of work,
and help you to craft the change so that it is successfully accepted into the project.
- For any **contribution**, first [open an issue](#submit-issue) and outline your proposal so that it can be
discussed. This will also allow us to better coordinate our efforts, prevent duplication of work,
and help you to craft the change so that it is successfully accepted into the project.
## <a name="submit"></a> Submission Guidelines
......@@ -63,16 +63,16 @@ You can file new issues by filling out our [new issue form][new-issue].
Before you submit your Merge Request (MR) consider the following steps:
* Search [GitLab][merge-request] for an open or closed MR that relates to your
- Search [GitLab][merge-request] for an open or closed MR that relates to your
submission. You don't want to duplicate effort.
* Pull the latest commits from GitLab
- Pull the latest commits from GitLab
```sh
git pull
```
* Check into the current development branch:
- Check into the current development branch:
All new commits are merged into this development branch before going live on
the site in a tagged release (merge into master branch).
......@@ -81,7 +81,7 @@ Before you submit your Merge Request (MR) consider the following steps:
git checkout consolidation
```
* Create a new git branch:
- Create a new git branch:
```sh
git checkout -B ##-shortdescription
......@@ -96,11 +96,11 @@ Before you submit your Merge Request (MR) consider the following steps:
a few hyphon (`-`) seperated words that consisely describe the branch. This helps people
who may be unfamiliar with the issue number to know at a glance what the branch
* Now you're ready to write your code in your new branch! Make sure to follow
- Now you're ready to write your code in your new branch! Make sure to follow
listed [style](#rules) & [commit](#commit) guidelines/rules when contributing
code.
* Unit tests are run at the CI (GitLab-CI) level once you push your code to GitLab.
- Unit tests are run at the CI (GitLab-CI) level once you push your code to GitLab.
We do this to ensure that the project builds properly and passes tests. In general,
if you are adding some new piece of code like a function you must **include
appropriate test cases**.
......@@ -120,13 +120,14 @@ Before you submit your Merge Request (MR) consider the following steps:
def TestOneplus(TestCase):
assertEquals(oneplus(1), 2)
```
* Before you push your code to GitLab it is suggested that you run all unit tests locally.
- Before you push your code to GitLab it is suggested that you run all unit tests locally.
```sh
python manage.py test
```
* Commit your changes using a descriptive commit message that follows our
- Commit your changes using a descriptive commit message that follows our
[commit message conventions](#commit). Adherence to these conventions is strongly
suggested as it makes it easier to determine what each commit does when, for example,
things break.
......@@ -136,11 +137,11 @@ Before you submit your Merge Request (MR) consider the following steps:
git commit # first line is title, two newlines is description
```
* You will need to ask in the slack channel to be added to the GitLab repo. This
- You will need to ask in the slack channel to be added to the GitLab repo. This
step is necessary such that you have the necessary permissions to push up your
branch.
* Push your branch to GitLab:
- Push your branch to GitLab:
```sh
git push origin ##-shortdescription
......@@ -148,12 +149,13 @@ Before you submit your Merge Request (MR) consider the following steps:
git push origin 31-contibution-guidelines-proposal
```
* In GitLab, send a merge request to the current development branch.
- In GitLab, send a merge request to the current development branch.
- If we suggest changes to your branch then:
* If we suggest changes to your branch then:
* Make the required updates.
* Re-run the unit tests to ensure tests are still passing.
* Rebase your branch and force push to your GitLab repository (this will update
- Make the required updates.
- Re-run the unit tests to ensure tests are still passing.
- Rebase your branch and force push to your GitLab repository (this will update
your Merge Request):
```sh
......@@ -168,7 +170,7 @@ That's it! Thank you for your contribution! :tada:
After your merge request is merged, you can safely delete your branch and merge
the changes from the main (upstream) repository:
* Delete the remote branch on GitLab either through the GitLab web UI or your
- Delete the remote branch on GitLab either through the GitLab web UI or your
local shell as follows:
```sh
......@@ -177,13 +179,13 @@ the changes from the main (upstream) repository:
git push origin --delete 31-contibution-guidelines-proposal
```
* Check out the current development branch:
- Check out the current development branch:
```sh
git checkout consolidation -f
```
* Delete the local branch:
- Delete the local branch:
```sh
git branch -D ##-shortdescription
......@@ -191,7 +193,7 @@ the changes from the main (upstream) repository:
git branch -D 31-contibution-guidelines-proposal
```
* Update your current development branch with the latest upstream version:
- Update your current development branch with the latest upstream version:
```sh
git l --ff upstream consolidation
......@@ -202,8 +204,8 @@ the changes from the main (upstream) repository:
To ensure consistency throughout the source code, keep these rules in mind as you
are working:
* All features or bug fixes **must be tested** by one or more specs (unit-tests).
* We follow [the PEP8 styleguide][style-guide].
- All features or bug fixes **must be tested** by one or more specs (unit-tests).
- We follow [the PEP8 styleguide][style-guide].
## <a name="commit"></a> Commit Message Guidelines
......@@ -231,24 +233,26 @@ Sample headers:
```
docs: update change log to beta.5
```
```
fix: need to depend on latest rxjs and zone.js
```
### \<header> Type
Must be one of the following:
* **build**: Changes that affect the build system or external dependencies
(example scopes: gulp, broccoli, npm)
* **ci**: Changes to our gitlab-ci configuration files and scripts
* **docs**: Documentation only changes
* **feat**: A new feature
* **fix**: A bug fix
* **perf**: A code change that improves performance
* **refactor**: A code change that neither fixes a bug nor adds a feature
* **style**: Changes that do not affect the meaning of the code (white-space, formatting,
- **build**: Changes that affect the build system or external dependencies
(example scopes: gulp, broccoli, npm)
- **ci**: Changes to our gitlab-ci configuration files and scripts
- **docs**: Documentation only changes
- **feat**: A new feature
- **fix**: A bug fix
- **perf**: A code change that improves performance
- **refactor**: A code change that neither fixes a bug nor adds a feature
- **style**: Changes that do not affect the meaning of the code (white-space, formatting,
etc.)
* **test**: Adding missing tests or correcting existing tests
- **test**: Adding missing tests or correcting existing tests
### \<header> Subject
......@@ -280,6 +284,7 @@ The rest of the commit message is then used for this. and is also the place to
reference GitLab issues that this commit **Closes**.
Sample footers:
```
BREAKING CHANGE: remove outdated dependency from requirements.txt. be sure to
reinstall your packages in order for the project to build.
......@@ -288,6 +293,7 @@ reinstall your packages in order for the project to build.
```
Closes #31
```
This "Closes" statement should only be incuded in commits that resolve an issue.
What's nice about the statement itself is that when the commit is merged, the issue
will auto close.
......@@ -298,6 +304,6 @@ then feel free to omit the footer.
[coc]: https://studentconduct.gmu.edu/wp-content/uploads/2011/09/2016-17-Code-of-Student-Conduct.pdf
[gitlab]: https://git.gmu.edu/srct/whats-open
[style-guide]: https://www.python.org/dev/peps/pep-0008/
[slack]:https://srct.slack.com/
[new-issue]:https://git.gmu.edu/srct/whats-open/issues/new
[merge-request]:https://git.gmu.edu/srct/whats-open/merge_requests
[slack]: https://srct.slack.com/
[new-issue]: https://git.gmu.edu/srct/whats-open/issues/new
[merge-request]: https://git.gmu.edu/srct/whats-open/merge_requests
......@@ -3,12 +3,19 @@
############################################################
# Set the base image to Ubuntu
FROM python:3.6
FROM python:3.7
ENV PYTHONUNBUFFERED 1
# Update the sources list
RUN apt-get update
RUN apt-get install netcat libgdal1h libproj-dev proj-data proj-bin -y
# Update the sources list and install all packages
# See: https://docs.docker.com/develop/develop-images/dockerfile_best-practices/#run
RUN apt-get update && apt-get install -y \
netcat \
libproj-dev \
proj-data \
proj-bin \
binutils \
gdal-bin \
&& rm -rf /var/lib/apt/lists/*
# Copy over all project files into /whats_open
RUN mkdir /whats-open/
......@@ -16,4 +23,5 @@ WORKDIR /whats-open/
ADD . /whats-open/
# Pip install all required dependecies
RUN pip install -r /whats-open/requirements/base.txt
RUN pip install pipenv
RUN pipenv install --system --deploy
\ No newline at end of file
......@@ -186,7 +186,7 @@ Apache License
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright 2017 George Mason University Student-Run Computing and Technology
Copyright 2018 George Mason University Student-Run Computing and Technology
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
......
[[source]]
name = "pypi"
url = "https://pypi.org/simple"
verify_ssl = true
[dev-packages]
black = "*"
pylint = "*"
pylint-django = "*"
[packages]
django-autoslug-iplweb = "*"
django-cas-client = "==1.3.0"
djangorestframework = "==3.7.7"
django-model-utils = "==3.0.0"
mysqlclient = "==1.3.12"
django-taggit = "==0.22.2"
django-taggit-serializer = "==0.1.5"
djangorestframework-gis = "==0.12.0"
django-filter = "==1.0.4"
django-crispy-forms = "==1.7.0"
coreapi = "==2.3.3"
urllib3 = "==1.22"
docutils = "==0.13.1"
gunicorn = "*"
Django = "<2.1,>=2.0"
Markdown = "==2.6.10"
[requires]
python_version = "3.7"
[pipenv]
allow_prereleases = true
This diff is collapsed.
......@@ -23,10 +23,11 @@ contribute, so if you are struggling, or just want to learn, then we are
willing to help.
Check out some of the other What's Open projects!
- https://git.gmu.edu/srct/whats-open-android
- https://git.gmu.edu/srct/whats-open-ios
- https://git.gmu.edu/srct/whats-open-web
- https://git.gmu.edu/srct/whats-open-alexa
- https://git.gmu.edu/srct/whats-open-android
- https://git.gmu.edu/srct/whats-open-ios
- https://git.gmu.edu/srct/whats-open-web
- https://git.gmu.edu/srct/whats-open-alexa
# Setup instructions for local development
......@@ -113,9 +114,9 @@ environments across machines.
Installing Docker on your system:
- For macOS: https://docs.docker.com/docker-for-mac/
- For Windows: https://docs.docker.com/docker-for-windows/
- For your specific \*nix distro: https://docs.docker.com/engine/installation/
- For macOS: https://docs.docker.com/docker-for-mac/
- For Windows: https://docs.docker.com/docker-for-windows/
- For your specific \*nix distro: https://docs.docker.com/engine/installation/
Additionally, you will need to install docker-compose: https://docs.docker.com/compose/install/
......@@ -148,9 +149,10 @@ pass: admin
Manual Setup involves all of the same steps as Docker, but just done manually.
First, install python, pip, and virtualenv on your system.
* `python` is the programming language used for Django, the web framework used by whats-open.
* `pip` is the python package manager.
* `virtualenv` allows you to isolate pip packages within virtual environments
- `python` is the programming language used for Django, the web framework used by whats-open.
- `pip` is the python package manager.
- `virtualenv` allows you to isolate pip packages within virtual environments
Open a terminal and run the following command:
......@@ -216,18 +218,17 @@ Run:
GRANT ALL ON test_wopen.* TO 'wopen'@'localhost'; FLUSH PRIVILEGES;
When running test cases, django creates a test database so your 'real' database
doesn't get screwed up. This database is called 'test_' + whatever your normal
doesn't get screwed up. This database is called 'test\_' + whatever your normal
database is named. Note that for permissions it doesn't matter that this database
hasn't yet been created.
The .* is to grant access all tables in the database, and 'flush privileges'
The .\* is to grant access all tables in the database, and 'flush privileges'
reloads privileges to ensure that your user is ready to go.
Exit the mysql shell by typing:
exit
At this point we will need to set some environment variables.
If you are using bash then just copy paste the following into your terminal:
......
version: '3'
version: "3"
services:
db:
image: mysql
deploy:
replicas: 1
restart_policy:
condition: on-failure
networks:
- wopen_net
image: mysql:5.7
command: mysqld --character-set-server=utf8mb4
--collation-server=utf8mb4_unicode_ci
ports:
- "3306:3306"
environment:
MYSQL_ALLOW_EMPTY_PASSWORD: 'yes'
MYSQL_ALLOW_EMPTY_PASSWORD: "yes"
MYSQL_DATABASE: wopen
MYSQL_USER: wopen
MYSQL_PASSWORD: wopen
api:
image: whats-open-api
deploy:
replicas: 1
restart_policy:
condition: on-failure
networks:
- wopen_net
build: .
ports:
- '8000:8000'
command: /bin/bash ./startup.sh
- "8000:8000"
command: ./docker-startup.sh
volumes:
- .:/whats-open
depends_on:
......@@ -39,6 +30,4 @@ services:
- WOPEN_DB_HOST=db
- WOPEN_DB_PORT=3306
- WOPEN_SUPERUSER=admin
networks:
wopen_net:
\ No newline at end of file
- WOPEN_ENV="dev"
......@@ -6,9 +6,8 @@ done
export WOPEN_SECRET_KEY=$(dd if=/dev/urandom count=100 | tr -dc "A-Za-z0-9" | fold -w 60 | head -n1 2>/dev/null)
python whats-open/manage.py flush --no-input
python whats-open/manage.py makemigrations
python whats-open/manage.py makemigrations api
python whats-open/manage.py migrate
echo "from django.contrib.auth.models import User; User.objects.filter(email='$WOPEN_SUPERUSER$WOPEN_EMAIL_DOMAIN').delete(); User.objects.create_superuser('$WOPEN_SUPERUSER$WOPEN_EMAIL_DOMAIN', '$WOPEN_SUPERUSER', 'admin')" | python whats-open/manage.py shell
echo "from django.contrib.auth.models import User; User.objects.filter(username='$WOPEN_SUPERUSER$WOPEN_EMAIL_DOMAIN').delete(); User.objects.create_superuser('$WOPEN_SUPERUSER$WOPEN_EMAIL_DOMAIN', '$WOPEN_SUPERUSER', 'admin')" | python whats-open/manage.py shell
python whats-open/manage.py runserver 0.0.0.0:8000
# This file is here because many Platforms as a Service look for
# requirements.txt in the root directory of a project.
-r requirements/production.txt
Django >= 2.0, < 2.1
django-autoslug-iplweb
django-cas-client==1.3.0
djangorestframework==3.7.7
django-model-utils==3.0.0
mysqlclient==1.3.12
setuptools==36.2.0
django-taggit==0.22.2
django-taggit-serializer==0.1.5
djangorestframework-gis==0.12.0
django-filter==1.0.4
django-crispy-forms==1.7.0
markdown==2.6.10
coreapi==2.3.3
urllib3==1.22
docutils==0.13.1
\ No newline at end of file
# Local development dependencies go here
-r test.txt
# Pro-tip: Try not to put anything here. There should be no dependency in
# production that isn't in development.
-r base.txt
gunicorn
\ No newline at end of file
# Test dependencies go here.
-r base.txt
coverage==4.4.1
......@@ -9,10 +9,16 @@ https://docs.djangoproject.com/en/1.11/ref/contrib/admin/
"""
# Django Imports
from django.contrib import admin
from django.contrib import messages
from django.contrib.gis.admin import OSMGeoAdmin
from django.core.exceptions import ObjectDoesNotExist
from django.http import HttpResponseRedirect
from django.shortcuts import render
# App Imports
from .models import Facility, Schedule, OpenTime, Category, Location, Alert
@admin.register(Facility)
class FacilityAdmin(admin.ModelAdmin):
"""
......@@ -20,41 +26,141 @@ class FacilityAdmin(admin.ModelAdmin):
Allows admins to create new facilities through the admin interface.
"""
def drop_special_schedules(self, request, queryset):
num = queryset.count()
for facility in queryset:
facility.special_schedules.clear()
self.message_user(
request,
"Successfully cleared all special schedules for %d facilities." % num,
)
drop_special_schedules.short_description = (
"Clear all special schedules for selected facilities"
)
def assign_bulk_schedules(self, request, queryset):
num = queryset.count()
# all admin actions-related requests are post requests, so we're looking for
# the one that has the associated value with our confirmation input button
if "bulk_schedule" in request.POST:
try:
new_schedule = Schedule.objects.get(pk=request.POST["schedule"])
name = new_schedule.name
for facility in queryset:
facility.main_schedule = new_schedule
facility.save()
self.message_user(
request,
"Set %s as the main schedule for %d facilities." % (name, num),
)
except ObjectDoesNotExist:
self.message_user(
request,
"Unable to set a new main schedule for %d facilities." % num,
level=messages.ERROR,
)
return HttpResponseRedirect(request.get_full_path())
return render(
request,
"bulk_schedules.html",
context={"facilities": queryset, "schedules": Schedule.objects.all()},
)
assign_bulk_schedules.short_description = (
"Set a main schedule for selected facilities"
)
def assign_bulk_special_schedules(self, request, queryset):
num = queryset.count()
if "bulk_special_schedule" in request.POST:
try:
new_special_schedule = Schedule.objects.get(
pk=request.POST["special_schedule"]
)
name = new_special_schedule.name
for facility in queryset:
facility.special_schedules.add(new_special_schedule)
facility.save()
self.message_user(
request,
"Added %s as a special schedule to %d facilities." % (name, num),
)
except ObjectDoesNotExist:
self.message_user(
request,
"Unable to add additional special schedule to %d facilities." % num,
level=messages.ERROR,
)
return HttpResponseRedirect(request.get_full_path())
return render(
request,
"bulk_special_schedules.html",
context={"facilities": queryset, "schedules": Schedule.objects.all()},
)
assign_bulk_special_schedules.short_description = (
"Add a special schedule to selected facilities"
)
# a list of all actions to be added
actions = [
drop_special_schedules,
assign_bulk_schedules,
assign_bulk_special_schedules,
]
# Allow filtering by the following fields
list_filter = ['facility_category', 'facility_location']
list_filter = ["facility_category", "facility_location"]
list_display = ("facility_name", "main_schedule", "modified")
# Modify the rendered layout of the "create a new facility" page
# We are basically reordering things to look nicer to the user here
fieldsets = (
(None, {
'fields': ('facility_name', 'logo', 'facility_category',
'facility_location', 'main_schedule', 'special_schedules',
('facility_product_tags', 'facility_labels',
'facility_classifier'),
'tapingo_url', 'phone_number', 'note', 'owners'),
}),
(
None,
{
"fields": (
"facility_name",
"logo",
"facility_category",
"facility_location",
"main_schedule",
"special_schedules",
("facility_product_tags", "facility_classifier"),
"tapingo_url",
"phone_number",
"note",
)
},
),
)
autocomplete_fields = ["main_schedule", "special_schedules"]
# despite the name of this method, ("change" seems to imply it would affect modify)
# it is called only when initially creating a model
def get_changeform_initial_data(self, request):
initial_data = super(FacilityAdmin, self).get_changeform_initial_data(request)
initial_data["owners"] = [request.user]