mirror of
https://github.com/wger-project/wger.git
synced 2026-02-18 00:17:51 +01:00
Merge branch 'master' into groups
# Conflicts: # docs/install.rst # requirements.txt # wger/core/apps.py # wger/core/templates/navigation.html # wger/gym/views/gym.py # wger/manager/api/views.py # wger/manager/apps.py # wger/manager/fixtures/test-workout-data.json # wger/manager/models.py # wger/manager/tests/test_workout.py # wger/manager/views/workout.py # wger/settings_global.py # wger/urls.py
This commit is contained in:
4
.bowerrc
4
.bowerrc
@@ -1,4 +0,0 @@
|
|||||||
{
|
|
||||||
"directory" : "wger/core/static/bower_components",
|
|
||||||
"interactive": false
|
|
||||||
}
|
|
||||||
4
.dockerignore
Normal file
4
.dockerignore
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
venv
|
||||||
|
node_modules
|
||||||
|
**/__pycache__
|
||||||
|
*.egg-info
|
||||||
@@ -11,18 +11,47 @@ indent_style = space
|
|||||||
insert_final_newline = true
|
insert_final_newline = true
|
||||||
trim_trailing_whitespace = true
|
trim_trailing_whitespace = true
|
||||||
|
|
||||||
# Docstrings and comments use max_line_length = 79
|
#
|
||||||
[*.py]
|
# Javascript
|
||||||
max_line_length = 100
|
#
|
||||||
|
|
||||||
[*.js]
|
[*.js]
|
||||||
indent_size = 2
|
indent_size = 2
|
||||||
|
|
||||||
[.eslintignore]
|
[{.eslintrc,.eslintignore}]
|
||||||
indent_size = 2
|
indent_size = 2
|
||||||
|
|
||||||
|
#
|
||||||
|
# Python
|
||||||
|
#
|
||||||
|
[*.py]
|
||||||
|
max_line_length = 100
|
||||||
|
|
||||||
|
#
|
||||||
|
# JSON File
|
||||||
|
#
|
||||||
[*.json]
|
[*.json]
|
||||||
indent_size = 2
|
indent_size = 2
|
||||||
|
|
||||||
|
#
|
||||||
|
# YAML File
|
||||||
|
#
|
||||||
[*.yml]
|
[*.yml]
|
||||||
indent_size = 2
|
indent_size = 2
|
||||||
|
|
||||||
|
#
|
||||||
|
# Structured text and Markdown
|
||||||
|
#
|
||||||
|
[*.md]
|
||||||
|
trim_trailing_whitespace = false
|
||||||
|
indent_size = 2
|
||||||
|
|
||||||
|
[*.rst]
|
||||||
|
indent_size = 4
|
||||||
|
|
||||||
|
#
|
||||||
|
# Makefiles
|
||||||
|
#
|
||||||
|
[{Makefile, makefile, GNUmakefile}]
|
||||||
|
indent_style = tab
|
||||||
|
indent_size = 4
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +0,0 @@
|
|||||||
# Ignore the following files and directories
|
|
||||||
/docs/
|
|
||||||
/extras/
|
|
||||||
/gulpfile.js
|
|
||||||
/node_modules/
|
|
||||||
/wger/core/static/bower_components/
|
|
||||||
/wger/core/static/js/Sortable.min.js
|
|
||||||
/wger/node_modules/
|
|
||||||
15
.gitattributes
vendored
15
.gitattributes
vendored
@@ -1,2 +1,13 @@
|
|||||||
# Auto detect text files and perform LF normalization
|
# Bash scripts (e.g. in Docker) make problems when the line ending is not LF
|
||||||
* text=auto
|
* text eol=lf
|
||||||
|
|
||||||
|
# These files are binary and should be left untouched
|
||||||
|
*.png binary
|
||||||
|
*.jpg binary
|
||||||
|
*.jpeg binary
|
||||||
|
*.gif binary
|
||||||
|
*.ico binary
|
||||||
|
*.ttf binary
|
||||||
|
*.woff binary
|
||||||
|
*.eot binary
|
||||||
|
*.pdf binary
|
||||||
|
|||||||
40
.github/contributing.md
vendored
Normal file
40
.github/contributing.md
vendored
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
# Contributing to wger
|
||||||
|
|
||||||
|
👍🎉 First off, thanks for taking the time to contribute! 🎉👍
|
||||||
|
|
||||||
|
Our goal is to build an awesome and flexible fitness and nutrition manager,
|
||||||
|
along with a comprehensive list of exercises and ingredients, all released
|
||||||
|
under a free license.
|
||||||
|
|
||||||
|
The following is a set of guidelines for contributing to wger
|
||||||
|
which is hosted in the wger-project Organization on GitHub.
|
||||||
|
These are mostly guidelines, not rules. As everywhere in life, use your
|
||||||
|
best judgment, and feel free to propose changes to this document
|
||||||
|
in a pull request.
|
||||||
|
|
||||||
|
## Questions
|
||||||
|
Are you just using the software and have a question or improvement?
|
||||||
|
|
||||||
|
* Ask it on the [gitter channel](https://gitter.im/wger-project/wger)
|
||||||
|
* or just [open an issue](https://github.com/wger-project/wger/issues)
|
||||||
|
|
||||||
|
## Issues
|
||||||
|
Describe the problem as well as you can. If useful, include any screenshots,
|
||||||
|
server logs or exceptions that you have access to and think might be relevant.
|
||||||
|
Include the git SHA1 if you have installed from source. If it's an enhancement,
|
||||||
|
describe a use-case or similar.
|
||||||
|
|
||||||
|
## Pull Requests
|
||||||
|
You want to contribute code? Awesome! Here are some tips:
|
||||||
|
|
||||||
|
* Make sure the tests are running (``python3 manage.py tests``)...
|
||||||
|
* ... and if you write new code, write new tests
|
||||||
|
* Lint the code with flake8 (``flake8 --config .github/linters/.flake8``)
|
||||||
|
and isort (``isort``)
|
||||||
|
* You can expect a response from a maintainer within a week, if you
|
||||||
|
haven’t heard anything by then, feel free to ping the thread.
|
||||||
|
|
||||||
|
|
||||||
|
Thanks!
|
||||||
|
|
||||||
|
-the wger Team
|
||||||
21
.github/dependabot.yml
vendored
Normal file
21
.github/dependabot.yml
vendored
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
# To get started with Dependabot version updates, you'll need to specify which
|
||||||
|
# package ecosystems to update and where the package manifests are located.
|
||||||
|
# Please see the documentation for all configuration options:
|
||||||
|
# https://help.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
|
||||||
|
|
||||||
|
version: 2
|
||||||
|
updates:
|
||||||
|
- package-ecosystem: "npm"
|
||||||
|
directory: "/"
|
||||||
|
schedule:
|
||||||
|
interval: "daily"
|
||||||
|
|
||||||
|
- package-ecosystem: "pip"
|
||||||
|
directory: "/"
|
||||||
|
schedule:
|
||||||
|
interval: "daily"
|
||||||
|
|
||||||
|
- package-ecosystem: "github-actions"
|
||||||
|
directory: "/"
|
||||||
|
schedule:
|
||||||
|
interval: "daily"
|
||||||
@@ -1,5 +1,4 @@
|
|||||||
{
|
{
|
||||||
"extends": "airbnb-base/legacy",
|
|
||||||
"env": {
|
"env": {
|
||||||
"browser": true,
|
"browser": true,
|
||||||
"jquery": true
|
"jquery": true
|
||||||
15
.github/linters/.flake8
vendored
Normal file
15
.github/linters/.flake8
vendored
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
[flake8]
|
||||||
|
# H101: Use TODO(NAME)
|
||||||
|
# W503: line break before binary operator
|
||||||
|
ignore = H101,W503
|
||||||
|
max-line-length = 100
|
||||||
|
exclude =
|
||||||
|
extras,
|
||||||
|
build,
|
||||||
|
dist,
|
||||||
|
yarn,
|
||||||
|
migrations,
|
||||||
|
settings.py,
|
||||||
|
docs,
|
||||||
|
urls.py : E501
|
||||||
|
apps.py : F401
|
||||||
597
.github/linters/.python-lint
vendored
Normal file
597
.github/linters/.python-lint
vendored
Normal file
@@ -0,0 +1,597 @@
|
|||||||
|
[MASTER]
|
||||||
|
|
||||||
|
# A comma-separated list of package or module names from where C extensions may
|
||||||
|
# be loaded. Extensions are loading into the active Python interpreter and may
|
||||||
|
# run arbitrary code.
|
||||||
|
extension-pkg-whitelist=
|
||||||
|
|
||||||
|
# Specify a score threshold to be exceeded before program exits with error.
|
||||||
|
fail-under=10
|
||||||
|
|
||||||
|
# Add files or directories to the blacklist. They should be base names, not
|
||||||
|
# paths.
|
||||||
|
ignore=tests,migrations
|
||||||
|
|
||||||
|
# Add files or directories matching the regex patterns to the blacklist. The
|
||||||
|
# regex matches against base names, not paths.
|
||||||
|
ignore-patterns=
|
||||||
|
|
||||||
|
# Python code to execute, usually for sys.path manipulation such as
|
||||||
|
# pygtk.require().
|
||||||
|
#init-hook=
|
||||||
|
|
||||||
|
# Use multiple processes to speed up Pylint. Specifying 0 will auto-detect the
|
||||||
|
# number of processors available to use.
|
||||||
|
jobs=0
|
||||||
|
|
||||||
|
# Control the amount of potential inferred values when inferring a single
|
||||||
|
# object. This can help the performance when dealing with large functions or
|
||||||
|
# complex, nested conditions.
|
||||||
|
limit-inference-results=100
|
||||||
|
|
||||||
|
# List of plugins (as comma separated values of python module names) to load,
|
||||||
|
# usually to register additional checkers.
|
||||||
|
load-plugins=
|
||||||
|
|
||||||
|
# Pickle collected data for later comparisons.
|
||||||
|
persistent=yes
|
||||||
|
|
||||||
|
# When enabled, pylint would attempt to guess common misconfiguration and emit
|
||||||
|
# user-friendly hints instead of false-positive error messages.
|
||||||
|
suggestion-mode=yes
|
||||||
|
|
||||||
|
# Allow loading of arbitrary C extensions. Extensions are imported into the
|
||||||
|
# active Python interpreter and may run arbitrary code.
|
||||||
|
unsafe-load-any-extension=no
|
||||||
|
|
||||||
|
|
||||||
|
[MESSAGES CONTROL]
|
||||||
|
|
||||||
|
# Only show warnings with the listed confidence levels. Leave empty to show
|
||||||
|
# all. Valid levels: HIGH, INFERENCE, INFERENCE_FAILURE, UNDEFINED.
|
||||||
|
confidence=
|
||||||
|
|
||||||
|
# Disable the message, report, category or checker with the given id(s). You
|
||||||
|
# can either give multiple identifiers separated by comma (,) or put this
|
||||||
|
# option multiple times (only on the command line, not in the configuration
|
||||||
|
# file where it should appear only once). You can also use "--disable=all" to
|
||||||
|
# disable everything first and then reenable specific checks. For example, if
|
||||||
|
# you want to run only the similarities checker, you can use "--disable=all
|
||||||
|
# --enable=similarities". If you want to run only the classes checker, but have
|
||||||
|
# no Warning level messages displayed, use "--disable=all --enable=classes
|
||||||
|
# --disable=W".
|
||||||
|
disable=import-error,
|
||||||
|
print-statement,
|
||||||
|
parameter-unpacking,
|
||||||
|
unpacking-in-except,
|
||||||
|
old-raise-syntax,
|
||||||
|
backtick,
|
||||||
|
long-suffix,
|
||||||
|
old-ne-operator,
|
||||||
|
old-octal-literal,
|
||||||
|
import-star-module-level,
|
||||||
|
non-ascii-bytes-literal,
|
||||||
|
raw-checker-failed,
|
||||||
|
bad-inline-option,
|
||||||
|
locally-disabled,
|
||||||
|
file-ignored,
|
||||||
|
suppressed-message,
|
||||||
|
useless-suppression,
|
||||||
|
deprecated-pragma,
|
||||||
|
use-symbolic-message-instead,
|
||||||
|
duplicate-code,
|
||||||
|
apply-builtin,
|
||||||
|
basestring-builtin,
|
||||||
|
buffer-builtin,
|
||||||
|
cmp-builtin,
|
||||||
|
coerce-builtin,
|
||||||
|
execfile-builtin,
|
||||||
|
file-builtin,
|
||||||
|
long-builtin,
|
||||||
|
raw_input-builtin,
|
||||||
|
reduce-builtin,
|
||||||
|
standarderror-builtin,
|
||||||
|
unicode-builtin,
|
||||||
|
xrange-builtin,
|
||||||
|
coerce-method,
|
||||||
|
delslice-method,
|
||||||
|
getslice-method,
|
||||||
|
setslice-method,
|
||||||
|
no-absolute-import,
|
||||||
|
old-division,
|
||||||
|
dict-iter-method,
|
||||||
|
dict-view-method,
|
||||||
|
next-method-called,
|
||||||
|
metaclass-assignment,
|
||||||
|
indexing-exception,
|
||||||
|
raising-string,
|
||||||
|
reload-builtin,
|
||||||
|
oct-method,
|
||||||
|
hex-method,
|
||||||
|
nonzero-method,
|
||||||
|
cmp-method,
|
||||||
|
input-builtin,
|
||||||
|
round-builtin,
|
||||||
|
intern-builtin,
|
||||||
|
unichr-builtin,
|
||||||
|
map-builtin-not-iterating,
|
||||||
|
zip-builtin-not-iterating,
|
||||||
|
range-builtin-not-iterating,
|
||||||
|
filter-builtin-not-iterating,
|
||||||
|
using-cmp-argument,
|
||||||
|
eq-without-hash,
|
||||||
|
div-method,
|
||||||
|
idiv-method,
|
||||||
|
rdiv-method,
|
||||||
|
exception-message-attribute,
|
||||||
|
invalid-str-codec,
|
||||||
|
sys-max-int,
|
||||||
|
bad-python3-import,
|
||||||
|
deprecated-string-function,
|
||||||
|
deprecated-str-translate-call,
|
||||||
|
deprecated-itertools-function,
|
||||||
|
deprecated-types-field,
|
||||||
|
next-method-defined,
|
||||||
|
dict-items-not-iterating,
|
||||||
|
dict-keys-not-iterating,
|
||||||
|
dict-values-not-iterating,
|
||||||
|
deprecated-operator-function,
|
||||||
|
deprecated-urllib-function,
|
||||||
|
xreadlines-attribute,
|
||||||
|
deprecated-sys-function,
|
||||||
|
exception-escape,
|
||||||
|
comprehension-escape
|
||||||
|
|
||||||
|
# Enable the message, report, category or checker with the given id(s). You can
|
||||||
|
# either give multiple identifier separated by comma (,) or put this option
|
||||||
|
# multiple time (only on the command line, not in the configuration file where
|
||||||
|
# it should appear only once). See also the "--disable" option for examples.
|
||||||
|
enable=c-extension-no-member
|
||||||
|
|
||||||
|
|
||||||
|
[REPORTS]
|
||||||
|
|
||||||
|
# Python expression which should return a score less than or equal to 10. You
|
||||||
|
# have access to the variables 'error', 'warning', 'refactor', and 'convention'
|
||||||
|
# which contain the number of messages in each category, as well as 'statement'
|
||||||
|
# which is the total number of statements analyzed. This score is used by the
|
||||||
|
# global evaluation report (RP0004).
|
||||||
|
evaluation=10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10)
|
||||||
|
|
||||||
|
# Template used to display messages. This is a python new-style format string
|
||||||
|
# used to format the message information. See doc for all details.
|
||||||
|
#msg-template=
|
||||||
|
|
||||||
|
# Set the output format. Available formats are text, parseable, colorized, json
|
||||||
|
# and msvs (visual studio). You can also give a reporter class, e.g.
|
||||||
|
# mypackage.mymodule.MyReporterClass.
|
||||||
|
output-format=text
|
||||||
|
|
||||||
|
# Tells whether to display a full report or only the messages.
|
||||||
|
reports=no
|
||||||
|
|
||||||
|
# Activate the evaluation score.
|
||||||
|
score=yes
|
||||||
|
|
||||||
|
|
||||||
|
[REFACTORING]
|
||||||
|
|
||||||
|
# Maximum number of nested blocks for function / method body
|
||||||
|
max-nested-blocks=5
|
||||||
|
|
||||||
|
# Complete name of functions that never returns. When checking for
|
||||||
|
# inconsistent-return-statements if a never returning function is called then
|
||||||
|
# it will be considered as an explicit return statement and no message will be
|
||||||
|
# printed.
|
||||||
|
never-returning-functions=sys.exit
|
||||||
|
|
||||||
|
|
||||||
|
[LOGGING]
|
||||||
|
|
||||||
|
# The type of string formatting that logging methods do. `old` means using %
|
||||||
|
# formatting, `new` is for `{}` formatting.
|
||||||
|
logging-format-style=old
|
||||||
|
|
||||||
|
# Logging modules to check that the string format arguments are in logging
|
||||||
|
# function parameter format.
|
||||||
|
logging-modules=logging
|
||||||
|
|
||||||
|
|
||||||
|
[STRING]
|
||||||
|
|
||||||
|
# This flag controls whether inconsistent-quotes generates a warning when the
|
||||||
|
# character used as a quote delimiter is used inconsistently within a module.
|
||||||
|
check-quote-consistency=no
|
||||||
|
|
||||||
|
# This flag controls whether the implicit-str-concat should generate a warning
|
||||||
|
# on implicit string concatenation in sequences defined over several lines.
|
||||||
|
check-str-concat-over-line-jumps=no
|
||||||
|
|
||||||
|
|
||||||
|
[TYPECHECK]
|
||||||
|
|
||||||
|
# List of decorators that produce context managers, such as
|
||||||
|
# contextlib.contextmanager. Add to this list to register other decorators that
|
||||||
|
# produce valid context managers.
|
||||||
|
contextmanager-decorators=contextlib.contextmanager
|
||||||
|
|
||||||
|
# List of members which are set dynamically and missed by pylint inference
|
||||||
|
# system, and so shouldn't trigger E1101 when accessed. Python regular
|
||||||
|
# expressions are accepted.
|
||||||
|
generated-members=
|
||||||
|
|
||||||
|
# Tells whether missing members accessed in mixin class should be ignored. A
|
||||||
|
# mixin class is detected if its name ends with "mixin" (case insensitive).
|
||||||
|
ignore-mixin-members=yes
|
||||||
|
|
||||||
|
# Tells whether to warn about missing members when the owner of the attribute
|
||||||
|
# is inferred to be None.
|
||||||
|
ignore-none=yes
|
||||||
|
|
||||||
|
# This flag controls whether pylint should warn about no-member and similar
|
||||||
|
# checks whenever an opaque object is returned when inferring. The inference
|
||||||
|
# can return multiple potential results while evaluating a Python object, but
|
||||||
|
# some branches might not be evaluated, which results in partial inference. In
|
||||||
|
# that case, it might be useful to still emit no-member and other checks for
|
||||||
|
# the rest of the inferred objects.
|
||||||
|
ignore-on-opaque-inference=yes
|
||||||
|
|
||||||
|
# List of class names for which member attributes should not be checked (useful
|
||||||
|
# for classes with dynamically set attributes). This supports the use of
|
||||||
|
# qualified names.
|
||||||
|
ignored-classes=optparse.Values,thread._local,_thread._local
|
||||||
|
|
||||||
|
# List of module names for which member attributes should not be checked
|
||||||
|
# (useful for modules/projects where namespaces are manipulated during runtime
|
||||||
|
# and thus existing member attributes cannot be deduced by static analysis). It
|
||||||
|
# supports qualified module names, as well as Unix pattern matching.
|
||||||
|
ignored-modules=
|
||||||
|
|
||||||
|
# Show a hint with possible names when a member name was not found. The aspect
|
||||||
|
# of finding the hint is based on edit distance.
|
||||||
|
missing-member-hint=yes
|
||||||
|
|
||||||
|
# The minimum edit distance a name should have in order to be considered a
|
||||||
|
# similar match for a missing member name.
|
||||||
|
missing-member-hint-distance=1
|
||||||
|
|
||||||
|
# The total number of similar names that should be taken in consideration when
|
||||||
|
# showing a hint for a missing member.
|
||||||
|
missing-member-max-choices=1
|
||||||
|
|
||||||
|
# List of decorators that change the signature of a decorated function.
|
||||||
|
signature-mutators=
|
||||||
|
|
||||||
|
|
||||||
|
[SIMILARITIES]
|
||||||
|
|
||||||
|
# Ignore comments when computing similarities.
|
||||||
|
ignore-comments=yes
|
||||||
|
|
||||||
|
# Ignore docstrings when computing similarities.
|
||||||
|
ignore-docstrings=yes
|
||||||
|
|
||||||
|
# Ignore imports when computing similarities.
|
||||||
|
ignore-imports=no
|
||||||
|
|
||||||
|
# Minimum lines number of a similarity.
|
||||||
|
min-similarity-lines=4
|
||||||
|
|
||||||
|
|
||||||
|
[BASIC]
|
||||||
|
|
||||||
|
# Naming style matching correct argument names.
|
||||||
|
argument-naming-style=snake_case
|
||||||
|
|
||||||
|
# Regular expression matching correct argument names. Overrides argument-
|
||||||
|
# naming-style.
|
||||||
|
#argument-rgx=
|
||||||
|
|
||||||
|
# Naming style matching correct attribute names.
|
||||||
|
attr-naming-style=snake_case
|
||||||
|
|
||||||
|
# Regular expression matching correct attribute names. Overrides attr-naming-
|
||||||
|
# style.
|
||||||
|
#attr-rgx=
|
||||||
|
|
||||||
|
# Bad variable names which should always be refused, separated by a comma.
|
||||||
|
bad-names=foo,
|
||||||
|
bar,
|
||||||
|
baz,
|
||||||
|
toto,
|
||||||
|
tutu,
|
||||||
|
tata
|
||||||
|
|
||||||
|
# Bad variable names regexes, separated by a comma. If names match any regex,
|
||||||
|
# they will always be refused
|
||||||
|
bad-names-rgxs=
|
||||||
|
|
||||||
|
# Naming style matching correct class attribute names.
|
||||||
|
class-attribute-naming-style=any
|
||||||
|
|
||||||
|
# Regular expression matching correct class attribute names. Overrides class-
|
||||||
|
# attribute-naming-style.
|
||||||
|
#class-attribute-rgx=
|
||||||
|
|
||||||
|
# Naming style matching correct class names.
|
||||||
|
class-naming-style=PascalCase
|
||||||
|
|
||||||
|
# Regular expression matching correct class names. Overrides class-naming-
|
||||||
|
# style.
|
||||||
|
#class-rgx=
|
||||||
|
|
||||||
|
# Naming style matching correct constant names.
|
||||||
|
const-naming-style=UPPER_CASE
|
||||||
|
|
||||||
|
# Regular expression matching correct constant names. Overrides const-naming-
|
||||||
|
# style.
|
||||||
|
#const-rgx=
|
||||||
|
|
||||||
|
# Minimum line length for functions/classes that require docstrings, shorter
|
||||||
|
# ones are exempt.
|
||||||
|
docstring-min-length=-1
|
||||||
|
|
||||||
|
# Naming style matching correct function names.
|
||||||
|
function-naming-style=snake_case
|
||||||
|
|
||||||
|
# Regular expression matching correct function names. Overrides function-
|
||||||
|
# naming-style.
|
||||||
|
#function-rgx=
|
||||||
|
|
||||||
|
# Good variable names which should always be accepted, separated by a comma.
|
||||||
|
good-names=i,
|
||||||
|
j,
|
||||||
|
k,
|
||||||
|
ex,
|
||||||
|
Run,
|
||||||
|
_
|
||||||
|
|
||||||
|
# Good variable names regexes, separated by a comma. If names match any regex,
|
||||||
|
# they will always be accepted
|
||||||
|
good-names-rgxs=
|
||||||
|
|
||||||
|
# Include a hint for the correct naming format with invalid-name.
|
||||||
|
include-naming-hint=no
|
||||||
|
|
||||||
|
# Naming style matching correct inline iteration names.
|
||||||
|
inlinevar-naming-style=any
|
||||||
|
|
||||||
|
# Regular expression matching correct inline iteration names. Overrides
|
||||||
|
# inlinevar-naming-style.
|
||||||
|
#inlinevar-rgx=
|
||||||
|
|
||||||
|
# Naming style matching correct method names.
|
||||||
|
method-naming-style=snake_case
|
||||||
|
|
||||||
|
# Regular expression matching correct method names. Overrides method-naming-
|
||||||
|
# style.
|
||||||
|
#method-rgx=
|
||||||
|
|
||||||
|
# Naming style matching correct module names.
|
||||||
|
module-naming-style=snake_case
|
||||||
|
|
||||||
|
# Regular expression matching correct module names. Overrides module-naming-
|
||||||
|
# style.
|
||||||
|
#module-rgx=
|
||||||
|
|
||||||
|
# Colon-delimited sets of names that determine each other's naming style when
|
||||||
|
# the name regexes allow several styles.
|
||||||
|
name-group=
|
||||||
|
|
||||||
|
# Regular expression which should only match function or class names that do
|
||||||
|
# not require a docstring.
|
||||||
|
no-docstring-rgx=^_
|
||||||
|
|
||||||
|
# List of decorators that produce properties, such as abc.abstractproperty. Add
|
||||||
|
# to this list to register other decorators that produce valid properties.
|
||||||
|
# These decorators are taken in consideration only for invalid-name.
|
||||||
|
property-classes=abc.abstractproperty
|
||||||
|
|
||||||
|
# Naming style matching correct variable names.
|
||||||
|
variable-naming-style=snake_case
|
||||||
|
|
||||||
|
# Regular expression matching correct variable names. Overrides variable-
|
||||||
|
# naming-style.
|
||||||
|
#variable-rgx=
|
||||||
|
|
||||||
|
|
||||||
|
[SPELLING]
|
||||||
|
|
||||||
|
# Limits count of emitted suggestions for spelling mistakes.
|
||||||
|
max-spelling-suggestions=4
|
||||||
|
|
||||||
|
# Spelling dictionary name. Available dictionaries: none. To make it work,
|
||||||
|
# install the python-enchant package.
|
||||||
|
spelling-dict=
|
||||||
|
|
||||||
|
# List of comma separated words that should not be checked.
|
||||||
|
spelling-ignore-words=
|
||||||
|
|
||||||
|
# A path to a file that contains the private dictionary; one word per line.
|
||||||
|
spelling-private-dict-file=
|
||||||
|
|
||||||
|
# Tells whether to store unknown words to the private dictionary (see the
|
||||||
|
# --spelling-private-dict-file option) instead of raising a message.
|
||||||
|
spelling-store-unknown-words=no
|
||||||
|
|
||||||
|
|
||||||
|
[MISCELLANEOUS]
|
||||||
|
|
||||||
|
# List of note tags to take in consideration, separated by a comma.
|
||||||
|
notes=FIXME,
|
||||||
|
XXX,
|
||||||
|
TODO
|
||||||
|
|
||||||
|
# Regular expression of note tags to take in consideration.
|
||||||
|
#notes-rgx=
|
||||||
|
|
||||||
|
|
||||||
|
[FORMAT]
|
||||||
|
|
||||||
|
# Expected format of line ending, e.g. empty (any line ending), LF or CRLF.
|
||||||
|
expected-line-ending-format=
|
||||||
|
|
||||||
|
# Regexp for a line that is allowed to be longer than the limit.
|
||||||
|
ignore-long-lines=^\s*(# )?<?https?://\S+>?$
|
||||||
|
|
||||||
|
# Number of spaces of indent required inside a hanging or continued line.
|
||||||
|
indent-after-paren=4
|
||||||
|
|
||||||
|
# String used as indentation unit. This is usually " " (4 spaces) or "\t" (1
|
||||||
|
# tab).
|
||||||
|
indent-string=' '
|
||||||
|
|
||||||
|
# Maximum number of characters on a single line.
|
||||||
|
max-line-length=100
|
||||||
|
|
||||||
|
# Maximum number of lines in a module.
|
||||||
|
max-module-lines=1000
|
||||||
|
|
||||||
|
# List of optional constructs for which whitespace checking is disabled. `dict-
|
||||||
|
# separator` is used to allow tabulation in dicts, etc.: {1 : 1,\n222: 2}.
|
||||||
|
# `trailing-comma` allows a space between comma and closing bracket: (a, ).
|
||||||
|
# `empty-line` allows space-only lines.
|
||||||
|
no-space-check=trailing-comma,
|
||||||
|
dict-separator
|
||||||
|
|
||||||
|
# Allow the body of a class to be on the same line as the declaration if body
|
||||||
|
# contains single statement.
|
||||||
|
single-line-class-stmt=no
|
||||||
|
|
||||||
|
# Allow the body of an if to be on the same line as the test if there is no
|
||||||
|
# else.
|
||||||
|
single-line-if-stmt=no
|
||||||
|
|
||||||
|
|
||||||
|
[VARIABLES]
|
||||||
|
|
||||||
|
# List of additional names supposed to be defined in builtins. Remember that
|
||||||
|
# you should avoid defining new builtins when possible.
|
||||||
|
additional-builtins=
|
||||||
|
|
||||||
|
# Tells whether unused global variables should be treated as a violation.
|
||||||
|
allow-global-unused-variables=yes
|
||||||
|
|
||||||
|
# List of strings which can identify a callback function by name. A callback
|
||||||
|
# name must start or end with one of those strings.
|
||||||
|
callbacks=cb_,
|
||||||
|
_cb
|
||||||
|
|
||||||
|
# A regular expression matching the name of dummy variables (i.e. expected to
|
||||||
|
# not be used).
|
||||||
|
dummy-variables-rgx=_+$|(_[a-zA-Z0-9_]*[a-zA-Z0-9]+?$)|dummy|^ignored_|^unused_
|
||||||
|
|
||||||
|
# Argument names that match this expression will be ignored. Default to name
|
||||||
|
# with leading underscore.
|
||||||
|
ignored-argument-names=_.*|^ignored_|^unused_
|
||||||
|
|
||||||
|
# Tells whether we should check for unused import in __init__ files.
|
||||||
|
init-import=no
|
||||||
|
|
||||||
|
# List of qualified module names which can have objects that can redefine
|
||||||
|
# builtins.
|
||||||
|
redefining-builtins-modules=six.moves,past.builtins,future.builtins,builtins,io
|
||||||
|
|
||||||
|
|
||||||
|
[DESIGN]
|
||||||
|
|
||||||
|
# Maximum number of arguments for function / method.
|
||||||
|
max-args=5
|
||||||
|
|
||||||
|
# Maximum number of attributes for a class (see R0902).
|
||||||
|
max-attributes=7
|
||||||
|
|
||||||
|
# Maximum number of boolean expressions in an if statement (see R0916).
|
||||||
|
max-bool-expr=5
|
||||||
|
|
||||||
|
# Maximum number of branch for function / method body.
|
||||||
|
max-branches=12
|
||||||
|
|
||||||
|
# Maximum number of locals for function / method body.
|
||||||
|
max-locals=15
|
||||||
|
|
||||||
|
# Maximum number of parents for a class (see R0901).
|
||||||
|
max-parents=7
|
||||||
|
|
||||||
|
# Maximum number of public methods for a class (see R0904).
|
||||||
|
max-public-methods=20
|
||||||
|
|
||||||
|
# Maximum number of return / yield for function / method body.
|
||||||
|
max-returns=6
|
||||||
|
|
||||||
|
# Maximum number of statements in function / method body.
|
||||||
|
max-statements=50
|
||||||
|
|
||||||
|
# Minimum number of public methods for a class (see R0903).
|
||||||
|
min-public-methods=2
|
||||||
|
|
||||||
|
|
||||||
|
[IMPORTS]
|
||||||
|
|
||||||
|
# List of modules that can be imported at any level, not just the top level
|
||||||
|
# one.
|
||||||
|
allow-any-import-level=
|
||||||
|
|
||||||
|
# Allow wildcard imports from modules that define __all__.
|
||||||
|
allow-wildcard-with-all=no
|
||||||
|
|
||||||
|
# Analyse import fallback blocks. This can be used to support both Python 2 and
|
||||||
|
# 3 compatible code, which means that the block might have code that exists
|
||||||
|
# only in one or another interpreter, leading to false positives when analysed.
|
||||||
|
analyse-fallback-blocks=no
|
||||||
|
|
||||||
|
# Deprecated modules which should not be used, separated by a comma.
|
||||||
|
deprecated-modules=optparse,tkinter.tix
|
||||||
|
|
||||||
|
# Create a graph of external dependencies in the given file (report RP0402 must
|
||||||
|
# not be disabled).
|
||||||
|
ext-import-graph=
|
||||||
|
|
||||||
|
# Create a graph of every (i.e. internal and external) dependencies in the
|
||||||
|
# given file (report RP0402 must not be disabled).
|
||||||
|
import-graph=
|
||||||
|
|
||||||
|
# Create a graph of internal dependencies in the given file (report RP0402 must
|
||||||
|
# not be disabled).
|
||||||
|
int-import-graph=
|
||||||
|
|
||||||
|
# Force import order to recognize a module as part of the standard
|
||||||
|
# compatibility libraries.
|
||||||
|
known-standard-library=
|
||||||
|
|
||||||
|
# Force import order to recognize a module as part of a third party library.
|
||||||
|
known-third-party=enchant
|
||||||
|
|
||||||
|
# Couples of modules and preferred modules, separated by a comma.
|
||||||
|
preferred-modules=
|
||||||
|
|
||||||
|
|
||||||
|
[CLASSES]
|
||||||
|
|
||||||
|
# List of method names used to declare (i.e. assign) instance attributes.
|
||||||
|
defining-attr-methods=__init__,
|
||||||
|
__new__,
|
||||||
|
setUp,
|
||||||
|
__post_init__
|
||||||
|
|
||||||
|
# List of member names, which should be excluded from the protected access
|
||||||
|
# warning.
|
||||||
|
exclude-protected=_asdict,
|
||||||
|
_fields,
|
||||||
|
_replace,
|
||||||
|
_source,
|
||||||
|
_make
|
||||||
|
|
||||||
|
# List of valid names for the first argument in a class method.
|
||||||
|
valid-classmethod-first-arg=cls
|
||||||
|
|
||||||
|
# List of valid names for the first argument in a metaclass class method.
|
||||||
|
valid-metaclass-classmethod-first-arg=cls
|
||||||
|
|
||||||
|
|
||||||
|
[EXCEPTIONS]
|
||||||
|
|
||||||
|
# Exceptions that will emit a warning when being caught. Defaults to
|
||||||
|
# "BaseException, Exception".
|
||||||
|
overgeneral-exceptions=BaseException,
|
||||||
|
Exception
|
||||||
6
.github/linters/.stylelintrc.json
vendored
Normal file
6
.github/linters/.stylelintrc.json
vendored
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"extends": "stylelint-config-standard",
|
||||||
|
"rules": {
|
||||||
|
"no-descending-specificity": null
|
||||||
|
}
|
||||||
|
}
|
||||||
18
.github/pull_request_template.md
vendored
Normal file
18
.github/pull_request_template.md
vendored
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
### Proposed Changes
|
||||||
|
|
||||||
|
-
|
||||||
|
-
|
||||||
|
-
|
||||||
|
|
||||||
|
### Please check that the PR fulfills these requirements
|
||||||
|
|
||||||
|
- [ ] Tests for the changes have been added (for bug fixes / features)
|
||||||
|
- [ ] New python code has been linted with with flake8 (``flake8 --config .github/linters/.flake8``)
|
||||||
|
and isort (``isort``)
|
||||||
|
- [ ] Added yourself to AUTHORS.rst
|
||||||
|
|
||||||
|
### Other questions
|
||||||
|
|
||||||
|
* Does this PR introduce a breaking change such as a database migration? (i.e.
|
||||||
|
what changes might users need to make in their running application due to
|
||||||
|
this PR?)
|
||||||
54
.github/workflows/codeql-analysis.yml
vendored
Normal file
54
.github/workflows/codeql-analysis.yml
vendored
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
name: "CodeQL"
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [master, ]
|
||||||
|
pull_request:
|
||||||
|
# The branches below must be a subset of the branches above
|
||||||
|
branches: [master]
|
||||||
|
schedule:
|
||||||
|
- cron: '0 1 * * 2'
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
analyse:
|
||||||
|
name: Analyse
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout repository
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
with:
|
||||||
|
# We must fetch at least the immediate parents so that if this is
|
||||||
|
# a pull request then we can checkout the head.
|
||||||
|
fetch-depth: 2
|
||||||
|
|
||||||
|
# If this run was triggered by a pull request event, then checkout
|
||||||
|
# the head of the pull request instead of the merge commit.
|
||||||
|
- run: git checkout HEAD^2
|
||||||
|
if: ${{ github.event_name == 'pull_request' }}
|
||||||
|
|
||||||
|
# Initializes the CodeQL tools for scanning.
|
||||||
|
- name: Initialize CodeQL
|
||||||
|
uses: github/codeql-action/init@v1
|
||||||
|
# Override language selection by uncommenting this and choosing your languages
|
||||||
|
# with:
|
||||||
|
# languages: go, javascript, csharp, python, cpp, java
|
||||||
|
|
||||||
|
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
|
||||||
|
# If this step fails, then you should remove it and run the build manually (see below)
|
||||||
|
- name: Autobuild
|
||||||
|
uses: github/codeql-action/autobuild@v1
|
||||||
|
|
||||||
|
# ℹ️ Command-line programs to run using the OS shell.
|
||||||
|
# 📚 https://git.io/JvXDl
|
||||||
|
|
||||||
|
# ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
|
||||||
|
# and modify them (or add more) to build your code if your project
|
||||||
|
# uses a compiled language
|
||||||
|
|
||||||
|
#- run: |
|
||||||
|
# make bootstrap
|
||||||
|
# make release
|
||||||
|
|
||||||
|
- name: Perform CodeQL Analysis
|
||||||
|
uses: github/codeql-action/analyze@v1
|
||||||
43
.github/workflows/docker.yml
vendored
Normal file
43
.github/workflows/docker.yml
vendored
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
name: Build and push Docker images
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- master
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
deploy:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Checkout code
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
|
||||||
|
- name: Build base image
|
||||||
|
uses: docker/build-push-action@v1
|
||||||
|
with:
|
||||||
|
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||||
|
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||||
|
repository: wger/base
|
||||||
|
dockerfile: extras/docker/base/Dockerfile
|
||||||
|
tags: latest,2.0-dev
|
||||||
|
tag_with_ref: true
|
||||||
|
|
||||||
|
- name: Build dev image
|
||||||
|
uses: docker/build-push-action@v1
|
||||||
|
with:
|
||||||
|
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||||
|
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||||
|
repository: wger/devel
|
||||||
|
dockerfile: extras/docker/development/Dockerfile
|
||||||
|
tags: latest,2.0-dev
|
||||||
|
tag_with_ref: true
|
||||||
|
|
||||||
|
- name: Build apache image
|
||||||
|
uses: docker/build-push-action@v1
|
||||||
|
with:
|
||||||
|
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||||
|
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||||
|
repository: wger/apache
|
||||||
|
dockerfile: extras/docker/apache/Dockerfile
|
||||||
|
tags: latest,2.0-dev
|
||||||
|
tag_with_ref: true
|
||||||
56
.github/workflows/linter.yml
vendored
Normal file
56
.github/workflows/linter.yml
vendored
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
###########################
|
||||||
|
###########################
|
||||||
|
## Linter GitHub Actions ##
|
||||||
|
###########################
|
||||||
|
###########################
|
||||||
|
name: Lint Code Base
|
||||||
|
|
||||||
|
#
|
||||||
|
# Documentation:
|
||||||
|
# https://help.github.com/en/articles/workflow-syntax-for-github-actions
|
||||||
|
#
|
||||||
|
|
||||||
|
################################################
|
||||||
|
# Trigger the workflow on push or pull request #
|
||||||
|
# but only for the master branch #
|
||||||
|
################################################
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- master
|
||||||
|
pull_request:
|
||||||
|
branches:
|
||||||
|
- master
|
||||||
|
|
||||||
|
###############
|
||||||
|
# Set the Job #
|
||||||
|
###############
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
# Name the Job
|
||||||
|
name: Lint Code Base
|
||||||
|
# Set the agent to run on
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
##################
|
||||||
|
# Load all steps #
|
||||||
|
##################
|
||||||
|
steps:
|
||||||
|
##########################
|
||||||
|
# Checkout the code base #
|
||||||
|
##########################
|
||||||
|
- name: Checkout Code
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
|
||||||
|
################################
|
||||||
|
# Run Linter against code base #
|
||||||
|
################################
|
||||||
|
- name: Lint Code Base
|
||||||
|
uses: docker://github/super-linter:v3.5.1
|
||||||
|
env:
|
||||||
|
VALIDATE_PYTHON_FLAKE8: true
|
||||||
|
VALIDATE_MD: true
|
||||||
|
VALIDATE_JAVASCRIPT_ES: true
|
||||||
|
VALIDATE_JSON: true
|
||||||
|
VALIDATE_DOCKER: true
|
||||||
|
|
||||||
31
.github/workflows/pypi-publish.yml
vendored
Normal file
31
.github/workflows/pypi-publish.yml
vendored
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
# This workflows will upload a Python Package using Twine when a release is created
|
||||||
|
# For more information see: https://help.github.com/en/actions/language-and-framework-guides/using-python-with-github-actions#publishing-to-package-registries
|
||||||
|
|
||||||
|
name: Upload Package to PyPI
|
||||||
|
|
||||||
|
on:
|
||||||
|
release:
|
||||||
|
types: [created]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
deploy:
|
||||||
|
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- name: Set up Python
|
||||||
|
uses: actions/setup-python@v2
|
||||||
|
with:
|
||||||
|
python-version: '3.x'
|
||||||
|
- name: Install dependencies
|
||||||
|
run: |
|
||||||
|
python -m pip install --upgrade pip
|
||||||
|
pip install setuptools wheel twine
|
||||||
|
- name: Build and publish
|
||||||
|
env:
|
||||||
|
TWINE_USERNAME: __token__
|
||||||
|
TWINE_PASSWORD: ${{ secrets.PYPI_API_TOKEN }}
|
||||||
|
run: |
|
||||||
|
python setup.py sdist bdist_wheel
|
||||||
|
twine upload dist/*
|
||||||
6
.gitignore
vendored
6
.gitignore
vendored
@@ -59,6 +59,8 @@ target/
|
|||||||
# IDE
|
# IDE
|
||||||
.idea/
|
.idea/
|
||||||
|
|
||||||
# External Libraries
|
# External Libraries
|
||||||
wger/core/static/bower_components
|
wger/core/static/yarn
|
||||||
node_modules
|
node_modules
|
||||||
|
|
||||||
|
venv
|
||||||
|
|||||||
15
.pre-commit-config.yaml
Normal file
15
.pre-commit-config.yaml
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
---
|
||||||
|
- repo: git://github.com/pre-commit/pre-commit-hooks
|
||||||
|
sha: v1.4.0
|
||||||
|
hooks:
|
||||||
|
- id: trailing-whitespace
|
||||||
|
- id: end-of-file-fixer
|
||||||
|
- id: autopep8-wrapper
|
||||||
|
- id: check-yaml
|
||||||
|
- id: check-merge-conflict
|
||||||
|
- id: debug-statements
|
||||||
|
- id: flake8
|
||||||
|
- repo: git://github.com/detailyang/pre-commit-shell
|
||||||
|
sha: 1.0.2
|
||||||
|
hooks:
|
||||||
|
- id: shell-lint
|
||||||
53
.travis.yml
53
.travis.yml
@@ -1,4 +1,8 @@
|
|||||||
language: python
|
language: python
|
||||||
|
dist: bionic
|
||||||
|
|
||||||
|
services:
|
||||||
|
- postgresql
|
||||||
|
|
||||||
# Cache the pip files
|
# Cache the pip files
|
||||||
cache:
|
cache:
|
||||||
@@ -8,60 +12,43 @@ cache:
|
|||||||
- node_modules
|
- node_modules
|
||||||
- wger/node_modules
|
- wger/node_modules
|
||||||
|
|
||||||
# Use container infrastructure
|
|
||||||
# http://blog.travis-ci.com/2014-12-17-faster-builds-with-container-based-infrastructure/
|
|
||||||
sudo: false
|
|
||||||
|
|
||||||
# Python versions to test
|
# Python versions to test
|
||||||
python:
|
python:
|
||||||
- "2.7"
|
- "3.6"
|
||||||
- "3.4"
|
- "3.7"
|
||||||
- "3.5"
|
- "3.8"
|
||||||
|
|
||||||
|
node_js: 10
|
||||||
|
|
||||||
# Manually define here the combinations environment variables to test
|
|
||||||
# https://github.com/travis-ci/travis-ci/issues/1519
|
|
||||||
env:
|
env:
|
||||||
- TEST_MOBILE=True DB=postgresql TRAVIS_NODE_VERSION="4"
|
- DB=postgresql
|
||||||
- TEST_MOBILE=True DB=sqlite TRAVIS_NODE_VERSION="4"
|
- DB=sqlite
|
||||||
- TEST_MOBILE=False DB=postgresql TRAVIS_NODE_VERSION="4"
|
|
||||||
- TEST_MOBILE=False DB=sqlite TRAVIS_NODE_VERSION="4"
|
|
||||||
|
|
||||||
# Install the application
|
# Install the application
|
||||||
install:
|
install:
|
||||||
# Update nvm and set wanted Node version.
|
|
||||||
# We update nvm using the script method instead of git, which is selected
|
|
||||||
# automatically, as git won't work because the $HOME/.nvm is not a git
|
|
||||||
# repository and the directory is not empty.
|
|
||||||
- curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.31.4/install.sh | METHOD=script bash
|
|
||||||
- . $HOME/.nvm/nvm.sh
|
|
||||||
- nvm install $TRAVIS_NODE_VERSION
|
|
||||||
- nvm use $TRAVIS_NODE_VERSION
|
|
||||||
|
|
||||||
# Install requirements
|
# Install requirements
|
||||||
- pip install -r requirements_devel.txt
|
- pip install -r requirements_devel.txt
|
||||||
- npm install
|
- python setup.py develop
|
||||||
|
- cd wger
|
||||||
- if [[ "$DB" = "postgresql" ]]; then pip install psycopg2; fi
|
- if [[ "$DB" = "postgresql" ]]; then pip install psycopg2; fi
|
||||||
|
|
||||||
# Setup application
|
# Setup application
|
||||||
- if [[ "$DB" = "sqlite" ]]; then invoke create_settings; fi
|
- if [[ "$DB" = "sqlite" ]]; then wger create-settings; fi
|
||||||
- if [[ "$DB" = "postgresql" ]]; then invoke create_settings --database-type postgresql; fi
|
- if [[ "$DB" = "postgresql" ]]; then wger create-settings --database-type postgresql; fi
|
||||||
|
|
||||||
|
# change back to the source folder
|
||||||
|
- cd ..
|
||||||
|
|
||||||
# Create test databases
|
# Create test databases
|
||||||
before_script:
|
before_script:
|
||||||
- if [[ "$DB" = "postgresq" ]]; then psql -c 'DROP DATABASE IF EXISTS test_wger;' -U postgres; fi
|
- if [[ "$DB" = "postgresql" ]]; then psql -c 'DROP DATABASE IF EXISTS test_wger;' -U postgres; fi
|
||||||
- if [[ "$DB" = "postgresql" ]]; then psql -c 'CREATE DATABASE test_wger;' -U postgres; fi
|
- if [[ "$DB" = "postgresql" ]]; then psql -c 'CREATE DATABASE test_wger;' -U postgres; fi
|
||||||
|
|
||||||
# Do the tests
|
# Do the tests
|
||||||
script:
|
script:
|
||||||
# Formatting
|
|
||||||
- pep8 wger
|
|
||||||
|
|
||||||
# Javascript linting
|
|
||||||
- gulp lint
|
|
||||||
|
|
||||||
# Regular application
|
# Regular application
|
||||||
- coverage run --source='.' ./manage.py test
|
- coverage run --source='.' ./manage.py test --parallel
|
||||||
|
|
||||||
|
|
||||||
# Code coverage
|
# Code coverage
|
||||||
- coverage report
|
- coverage report
|
||||||
|
|||||||
8
.tx/config
Normal file
8
.tx/config
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
[main]
|
||||||
|
host = https://www.transifex.com
|
||||||
|
|
||||||
|
[wger-workout-manager.application]
|
||||||
|
file_filter = wger/locale/<lang>/LC_MESSAGES/django.po
|
||||||
|
source_lang = en
|
||||||
|
type = PO
|
||||||
|
|
||||||
2
.yarnrc
Normal file
2
.yarnrc
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
# install modules here
|
||||||
|
--modules-folder wger/core/static/yarn/
|
||||||
@@ -24,6 +24,7 @@ Developers
|
|||||||
* Peter van der Does: https://github.com/petervanderdoes
|
* Peter van der Does: https://github.com/petervanderdoes
|
||||||
* Malcolm Jones: https://github.com/DevloperMal
|
* Malcolm Jones: https://github.com/DevloperMal
|
||||||
* Boniface Mwenda: https://github.com/andela-bmwenda
|
* Boniface Mwenda: https://github.com/andela-bmwenda
|
||||||
|
* Scott Peshak: https://github.com/speshak
|
||||||
|
|
||||||
Translators
|
Translators
|
||||||
-----------
|
-----------
|
||||||
|
|||||||
15
MANIFEST.in
15
MANIFEST.in
@@ -1,24 +1,21 @@
|
|||||||
|
# Files in root folder
|
||||||
include README.rst
|
include README.rst
|
||||||
include AUTHORS.txt
|
include AUTHORS.txt
|
||||||
include AGPL.txt
|
include AGPL.txt
|
||||||
include CC-BY-SA.txt
|
include CC-BY-SA.txt
|
||||||
include requirements.txt
|
include requirements.txt
|
||||||
include tasks.py
|
include requirements_devel.txt
|
||||||
|
|
||||||
|
# Application folder as well as extras
|
||||||
|
recursive-include extras *.*
|
||||||
recursive-include wger *.*
|
recursive-include wger *.*
|
||||||
recursive-exclude wger *.pyc
|
recursive-exclude wger *.pyc
|
||||||
recursive-exclude wger *.swp
|
recursive-exclude wger *.swp
|
||||||
recursive-exclude wger *~
|
recursive-exclude wger *~
|
||||||
|
include extras/docker/*/Dockerfile
|
||||||
|
|
||||||
# added by check_manifest.py
|
# Documentation
|
||||||
include *.rst
|
|
||||||
include *.txt
|
|
||||||
recursive-include docs *.bat
|
recursive-include docs *.bat
|
||||||
recursive-include docs *.py
|
recursive-include docs *.py
|
||||||
recursive-include docs *.rst
|
recursive-include docs *.rst
|
||||||
recursive-include docs Makefile
|
recursive-include docs Makefile
|
||||||
recursive-include extras *.README
|
|
||||||
recursive-include extras *.conf
|
|
||||||
recursive-include extras *.csv
|
|
||||||
recursive-include extras *.py
|
|
||||||
recursive-include extras *.txt
|
|
||||||
|
|||||||
133
README.rst
133
README.rst
@@ -1,22 +1,21 @@
|
|||||||
Thank you for downloading wger Workout Manager. wger (ˈvɛɡɐ) is a free, open source web
|
wger
|
||||||
application that manages your exercises and personal workouts, weight and diet
|
====
|
||||||
plans. It can also be used as a simple gym management utility, providing different
|
|
||||||
administrative roles (trainer, manager, etc.). It offers a REST API as well, for
|
|
||||||
easy integration with other projects and tools.
|
|
||||||
|
|
||||||
It is written with python/django and uses jQuery and some D3js for charts.
|
wger (ˈvɛɡɐ) Workout Manager is a free, open source web application that help
|
||||||
|
you manage your personal workouts, weight and diet plans and can also be used
|
||||||
|
as a simple gym management utility. It offers a REST API as well, for easy
|
||||||
|
integration with other projects and tools.
|
||||||
|
|
||||||
For more details and a live system, refer to the project's site: https://wger.de/
|
For a live system, refer to the project's site: https://wger.de/
|
||||||
|
|
||||||
|
|
||||||
Installation
|
Installation
|
||||||
============
|
============
|
||||||
|
|
||||||
These are the basic steps to install and run the application locally on a linux
|
These are the basic steps to install and run the application locally on a Linux
|
||||||
system. There are more detailed instructions, other deployment options as well
|
system. There are more detailed instructions, other deployment options as well
|
||||||
as an administration guide available at https://wger.readthedocs.io or locally
|
as an administration guide available at https://wger.readthedocs.io or locally
|
||||||
in your code repository in the docs folder (``make html`` to compile, then open
|
in your code repository in the docs folder.
|
||||||
_build/index.html).
|
|
||||||
|
|
||||||
Please consult the commands' help for further information and available
|
Please consult the commands' help for further information and available
|
||||||
parameters.
|
parameters.
|
||||||
@@ -25,7 +24,8 @@ parameters.
|
|||||||
Docker
|
Docker
|
||||||
------
|
------
|
||||||
|
|
||||||
Useful to just try it out::
|
Useful to just try it out. Check the documentation on how to use the wger/devel
|
||||||
|
docker image or the docker-compose file for development::
|
||||||
|
|
||||||
docker run -ti --name wger.apache --publish 8000:80 wger/apache
|
docker run -ti --name wger.apache --publish 8000:80 wger/apache
|
||||||
|
|
||||||
@@ -43,19 +43,14 @@ and stable state.
|
|||||||
|
|
||||||
::
|
::
|
||||||
|
|
||||||
$ sudo apt-get install python3-dev python-virtualenv nodejs nodejs-legacy npm libjpeg8-dev zlib1g-dev git
|
$ sudo apt-get install python3-dev nodejs npm git
|
||||||
|
$ sudo npm install -g yarn sass
|
||||||
|
|
||||||
|
|
||||||
On fedora 23
|
|
||||||
|
|
||||||
::
|
|
||||||
|
|
||||||
$ sudo dnf install python3-devel python-virtualenv nodejs npm libjpeg-turbo-devel zlib-devel git
|
|
||||||
|
|
||||||
Then install the python packages from pypi in the virtualenv::
|
Then install the python packages from pypi in the virtualenv::
|
||||||
|
|
||||||
$ virtualenv --python python3 venv-django
|
$ python3 -m venv venv-wger
|
||||||
$ source venv-django/bin/activate
|
$ source venv-wger/bin/activate
|
||||||
|
|
||||||
|
|
||||||
2) Start the application. This will download the required JS and CSS libraries
|
2) Start the application. This will download the required JS and CSS libraries
|
||||||
@@ -65,52 +60,18 @@ Then install the python packages from pypi in the virtualenv::
|
|||||||
|
|
||||||
$ git clone https://github.com/wger-project/wger.git
|
$ git clone https://github.com/wger-project/wger.git
|
||||||
$ cd wger
|
$ cd wger
|
||||||
$ pip install -r requirements.txt # or requirements_devel.txt to develop
|
$ pip install -r requirements.txt
|
||||||
$ invoke create_settings \
|
$ python setup.py develop
|
||||||
--settings-path /home/wger/wger/settings.py \
|
$ wger create-settings --settings-path $(pwd)/settings.py --database-path $(pwd)/database.sqlite
|
||||||
--database-path /home/wger/wger/database.sqlite
|
$ wger bootstrap --settings-path $(pwd)/settings.py --no-start-server
|
||||||
$ invoke bootstrap_wger \
|
|
||||||
--settings-path /home/wger/wger/settings.py \
|
|
||||||
--no-start-server
|
|
||||||
$ python manage.py runserver
|
$ python manage.py runserver
|
||||||
|
|
||||||
3) Log in as: **admin**, password **admin**
|
3) Log in as: **admin**, password **admin**
|
||||||
|
|
||||||
After the first run you can just use django's development server. You will
|
After the first run you just start django's development server::
|
||||||
probably want to move the settings and sqlite files to your git folder, see
|
|
||||||
the comments in the documentation (development chapter) about this::
|
|
||||||
|
|
||||||
$ python manage.py runserver
|
$ python manage.py runserver
|
||||||
|
|
||||||
Docker images
|
|
||||||
~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
Alternatively, there are docker images for development as well, ``wger/devel``
|
|
||||||
and ``wger/devel-fedora``. Both images contain an instance of the application
|
|
||||||
running with django's development server using a sqlite database and can be
|
|
||||||
used to quickly setup a development instance (vim and tmux are already
|
|
||||||
installed). The only difference is that devel has an ubuntu base image while
|
|
||||||
devel-fedora uses fedora.
|
|
||||||
|
|
||||||
::
|
|
||||||
|
|
||||||
$ docker run -ti --name wger.devel --publish 8000:8000 wger/devel
|
|
||||||
|
|
||||||
Then, *within the docker image*, activate the virtualenv
|
|
||||||
|
|
||||||
::
|
|
||||||
|
|
||||||
$ source ~/venv/bin/activate
|
|
||||||
|
|
||||||
and start the development server
|
|
||||||
|
|
||||||
::
|
|
||||||
|
|
||||||
$ python manage.py runserver 0.0.0.0:8000
|
|
||||||
|
|
||||||
Then just open http://localhost:8000 and log in as: **admin**, password **admin**
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Stable version (from PyPI)
|
Stable version (from PyPI)
|
||||||
--------------------------
|
--------------------------
|
||||||
@@ -119,38 +80,45 @@ Stable version (from PyPI)
|
|||||||
|
|
||||||
::
|
::
|
||||||
|
|
||||||
$ sudo apt-get install python3-dev python-virtualenv nodejs nodejs-legacy npm libjpeg8-dev zlib1g-dev
|
$ sudo apt-get install python3-dev nodejs npm git
|
||||||
$ virtualenv venv-django
|
$ sudo npm install -g yarn
|
||||||
$ source venv-django/bin/activate
|
$ python3 -m venv venv-wger
|
||||||
|
$ source venv-wger/bin/activate
|
||||||
$ pip install wger
|
$ pip install wger
|
||||||
|
|
||||||
|
|
||||||
2) Start the application. This will download the required JS and CSS libraries
|
2) Start the application. This will download the required JS and CSS libraries
|
||||||
and create a SQlite database and populate it with data on the first run.
|
and create a SQlite database and populate it with data on the first run.
|
||||||
|
Then, log in as: **admin**, password **admin**
|
||||||
|
|
||||||
::
|
::
|
||||||
|
|
||||||
$ wger bootstrap_wger
|
$ wger bootstrap
|
||||||
|
|
||||||
|
|
||||||
3) Log in as: **admin**, password **admin**
|
3) To start the installation again, just call wger start
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
$ wger start
|
||||||
|
|
||||||
|
|
||||||
Command line options
|
Command line options
|
||||||
--------------------
|
--------------------
|
||||||
|
You can get a list of all available commands by calling ``wger`` without any
|
||||||
|
arguments::
|
||||||
|
|
||||||
The available options for the ``wger`` command (if installed from PyPI) or
|
Available tasks:
|
||||||
``invoke`` (if installed from source) are the following (use e.g. ``wger
|
|
||||||
<command>``::
|
|
||||||
|
|
||||||
|
bootstrap Performs all steps necessary to bootstrap the application
|
||||||
|
config-location Returns the default location for the settings file and the data folder
|
||||||
|
create-or-reset-admin Creates an admin user or resets the password for an existing one
|
||||||
|
create-settings Creates a local settings file
|
||||||
|
load-fixtures Loads all fixtures
|
||||||
|
migrate-db Run all database migrations
|
||||||
|
start Start the application using django's built in webserver
|
||||||
|
|
||||||
bootstrap_wger Performs all steps necessary to bootstrap the application
|
You can also get help on a specific command with ``wger --help <command>``.
|
||||||
config_location Returns the default location for the settings file and the data folder
|
|
||||||
create_or_reset_admin Creates an admin user or resets the password for an existing one
|
|
||||||
create_settings Creates a local settings file
|
|
||||||
load_fixtures Loads all fixtures
|
|
||||||
migrate_db Run all database migrations
|
|
||||||
start_wger Start the application using django's built in webserver
|
|
||||||
|
|
||||||
Contact
|
Contact
|
||||||
=======
|
=======
|
||||||
@@ -160,11 +128,9 @@ didn't behave as you expected. We can't fix what we don't know about, so please
|
|||||||
report liberally. If you're not sure if something is a bug or not, feel free to
|
report liberally. If you're not sure if something is a bug or not, feel free to
|
||||||
file a bug anyway.
|
file a bug anyway.
|
||||||
|
|
||||||
* **twitter:** https://twitter.com/wger_de
|
* **gitter:** https://gitter.im/wger-project/wger
|
||||||
* **mailing list:** https://groups.google.com/group/wger / wger@googlegroups.com,
|
|
||||||
no registration needed
|
|
||||||
* **IRC:** channel #wger on freenode.net, webchat: http://webchat.freenode.net/?channels=wger
|
|
||||||
* **issue tracker:** https://github.com/wger-project/wger/issues
|
* **issue tracker:** https://github.com/wger-project/wger/issues
|
||||||
|
* **twitter:** https://twitter.com/wger_project
|
||||||
|
|
||||||
|
|
||||||
Sources
|
Sources
|
||||||
@@ -173,29 +139,28 @@ Sources
|
|||||||
All the code and the content is freely available:
|
All the code and the content is freely available:
|
||||||
|
|
||||||
* **Main repository:** https://github.com/wger-project/wger
|
* **Main repository:** https://github.com/wger-project/wger
|
||||||
* **Mirror:** https://bitbucket.org/rolandgeider/wger
|
|
||||||
|
|
||||||
|
|
||||||
Donations
|
Donations
|
||||||
=========
|
=========
|
||||||
wger is free software and will always remain that way, however if you want to
|
wger is free software and will always remain that way. However, if you want to
|
||||||
help and support the project you are more than welcome to donate an amount of
|
help and support the project you are more than welcome to donate an amount of
|
||||||
your choice.
|
your choice.
|
||||||
|
|
||||||
.. image:: https://www.paypalobjects.com/en_US/i/btn/btn_donate_LG.gif
|
.. image:: https://www.paypalobjects.com/en_US/i/btn/btn_donate_LG.gif
|
||||||
:target: https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=UPMWQJY85JC5N
|
:target: https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=UPMWQJY85JC5N
|
||||||
|
|
||||||
Licence
|
License
|
||||||
=======
|
=======
|
||||||
|
|
||||||
The application is licenced under the Affero GNU General Public License 3 or
|
The application is licensed under the Affero GNU General Public License 3 or
|
||||||
later (AGPL 3+).
|
later (AGPL 3+).
|
||||||
|
|
||||||
The initial exercise and ingredient data is licensed additionally under one of
|
The initial exercise and ingredient data is licensed additionally under one of
|
||||||
the Creative Commons licenses, see the individual exercises for more details.
|
the Creative Commons licenses, see the individual exercises for more details.
|
||||||
|
|
||||||
The documentation is released under a CC-BY-SA either version 4 of the License,
|
The documentation is released under a CC-BY-SA: either version 4 of the License,
|
||||||
or (at your option) any later version.
|
or (at your option) any later version.
|
||||||
|
|
||||||
Some images where taken from Wikipedia, see the SOURCES file in their respective
|
Some images were taken from Wikipedia, see the SOURCES file in their respective
|
||||||
folders for more details.
|
folders for more details.
|
||||||
|
|||||||
@@ -1,9 +1,113 @@
|
|||||||
Changelog
|
Changelog
|
||||||
=========
|
=========
|
||||||
|
|
||||||
1.8 - IN DEVELOPMENT
|
2.0 - IN DEVELOPMENT
|
||||||
--------------------
|
**2020-xx-xx**
|
||||||
**2016-XX-XX**
|
|
||||||
|
Upgrade steps from 1.9:
|
||||||
|
|
||||||
|
* Update python libraries ``pip install -r requirements.txt``
|
||||||
|
* Install ``yarn`` and ``sass`` (e.g. ``sudo npm install -g yarn sass``)
|
||||||
|
* Update CSS and JS libraries ``yarn install``
|
||||||
|
* Compile the CSS ``sass wger/core/static/scss/main.scss:wger/core/static/yarn/bootstrap-compiled.css``
|
||||||
|
* Run migrations ``python manage.py migrate``
|
||||||
|
* Update static files (only production): ``python manage.py collectstatic``
|
||||||
|
* Subcommands for ``wger`` now use dashes in their names (i.e. create-settings instead of create_settings)
|
||||||
|
|
||||||
|
|
||||||
|
🚀 Features:
|
||||||
|
|
||||||
|
* Add nutrition diary to log the daily calories actually taken `#284`_
|
||||||
|
* Improved user experience, on desktop and mobile `#337`_
|
||||||
|
|
||||||
|
|
||||||
|
🐛 Bug Fixes:
|
||||||
|
|
||||||
|
* `#499`_, `#505`_, `#504`_
|
||||||
|
|
||||||
|
|
||||||
|
🧰 Maintenance:
|
||||||
|
|
||||||
|
* Improved docker and docker-compose images `#340`_
|
||||||
|
* Updated many libraries to last version (bootstrap, font awesome, etc.)
|
||||||
|
* Use yarn to download CSS/JS libraries
|
||||||
|
* Improvements to documentation (e.g. `#494`_)
|
||||||
|
|
||||||
|
.. _#284: https://github.com/wger-project/wger/issues/284
|
||||||
|
.. _#337: https://github.com/wger-project/wger/issues/337
|
||||||
|
.. _#340: https://github.com/wger-project/wger/issues/340
|
||||||
|
.. _#494: https://github.com/wger-project/wger/issues/494
|
||||||
|
.. _#499: https://github.com/wger-project/wger/issues/499
|
||||||
|
.. _#504: https://github.com/wger-project/wger/issues/504
|
||||||
|
.. _#505: https://github.com/wger-project/wger/issues/505
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
1.9
|
||||||
|
---
|
||||||
|
**2020-06-29**
|
||||||
|
|
||||||
|
Upgrade steps from 1.8:
|
||||||
|
|
||||||
|
* Django update to 3.x: ``pip install -r requirements.txt``
|
||||||
|
* Database upgrade: ``python manage.py migrate``
|
||||||
|
* Update static files (only production): ``python manage.py collectstatic``
|
||||||
|
|
||||||
|
New features:
|
||||||
|
|
||||||
|
* Allow users to enter their birthdate instead of just the age (thanks `@dtopal`_) `#332`_
|
||||||
|
* Work to ensure that mobile templates are used when appropriate
|
||||||
|
* Added optional S3 static asset hosting.
|
||||||
|
* Drop Python 2 support.
|
||||||
|
* Replaced django-mobile with django-user_agent (and some custom code)
|
||||||
|
This isn't as slick as django-mobile was, but it unblocks possible Django 2.x support.
|
||||||
|
* Update many dependencies to current versions.
|
||||||
|
|
||||||
|
Improvements:
|
||||||
|
|
||||||
|
* Improve look of weight graph (thanks `@alokhan`_) `#381`_
|
||||||
|
* Added password validation rules for more security
|
||||||
|
* Exercise image downloader checks only accepted exercises (thanks `@gmmoraes`_) `#363`_
|
||||||
|
* Use a native data type for the exercises' UUID (thanks `@gmmoraes`_) `#364`_
|
||||||
|
* Increase speed of testsuite by performing the tests in parallel (thanks `@Mbarak-Mbigo`_) `wger_vulcan/#6`_
|
||||||
|
* Update screen when adding an exercise to the workout while using set slider (thanks `@gmmoraes`_) `#374`_
|
||||||
|
* Work to slim docker image
|
||||||
|
* Download images at startup - If `DOWNLOAD_IMGS` environmental variable is set to `TRUE`
|
||||||
|
* Uninstall dev packages
|
||||||
|
* Update Ubuntu version used in docker container.
|
||||||
|
* Fixed a handful of hard coded static path references to use `static` taglib
|
||||||
|
* Updated tinymce theme for v5.
|
||||||
|
|
||||||
|
Other improvements and bugfixes: `#336`_, `#359`_,`#386`_, `#443`_
|
||||||
|
|
||||||
|
.. _@gmmoraes: https://github.com/gmmoraes
|
||||||
|
.. _@Mbarak-Mbigo: https://github.com/Mbarak-Mbigo
|
||||||
|
.. _@dtopal: https://github.com/dtopal
|
||||||
|
|
||||||
|
.. _wger_vulcan/#6: https://github.com/andela/wger_vulcan/pull/6
|
||||||
|
|
||||||
|
.. _#332: https://github.com/wger-project/wger/issues/332
|
||||||
|
.. _#336: https://github.com/wger-project/wger/issues/336
|
||||||
|
.. _#359: https://github.com/wger-project/wger/issues/359
|
||||||
|
.. _#363: https://github.com/wger-project/wger/issues/363
|
||||||
|
.. _#364: https://github.com/wger-project/wger/issues/364
|
||||||
|
.. _#374: https://github.com/wger-project/wger/issues/374
|
||||||
|
.. _#381: https://github.com/wger-project/wger/issues/381
|
||||||
|
.. _#386: https://github.com/wger-project/wger/issues/386
|
||||||
|
.. _#443: https://github.com/wger-project/wger/issues/443
|
||||||
|
|
||||||
|
|
||||||
|
1.8
|
||||||
|
---
|
||||||
|
**2017-04-05**
|
||||||
|
|
||||||
|
.. warning ::
|
||||||
|
There have been some changes to the installation procedure. Calling 'invoke'
|
||||||
|
on its own has been deprecated, you should use the 'wger' command (which
|
||||||
|
accepts the same options). Also some of these commands have been renamed:
|
||||||
|
|
||||||
|
* ``start_wger`` to ``wger``
|
||||||
|
* ``bootstrap_wger`` to ``bootstrap``
|
||||||
|
|
||||||
Upgrade steps from 1.7:
|
Upgrade steps from 1.7:
|
||||||
|
|
||||||
@@ -22,6 +126,7 @@ Upgrade steps from 1.7:
|
|||||||
New languages:
|
New languages:
|
||||||
|
|
||||||
* Norwegian (many thanks to Kjetil Elde `@w00p`_ `#304`_)
|
* Norwegian (many thanks to Kjetil Elde `@w00p`_ `#304`_)
|
||||||
|
* French (many thanks to all translators)
|
||||||
|
|
||||||
New features:
|
New features:
|
||||||
|
|
||||||
@@ -43,6 +148,7 @@ Improvements:
|
|||||||
* Give feedback when autocompleter didn't find any results `#293`_
|
* Give feedback when autocompleter didn't find any results `#293`_
|
||||||
* Make exercise names links to their detail page in training log pages `#350`_
|
* Make exercise names links to their detail page in training log pages `#350`_
|
||||||
* Better GUI consistency in modal dialogs (thanks `@jstoebel`_ ) `#274`_
|
* Better GUI consistency in modal dialogs (thanks `@jstoebel`_ ) `#274`_
|
||||||
|
* Cache is cleared when editing muscles (thanks `@RyanSept`_ `@pythonGeek`_ ) `#260`_
|
||||||
* Fields in workout log form are no longer required, making it possible to only log weight for certain exercises `#334`_
|
* Fields in workout log form are no longer required, making it possible to only log weight for certain exercises `#334`_
|
||||||
* New, more verbose, API endpoint for exercises, (thanks `@andela-bmwenda`_)
|
* New, more verbose, API endpoint for exercises, (thanks `@andela-bmwenda`_)
|
||||||
* The dashboard page was improved and made more user friendly `#201`_ (partly)
|
* The dashboard page was improved and made more user friendly `#201`_ (partly)
|
||||||
@@ -67,6 +173,7 @@ Other improvements and bugfixes: `#25`_, `#243`_, `#279`_, `#275`_, `#270`_,
|
|||||||
.. _#243: https://github.com/wger-project/wger/issues/243
|
.. _#243: https://github.com/wger-project/wger/issues/243
|
||||||
.. _#248: https://github.com/wger-project/wger/issues/248
|
.. _#248: https://github.com/wger-project/wger/issues/248
|
||||||
.. _#247: https://github.com/wger-project/wger/issues/247
|
.. _#247: https://github.com/wger-project/wger/issues/247
|
||||||
|
.. _#260: https://github.com/wger-project/wger/issues/260
|
||||||
.. _#263: https://github.com/wger-project/wger/issues/263
|
.. _#263: https://github.com/wger-project/wger/issues/263
|
||||||
.. _#269: https://github.com/wger-project/wger/issues/269
|
.. _#269: https://github.com/wger-project/wger/issues/269
|
||||||
.. _#272: https://github.com/wger-project/wger/issues/272
|
.. _#272: https://github.com/wger-project/wger/issues/272
|
||||||
@@ -99,6 +206,8 @@ Other improvements and bugfixes: `#25`_, `#243`_, `#279`_, `#275`_, `#270`_,
|
|||||||
.. _@alokhan: https://github.com/alokhan
|
.. _@alokhan: https://github.com/alokhan
|
||||||
.. _@w00p: https://github.com/w00p
|
.. _@w00p: https://github.com/w00p
|
||||||
.. _@andela-bmwenda: https://github.com/andela-bmwenda
|
.. _@andela-bmwenda: https://github.com/andela-bmwenda
|
||||||
|
.. _@RyanSept: https://github.com/RyanSept
|
||||||
|
.. _@pythonGeek: https://github.com/pythonGeek
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -6,16 +6,7 @@ Coding Style Guide
|
|||||||
Python
|
Python
|
||||||
------
|
------
|
||||||
|
|
||||||
* Code according to PEP8
|
Code according to PEP8, but with but with a maximum line length of 100.
|
||||||
|
|
||||||
Check that the code is structured as per pep8 but with a maximum line
|
|
||||||
length of 100.
|
|
||||||
|
|
||||||
* Code for Python 3
|
|
||||||
|
|
||||||
While the application should remain compatible with python2, use django's
|
|
||||||
suggestion to mantain sanity: code for py3 and treat py2 as a backwards
|
|
||||||
compatibility requirement. If you need, you can use six.
|
|
||||||
|
|
||||||
|
|
||||||
Javascript
|
Javascript
|
||||||
@@ -29,12 +20,8 @@ Javascript
|
|||||||
* Functions called from Django templates need to start with ``wger``
|
* Functions called from Django templates need to start with ``wger``
|
||||||
|
|
||||||
|
|
||||||
Check Coding Style
|
Automatic coding style checks
|
||||||
==================
|
-----------------------------
|
||||||
|
|
||||||
The coding style is automatically check by Travis-CI. To manually check your
|
The coding style is automatically checked by GitHub actions after sending a
|
||||||
files you can run the following commands:
|
pull request.
|
||||||
|
|
||||||
* Python: ``pep8 wger``
|
|
||||||
* Javascript: ``./node_modules/.bin/gulp lint-js`` (or just ``gulp lint-js`` if
|
|
||||||
you installed the node libraries globally on your system)
|
|
||||||
|
|||||||
@@ -8,56 +8,47 @@ running application (to e.g. delete guest users, send emails, etc.).
|
|||||||
Administration Commands
|
Administration Commands
|
||||||
-----------------------
|
-----------------------
|
||||||
|
|
||||||
The application provides several administration and bootstraping commands. They
|
The application provides several administration and bootstraping commands that
|
||||||
are all available with ``wger`` (if installed from PyPI) or ``invoke`` (if
|
can be passed to the ``wger`` command::
|
||||||
installed from source)::
|
|
||||||
|
|
||||||
wger <command>
|
wger <command>
|
||||||
|
|
||||||
or ::
|
|
||||||
|
|
||||||
invoke <command>
|
You can get a list of all available commands by calling ``wger`` without any
|
||||||
|
arguments::
|
||||||
Both versions behave the same but for simplicity, the invoke version will be used
|
|
||||||
in this manual.
|
|
||||||
|
|
||||||
|
|
||||||
You can get a list of all available commands with ``invoke --list`` or ``wger``.
|
|
||||||
While you can do this from any folder in the application, some of them (e.g.
|
|
||||||
``start_wger``) might only work from the root folder::
|
|
||||||
|
|
||||||
Available tasks:
|
Available tasks:
|
||||||
|
|
||||||
bootstrap_wger Performs all steps necessary to bootstrap the application
|
bootstrap Performs all steps necessary to bootstrap the application
|
||||||
config_location Returns the default location for the settings file and the data folder
|
config-location Returns the default location for the settings file and the data folder
|
||||||
create_or_reset_admin Creates an admin user or resets the password for an existing one
|
create-or-reset-admin Creates an admin user or resets the password for an existing one
|
||||||
create_settings Creates a local settings file
|
create-settings Creates a local settings file
|
||||||
load_fixtures Loads all fixtures
|
load-fixtures Loads all fixtures
|
||||||
migrate_db Run all database migrations
|
migrate-db Run all database migrations
|
||||||
start_wger Start the application using django's built in webserver
|
start Start the application using django's built in webserver
|
||||||
|
|
||||||
You can also get help on a specific command with ``invoke --help <command>``.
|
You can also get help on a specific command with ``wger --help <command>``.
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
Most commands support a ``--settings-path`` command line option that sets the
|
Most commands support a ``--settings-path`` command line option that sets the
|
||||||
settings file to use for the operation. If you use it, it is recommended to
|
settings file to use for the operation. If you use it, it is recommended to
|
||||||
use absolute paths, for example::
|
use absolute paths, for example::
|
||||||
|
|
||||||
invoke bootstrap_wger --settings-path /path/to/development/wger/settings-test.py
|
wger bootstrap --settings-path /path/to/development/wger/settings-test.py
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Bootstrap wger
|
Bootstrap
|
||||||
~~~~~~~~~~~~~~
|
~~~~~~~~~
|
||||||
|
|
||||||
Command: **bootstrap_wger**
|
Command: **bootstrap**
|
||||||
|
|
||||||
This command bootstraps the application: it creates a settings file, initialises
|
This command bootstraps the application: it creates a settings file, initialises
|
||||||
a sqlite database, loads all necessary fixtures for the application to work and
|
a sqlite database, loads all necessary fixtures for the application to work and
|
||||||
creates a default administrator user. While it can also work with e.g. a postgreSQL
|
creates a default administrator user. While it can also work with e.g. a postgreSQL
|
||||||
database, you will need to create it yourself::
|
database, you will need to create it yourself::
|
||||||
|
|
||||||
invoke bootstrap_wger
|
wger bootstrap
|
||||||
|
|
||||||
The most usual use-case is creating the settings file and the sqlite database to
|
The most usual use-case is creating the settings file and the sqlite database to
|
||||||
their default locations, but you can set your own paths if you want e.g. start
|
their default locations, but you can set your own paths if you want e.g. start
|
||||||
@@ -65,7 +56,7 @@ developing on a branch that is going to change the database schema.
|
|||||||
|
|
||||||
Usage::
|
Usage::
|
||||||
|
|
||||||
Usage: inv[oke] [--core-opts] bootstrap_wger [--options] [other tasks here ...]
|
Usage: inv[oke] [--core-opts] bootstrap [--options] [other tasks here ...]
|
||||||
|
|
||||||
Docstring:
|
Docstring:
|
||||||
Performs all steps necessary to bootstrap the application
|
Performs all steps necessary to bootstrap the application
|
||||||
@@ -81,11 +72,11 @@ Usage::
|
|||||||
Start wger
|
Start wger
|
||||||
~~~~~~~~~~
|
~~~~~~~~~~
|
||||||
|
|
||||||
Command: **start_wger**
|
Command: **start**
|
||||||
|
|
||||||
Starts an already installed application::
|
Starts an already installed application::
|
||||||
|
|
||||||
invoke start_wger
|
wger start
|
||||||
|
|
||||||
Please note that this is simply a comfort function and does not use any *magic*,
|
Please note that this is simply a comfort function and does not use any *magic*,
|
||||||
it simply calls django's development server and (optionally) opens a browser
|
it simply calls django's development server and (optionally) opens a browser
|
||||||
@@ -94,7 +85,7 @@ is probably better.
|
|||||||
|
|
||||||
Usage::
|
Usage::
|
||||||
|
|
||||||
Usage: inv[oke] [--core-opts] start_wger [--options] [other tasks here ...]
|
Usage: inv[oke] [--core-opts] start [--options] [other tasks here ...]
|
||||||
|
|
||||||
Docstring:
|
Docstring:
|
||||||
Start the application using django's built in webserver
|
Start the application using django's built in webserver
|
||||||
@@ -111,7 +102,7 @@ Usage::
|
|||||||
Default locations
|
Default locations
|
||||||
~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
Command: **config_location**
|
Command: **config-location**
|
||||||
|
|
||||||
Information command that simply outputs the default locations for the settings
|
Information command that simply outputs the default locations for the settings
|
||||||
file as well as the data folder used for the sqlite database and the uploaded
|
file as well as the data folder used for the sqlite database and the uploaded
|
||||||
@@ -121,21 +112,21 @@ files.
|
|||||||
Create settings
|
Create settings
|
||||||
~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
Command: **create_settings**
|
Command: **create-settings**
|
||||||
|
|
||||||
Creates a new settings file based. If you call it without further arguments it
|
Creates a new settings file based. If you call it without further arguments it
|
||||||
will create the settings in the default locations::
|
will create the settings in the default locations::
|
||||||
|
|
||||||
invoke create settings
|
wger create-settings
|
||||||
|
|
||||||
If you pass custom paths, it's recommended to use absolute paths::
|
If you pass custom paths, it's recommended to use absolute paths::
|
||||||
|
|
||||||
invoke create_settings --settings-path /path/to/development/wger/settings-test.py --database-path /path/to/development/wger/database-test.sqlite
|
wger create-settings --settings-path /path/to/development/wger/settings-test.py --database-path /path/to/development/wger/database-test.sqlite
|
||||||
|
|
||||||
|
|
||||||
Usage::
|
Usage::
|
||||||
|
|
||||||
Usage: inv[oke] [--core-opts] create_settings [--options] [other tasks here ...]
|
Usage: inv[oke] [--core-opts] create-settings [--options] [other tasks here ...]
|
||||||
|
|
||||||
Docstring:
|
Docstring:
|
||||||
Creates a local settings file
|
Creates a local settings file
|
||||||
@@ -152,7 +143,7 @@ Usage::
|
|||||||
Create or reset admin
|
Create or reset admin
|
||||||
~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
Command: **create_or_reset_admin**
|
Command: **create-or-reset-admin**
|
||||||
|
|
||||||
Makes sure that the default administrator user exists. If you change the password
|
Makes sure that the default administrator user exists. If you change the password
|
||||||
it is reset.
|
it is reset.
|
||||||
@@ -160,7 +151,7 @@ it is reset.
|
|||||||
|
|
||||||
Usage::
|
Usage::
|
||||||
|
|
||||||
Usage: inv[oke] [--core-opts] create_or_reset_admin [--options] [other tasks here ...]
|
Usage: inv[oke] [--core-opts] create-or-reset-admin [--options] [other tasks here ...]
|
||||||
|
|
||||||
Docstring:
|
Docstring:
|
||||||
Creates an admin user or resets the password for an existing one
|
Creates an admin user or resets the password for an existing one
|
||||||
@@ -173,7 +164,7 @@ Usage::
|
|||||||
Migrate database
|
Migrate database
|
||||||
~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
Command: **migrate_db**
|
Command: **migrate-db**
|
||||||
|
|
||||||
Migrates the database schema. This command is called internally when installing
|
Migrates the database schema. This command is called internally when installing
|
||||||
the application. The only need to call this explicitly is after installing a new
|
the application. The only need to call this explicitly is after installing a new
|
||||||
@@ -185,7 +176,7 @@ will happen.
|
|||||||
|
|
||||||
Usage::
|
Usage::
|
||||||
|
|
||||||
Usage: inv[oke] [--core-opts] migrate_db [--options] [other tasks here ...]
|
Usage: inv[oke] [--core-opts] migrate-db [--options] [other tasks here ...]
|
||||||
|
|
||||||
Docstring:
|
Docstring:
|
||||||
Run all database migrations
|
Run all database migrations
|
||||||
@@ -198,7 +189,7 @@ Usage::
|
|||||||
Load all fixtures
|
Load all fixtures
|
||||||
~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
Command: **load_fixtures**
|
Command: **load-fixtures**
|
||||||
|
|
||||||
Loads all fixture file with the default data. This data includes all data necessary
|
Loads all fixture file with the default data. This data includes all data necessary
|
||||||
for the application to work such as:
|
for the application to work such as:
|
||||||
@@ -215,7 +206,7 @@ as workouts are *not* reset with this, only the application data.
|
|||||||
|
|
||||||
Usage::
|
Usage::
|
||||||
|
|
||||||
Usage: inv[oke] [--core-opts] load_fixtures [--options] [other tasks here ...]
|
Usage: inv[oke] [--core-opts] load-fixtures [--options] [other tasks here ...]
|
||||||
|
|
||||||
Docstring:
|
Docstring:
|
||||||
Loads all fixtures
|
Loads all fixtures
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
# flake8: noqa
|
||||||
#
|
#
|
||||||
# wger Workout Manager documentation build configuration file, created by
|
# wger Workout Manager documentation build configuration file, created by
|
||||||
# sphinx-quickstart on Mon Dec 1 22:22:02 2014.
|
# sphinx-quickstart on Mon Dec 1 22:22:02 2014.
|
||||||
@@ -47,16 +48,16 @@ master_doc = 'index'
|
|||||||
|
|
||||||
# General information about the project.
|
# General information about the project.
|
||||||
project = u'wger Workout Manager'
|
project = u'wger Workout Manager'
|
||||||
copyright = u'2015, Roland Geider'
|
copyright = u'2020, Roland Geider'
|
||||||
|
|
||||||
# The version info for the project you're documenting, acts as replacement for
|
# The version info for the project you're documenting, acts as replacement for
|
||||||
# |version| and |release|, also used in various other places throughout the
|
# |version| and |release|, also used in various other places throughout the
|
||||||
# built documents.
|
# built documents.
|
||||||
#
|
#
|
||||||
# The short X.Y version.
|
# The short X.Y version.
|
||||||
version = '1.8'
|
version = '2.0'
|
||||||
# The full version, including alpha/beta/rc tags.
|
# The full version, including alpha/beta/rc tags.
|
||||||
release = '1.8 alpha2'
|
release = '2.0 alpha'
|
||||||
|
|
||||||
# The language for content autogenerated by Sphinx. Refer to documentation
|
# The language for content autogenerated by Sphinx. Refer to documentation
|
||||||
# for a list of supported languages.
|
# for a list of supported languages.
|
||||||
|
|||||||
@@ -3,210 +3,63 @@
|
|||||||
Development
|
Development
|
||||||
===========
|
===========
|
||||||
|
|
||||||
Requirements
|
You can safely install from master, it is almost always in a usable
|
||||||
------------
|
and stable state.
|
||||||
|
|
||||||
|
Virtual environment
|
||||||
|
~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
$ python3 -m venv venv-wger
|
||||||
|
$ source venv-wger/bin/activate
|
||||||
|
|
||||||
|
|
||||||
Get the code
|
Get the code
|
||||||
~~~~~~~~~~~~
|
~~~~~~~~~~~~
|
||||||
|
::
|
||||||
|
|
||||||
The code is available on Github::
|
$ git clone https://github.com/wger-project/wger.git src
|
||||||
|
$ cd src
|
||||||
$ git clone https://github.com/wger-project/wger.git
|
$ WGER_PATH=$(pwd)
|
||||||
|
|
||||||
Create a virtual environment
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
It's a best practise to create a Python virtual environment::
|
|
||||||
|
|
||||||
$ virtualenv --python python3 venv-wger
|
|
||||||
$ source venv-wger/bin/activate
|
|
||||||
$ cd wger
|
|
||||||
|
|
||||||
|
|
||||||
Install Requirements
|
Install Requirements
|
||||||
~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~
|
||||||
|
::
|
||||||
To install the Python requirements::
|
|
||||||
|
|
||||||
$ pip install -r requirements_devel.txt
|
$ pip install -r requirements_devel.txt
|
||||||
|
$ npm install -g yarn sass
|
||||||
|
$ python setup.py develop
|
||||||
|
|
||||||
Install NodeJS and npm::
|
Install application
|
||||||
Follow the instructions on the `NPM website <https://docs.npmjs
|
~~~~~~~~~~~~~~~~~~~
|
||||||
.com/getting-started/installing-node>`_ and make sure to use Node LTS (4
|
|
||||||
.x).
|
|
||||||
|
|
||||||
Install the npm modules::
|
This will download the required JS and CSS libraries and create a SQlite
|
||||||
|
database and populate it with data on the first run::
|
||||||
$ npm install
|
|
||||||
|
|
||||||
|
|
||||||
Install site
|
$ wger create-settings \
|
||||||
~~~~~~~~~~~~
|
--settings-path $WGER_PATH/settings.py \
|
||||||
|
--database-path $WGER_PATH/database.sqlite
|
||||||
To install the server::
|
$ wger bootstrap \
|
||||||
|
--settings-path $WGER_PATH/settings.py \
|
||||||
$ invoke create_settings \
|
|
||||||
--settings-path /home/wger/wger/settings.py \
|
|
||||||
--database-path /home/wger/wger/database.sqlite
|
|
||||||
$ invoke bootstrap_wger \
|
|
||||||
--settings-path /home/wger/wger/settings.py \
|
|
||||||
--no-start-server
|
--no-start-server
|
||||||
|
|
||||||
|
You can of course also use other databases such as postgres or mariaDB. Create
|
||||||
|
a database and user and edit the DATABASES settings before calling bootstrap.
|
||||||
|
Take a look at the :ref:`prod_postgres` on apache on how that could look like.
|
||||||
|
|
||||||
Start the server
|
Start the server
|
||||||
----------------
|
----------------
|
||||||
|
|
||||||
To start the server::
|
After the first run you can just use django's development server::
|
||||||
|
|
||||||
$ python manage.py runserver
|
$ python manage.py runserver
|
||||||
|
|
||||||
That's it. You can log in with the default administator user:
|
That's it. You can log in with the default administrator user:
|
||||||
|
|
||||||
* **username**: admin
|
* **username**: admin
|
||||||
* **passsword**: admin
|
* **password**: admin
|
||||||
|
|
||||||
You can start the application again with the django server with
|
You can start the application again with the django server with
|
||||||
``python manage.py runserver``.
|
``python manage.py runserver``.
|
||||||
|
|
||||||
.. _tips:
|
|
||||||
|
|
||||||
Tips
|
|
||||||
----
|
|
||||||
|
|
||||||
Updating the code
|
|
||||||
~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
When pulling updates from upstream there are a couple of things to consider.
|
|
||||||
These steps apply to all installation methods above.
|
|
||||||
|
|
||||||
Upgrading the database
|
|
||||||
``````````````````````
|
|
||||||
|
|
||||||
There are regularly changes and upgrades to the database schema (these may also
|
|
||||||
come from new versions of django or the installed dependencies). If you start
|
|
||||||
the development server and see a message that there are unapplied migrations,
|
|
||||||
just do ``python manage.py migrate --all``.
|
|
||||||
|
|
||||||
Downloading dependencies with Bower
|
|
||||||
```````````````````````````````````
|
|
||||||
|
|
||||||
Bower is used to download different JS and CSS libraries. If you update master
|
|
||||||
it is recommended that you first delete the existing libraries
|
|
||||||
(``rm wger/core/static/bower_components``) and then download the new versions
|
|
||||||
with::
|
|
||||||
|
|
||||||
$ python manage.py bower install
|
|
||||||
|
|
||||||
|
|
||||||
Some info about bower, during the bootstrap process bower is installed locally
|
|
||||||
to src/wger. If this didn't work and you get an error saying that bower is not
|
|
||||||
installed, you can manually install it by going to the project's root directory
|
|
||||||
and performing the step manually::
|
|
||||||
|
|
||||||
$ cd src/wger
|
|
||||||
$ npm install bower
|
|
||||||
|
|
||||||
Alternatively, you can manually set the path to the bower binary by editing
|
|
||||||
``BOWER_PATH`` (see ``wger/settings_global.py``).
|
|
||||||
|
|
||||||
|
|
||||||
Clearing the cache
|
|
||||||
``````````````````
|
|
||||||
|
|
||||||
Sometimes there are changes to the internal changes of the cached structures.
|
|
||||||
It is recommended that you just clear all the existing caches
|
|
||||||
``python manage.py clear-cache --clear-all``
|
|
||||||
|
|
||||||
Miscellaneous settings
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
The following settings can be very useful during development (add to your
|
|
||||||
settings.py):
|
|
||||||
|
|
||||||
|
|
||||||
**Setting the email backend**
|
|
||||||
Use the console backend, all sent emails will be printed to it::
|
|
||||||
|
|
||||||
EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'
|
|
||||||
|
|
||||||
Dummy data generator
|
|
||||||
~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
To properly test the different parts of the application for usability or
|
|
||||||
performance, it is often very useful to have some data to work with. For this
|
|
||||||
reason, there is a dummy data generator script in
|
|
||||||
extras/dummy_generator/generator.py. It allows you to generate entries for
|
|
||||||
users, gyms, workouts and logs. For detailed usage options do::
|
|
||||||
|
|
||||||
python generator.py --help
|
|
||||||
|
|
||||||
Or for options for, e.g. user generation::
|
|
||||||
|
|
||||||
python generator.py users --help
|
|
||||||
|
|
||||||
To get you started, you might want to invoke the script in the following way. This
|
|
||||||
will create 10 gyms and 300 users, randomly assigning them to a different gym. Each
|
|
||||||
user will have 20 workouts and each exercise in each workout 30 log entries::
|
|
||||||
|
|
||||||
python generator.py gyms 10
|
|
||||||
python generator.py users 300
|
|
||||||
python generator.py workouts 20
|
|
||||||
python generator.py logs 30
|
|
||||||
python generator.py sessions random
|
|
||||||
python generator.py weight 100
|
|
||||||
python generator.py nutrition 20
|
|
||||||
|
|
||||||
.. note::
|
|
||||||
All generated users have their username as password.
|
|
||||||
|
|
||||||
.. note::
|
|
||||||
While it is possible to generate hundreds of users, gyms are more restricted and
|
|
||||||
you will probably get duplicate names if you generate more than a dozen.
|
|
||||||
|
|
||||||
|
|
||||||
Selectively running tests
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
If you do a ``python manage.py test`` you will run the complete testsuite, and
|
|
||||||
this can take a while. You can control which tests will be executed like this.
|
|
||||||
|
|
||||||
Test only the tests in the 'core' app::
|
|
||||||
|
|
||||||
python manage.py test wger.core
|
|
||||||
|
|
||||||
Test only the tests in the 'test_user.py` file in the core app::
|
|
||||||
|
|
||||||
python manage.py test wger.core.tests.test_user
|
|
||||||
|
|
||||||
Test only the tests in 'StatusUserTestCase' in the file 'test_user.py` file in
|
|
||||||
the core app::
|
|
||||||
|
|
||||||
python manage.py test wger.core.tests.test_user.StatusUserTestCase
|
|
||||||
|
|
||||||
|
|
||||||
Using runserver_plus
|
|
||||||
~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
During development you can use ``runserver_plus`` instead of the default django
|
|
||||||
server as you can use an interactive debugger directly from the browser if an
|
|
||||||
exception occurs. It also accepts the same command line options. For this just
|
|
||||||
install the following packages::
|
|
||||||
|
|
||||||
pip install django_extensions werkzeug
|
|
||||||
python manage.py runserver_plus [options]
|
|
||||||
|
|
||||||
|
|
||||||
Contributing
|
|
||||||
------------
|
|
||||||
|
|
||||||
* **Send pull requests**: for new code you want to share, please send pull
|
|
||||||
requests in github. Sending patches by email or attaching them to an issue
|
|
||||||
means a lot more of work. It's recommended that you work on a feature branch
|
|
||||||
when working on something, specially when it's something bigger. While many
|
|
||||||
people insist on rebasing before sending a pull request, it's not necessary.
|
|
||||||
|
|
||||||
* **Run the tests**: wger is proud to have a test coverage of over 90%. When you
|
|
||||||
implement something new, don't forget to run the testsuite and write approriate
|
|
||||||
tests for the new code. If you use github, configure the awesome Travis CI,
|
|
||||||
there is already a .travis file in the sources.
|
|
||||||
|
|
||||||
* **Code according to the coding style**: :ref:`codingstyle`
|
|
||||||
|
|||||||
@@ -1,10 +1,31 @@
|
|||||||
Docker
|
Docker images
|
||||||
======
|
=============
|
||||||
|
|
||||||
There are docker files available to quickly get a version of wger up and
|
There are docker files available to quickly get a version of wger up and
|
||||||
running. They are all located under ``extras/docker`` if you want to build
|
running. They are all located under ``extras/docker`` if you want to build
|
||||||
them yourself.
|
them yourself.
|
||||||
|
|
||||||
|
Note that you need to build from the project's source folder, e.g::
|
||||||
|
|
||||||
|
docker build -f extras/docker/development/Dockerfile -t wger/devel .
|
||||||
|
docker build -f extras/docker/apache/Dockerfile --tag wger/apache .
|
||||||
|
|
||||||
|
|
||||||
|
Apache
|
||||||
|
------
|
||||||
|
|
||||||
|
This image runs the application using WSGI and apache.
|
||||||
|
|
||||||
|
Get the image::
|
||||||
|
|
||||||
|
docker pull wger/apache
|
||||||
|
|
||||||
|
Run a container and start the application::
|
||||||
|
|
||||||
|
docker run -ti --name wger.apache --publish 8000:80 wger/apache
|
||||||
|
|
||||||
|
Then just open http://localhost:8000 and log in as: **admin**, password **admin**
|
||||||
|
|
||||||
|
|
||||||
Development
|
Development
|
||||||
-----------
|
-----------
|
||||||
@@ -12,10 +33,9 @@ Development
|
|||||||
This image installs the application using virtualenv, uses a sqlite database
|
This image installs the application using virtualenv, uses a sqlite database
|
||||||
and serves it with django's development server.
|
and serves it with django's development server.
|
||||||
|
|
||||||
|
Get the image::
|
||||||
|
|
||||||
First build the image::
|
docker pull wger/devel
|
||||||
|
|
||||||
docker build -t wger/devel .
|
|
||||||
|
|
||||||
Run a container and start the application::
|
Run a container and start the application::
|
||||||
|
|
||||||
@@ -23,12 +43,11 @@ Run a container and start the application::
|
|||||||
(in docker) source ~/venv/bin/activate
|
(in docker) source ~/venv/bin/activate
|
||||||
(in docker) python manage.py runserver 0.0.0.0:8000
|
(in docker) python manage.py runserver 0.0.0.0:8000
|
||||||
|
|
||||||
Now you can access the application on port 8000 of your host (probably just
|
Then just open http://localhost:8000 and log in as: **admin**, password **admin**
|
||||||
http://localhost:8000).
|
|
||||||
|
|
||||||
Depending on what you intend to do with it, you might want to map a local folder
|
As an alternative you might want to map a local folder to the container.
|
||||||
to the container. This is interesting if e.g. you want to keep the wger source
|
This is interesting if e.g. you want to keep the wger source code on
|
||||||
code on your host machine and use docker only to serve it. Then you can do this::
|
your host machine and use docker only to serve it. Then do this::
|
||||||
|
|
||||||
docker run -ti \
|
docker run -ti \
|
||||||
--name wger.test1 \
|
--name wger.test1 \
|
||||||
@@ -36,24 +55,7 @@ code on your host machine and use docker only to serve it. Then you can do this:
|
|||||||
--volume /path/to/local/wger/:/home/wger/src \
|
--volume /path/to/local/wger/:/home/wger/src \
|
||||||
wger/devel
|
wger/devel
|
||||||
|
|
||||||
It will mount the local path *on top* of the folder in the container, basically
|
It will mount the local path *on top* of the folder in the container. For this to
|
||||||
exchanging one for the other. Please note that for this to work you need to
|
work you obviously need to manually checkout the code to ``/path/to/local/wger/``
|
||||||
manually checkout the code to ``/path/to/local/wger/`` and create a settings file
|
and create a settings file as well.
|
||||||
as well.
|
|
||||||
|
|
||||||
|
|
||||||
Apache
|
|
||||||
------
|
|
||||||
|
|
||||||
This image runs the application using WSGI and apache.
|
|
||||||
|
|
||||||
First build the image::
|
|
||||||
|
|
||||||
docker build --tag wger/apache .
|
|
||||||
|
|
||||||
Run a container and start the application::
|
|
||||||
|
|
||||||
docker run -ti --name wger.apache --publish 8000:80 wger/apache
|
|
||||||
|
|
||||||
Now you can access the application on port 8000 of your host (probably just
|
|
||||||
http://localhost:8000).
|
|
||||||
@@ -19,22 +19,27 @@ https://github.com/wger-project/wger
|
|||||||
This documentation is intended for developers and administrators of the software.
|
This documentation is intended for developers and administrators of the software.
|
||||||
|
|
||||||
|
|
||||||
Installation and development
|
Installation and administration
|
||||||
----------------------------
|
-------------------------------
|
||||||
.. toctree::
|
.. toctree::
|
||||||
:maxdepth: 2
|
|
||||||
|
|
||||||
install
|
installation
|
||||||
commands
|
|
||||||
|
|
||||||
|
Development
|
||||||
|
-------------------------------
|
||||||
|
.. toctree::
|
||||||
|
|
||||||
|
tips_and_tricks
|
||||||
|
codingstyle
|
||||||
i18n
|
i18n
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Administration guide
|
Administration guide
|
||||||
--------------------
|
--------------------
|
||||||
.. toctree::
|
.. toctree::
|
||||||
:maxdepth: 2
|
|
||||||
|
|
||||||
|
commands
|
||||||
settings
|
settings
|
||||||
gym
|
gym
|
||||||
|
|
||||||
@@ -53,11 +58,11 @@ Feel free to contact us if you found this useful or if there was something that
|
|||||||
didn't behave as you expected (in this case you can also open a ticket on the
|
didn't behave as you expected (in this case you can also open a ticket on the
|
||||||
issue tracker).
|
issue tracker).
|
||||||
|
|
||||||
* **twitter:** https://twitter.com/wger_de
|
* **gitter:** https://gitter.im/wger-project/wger
|
||||||
|
* **issue tracker:** https://github.com/wger-project/wger/issues
|
||||||
|
* **twitter:** https://twitter.com/wger_project
|
||||||
* **mailing list:** https://groups.google.com/group/wger / wger@googlegroups.com,
|
* **mailing list:** https://groups.google.com/group/wger / wger@googlegroups.com,
|
||||||
no registration needed
|
no registration needed
|
||||||
* **IRC:** channel #wger on freenode.net, webchat: http://webchat.freenode.net/?channels=wger
|
|
||||||
* **issue tracker:** https://github.com/wger-project/wger/issues
|
|
||||||
|
|
||||||
|
|
||||||
Sources
|
Sources
|
||||||
@@ -85,11 +90,3 @@ folders for more details.
|
|||||||
.. include the authors file from the root folder
|
.. include the authors file from the root folder
|
||||||
.. include:: ../AUTHORS.rst
|
.. include:: ../AUTHORS.rst
|
||||||
|
|
||||||
|
|
||||||
Indices and tables
|
|
||||||
==================
|
|
||||||
|
|
||||||
* :ref:`genindex`
|
|
||||||
* :ref:`search`
|
|
||||||
* :ref:`modindex`
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,59 +0,0 @@
|
|||||||
.. _install:
|
|
||||||
|
|
||||||
Installation
|
|
||||||
============
|
|
||||||
|
|
||||||
This file gives a broad description of the necessary steps to install wger
|
|
||||||
on a debian based linux distribution. If your setup differs (e.g. in Red Hat
|
|
||||||
based distros the package names are slightly different) you will need to
|
|
||||||
change the steps but in the end, this is a regular django application so it
|
|
||||||
should run wherever django runs.
|
|
||||||
|
|
||||||
The application is compatible and regularly tested with
|
|
||||||
|
|
||||||
* sqlite, postgres
|
|
||||||
* python 2.7, 3.4 and 3.5
|
|
||||||
|
|
||||||
You might also want to take a look at the :ref:`other-changes` section for other
|
|
||||||
changes you might want to do to your local instance such as Terms of Service or
|
|
||||||
contact page.
|
|
||||||
|
|
||||||
.. note::
|
|
||||||
Please note that all the steps related to upgrading the database or
|
|
||||||
downloading external JS dependencies mentioned in the :ref:`tips` section
|
|
||||||
in the development page apply to all the installation options.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Base
|
|
||||||
----
|
|
||||||
|
|
||||||
These are the necessary packages for both development and production
|
|
||||||
(node and npm are only used to download JS and CSS libraries)::
|
|
||||||
|
|
||||||
sudo apt-get install nodejs nodejs-legacy npm git \
|
|
||||||
python-virtualenv python3-dev \
|
|
||||||
libjpeg8-dev zlib1g-dev libwebp-dev
|
|
||||||
|
|
||||||
.. note::
|
|
||||||
The application is developed with python 3, which these installation
|
|
||||||
instructions also use. If you want to use python 2.7, make sure you install
|
|
||||||
the appropriate packages (e.g. python-dev instead of python3-dev, etc.)!
|
|
||||||
|
|
||||||
|
|
||||||
Development
|
|
||||||
-----------
|
|
||||||
For development consult the :doc:`development` section.
|
|
||||||
|
|
||||||
|
|
||||||
Production
|
|
||||||
----------
|
|
||||||
|
|
||||||
For a more production-like setting with apache and mod-wsgi consult the
|
|
||||||
:doc:`production` chapter.
|
|
||||||
|
|
||||||
|
|
||||||
Docker
|
|
||||||
------
|
|
||||||
|
|
||||||
There are also docker images available, see the :doc:`docker` chapter.
|
|
||||||
|
|||||||
39
docs/installation.rst
Normal file
39
docs/installation.rst
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
.. _installation:
|
||||||
|
|
||||||
|
Installation
|
||||||
|
============
|
||||||
|
|
||||||
|
You can get a local instance of wger installed in a couple of minutes.
|
||||||
|
|
||||||
|
It is recommended to install a development instance or start a docker
|
||||||
|
image if you just want to try the application on your server or PC. All
|
||||||
|
the following steps are performed on a debian based linux distribution.
|
||||||
|
If your setup differs (e.g. in Red Hat based distros the package names are
|
||||||
|
slightly different) you will need to change the steps as appropriate.
|
||||||
|
|
||||||
|
The application is compatible and regularly tested with
|
||||||
|
|
||||||
|
* sqlite, postgres
|
||||||
|
* python 3.6, 3.7 and 3.8
|
||||||
|
|
||||||
|
After installation you might also want to take a look at the :ref:`other-changes` section for other
|
||||||
|
changes you might want to do to your local instance such as Terms of Service or
|
||||||
|
contact page.
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
Please note that all the steps related to upgrading the database or
|
||||||
|
downloading external JS dependencies mentioned in the :ref:`tips` section
|
||||||
|
in the development page apply to all the installation options.
|
||||||
|
|
||||||
|
|
||||||
|
These are the necessary packages for both development and production::
|
||||||
|
|
||||||
|
sudo apt-get install nodejs npm git python3-dev python3-venv
|
||||||
|
|
||||||
|
|
||||||
|
.. toctree::
|
||||||
|
|
||||||
|
development
|
||||||
|
docker
|
||||||
|
production
|
||||||
|
|
||||||
484
docs/make.bat
484
docs/make.bat
@@ -1,242 +1,242 @@
|
|||||||
@ECHO OFF
|
@ECHO OFF
|
||||||
|
|
||||||
REM Command file for Sphinx documentation
|
REM Command file for Sphinx documentation
|
||||||
|
|
||||||
if "%SPHINXBUILD%" == "" (
|
if "%SPHINXBUILD%" == "" (
|
||||||
set SPHINXBUILD=sphinx-build
|
set SPHINXBUILD=sphinx-build
|
||||||
)
|
)
|
||||||
set BUILDDIR=_build
|
set BUILDDIR=_build
|
||||||
set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% .
|
set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% .
|
||||||
set I18NSPHINXOPTS=%SPHINXOPTS% .
|
set I18NSPHINXOPTS=%SPHINXOPTS% .
|
||||||
if NOT "%PAPER%" == "" (
|
if NOT "%PAPER%" == "" (
|
||||||
set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS%
|
set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS%
|
||||||
set I18NSPHINXOPTS=-D latex_paper_size=%PAPER% %I18NSPHINXOPTS%
|
set I18NSPHINXOPTS=-D latex_paper_size=%PAPER% %I18NSPHINXOPTS%
|
||||||
)
|
)
|
||||||
|
|
||||||
if "%1" == "" goto help
|
if "%1" == "" goto help
|
||||||
|
|
||||||
if "%1" == "help" (
|
if "%1" == "help" (
|
||||||
:help
|
:help
|
||||||
echo.Please use `make ^<target^>` where ^<target^> is one of
|
echo.Please use `make ^<target^>` where ^<target^> is one of
|
||||||
echo. html to make standalone HTML files
|
echo. html to make standalone HTML files
|
||||||
echo. dirhtml to make HTML files named index.html in directories
|
echo. dirhtml to make HTML files named index.html in directories
|
||||||
echo. singlehtml to make a single large HTML file
|
echo. singlehtml to make a single large HTML file
|
||||||
echo. pickle to make pickle files
|
echo. pickle to make pickle files
|
||||||
echo. json to make JSON files
|
echo. json to make JSON files
|
||||||
echo. htmlhelp to make HTML files and a HTML help project
|
echo. htmlhelp to make HTML files and a HTML help project
|
||||||
echo. qthelp to make HTML files and a qthelp project
|
echo. qthelp to make HTML files and a qthelp project
|
||||||
echo. devhelp to make HTML files and a Devhelp project
|
echo. devhelp to make HTML files and a Devhelp project
|
||||||
echo. epub to make an epub
|
echo. epub to make an epub
|
||||||
echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter
|
echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter
|
||||||
echo. text to make text files
|
echo. text to make text files
|
||||||
echo. man to make manual pages
|
echo. man to make manual pages
|
||||||
echo. texinfo to make Texinfo files
|
echo. texinfo to make Texinfo files
|
||||||
echo. gettext to make PO message catalogs
|
echo. gettext to make PO message catalogs
|
||||||
echo. changes to make an overview over all changed/added/deprecated items
|
echo. changes to make an overview over all changed/added/deprecated items
|
||||||
echo. xml to make Docutils-native XML files
|
echo. xml to make Docutils-native XML files
|
||||||
echo. pseudoxml to make pseudoxml-XML files for display purposes
|
echo. pseudoxml to make pseudoxml-XML files for display purposes
|
||||||
echo. linkcheck to check all external links for integrity
|
echo. linkcheck to check all external links for integrity
|
||||||
echo. doctest to run all doctests embedded in the documentation if enabled
|
echo. doctest to run all doctests embedded in the documentation if enabled
|
||||||
goto end
|
goto end
|
||||||
)
|
)
|
||||||
|
|
||||||
if "%1" == "clean" (
|
if "%1" == "clean" (
|
||||||
for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i
|
for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i
|
||||||
del /q /s %BUILDDIR%\*
|
del /q /s %BUILDDIR%\*
|
||||||
goto end
|
goto end
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
%SPHINXBUILD% 2> nul
|
%SPHINXBUILD% 2> nul
|
||||||
if errorlevel 9009 (
|
if errorlevel 9009 (
|
||||||
echo.
|
echo.
|
||||||
echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
|
echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
|
||||||
echo.installed, then set the SPHINXBUILD environment variable to point
|
echo.installed, then set the SPHINXBUILD environment variable to point
|
||||||
echo.to the full path of the 'sphinx-build' executable. Alternatively you
|
echo.to the full path of the 'sphinx-build' executable. Alternatively you
|
||||||
echo.may add the Sphinx directory to PATH.
|
echo.may add the Sphinx directory to PATH.
|
||||||
echo.
|
echo.
|
||||||
echo.If you don't have Sphinx installed, grab it from
|
echo.If you don't have Sphinx installed, grab it from
|
||||||
echo.http://sphinx-doc.org/
|
echo.http://sphinx-doc.org/
|
||||||
exit /b 1
|
exit /b 1
|
||||||
)
|
)
|
||||||
|
|
||||||
if "%1" == "html" (
|
if "%1" == "html" (
|
||||||
%SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html
|
%SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html
|
||||||
if errorlevel 1 exit /b 1
|
if errorlevel 1 exit /b 1
|
||||||
echo.
|
echo.
|
||||||
echo.Build finished. The HTML pages are in %BUILDDIR%/html.
|
echo.Build finished. The HTML pages are in %BUILDDIR%/html.
|
||||||
goto end
|
goto end
|
||||||
)
|
)
|
||||||
|
|
||||||
if "%1" == "dirhtml" (
|
if "%1" == "dirhtml" (
|
||||||
%SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml
|
%SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml
|
||||||
if errorlevel 1 exit /b 1
|
if errorlevel 1 exit /b 1
|
||||||
echo.
|
echo.
|
||||||
echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml.
|
echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml.
|
||||||
goto end
|
goto end
|
||||||
)
|
)
|
||||||
|
|
||||||
if "%1" == "singlehtml" (
|
if "%1" == "singlehtml" (
|
||||||
%SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml
|
%SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml
|
||||||
if errorlevel 1 exit /b 1
|
if errorlevel 1 exit /b 1
|
||||||
echo.
|
echo.
|
||||||
echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml.
|
echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml.
|
||||||
goto end
|
goto end
|
||||||
)
|
)
|
||||||
|
|
||||||
if "%1" == "pickle" (
|
if "%1" == "pickle" (
|
||||||
%SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle
|
%SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle
|
||||||
if errorlevel 1 exit /b 1
|
if errorlevel 1 exit /b 1
|
||||||
echo.
|
echo.
|
||||||
echo.Build finished; now you can process the pickle files.
|
echo.Build finished; now you can process the pickle files.
|
||||||
goto end
|
goto end
|
||||||
)
|
)
|
||||||
|
|
||||||
if "%1" == "json" (
|
if "%1" == "json" (
|
||||||
%SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json
|
%SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json
|
||||||
if errorlevel 1 exit /b 1
|
if errorlevel 1 exit /b 1
|
||||||
echo.
|
echo.
|
||||||
echo.Build finished; now you can process the JSON files.
|
echo.Build finished; now you can process the JSON files.
|
||||||
goto end
|
goto end
|
||||||
)
|
)
|
||||||
|
|
||||||
if "%1" == "htmlhelp" (
|
if "%1" == "htmlhelp" (
|
||||||
%SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp
|
%SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp
|
||||||
if errorlevel 1 exit /b 1
|
if errorlevel 1 exit /b 1
|
||||||
echo.
|
echo.
|
||||||
echo.Build finished; now you can run HTML Help Workshop with the ^
|
echo.Build finished; now you can run HTML Help Workshop with the ^
|
||||||
.hhp project file in %BUILDDIR%/htmlhelp.
|
.hhp project file in %BUILDDIR%/htmlhelp.
|
||||||
goto end
|
goto end
|
||||||
)
|
)
|
||||||
|
|
||||||
if "%1" == "qthelp" (
|
if "%1" == "qthelp" (
|
||||||
%SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp
|
%SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp
|
||||||
if errorlevel 1 exit /b 1
|
if errorlevel 1 exit /b 1
|
||||||
echo.
|
echo.
|
||||||
echo.Build finished; now you can run "qcollectiongenerator" with the ^
|
echo.Build finished; now you can run "qcollectiongenerator" with the ^
|
||||||
.qhcp project file in %BUILDDIR%/qthelp, like this:
|
.qhcp project file in %BUILDDIR%/qthelp, like this:
|
||||||
echo.^> qcollectiongenerator %BUILDDIR%\qthelp\wgerWorkoutManager.qhcp
|
echo.^> qcollectiongenerator %BUILDDIR%\qthelp\wgerWorkoutManager.qhcp
|
||||||
echo.To view the help file:
|
echo.To view the help file:
|
||||||
echo.^> assistant -collectionFile %BUILDDIR%\qthelp\wgerWorkoutManager.ghc
|
echo.^> assistant -collectionFile %BUILDDIR%\qthelp\wgerWorkoutManager.ghc
|
||||||
goto end
|
goto end
|
||||||
)
|
)
|
||||||
|
|
||||||
if "%1" == "devhelp" (
|
if "%1" == "devhelp" (
|
||||||
%SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp
|
%SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp
|
||||||
if errorlevel 1 exit /b 1
|
if errorlevel 1 exit /b 1
|
||||||
echo.
|
echo.
|
||||||
echo.Build finished.
|
echo.Build finished.
|
||||||
goto end
|
goto end
|
||||||
)
|
)
|
||||||
|
|
||||||
if "%1" == "epub" (
|
if "%1" == "epub" (
|
||||||
%SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub
|
%SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub
|
||||||
if errorlevel 1 exit /b 1
|
if errorlevel 1 exit /b 1
|
||||||
echo.
|
echo.
|
||||||
echo.Build finished. The epub file is in %BUILDDIR%/epub.
|
echo.Build finished. The epub file is in %BUILDDIR%/epub.
|
||||||
goto end
|
goto end
|
||||||
)
|
)
|
||||||
|
|
||||||
if "%1" == "latex" (
|
if "%1" == "latex" (
|
||||||
%SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
|
%SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
|
||||||
if errorlevel 1 exit /b 1
|
if errorlevel 1 exit /b 1
|
||||||
echo.
|
echo.
|
||||||
echo.Build finished; the LaTeX files are in %BUILDDIR%/latex.
|
echo.Build finished; the LaTeX files are in %BUILDDIR%/latex.
|
||||||
goto end
|
goto end
|
||||||
)
|
)
|
||||||
|
|
||||||
if "%1" == "latexpdf" (
|
if "%1" == "latexpdf" (
|
||||||
%SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
|
%SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
|
||||||
cd %BUILDDIR%/latex
|
cd %BUILDDIR%/latex
|
||||||
make all-pdf
|
make all-pdf
|
||||||
cd %BUILDDIR%/..
|
cd %BUILDDIR%/..
|
||||||
echo.
|
echo.
|
||||||
echo.Build finished; the PDF files are in %BUILDDIR%/latex.
|
echo.Build finished; the PDF files are in %BUILDDIR%/latex.
|
||||||
goto end
|
goto end
|
||||||
)
|
)
|
||||||
|
|
||||||
if "%1" == "latexpdfja" (
|
if "%1" == "latexpdfja" (
|
||||||
%SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
|
%SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
|
||||||
cd %BUILDDIR%/latex
|
cd %BUILDDIR%/latex
|
||||||
make all-pdf-ja
|
make all-pdf-ja
|
||||||
cd %BUILDDIR%/..
|
cd %BUILDDIR%/..
|
||||||
echo.
|
echo.
|
||||||
echo.Build finished; the PDF files are in %BUILDDIR%/latex.
|
echo.Build finished; the PDF files are in %BUILDDIR%/latex.
|
||||||
goto end
|
goto end
|
||||||
)
|
)
|
||||||
|
|
||||||
if "%1" == "text" (
|
if "%1" == "text" (
|
||||||
%SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text
|
%SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text
|
||||||
if errorlevel 1 exit /b 1
|
if errorlevel 1 exit /b 1
|
||||||
echo.
|
echo.
|
||||||
echo.Build finished. The text files are in %BUILDDIR%/text.
|
echo.Build finished. The text files are in %BUILDDIR%/text.
|
||||||
goto end
|
goto end
|
||||||
)
|
)
|
||||||
|
|
||||||
if "%1" == "man" (
|
if "%1" == "man" (
|
||||||
%SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man
|
%SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man
|
||||||
if errorlevel 1 exit /b 1
|
if errorlevel 1 exit /b 1
|
||||||
echo.
|
echo.
|
||||||
echo.Build finished. The manual pages are in %BUILDDIR%/man.
|
echo.Build finished. The manual pages are in %BUILDDIR%/man.
|
||||||
goto end
|
goto end
|
||||||
)
|
)
|
||||||
|
|
||||||
if "%1" == "texinfo" (
|
if "%1" == "texinfo" (
|
||||||
%SPHINXBUILD% -b texinfo %ALLSPHINXOPTS% %BUILDDIR%/texinfo
|
%SPHINXBUILD% -b texinfo %ALLSPHINXOPTS% %BUILDDIR%/texinfo
|
||||||
if errorlevel 1 exit /b 1
|
if errorlevel 1 exit /b 1
|
||||||
echo.
|
echo.
|
||||||
echo.Build finished. The Texinfo files are in %BUILDDIR%/texinfo.
|
echo.Build finished. The Texinfo files are in %BUILDDIR%/texinfo.
|
||||||
goto end
|
goto end
|
||||||
)
|
)
|
||||||
|
|
||||||
if "%1" == "gettext" (
|
if "%1" == "gettext" (
|
||||||
%SPHINXBUILD% -b gettext %I18NSPHINXOPTS% %BUILDDIR%/locale
|
%SPHINXBUILD% -b gettext %I18NSPHINXOPTS% %BUILDDIR%/locale
|
||||||
if errorlevel 1 exit /b 1
|
if errorlevel 1 exit /b 1
|
||||||
echo.
|
echo.
|
||||||
echo.Build finished. The message catalogs are in %BUILDDIR%/locale.
|
echo.Build finished. The message catalogs are in %BUILDDIR%/locale.
|
||||||
goto end
|
goto end
|
||||||
)
|
)
|
||||||
|
|
||||||
if "%1" == "changes" (
|
if "%1" == "changes" (
|
||||||
%SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes
|
%SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes
|
||||||
if errorlevel 1 exit /b 1
|
if errorlevel 1 exit /b 1
|
||||||
echo.
|
echo.
|
||||||
echo.The overview file is in %BUILDDIR%/changes.
|
echo.The overview file is in %BUILDDIR%/changes.
|
||||||
goto end
|
goto end
|
||||||
)
|
)
|
||||||
|
|
||||||
if "%1" == "linkcheck" (
|
if "%1" == "linkcheck" (
|
||||||
%SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck
|
%SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck
|
||||||
if errorlevel 1 exit /b 1
|
if errorlevel 1 exit /b 1
|
||||||
echo.
|
echo.
|
||||||
echo.Link check complete; look for any errors in the above output ^
|
echo.Link check complete; look for any errors in the above output ^
|
||||||
or in %BUILDDIR%/linkcheck/output.txt.
|
or in %BUILDDIR%/linkcheck/output.txt.
|
||||||
goto end
|
goto end
|
||||||
)
|
)
|
||||||
|
|
||||||
if "%1" == "doctest" (
|
if "%1" == "doctest" (
|
||||||
%SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest
|
%SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest
|
||||||
if errorlevel 1 exit /b 1
|
if errorlevel 1 exit /b 1
|
||||||
echo.
|
echo.
|
||||||
echo.Testing of doctests in the sources finished, look at the ^
|
echo.Testing of doctests in the sources finished, look at the ^
|
||||||
results in %BUILDDIR%/doctest/output.txt.
|
results in %BUILDDIR%/doctest/output.txt.
|
||||||
goto end
|
goto end
|
||||||
)
|
)
|
||||||
|
|
||||||
if "%1" == "xml" (
|
if "%1" == "xml" (
|
||||||
%SPHINXBUILD% -b xml %ALLSPHINXOPTS% %BUILDDIR%/xml
|
%SPHINXBUILD% -b xml %ALLSPHINXOPTS% %BUILDDIR%/xml
|
||||||
if errorlevel 1 exit /b 1
|
if errorlevel 1 exit /b 1
|
||||||
echo.
|
echo.
|
||||||
echo.Build finished. The XML files are in %BUILDDIR%/xml.
|
echo.Build finished. The XML files are in %BUILDDIR%/xml.
|
||||||
goto end
|
goto end
|
||||||
)
|
)
|
||||||
|
|
||||||
if "%1" == "pseudoxml" (
|
if "%1" == "pseudoxml" (
|
||||||
%SPHINXBUILD% -b pseudoxml %ALLSPHINXOPTS% %BUILDDIR%/pseudoxml
|
%SPHINXBUILD% -b pseudoxml %ALLSPHINXOPTS% %BUILDDIR%/pseudoxml
|
||||||
if errorlevel 1 exit /b 1
|
if errorlevel 1 exit /b 1
|
||||||
echo.
|
echo.
|
||||||
echo.Build finished. The pseudo-XML files are in %BUILDDIR%/pseudoxml.
|
echo.Build finished. The pseudo-XML files are in %BUILDDIR%/pseudoxml.
|
||||||
goto end
|
goto end
|
||||||
)
|
)
|
||||||
|
|
||||||
:end
|
:end
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ Configure apache to serve the application::
|
|||||||
|
|
||||||
|
|
||||||
<VirtualHost *:80>
|
<VirtualHost *:80>
|
||||||
WSGIDaemonProcess wger python-path=/home/wger/src:/home/wger/venv/lib/python3.4/site-packages
|
WSGIDaemonProcess wger python-path=/home/wger/src python-home=/home/wger/venv
|
||||||
WSGIProcessGroup wger
|
WSGIProcessGroup wger
|
||||||
WSGIScriptAlias / /home/wger/src/wger/wsgi.py
|
WSGIScriptAlias / /home/wger/src/wger/wsgi.py
|
||||||
|
|
||||||
@@ -44,13 +44,13 @@ Configure apache to serve the application::
|
|||||||
Require all granted
|
Require all granted
|
||||||
</Directory>
|
</Directory>
|
||||||
|
|
||||||
ErrorLog ${APACHE_LOG_DIR}/error.log
|
ErrorLog ${APACHE_LOG_DIR}/wger-error.log
|
||||||
CustomLog ${APACHE_LOG_DIR}/access.log combined
|
CustomLog ${APACHE_LOG_DIR}/wger-access.log combined
|
||||||
</VirtualHost>
|
</VirtualHost>
|
||||||
|
|
||||||
Apache has a problem when uploading files that have non-ASCII characters, e.g.
|
Apache has a problem when uploading files that have non-ASCII characters, e.g.
|
||||||
for exercise images. To avoid this, add to /etc/apache2/envvars (if there is
|
for exercise images. To avoid this, add to /etc/apache2/envvars (if there is
|
||||||
already an ``export LANG``, replace it)::
|
already an ``export LANG``, replace it) or set your system's locale::
|
||||||
|
|
||||||
export LANG='en_US.UTF-8'
|
export LANG='en_US.UTF-8'
|
||||||
export LC_ALL='en_US.UTF-8'
|
export LC_ALL='en_US.UTF-8'
|
||||||
@@ -63,14 +63,15 @@ Activate the settings and disable apache's default::
|
|||||||
sudo service apache2 reload
|
sudo service apache2 reload
|
||||||
|
|
||||||
Database
|
Database
|
||||||
---------
|
--------
|
||||||
|
|
||||||
|
.. _prod_postgres:
|
||||||
postgreSQL
|
postgreSQL
|
||||||
~~~~~~~~~~
|
~~~~~~~~~~
|
||||||
|
|
||||||
Install the postgres server and create a database and a user::
|
Install the postgres server and create a database and a user::
|
||||||
|
|
||||||
sudo apt-get install postgresql postgresql-server-dev-9.3 # or appropriate version
|
sudo apt-get install postgresql postgresql-server-dev-12 # or appropriate version
|
||||||
su - postgres
|
su - postgres
|
||||||
createdb wger
|
createdb wger
|
||||||
psql wger -c "CREATE USER wger WITH PASSWORD 'wger'";
|
psql wger -c "CREATE USER wger WITH PASSWORD 'wger'";
|
||||||
@@ -94,7 +95,7 @@ Application
|
|||||||
|
|
||||||
Make a virtualenv for python and activate it::
|
Make a virtualenv for python and activate it::
|
||||||
|
|
||||||
virtualenv --python python3 /home/wger/venv
|
python3 -m venv /home/wger/venv
|
||||||
source /home/wger/venv/bin/activate
|
source /home/wger/venv/bin/activate
|
||||||
|
|
||||||
Create folders to collect all static resources and save uploaded files. The
|
Create folders to collect all static resources and save uploaded files. The
|
||||||
@@ -111,10 +112,11 @@ Get the application::
|
|||||||
|
|
||||||
git clone https://github.com/wger-project/wger.git /home/wger/src
|
git clone https://github.com/wger-project/wger.git /home/wger/src
|
||||||
cd /home/wger/src
|
cd /home/wger/src
|
||||||
npm install bower
|
|
||||||
pip install -r requirements.txt
|
pip install -r requirements.txt
|
||||||
|
npm install -g yarn sass
|
||||||
|
python setup.py develop
|
||||||
pip install psycopg2 # Only if using postgres
|
pip install psycopg2 # Only if using postgres
|
||||||
invoke create_settings \
|
wger create-settings \
|
||||||
--settings-path /home/wger/src/settings.py \
|
--settings-path /home/wger/src/settings.py \
|
||||||
--database-path /home/wger/db/database.sqlite
|
--database-path /home/wger/db/database.sqlite
|
||||||
|
|
||||||
@@ -126,7 +128,7 @@ for the engine). Also set ``MEDIA_ROOT`` to ``/home/wger/media`` and
|
|||||||
Run the installation script, this will download some CSS and JS libraries and
|
Run the installation script, this will download some CSS and JS libraries and
|
||||||
load all initial data::
|
load all initial data::
|
||||||
|
|
||||||
invoke bootstrap_wger --settings-path /path/to/settings.py --no-start-server
|
wger bootstrap --settings-path /home/wger/src/settings.py --no-start-server
|
||||||
|
|
||||||
|
|
||||||
Collect all static resources::
|
Collect all static resources::
|
||||||
|
|||||||
147
docs/tips_and_tricks.rst
Normal file
147
docs/tips_and_tricks.rst
Normal file
@@ -0,0 +1,147 @@
|
|||||||
|
.. _tips:
|
||||||
|
|
||||||
|
Tips and tricks
|
||||||
|
---------------
|
||||||
|
|
||||||
|
Updating the code
|
||||||
|
~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
When pulling updates from upstream there are a couple of things to consider.
|
||||||
|
These steps apply to all installation methods above.
|
||||||
|
|
||||||
|
Upgrading the database
|
||||||
|
``````````````````````
|
||||||
|
|
||||||
|
There are regularly changes and upgrades to the database schema (these may also
|
||||||
|
come from new versions of django or the installed dependencies). If you start
|
||||||
|
the development server and see a message that there are unapplied migrations,
|
||||||
|
just do ``python manage.py migrate --all``.
|
||||||
|
|
||||||
|
Downloading JS and CSS libraries
|
||||||
|
````````````````````````````````
|
||||||
|
|
||||||
|
We use yarn to download the JS and CSS libraries. To update them just go to
|
||||||
|
the source and do ::
|
||||||
|
|
||||||
|
$ yarn install
|
||||||
|
|
||||||
|
This happens automatically during the bootstrap process.
|
||||||
|
|
||||||
|
|
||||||
|
Updating SASS files
|
||||||
|
```````````````````
|
||||||
|
After updating the SASS files, you need to compile them to regular CSS::
|
||||||
|
|
||||||
|
sass wger/core/static/scss/main.scss:wger/core/static/yarn/bootstrap-compiled.css
|
||||||
|
|
||||||
|
|
||||||
|
Clearing the cache
|
||||||
|
``````````````````
|
||||||
|
|
||||||
|
Sometimes there are changes to the internal changes of the cached structures.
|
||||||
|
It is recommended that you just clear all the existing caches
|
||||||
|
``python manage.py clear-cache --clear-all`` or just set the timeout to something
|
||||||
|
like one second (in settings.py::
|
||||||
|
|
||||||
|
CACHES = {
|
||||||
|
'default': {
|
||||||
|
'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',
|
||||||
|
'LOCATION': 'wger-cache',
|
||||||
|
'TIMEOUT': 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Miscellaneous settings
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
The following settings can be very useful during development (add to your
|
||||||
|
settings.py):
|
||||||
|
|
||||||
|
|
||||||
|
**Setting the email backend**
|
||||||
|
Use the console backend, all sent emails will be printed to it::
|
||||||
|
|
||||||
|
EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'
|
||||||
|
|
||||||
|
Dummy data generator
|
||||||
|
~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
To properly test the different parts of the application for usability or
|
||||||
|
performance, it is often very useful to have some data to work with. For this
|
||||||
|
reason, there is a dummy data generator script in
|
||||||
|
extras/dummy_generator/generator.py. It allows you to generate entries for
|
||||||
|
users, gyms, workouts and logs. For detailed usage options do::
|
||||||
|
|
||||||
|
python generator.py --help
|
||||||
|
|
||||||
|
Or for options for, e.g. user generation::
|
||||||
|
|
||||||
|
python generator.py users --help
|
||||||
|
|
||||||
|
To get you started, you might want to invoke the script in the following way. This
|
||||||
|
will create 10 gyms and 300 users, randomly assigning them to a different gym. Each
|
||||||
|
user will have 20 workouts and each exercise in each workout 30 log entries::
|
||||||
|
|
||||||
|
python generator.py gyms 10
|
||||||
|
python generator.py users 300
|
||||||
|
python generator.py workouts 20
|
||||||
|
python generator.py logs 30
|
||||||
|
python generator.py sessions random
|
||||||
|
python generator.py weight 100
|
||||||
|
python generator.py nutrition 20
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
All generated users have their username as password.
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
While it is possible to generate hundreds of users, gyms are more restricted and
|
||||||
|
you will probably get duplicate names if you generate more than a dozen.
|
||||||
|
|
||||||
|
|
||||||
|
Selectively running tests
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
If you do a ``python manage.py test`` you will run the complete testsuite, and
|
||||||
|
this can take a while. You can control which tests will be executed like this.
|
||||||
|
|
||||||
|
Test only the tests in the 'core' app::
|
||||||
|
|
||||||
|
python manage.py test wger.core
|
||||||
|
|
||||||
|
Test only the tests in the 'test_user.py` file in the core app::
|
||||||
|
|
||||||
|
python manage.py test wger.core.tests.test_user
|
||||||
|
|
||||||
|
Test only the tests in 'StatusUserTestCase' in the file 'test_user.py` file in
|
||||||
|
the core app::
|
||||||
|
|
||||||
|
python manage.py test wger.core.tests.test_user.StatusUserTestCase
|
||||||
|
|
||||||
|
|
||||||
|
Using runserver_plus
|
||||||
|
~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
During development you can use ``runserver_plus`` instead of the default django
|
||||||
|
server as you can use an interactive debugger directly from the browser if an
|
||||||
|
exception occurs. It also accepts the same command line options. For this just
|
||||||
|
install the following packages::
|
||||||
|
|
||||||
|
pip install django_extensions werkzeug
|
||||||
|
python manage.py runserver_plus [options]
|
||||||
|
|
||||||
|
|
||||||
|
Contributing
|
||||||
|
------------
|
||||||
|
|
||||||
|
* **Send pull requests**: for new code you want to share, please send pull
|
||||||
|
requests in github. Sending patches by email or attaching them to an issue
|
||||||
|
means a lot more of work. It's recommended that you work on a feature branch
|
||||||
|
when working on something, specially when it's something bigger. While many
|
||||||
|
people insist on rebasing before sending a pull request, it's not necessary.
|
||||||
|
|
||||||
|
* **Run the tests**: wger is proud to have a test coverage of over 90%. When you
|
||||||
|
implement something new, don't forget to run the testsuite and write approriate
|
||||||
|
tests for the new code. If you use github, configure the awesome Travis CI,
|
||||||
|
there is already a .travis file in the sources.
|
||||||
|
|
||||||
|
* **Code according to the coding style**: :ref:`codingstyle`
|
||||||
@@ -1,27 +1,28 @@
|
|||||||
# -*- coding: iso-8859-15 -*-
|
# -*- coding: utf-8 -*-
|
||||||
'''
|
# flake8: noqa
|
||||||
|
"""
|
||||||
Simple FunkLoad test
|
Simple FunkLoad test
|
||||||
'''
|
"""
|
||||||
import unittest
|
import unittest
|
||||||
from random import random
|
from random import random
|
||||||
from funkload.FunkLoadTestCase import FunkLoadTestCase
|
from funkload.FunkLoadTestCase import FunkLoadTestCase
|
||||||
|
|
||||||
class Simple(FunkLoadTestCase):
|
class Simple(FunkLoadTestCase):
|
||||||
'''
|
"""
|
||||||
This test uses the configuration file Simple.conf.
|
This test uses the configuration file Simple.conf.
|
||||||
'''
|
"""
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
'''
|
"""
|
||||||
Setting up test.
|
Setting up test.
|
||||||
'''
|
"""
|
||||||
self.server_url = self.conf_get('main', 'url')
|
self.server_url = self.conf_get('main', 'url')
|
||||||
|
|
||||||
def test_simple(self):
|
def test_simple(self):
|
||||||
# The description should be set in the configuration file
|
# The description should be set in the configuration file
|
||||||
server_url = self.server_url
|
server_url = self.server_url
|
||||||
|
|
||||||
# Exercises
|
# Exercises
|
||||||
self.get(server_url + '/en/exercise/overview/', description='Get exercise overview')
|
self.get(server_url + '/en/exercise/overview/', description='Get exercise overview')
|
||||||
self.get(server_url + '/en/exercise/muscle/overview/', description='Get muscle overview')
|
self.get(server_url + '/en/exercise/muscle/overview/', description='Get muscle overview')
|
||||||
self.get(server_url + '/de/exercise/79/view/', description='Get exercise page')
|
self.get(server_url + '/de/exercise/79/view/', description='Get exercise page')
|
||||||
|
|||||||
@@ -1,55 +1,109 @@
|
|||||||
#
|
#
|
||||||
# A wger installation under apache with WSGI
|
# A wger installation under apache with WSGI
|
||||||
#
|
#
|
||||||
|
# Note: you MUST build this image from the projec's root!
|
||||||
|
# docker build -f extras/docker/apache/Dockerfile --tag wger/apache .
|
||||||
|
#
|
||||||
# Please consult the documentation for usage
|
# Please consult the documentation for usage
|
||||||
# docker build --tag wger/apache .
|
# docker build --tag wger/apache .
|
||||||
# docker run -ti --name wger.apache --publish 8000:80 wger/apache
|
# docker run -ti --name wger.apache --publish 8000:80 wger/apache
|
||||||
#
|
#
|
||||||
|
# To stop the container:
|
||||||
|
# sudo docker container stop wger.apache
|
||||||
|
#
|
||||||
|
# To start developing again
|
||||||
|
# sudo docker container start --attach wger.apache
|
||||||
#
|
#
|
||||||
|
|
||||||
FROM wger/base
|
##########
|
||||||
|
# Builder
|
||||||
|
##########
|
||||||
|
FROM ubuntu:20.04 as builder
|
||||||
|
|
||||||
MAINTAINER Roland Geider <roland@geider.net>
|
RUN apt-get update \
|
||||||
EXPOSE 80
|
&& apt-get install --no-install-recommends -y \
|
||||||
|
build-essential \
|
||||||
# Install dependencies
|
python3-dev \
|
||||||
RUN apt-get install -y apache2 libapache2-mod-wsgi-py3
|
python3-pip \
|
||||||
|
python3-wheel \
|
||||||
# Configure apache
|
git \
|
||||||
RUN a2dissite 000-default.conf
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
ADD wger.conf /etc/apache2/sites-available/
|
|
||||||
RUN a2ensite wger
|
|
||||||
|
|
||||||
# Set up the application
|
# Set up the application
|
||||||
|
COPY requirements* ./
|
||||||
|
RUN pip3 wheel --no-cache-dir --wheel-dir /usr/src/app/wheels -r requirements_devel.txt
|
||||||
|
|
||||||
|
|
||||||
|
########
|
||||||
|
# Final
|
||||||
|
########
|
||||||
|
FROM wger/base:2.0-dev
|
||||||
|
LABEL maintainer="Roland Geider <roland@geider.net>"
|
||||||
|
|
||||||
|
ARG DOCKER_DIR=./extras/docker/apache
|
||||||
|
EXPOSE 80
|
||||||
|
|
||||||
|
|
||||||
|
# Install dependencies
|
||||||
|
RUN apt-get update \
|
||||||
|
&& apt-get install --no-install-recommends -y \
|
||||||
|
apache2 \
|
||||||
|
cron \
|
||||||
|
libapache2-mod-wsgi-py3 \
|
||||||
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
|
# Configure apache
|
||||||
|
COPY ${DOCKER_DIR}/wger.conf /etc/apache2/sites-available/
|
||||||
|
RUN a2dissite 000-default.conf \
|
||||||
|
&& a2enmod headers \
|
||||||
|
&& a2ensite wger \
|
||||||
|
&& echo "ServerName localhost" >> /etc/apache2/conf-available/fqdn.conf \
|
||||||
|
&& a2enconf fqdn \
|
||||||
|
&& usermod -G wger www-data
|
||||||
|
|
||||||
|
# Configure cron
|
||||||
|
COPY ${DOCKER_DIR}/crontab /etc/cron.d/wger
|
||||||
|
COPY ${DOCKER_DIR}/venvwrapper /home/wger/venvwrapper
|
||||||
|
COPY ${DOCKER_DIR}/entrypoint.sh /home/wger/entrypoint.sh
|
||||||
|
|
||||||
|
RUN chmod 0644 /etc/cron.d/wger \
|
||||||
|
&& chmod +x /home/wger/venvwrapper /home/wger/entrypoint.sh \
|
||||||
|
&& touch /var/log/cron.log
|
||||||
|
|
||||||
|
COPY --from=builder /usr/src/app/wheels /wheels
|
||||||
|
COPY --chown=wger:www-data . /home/wger/src
|
||||||
|
|
||||||
|
# Set up the application
|
||||||
|
RUN ln -s /home/wger/static/CACHE /var/www
|
||||||
USER wger
|
USER wger
|
||||||
RUN git clone https://github.com/wger-project/wger.git /home/wger/src
|
|
||||||
|
|
||||||
WORKDIR /home/wger/src
|
WORKDIR /home/wger/src
|
||||||
RUN virtualenv --python python3 /home/wger/venv
|
#RUN git clone https://github.com/wger-project/wger.git
|
||||||
|
RUN python3 -m venv /home/wger/venv
|
||||||
RUN . /home/wger/venv/bin/activate \
|
RUN . /home/wger/venv/bin/activate \
|
||||||
&& pip install --upgrade pip \
|
&& pip install --upgrade pip \
|
||||||
&& pip install -r requirements.txt \
|
&& pip install wheel \
|
||||||
&& invoke create_settings \
|
&& pip install --no-cache /wheels/* \
|
||||||
|
&& python setup.py develop \
|
||||||
|
&& wger create-settings \
|
||||||
--settings-path /home/wger/src/settings.py \
|
--settings-path /home/wger/src/settings.py \
|
||||||
--database-path /home/wger/db/database.sqlite \
|
--database-path /home/wger/db/database.sqlite \
|
||||||
&& invoke bootstrap_wger \
|
&& wger bootstrap \
|
||||||
--settings-path /home/wger/src/settings.py \
|
--settings-path /home/wger/src/settings.py \
|
||||||
--no-start-server
|
--no-start-server
|
||||||
|
|
||||||
|
|
||||||
# Change permissions of some files and folders so the apache process
|
# Change permissions of some files and folders so the apache process
|
||||||
# can access them.
|
# can access them.
|
||||||
RUN chmod o+w -R ~/db/ \
|
RUN mkdir -p ~/static/CACHE ~/media \
|
||||||
&& . /home/wger/venv/bin/activate \
|
&& ln -s /home/wger/static/CACHE /home/wger/src/CACHE \
|
||||||
&& mkdir ~/static \
|
&& chmod g+w /home/wger/static/CACHE \
|
||||||
&& mkdir ~/media \
|
|
||||||
&& chmod o+w ~/media \
|
|
||||||
&& sed -i "/^MEDIA_ROOT/c\MEDIA_ROOT='\/home\/wger\/media'" settings.py \
|
&& sed -i "/^MEDIA_ROOT/c\MEDIA_ROOT='\/home\/wger\/media'" settings.py \
|
||||||
&& python manage.py download-exercise-images \
|
&& echo STATIC_ROOT=\'/home/wger/static\' >> settings.py
|
||||||
&& echo STATIC_ROOT=\'/home/wger/static\' >> settings.py \
|
|
||||||
&& python manage.py collectstatic --noinput
|
|
||||||
|
|
||||||
USER root
|
USER root
|
||||||
|
RUN apt-get remove build-essential -y \
|
||||||
|
&& apt autoremove -y \
|
||||||
|
&& chown www-data:www-data -R /home/wger/db
|
||||||
|
|
||||||
ENTRYPOINT ["/usr/sbin/apache2ctl"]
|
ENTRYPOINT ["/home/wger/entrypoint.sh"]
|
||||||
CMD ["-D", "FOREGROUND"]
|
|
||||||
|
|||||||
@@ -18,7 +18,25 @@ play around. To start it:
|
|||||||
|
|
||||||
```docker run -ti --name wger.apache --publish 8000:80 wger/apache```
|
```docker run -ti --name wger.apache --publish 8000:80 wger/apache```
|
||||||
|
|
||||||
Then just open http://localhost:8000 and log in as: **admin**, password **admin**
|
Then just open <http://localhost:8000> and log in as: **admin**, password **admin**
|
||||||
|
|
||||||
|
To stop the container:
|
||||||
|
|
||||||
|
```sudo docker container stop wger.apache```
|
||||||
|
|
||||||
|
To start developing again:
|
||||||
|
|
||||||
|
```sudo docker container start --attach wger.apache```
|
||||||
|
|
||||||
|
|
||||||
|
Building
|
||||||
|
--------
|
||||||
|
|
||||||
|
If you build this yourself, keep in mind that you **must** build from the
|
||||||
|
project root!
|
||||||
|
|
||||||
|
```docker build -f extras/docker/apache/Dockerfile --tag wger/apache .```
|
||||||
|
|
||||||
|
|
||||||
Contact
|
Contact
|
||||||
-------
|
-------
|
||||||
@@ -28,19 +46,17 @@ didn't behave as you expected. We can't fix what we don't know about, so please
|
|||||||
report liberally. If you're not sure if something is a bug or not, feel free to
|
report liberally. If you're not sure if something is a bug or not, feel free to
|
||||||
file a bug anyway.
|
file a bug anyway.
|
||||||
|
|
||||||
* twitter: https://twitter.com/wger_de
|
* gitter: <https://gitter.im/wger-project/wger>
|
||||||
* mailing list: https://groups.google.com/group/wger / wger@googlegroups.com, no registration needed
|
* issue tracker: <https://github.com/wger-project/wger/issues>
|
||||||
* IRC: channel #wger on freenode.net, webchat: http://webchat.freenode.net/?channels=wger
|
* twitter: <https://twitter.com/wger_project>
|
||||||
* issue tracker: https://github.com/wger-project/wger/issues
|
* mailing list: <https://groups.google.com/group/wger> / wger@googlegroups.com, no registration needed
|
||||||
|
|
||||||
Sources
|
Sources
|
||||||
-------
|
-------
|
||||||
|
|
||||||
All the code and the content is freely available:
|
All the code and the content is freely available:
|
||||||
|
|
||||||
* Main repository: https://github.com/wger-project/wger
|
* Main repository: <https://github.com/wger-project/wger>
|
||||||
* Mirror: https://bitbucket.org/rolandgeider/wger
|
|
||||||
|
|
||||||
|
|
||||||
Licence
|
Licence
|
||||||
-------
|
-------
|
||||||
|
|||||||
6
extras/docker/apache/crontab
Normal file
6
extras/docker/apache/crontab
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
# wger cron jobs
|
||||||
|
0 5 * * * wger /home/wger/venvwrapper email-reminders
|
||||||
|
15 5 * * * wger /home/wger/venvwrapper email-weight-reminders
|
||||||
|
30 5 * * * wger /home/wger/venvwrapper inactive-members
|
||||||
|
42 4 * * * wger /home/wger/venvwrapper delete-temp-users
|
||||||
|
# Don't remove the empty line at the end of this file. It is required to run the cron job
|
||||||
14
extras/docker/apache/entrypoint.sh
Executable file
14
extras/docker/apache/entrypoint.sh
Executable file
@@ -0,0 +1,14 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
/home/wger/venvwrapper migrate
|
||||||
|
|
||||||
|
if [ "${DOWNLOAD_IMGS}" = "TRUE" ]; then
|
||||||
|
/home/wger/venvwrapper download-exercise-images
|
||||||
|
chmod -R g+w ~wger/media
|
||||||
|
fi
|
||||||
|
|
||||||
|
/home/wger/venvwrapper collectstatic --no-input
|
||||||
|
/home/wger/venvwrapper compress --force
|
||||||
|
chown www-data:www-data -R /home/wger/static
|
||||||
|
|
||||||
|
/usr/sbin/apache2ctl -D FOREGROUND
|
||||||
5
extras/docker/apache/venvwrapper
Normal file
5
extras/docker/apache/venvwrapper
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
. /home/wger/venv/bin/activate
|
||||||
|
|
||||||
|
python /home/wger/src/manage.py "$@"
|
||||||
@@ -6,20 +6,26 @@
|
|||||||
|
|
||||||
|
|
||||||
<VirtualHost *:80>
|
<VirtualHost *:80>
|
||||||
WSGIDaemonProcess wger python-path=/home/wger/src:/home/wger/venv/lib/python3.4/site-packages
|
WSGIDaemonProcess wger python-path=/home/wger/src python-home=/home/wger/venv
|
||||||
WSGIProcessGroup wger
|
WSGIProcessGroup wger
|
||||||
WSGIScriptAlias / /home/wger/src/wger/wsgi.py
|
WSGIScriptAlias / /home/wger/src/wger/wsgi.py
|
||||||
|
WSGIPassAuthorization On
|
||||||
|
|
||||||
Alias /static/ /home/wger/static/
|
Alias /static/ /home/wger/static/
|
||||||
<Directory /home/wger/static>
|
<Directory /home/wger/static>
|
||||||
Require all granted
|
Require all granted
|
||||||
|
Header set Cache-Control "max-age=604800, public"
|
||||||
</Directory>
|
</Directory>
|
||||||
|
|
||||||
Alias /media/ /home/wger/media/
|
Alias /media/ /home/wger/media/
|
||||||
<Directory /home/wger//media>
|
<Directory /home/wger/media>
|
||||||
Require all granted
|
Require all granted
|
||||||
|
Header set Cache-Control "max-age=604800, public"
|
||||||
</Directory>
|
</Directory>
|
||||||
|
|
||||||
ErrorLog ${APACHE_LOG_DIR}/error.log
|
ErrorLog ${APACHE_LOG_DIR}/wger-error.log
|
||||||
CustomLog ${APACHE_LOG_DIR}/access.log combined
|
CustomLog ${APACHE_LOG_DIR}/wger-access.log combined
|
||||||
</VirtualHost>
|
</VirtualHost>
|
||||||
|
|
||||||
|
ServerSignature Off
|
||||||
|
ServerTokens Prod
|
||||||
|
|||||||
@@ -8,17 +8,34 @@
|
|||||||
# docker build --tag wger/base .
|
# docker build --tag wger/base .
|
||||||
#
|
#
|
||||||
|
|
||||||
FROM ubuntu:16.04
|
FROM ubuntu:20.04
|
||||||
|
|
||||||
MAINTAINER Roland Geider <roland@geider.net>
|
LABEL maintainer="Roland Geider <roland@geider.net>"
|
||||||
|
|
||||||
# Install dependencies
|
# Install dependencies
|
||||||
RUN apt-get update;\
|
ENV DEBIAN_FRONTEND=noninteractive
|
||||||
apt-get install -y nodejs nodejs-legacy npm git \
|
RUN apt-get update \
|
||||||
python-virtualenv python3-dev \
|
&& apt-get install --no-install-recommends -y \
|
||||||
libjpeg8-dev zlib1g-dev libwebp-dev \
|
git \
|
||||||
sudo
|
locales \
|
||||||
|
nodejs \
|
||||||
|
npm \
|
||||||
|
python3-venv \
|
||||||
|
python3-pip \
|
||||||
|
sqlite3 \
|
||||||
|
netcat-openbsd \
|
||||||
|
&& rm -rf /var/lib/apt/lists/* \
|
||||||
|
&& npm install -g yarn sass \
|
||||||
|
&& locale-gen en_US.UTF-8
|
||||||
|
|
||||||
|
# Environmental variables
|
||||||
|
ENV LANG en_US.UTF-8
|
||||||
|
ENV LANGUAGE en_US:en
|
||||||
|
ENV LC_ALL en_US.UTF-8
|
||||||
|
|
||||||
|
ENV PYTHONDONTWRITEBYTECODE 1
|
||||||
|
ENV PYTHONUNBUFFERED 1
|
||||||
|
|
||||||
|
|
||||||
# Add wger user
|
# Add wger user
|
||||||
RUN adduser wger --disabled-password --gecos ""
|
RUN adduser wger --disabled-password --gecos ""
|
||||||
RUN echo "wger ALL=(ALL) NOPASSWD:ALL" > /etc/sudoers.d/wger
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ Development image for wger - Base image
|
|||||||
This is the base image for some of the other wger images and offers no
|
This is the base image for some of the other wger images and offers no
|
||||||
functionality, it's only use is to provide some common dependencies.
|
functionality, it's only use is to provide some common dependencies.
|
||||||
|
|
||||||
If you want to develop, try either ``wger/devel`` oder ``wger/devel-fedora``.
|
If you want to develop, try ``wger/devel``.
|
||||||
|
|
||||||
|
|
||||||
Contact
|
Contact
|
||||||
@@ -14,18 +14,17 @@ didn't behave as you expected. We can't fix what we don't know about, so please
|
|||||||
report liberally. If you're not sure if something is a bug or not, feel free to
|
report liberally. If you're not sure if something is a bug or not, feel free to
|
||||||
file a bug anyway.
|
file a bug anyway.
|
||||||
|
|
||||||
* twitter: https://twitter.com/wger_de
|
* gitter: <https://gitter.im/wger-project/wger>
|
||||||
* mailing list: https://groups.google.com/group/wger / wger@googlegroups.com, no registration needed
|
* issue tracker: <https://github.com/wger-project/wger/issues>
|
||||||
* IRC: channel #wger on freenode.net, webchat: http://webchat.freenode.net/?channels=wger
|
* twitter: <https://twitter.com/wger_project>
|
||||||
* issue tracker: https://github.com/wger-project/wger/issues
|
* mailing list: <https://groups.google.com/group/wger> / wger@googlegroups.com, no registration needed
|
||||||
|
|
||||||
Sources
|
Sources
|
||||||
-------
|
-------
|
||||||
|
|
||||||
All the code and the content is freely available:
|
All the code and the content is freely available:
|
||||||
|
|
||||||
* Main repository: https://github.com/wger-project/wger
|
* Main repository: <https://github.com/wger-project/wger>
|
||||||
* Mirror: https://bitbucket.org/rolandgeider/wger
|
|
||||||
|
|
||||||
Licence
|
Licence
|
||||||
-------
|
-------
|
||||||
|
|||||||
92
extras/docker/compose/README.md
Normal file
92
extras/docker/compose/README.md
Normal file
@@ -0,0 +1,92 @@
|
|||||||
|
# Development image for wger
|
||||||
|
|
||||||
|
Thank you for downloading wger Workout Manager. wger (ˈvɛɡɐ) is a free, open
|
||||||
|
source web application that manages your exercises and personal workouts, weight
|
||||||
|
and diet plans. It can also be used as a simple gym management utility, providing
|
||||||
|
different administrative roles (trainer, manager, etc.). It offers a REST API
|
||||||
|
as well, for easy integration with other projects and tools.
|
||||||
|
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
This docker-compose file starts up a development environment with django's
|
||||||
|
development server, postgres as a database and redis for caching and saving
|
||||||
|
the sessions. It binds your current code checkout into the volume, if you
|
||||||
|
don't want or have one, use the wger/apache image, it is self-contained.
|
||||||
|
|
||||||
|
### 1 - Start all services
|
||||||
|
|
||||||
|
To start all services:
|
||||||
|
|
||||||
|
docker-compose -f extras/docker/compose/docker-compose.yml up
|
||||||
|
|
||||||
|
Then open <http://localhost:8000> and log in as: **admin**, password **admin**
|
||||||
|
|
||||||
|
|
||||||
|
### 2 - Lifecycle Management
|
||||||
|
|
||||||
|
To stop all services issue a stop command, this will preserve all containers
|
||||||
|
and volumes:
|
||||||
|
|
||||||
|
docker-compose -f extras/docker/compose/docker-compose.yml stop
|
||||||
|
|
||||||
|
To start everything up again:
|
||||||
|
|
||||||
|
docker-compose -f extras/docker/compose/docker-compose.yml start
|
||||||
|
|
||||||
|
To remove all containers (except for the postgres volume)
|
||||||
|
|
||||||
|
docker-compose -f extras/docker/compose/docker-compose.yml down
|
||||||
|
|
||||||
|
To view the application's log:
|
||||||
|
|
||||||
|
docker-compose -f extras/docker/compose/docker-compose.yml logs -f
|
||||||
|
|
||||||
|
### 2 - Other commands
|
||||||
|
|
||||||
|
You might need to issue other commands or do other manual work in the container,
|
||||||
|
e.g.
|
||||||
|
|
||||||
|
docker-compose -f extras/docker/compose/docker-compose.yml exec web yarn install
|
||||||
|
docker-compose -f extras/docker/compose/docker-compose.yml exec --user root web /bin/bash
|
||||||
|
|
||||||
|
|
||||||
|
## Building
|
||||||
|
|
||||||
|
If you want to build this yourself, keep in mind that you **must** build from the
|
||||||
|
project root. Make sure the wger/devel image is available locally as well:
|
||||||
|
|
||||||
|
docker-compose -f extras/docker/compose/docker-compose.yml build.
|
||||||
|
|
||||||
|
|
||||||
|
## Contact
|
||||||
|
|
||||||
|
Feel free to contact us if you found this useful or if there was something that
|
||||||
|
didn't behave as you expected. We can't fix what we don't know about, so please
|
||||||
|
report liberally. If you're not sure if something is a bug or not, feel free to
|
||||||
|
file a bug anyway.
|
||||||
|
|
||||||
|
* gitter: <https://gitter.im/wger-project/wger>
|
||||||
|
* issue tracker: <https://github.com/wger-project/wger/issues>
|
||||||
|
* twitter: <https://twitter.com/wger_project>
|
||||||
|
* mailing list: <https://groups.google.com/group/wger> / wger@googlegroups.com, no registration needed
|
||||||
|
|
||||||
|
## Sources
|
||||||
|
|
||||||
|
All the code and the content is freely available:
|
||||||
|
|
||||||
|
* Main repository: <https://github.com/wger-project/wger>
|
||||||
|
|
||||||
|
## Licence
|
||||||
|
|
||||||
|
The application is licenced under the Affero GNU General Public License 3 or
|
||||||
|
later (AGPL 3+).
|
||||||
|
|
||||||
|
The initial exercise and ingredient data is licensed additionally under one of
|
||||||
|
the Creative Commons licenses, see the individual exercises for more details.
|
||||||
|
|
||||||
|
The documentation is released under a CC-BY-SA either version 4 of the License,
|
||||||
|
or (at your option) any later version.
|
||||||
|
|
||||||
|
Some images where taken from Wikipedia, see the SOURCES file in their respective
|
||||||
|
folders for more details.
|
||||||
16
extras/docker/compose/dev.env
Normal file
16
extras/docker/compose/dev.env
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
|
||||||
|
# Database
|
||||||
|
DJANGO_DB_ENGINE=django.db.backends.postgresql
|
||||||
|
DJANGO_DB_DATABASE=wger
|
||||||
|
DJANGO_DB_USER=wger
|
||||||
|
DJANGO_DB_PASSWORD=wger
|
||||||
|
DJANGO_DB_HOST=db
|
||||||
|
DJANGO_DB_PORT=5432
|
||||||
|
|
||||||
|
# Cache
|
||||||
|
DJANGO_CACHE_BACKEND=django_redis.cache.RedisCache
|
||||||
|
DJANGO_CACHE_LOCATION=redis://cache:6379/1
|
||||||
|
DJANGO_CACHE_TIMEOUT=100
|
||||||
|
DJANGO_CACHE_CLIENT_CLASS=django_redis.client.DefaultClient
|
||||||
|
|
||||||
|
DJANGO_MEDIA_ROOT=/home/wger/media
|
||||||
36
extras/docker/compose/docker-compose.yml
Normal file
36
extras/docker/compose/docker-compose.yml
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
version: '3.7'
|
||||||
|
|
||||||
|
services:
|
||||||
|
web:
|
||||||
|
image: wger/devel:2.0-dev
|
||||||
|
volumes:
|
||||||
|
- type: bind
|
||||||
|
source: ../../../
|
||||||
|
target: /home/wger/src/
|
||||||
|
ports:
|
||||||
|
- 8000:8000
|
||||||
|
env_file:
|
||||||
|
- ./dev.env
|
||||||
|
depends_on:
|
||||||
|
- db
|
||||||
|
- cache
|
||||||
|
|
||||||
|
db:
|
||||||
|
image: postgres:12.0-alpine
|
||||||
|
volumes:
|
||||||
|
- wger-postgres-data:/var/lib/postgresql/data/
|
||||||
|
expose:
|
||||||
|
- 5432
|
||||||
|
environment:
|
||||||
|
- POSTGRES_USER=wger
|
||||||
|
- POSTGRES_PASSWORD=wger
|
||||||
|
- POSTGRES_DB=wger
|
||||||
|
|
||||||
|
cache:
|
||||||
|
restart: always
|
||||||
|
image: redis:latest
|
||||||
|
expose:
|
||||||
|
- 6379
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
wger-postgres-data:
|
||||||
@@ -1,57 +0,0 @@
|
|||||||
#
|
|
||||||
# Docker image for wger development on a fedora base image
|
|
||||||
#
|
|
||||||
# Please consult the documentation for usage
|
|
||||||
# docker build -t wger/devel-fedora .
|
|
||||||
# docker run -ti --name wger.devel-fedora --publish 8000:8000 wger/devel-fedora
|
|
||||||
# (in docker) source ~/venv/bin/activate
|
|
||||||
# (in docker) python manage.py runserver 0.0.0.0:8000
|
|
||||||
#
|
|
||||||
#
|
|
||||||
FROM fedora:24
|
|
||||||
MAINTAINER Roland Geider <roland@geider.net>
|
|
||||||
|
|
||||||
# Install dependencies
|
|
||||||
RUN dnf update;\
|
|
||||||
dnf install -y python3-devel python-virtualenv \
|
|
||||||
nodejs npm libjpeg-turbo-devel zlib-devel git \
|
|
||||||
tmux sudo redhat-rpm-config gcc python-imaging
|
|
||||||
|
|
||||||
# Add wger user
|
|
||||||
RUN adduser wger
|
|
||||||
RUN echo "wger ALL=(ALL) NOPASSWD:ALL" > /etc/sudoers.d/wger
|
|
||||||
EXPOSE 8000
|
|
||||||
|
|
||||||
|
|
||||||
# Set up the application
|
|
||||||
USER wger
|
|
||||||
RUN git clone https://github.com/wger-project/wger.git /home/wger/src
|
|
||||||
|
|
||||||
WORKDIR /home/wger/src
|
|
||||||
RUN virtualenv --python python3 /home/wger/venv
|
|
||||||
RUN . /home/wger/venv/bin/activate \
|
|
||||||
&& pip install --upgrade pip \
|
|
||||||
&& pip install -r requirements_devel.txt \
|
|
||||||
&& invoke create_settings \
|
|
||||||
--settings-path /home/wger/src/settings.py \
|
|
||||||
--database-path /home/wger/db/database.sqlite \
|
|
||||||
&& invoke bootstrap_wger \
|
|
||||||
--settings-path /home/wger/src/settings.py \
|
|
||||||
--no-start-server
|
|
||||||
|
|
||||||
# Install node modules for JS linting and download the exercise images
|
|
||||||
#
|
|
||||||
# Note: it seems there are problems with node and docker, so it's necessary
|
|
||||||
# to delete the node_modules folder and install everything again
|
|
||||||
# -> https://github.com/npm/npm/issues/9863
|
|
||||||
# -> https://github.com/npm/npm/issues/13306
|
|
||||||
RUN rm -r node_modules \
|
|
||||||
&& npm install bower \
|
|
||||||
&& npm install \
|
|
||||||
&& mkdir ~/media \
|
|
||||||
&& sed -i "/^MEDIA_ROOT/c\MEDIA_ROOT='\/home\/wger\/media'" settings.py \
|
|
||||||
&& . /home/wger/venv/bin/activate \
|
|
||||||
&& python manage.py download-exercise-images
|
|
||||||
|
|
||||||
|
|
||||||
CMD ["/bin/bash"]
|
|
||||||
@@ -1,65 +0,0 @@
|
|||||||
Development image for wger - Fedora based
|
|
||||||
=========================================
|
|
||||||
Thank you for downloading wger Workout Manager. wger (ˈvɛɡɐ) is a free, open
|
|
||||||
source web application that manages your exercises and personal workouts, weight
|
|
||||||
and diet plans. It can also be used as a simple gym management utility, providing
|
|
||||||
different administrative roles (trainer, manager, etc.). It offers a REST API
|
|
||||||
as well, for easy integration with other projects and tools.
|
|
||||||
|
|
||||||
It is written with python/django and uses jQuery and some D3js for charts.
|
|
||||||
|
|
||||||
Installation
|
|
||||||
------------
|
|
||||||
|
|
||||||
This docker image contains an instance of the application running with django's
|
|
||||||
development server using a sqlite database. It can be used to quickly setup a
|
|
||||||
development instance (vim and tmux are already installed):
|
|
||||||
|
|
||||||
```docker run -ti --name wger.devel-fedora --publish 8000:8000 wger/devel-fedora```
|
|
||||||
|
|
||||||
Then, *within the docker image*, activate the virtualenv
|
|
||||||
|
|
||||||
```source ~/venv/bin/activate```
|
|
||||||
|
|
||||||
and start the development server
|
|
||||||
|
|
||||||
```python manage.py runserver 0.0.0.0:8000```
|
|
||||||
|
|
||||||
Then just open http://localhost:8000 and log in as: **admin**, password **admin**
|
|
||||||
|
|
||||||
|
|
||||||
Contact
|
|
||||||
-------
|
|
||||||
|
|
||||||
Feel free to contact us if you found this useful or if there was something that
|
|
||||||
didn't behave as you expected. We can't fix what we don't know about, so please
|
|
||||||
report liberally. If you're not sure if something is a bug or not, feel free to
|
|
||||||
file a bug anyway.
|
|
||||||
|
|
||||||
* twitter: https://twitter.com/wger_de
|
|
||||||
* mailing list: https://groups.google.com/group/wger / wger@googlegroups.com, no registration needed
|
|
||||||
* IRC: channel #wger on freenode.net, webchat: http://webchat.freenode.net/?channels=wger
|
|
||||||
* issue tracker: https://github.com/wger-project/wger/issues
|
|
||||||
|
|
||||||
Sources
|
|
||||||
-------
|
|
||||||
|
|
||||||
All the code and the content is freely available:
|
|
||||||
|
|
||||||
* Main repository: https://github.com/wger-project/wger
|
|
||||||
* Mirror: https://bitbucket.org/rolandgeider/wger
|
|
||||||
|
|
||||||
Licence
|
|
||||||
-------
|
|
||||||
|
|
||||||
The application is licenced under the Affero GNU General Public License 3 or
|
|
||||||
later (AGPL 3+).
|
|
||||||
|
|
||||||
The initial exercise and ingredient data is licensed additionally under one of
|
|
||||||
the Creative Commons licenses, see the individual exercises for more details.
|
|
||||||
|
|
||||||
The documentation is released under a CC-BY-SA either version 4 of the License,
|
|
||||||
or (at your option) any later version.
|
|
||||||
|
|
||||||
Some images where taken from Wikipedia, see the SOURCES file in their respective
|
|
||||||
folders for more details.
|
|
||||||
80
extras/docker/development-venv/Dockerfile
Normal file
80
extras/docker/development-venv/Dockerfile
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
#
|
||||||
|
# Docker image for wger development:
|
||||||
|
#
|
||||||
|
# This image uses a virtual environment, which is not necessary in a docker
|
||||||
|
# image and is more or less intented to check that the installation instructions
|
||||||
|
# for a local develoment are up-to-date
|
||||||
|
#
|
||||||
|
# Please consult the documentation for usage
|
||||||
|
#
|
||||||
|
# Note: you MUST build this image from the projec's root!
|
||||||
|
# docker build -f extras/docker/development/Dockerfile --tag wger/devel .
|
||||||
|
#
|
||||||
|
# Run the container:
|
||||||
|
# docker run -ti --publish 8000:8000 --name wger.devel wger/devel
|
||||||
|
# (in docker) source ~/venv/bin/activate
|
||||||
|
# (in docker) python manage.py download-exercise-images (optional, may take some time)
|
||||||
|
# (in docker) python manage.py runserver 0.0.0.0:8000
|
||||||
|
#
|
||||||
|
# Alternatively, you can bind the local checkout into the container:
|
||||||
|
# docker run -ti -v /path/to/this/checkout:/home/wger/src --name wger.devel --publish 8000:8000 wger/devel
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# To stop the container:
|
||||||
|
# sudo docker container stop wger.devel
|
||||||
|
#
|
||||||
|
# To start developing again
|
||||||
|
# sudo docker container start --attach wger.devel
|
||||||
|
#
|
||||||
|
|
||||||
|
##########
|
||||||
|
# Builder
|
||||||
|
##########
|
||||||
|
FROM ubuntu:20.04 as builder
|
||||||
|
|
||||||
|
RUN apt-get update \
|
||||||
|
&& apt-get install --no-install-recommends -y \
|
||||||
|
build-essential \
|
||||||
|
python3-dev \
|
||||||
|
python3-pip \
|
||||||
|
git \
|
||||||
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
|
# Set up the application
|
||||||
|
COPY . .
|
||||||
|
RUN pip3 install wheel \
|
||||||
|
&& pip3 wheel --no-cache-dir --wheel-dir /usr/src/app/wheels -r requirements_devel.txt
|
||||||
|
|
||||||
|
|
||||||
|
########
|
||||||
|
# Final
|
||||||
|
########
|
||||||
|
FROM wger/base:2.0-dev
|
||||||
|
LABEL maintainer="Roland Geider <roland@geider.net>"
|
||||||
|
ARG DOCKER_DIR=./extras/docker/development
|
||||||
|
EXPOSE 8000
|
||||||
|
|
||||||
|
# Set up the application
|
||||||
|
USER wger
|
||||||
|
COPY --chown=wger:wger . /home/wger/src
|
||||||
|
COPY --from=builder /usr/src/app/wheels /wheels
|
||||||
|
#RUN git clone https://github.com/wger-project/wger.git /home/wger/src
|
||||||
|
|
||||||
|
WORKDIR /home/wger/src
|
||||||
|
RUN python3 -m venv /home/wger/venv
|
||||||
|
RUN . /home/wger/venv/bin/activate \
|
||||||
|
&& pip install --upgrade pip \
|
||||||
|
&& pip install --no-cache /wheels/* \
|
||||||
|
&& python setup.py develop \
|
||||||
|
&& wger create-settings \
|
||||||
|
--settings-path /home/wger/src/settings.py \
|
||||||
|
--database-path /home/wger/db/database.sqlite \
|
||||||
|
&& wger bootstrap \
|
||||||
|
--settings-path /home/wger/src/settings.py \
|
||||||
|
--no-start-server
|
||||||
|
|
||||||
|
# Download the exercise images
|
||||||
|
RUN mkdir ~/media \
|
||||||
|
&& sed -i "/^MEDIA_ROOT/c\MEDIA_ROOT='\/home\/wger\/media'" settings.py
|
||||||
|
|
||||||
|
CMD ["/bin/bash"]
|
||||||
@@ -1,52 +1,60 @@
|
|||||||
#
|
#
|
||||||
# Docker image for wger development
|
# Docker image for wger development
|
||||||
#
|
#
|
||||||
# Please consult the documentation for usage
|
# Please consult the README for usage
|
||||||
# docker build -t wger/devel .
|
|
||||||
# docker run -ti --name wger.devel --publish 8000:8000 wger/devel
|
|
||||||
# (in docker) source ~/venv/bin/activate
|
|
||||||
# (in docker) python manage.py runserver 0.0.0.0:8000
|
|
||||||
#
|
#
|
||||||
|
# Note: you MUST build this image from the projec's root!
|
||||||
|
# docker build -f extras/docker/development/Dockerfile --tag wger/devel .
|
||||||
#
|
#
|
||||||
|
# Run the container:
|
||||||
|
# docker run -ti -v /path/to/this/checkout:/home/wger/src --name wger.devel --publish 8000:8000 wger/devel
|
||||||
|
|
||||||
|
##########
|
||||||
|
# Builder
|
||||||
|
##########
|
||||||
|
FROM ubuntu:20.04 as builder
|
||||||
|
|
||||||
|
RUN apt-get update \
|
||||||
|
&& apt-get install --no-install-recommends -y \
|
||||||
|
build-essential \
|
||||||
|
python3-dev \
|
||||||
|
python3-pip \
|
||||||
|
python3-wheel \
|
||||||
|
git \
|
||||||
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
|
# Build the necessary python wheels
|
||||||
|
COPY requirements* ./
|
||||||
|
RUN pip3 wheel --no-cache-dir --wheel-dir /wheels -r requirements_devel.txt
|
||||||
|
|
||||||
|
|
||||||
FROM wger/base
|
|
||||||
|
|
||||||
MAINTAINER Roland Geider <roland@geider.net>
|
########
|
||||||
|
# Final
|
||||||
|
########
|
||||||
|
FROM wger/base:2.0-dev
|
||||||
|
LABEL maintainer="Roland Geider <roland@geider.net>"
|
||||||
|
ARG DOCKER_DIR=./extras/docker/development
|
||||||
EXPOSE 8000
|
EXPOSE 8000
|
||||||
|
|
||||||
# Install dependencies
|
|
||||||
RUN apt-get install -y vim tmux sqlite3
|
|
||||||
|
|
||||||
# Set up the application
|
# Set up the application
|
||||||
USER wger
|
|
||||||
RUN git clone https://github.com/wger-project/wger.git /home/wger/src
|
|
||||||
|
|
||||||
WORKDIR /home/wger/src
|
WORKDIR /home/wger/src
|
||||||
RUN virtualenv --python python3 /home/wger/venv
|
COPY --chown=wger:wger . /home/wger/src
|
||||||
RUN . /home/wger/venv/bin/activate \
|
COPY --from=builder /wheels /wheels
|
||||||
&& pip install --upgrade pip \
|
COPY ${DOCKER_DIR}/settings.py /home/wger/src
|
||||||
&& pip install -r requirements_devel.txt \
|
COPY ${DOCKER_DIR}/settings.py /tmp/
|
||||||
&& invoke create_settings \
|
COPY ${DOCKER_DIR}/entrypoint.sh /home/wger/entrypoint.sh
|
||||||
--settings-path /home/wger/src/settings.py \
|
RUN chmod +x /home/wger/entrypoint.sh
|
||||||
--database-path /home/wger/db/database.sqlite \
|
RUN pip3 install --no-cache /wheels/* \
|
||||||
&& invoke bootstrap_wger \
|
&& pip3 install psycopg2-binary \
|
||||||
--settings-path /home/wger/src/settings.py \
|
&& pip3 install django-redis \
|
||||||
--no-start-server
|
&& python3 setup.py develop
|
||||||
|
|
||||||
# Install node modules for JS linting and download the exercise images
|
RUN chown -R wger:wger .
|
||||||
#
|
|
||||||
# Note: it seems there are problems with node and docker, so it's necessary
|
|
||||||
# to delete the node_modules folder and install everything again
|
|
||||||
# -> https://github.com/npm/npm/issues/9863
|
|
||||||
# -> https://github.com/npm/npm/issues/13306
|
|
||||||
RUN rm -r node_modules \
|
|
||||||
&& npm install bower \
|
|
||||||
&& npm install \
|
|
||||||
&& mkdir ~/media \
|
|
||||||
&& sed -i "/^MEDIA_ROOT/c\MEDIA_ROOT='\/home\/wger\/media'" settings.py \
|
|
||||||
&& . /home/wger/venv/bin/activate \
|
|
||||||
&& python manage.py download-exercise-images
|
|
||||||
|
|
||||||
|
USER wger
|
||||||
|
RUN mkdir ~/media \
|
||||||
|
&& mkdir ~/db/
|
||||||
|
|
||||||
CMD ["/bin/bash"]
|
CMD ["/home/wger/entrypoint.sh"]
|
||||||
|
|||||||
@@ -1,55 +1,82 @@
|
|||||||
Development image for wger - Ubuntu based
|
# Development image for wger
|
||||||
=========================================
|
|
||||||
Thank you for downloading wger Workout Manager. wger (ˈvɛɡɐ) is a free, open
|
Thank you for downloading wger Workout Manager. wger (ˈvɛɡɐ) is a free, open
|
||||||
source web application that manages your exercises and personal workouts, weight
|
source web application that manages your exercises and personal workouts, weight
|
||||||
and diet plans. It can also be used as a simple gym management utility, providing
|
and diet plans. It can also be used as a simple gym management utility, providing
|
||||||
different administrative roles (trainer, manager, etc.). It offers a REST API
|
different administrative roles (trainer, manager, etc.). It offers a REST API
|
||||||
as well, for easy integration with other projects and tools.
|
as well, for easy integration with other projects and tools.
|
||||||
|
|
||||||
It is written with python/django and uses jQuery and some D3js for charts.
|
|
||||||
|
|
||||||
Installation
|
## Usage
|
||||||
------------
|
|
||||||
|
|
||||||
This docker image contains an instance of the application running with django's
|
This docker image is meant to provide a quick development environment using
|
||||||
development server using a sqlite database. It can be used to quickly setup a
|
django's development server and an sqlite database from your current code
|
||||||
development instance (vim and tmux are already installed):
|
checkout (if you don't want or need a local checkout, use the wger/apache image,
|
||||||
|
it is self-contained)
|
||||||
|
|
||||||
```docker run -ti --name wger.devel --publish 8000:8000 wger/devel```
|
### 1 - Start the container
|
||||||
|
|
||||||
Then, *within the docker image*, activate the virtualenv
|
|
||||||
|
|
||||||
```source ~/venv/bin/activate```
|
docker run -ti \
|
||||||
|
-v /path/to/your/wger/checkout:/home/wger/src \
|
||||||
|
--name wger.devel \
|
||||||
|
--publish 8000:8000 wger/devel
|
||||||
|
|
||||||
and start the development server
|
When developing with windows, you might have problems with the `--volume` option,
|
||||||
|
use the more verbose mount instead:
|
||||||
|
|
||||||
```python manage.py runserver 0.0.0.0:8000```
|
--mount type=bind,source='"C:\your\path\to your\checkout"',target=/home/wger/src
|
||||||
|
|
||||||
Then just open http://localhost:8000 and log in as: **admin**, password **admin**
|
You might also want to download the exercise images (will take some time):
|
||||||
|
|
||||||
Contact
|
docker exec -ti wger.devel python3 manage.py download-exercise-images
|
||||||
-------
|
|
||||||
|
### 2 - Open the Application
|
||||||
|
|
||||||
|
Just open <http://localhost:8000> and log in as: **admin**, password **admin**
|
||||||
|
|
||||||
|
To stop the container:
|
||||||
|
|
||||||
|
```sudo docker container stop wger.devel```
|
||||||
|
|
||||||
|
To start developing again:
|
||||||
|
|
||||||
|
```sudo docker container start --attach wger.devel```
|
||||||
|
|
||||||
|
### 3 - Other commands
|
||||||
|
|
||||||
|
If you need to update the CSS/JS libraries or just issue some other command:
|
||||||
|
|
||||||
|
docker exec -ti wger.devel yarn
|
||||||
|
docker exec -ti wger.devel /bin/bash
|
||||||
|
|
||||||
|
## Building
|
||||||
|
|
||||||
|
If you build this yourself, keep in mind that you **must** build from the
|
||||||
|
project root!
|
||||||
|
|
||||||
|
```docker build -f extras/docker/development/Dockerfile --tag wger/devel .```
|
||||||
|
|
||||||
|
|
||||||
|
## Contact
|
||||||
|
|
||||||
Feel free to contact us if you found this useful or if there was something that
|
Feel free to contact us if you found this useful or if there was something that
|
||||||
didn't behave as you expected. We can't fix what we don't know about, so please
|
didn't behave as you expected. We can't fix what we don't know about, so please
|
||||||
report liberally. If you're not sure if something is a bug or not, feel free to
|
report liberally. If you're not sure if something is a bug or not, feel free to
|
||||||
file a bug anyway.
|
file a bug anyway.
|
||||||
|
|
||||||
* twitter: https://twitter.com/wger_de
|
* gitter: <https://gitter.im/wger-project/wger>
|
||||||
* mailing list: https://groups.google.com/group/wger / wger@googlegroups.com, no registration needed
|
* issue tracker: <https://github.com/wger-project/wger/issues>
|
||||||
* IRC: channel #wger on freenode.net, webchat: http://webchat.freenode.net/?channels=wger
|
* twitter: <https://twitter.com/wger_project>
|
||||||
* issue tracker: https://github.com/wger-project/wger/issues
|
* mailing list: <https://groups.google.com/group/wger> / wger@googlegroups.com, no registration needed
|
||||||
|
|
||||||
Sources
|
## Sources
|
||||||
-------
|
|
||||||
|
|
||||||
All the code and the content is freely available:
|
All the code and the content is freely available:
|
||||||
|
|
||||||
* Main repository: https://github.com/wger-project/wger
|
* Main repository: <https://github.com/wger-project/wger>
|
||||||
* Mirror: https://bitbucket.org/rolandgeider/wger
|
|
||||||
|
|
||||||
Licence
|
## Licence
|
||||||
-------
|
|
||||||
|
|
||||||
The application is licenced under the Affero GNU General Public License 3 or
|
The application is licenced under the Affero GNU General Public License 3 or
|
||||||
later (AGPL 3+).
|
later (AGPL 3+).
|
||||||
|
|||||||
31
extras/docker/development/entrypoint.sh
Normal file
31
extras/docker/development/entrypoint.sh
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Copy a settings file if nothing's found (e.g. when mounting a fresh checkout)
|
||||||
|
if [ ! -f /home/wger/src/settings.py ]; then
|
||||||
|
cp /tmp/settings.py /home/wger/src
|
||||||
|
fi
|
||||||
|
|
||||||
|
# If using docker compose, wait for postgres
|
||||||
|
if [[ "$DJANGO_DB_PORT" == "5432" ]]; then
|
||||||
|
echo "Waiting for postgres..."
|
||||||
|
|
||||||
|
while ! nc -z $DJANGO_DB_HOST $DJANGO_DB_PORT; do
|
||||||
|
sleep 0.1
|
||||||
|
done
|
||||||
|
|
||||||
|
echo "PostgreSQL started :)"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Bootstrap the application
|
||||||
|
wger bootstrap \
|
||||||
|
--settings-path /home/wger/src/settings.py \
|
||||||
|
--no-start-server
|
||||||
|
|
||||||
|
if [[ "$WGER_DOWNLOAD_IMGS" == "TRUE" ]];
|
||||||
|
then
|
||||||
|
wger download-exercise-images
|
||||||
|
chmod -R g+w ~wger/media
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Run the development server
|
||||||
|
python3 manage.py runserver 0.0.0.0:8000
|
||||||
79
extras/docker/development/settings.py
Normal file
79
extras/docker/development/settings.py
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
# wger
|
||||||
|
from wger.settings_global import *
|
||||||
|
|
||||||
|
|
||||||
|
# Use 'DEBUG = True' to get more details for server errors
|
||||||
|
DEBUG = True
|
||||||
|
TEMPLATES[0]['OPTIONS']['debug'] = True
|
||||||
|
|
||||||
|
ADMINS = (
|
||||||
|
('Your name', 'your_email@example.com'),
|
||||||
|
)
|
||||||
|
MANAGERS = ADMINS
|
||||||
|
|
||||||
|
if os.environ.get("DJANGO_DB_ENGINE"):
|
||||||
|
DATABASES = {
|
||||||
|
'default': {
|
||||||
|
'ENGINE': os.environ.get("DJANGO_DB_ENGINE"),
|
||||||
|
'NAME': os.environ.get("DJANGO_DB_DATABASE"),
|
||||||
|
'USER': os.environ.get("DJANGO_DB_USER"),
|
||||||
|
'PASSWORD': os.environ.get("DJANGO_DB_PASSWORD"),
|
||||||
|
'HOST': os.environ.get("DJANGO_DB_HOST"),
|
||||||
|
'PORT': os.environ.get("DJANGO_DB_PART"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else:
|
||||||
|
DATABASES = {
|
||||||
|
'default': {
|
||||||
|
'ENGINE': 'django.db.backends.sqlite3',
|
||||||
|
'NAME': '/home/wger/db/database.sqlite',
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Timezone for this installation. Consult settings_global.py for more information
|
||||||
|
TIME_ZONE = 'Europe/Berlin'
|
||||||
|
|
||||||
|
# Make this unique, and don't share it with anybody.
|
||||||
|
SECRET_KEY = '3^st!i-*a*iy!-4-^!rc8nv)-q34dg3u6f=bl%!h+!$xbznqj5'
|
||||||
|
|
||||||
|
# Your reCaptcha keys
|
||||||
|
RECAPTCHA_PUBLIC_KEY = ''
|
||||||
|
RECAPTCHA_PRIVATE_KEY = ''
|
||||||
|
NOCAPTCHA = True
|
||||||
|
|
||||||
|
# The site's URL (e.g. http://www.my-local-gym.com or http://localhost:8000)
|
||||||
|
# This is needed for uploaded files and images (exercise images, etc.) to be
|
||||||
|
# properly served.
|
||||||
|
SITE_URL = 'http://localhost:8000'
|
||||||
|
|
||||||
|
# Path to uploaded files
|
||||||
|
# Absolute filesystem path to the directory that will hold user-uploaded files.
|
||||||
|
MEDIA_ROOT = '/home/wger/media'
|
||||||
|
MEDIA_URL = '/media/'
|
||||||
|
|
||||||
|
# Allow all hosts to access the application. Change if used in production.
|
||||||
|
ALLOWED_HOSTS = '*'
|
||||||
|
|
||||||
|
SESSION_ENGINE = "django.contrib.sessions.backends.cache"
|
||||||
|
|
||||||
|
# Configure a real backend in production
|
||||||
|
if DEBUG:
|
||||||
|
EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'
|
||||||
|
|
||||||
|
# Sender address used for sent emails
|
||||||
|
WGER_SETTINGS['EMAIL_FROM'] = 'wger Workout Manager <wger@example.com>'
|
||||||
|
|
||||||
|
if os.environ.get("DJANGO_CACHE_BACKEND"):
|
||||||
|
CACHES = {
|
||||||
|
'default': {
|
||||||
|
'BACKEND': os.environ.get("DJANGO_CACHE_BACKEND"),
|
||||||
|
'LOCATION': os.environ.get("DJANGO_CACHE_LOCATION"),
|
||||||
|
'TIMEOUT': os.environ.get("DJANGO_CACHE_TIMEOUT"),
|
||||||
|
'OPTIONS': {
|
||||||
|
'CLIENT_CLASS': os.environ.get("DJANGO_CACHE_CLIENT_CLASS"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
1
extras/dummy_generator/csv/first_names_usa.README
Normal file
1
extras/dummy_generator/csv/first_names_usa.README
Normal file
@@ -0,0 +1 @@
|
|||||||
|
https://www.ssa.gov/oact/babynames/decades/names2010s.html
|
||||||
400
extras/dummy_generator/csv/first_names_usa.csv
Normal file
400
extras/dummy_generator/csv/first_names_usa.csv
Normal file
@@ -0,0 +1,400 @@
|
|||||||
|
"Jacob","m"
|
||||||
|
"Noah","m"
|
||||||
|
"Mason","m"
|
||||||
|
"William","m"
|
||||||
|
"Ethan","m"
|
||||||
|
"Liam","m"
|
||||||
|
"Michael","m"
|
||||||
|
"Alexander","m"
|
||||||
|
"Jayden","m"
|
||||||
|
"Daniel","m"
|
||||||
|
"Aiden","m"
|
||||||
|
"James","m"
|
||||||
|
"Elijah","m"
|
||||||
|
"Matthew","m"
|
||||||
|
"Benjamin","m"
|
||||||
|
"Logan","m"
|
||||||
|
"Anthony","m"
|
||||||
|
"David","m"
|
||||||
|
"Joseph","m"
|
||||||
|
"Joshua","m"
|
||||||
|
"Jackson","m"
|
||||||
|
"Andrew","m"
|
||||||
|
"Christopher","m"
|
||||||
|
"Gabriel","m"
|
||||||
|
"Samuel","m"
|
||||||
|
"Lucas","m"
|
||||||
|
"John","m"
|
||||||
|
"Ryan","m"
|
||||||
|
"Dylan","m"
|
||||||
|
"Nathan","m"
|
||||||
|
"Isaac","m"
|
||||||
|
"Caleb","m"
|
||||||
|
"Carter","m"
|
||||||
|
"Christian","m"
|
||||||
|
"Luke","m"
|
||||||
|
"Jonathan","m"
|
||||||
|
"Landon","m"
|
||||||
|
"Owen","m"
|
||||||
|
"Jack","m"
|
||||||
|
"Wyatt","m"
|
||||||
|
"Henry","m"
|
||||||
|
"Hunter","m"
|
||||||
|
"Isaiah","m"
|
||||||
|
"Brayden","m"
|
||||||
|
"Gavin","m"
|
||||||
|
"Nicholas","m"
|
||||||
|
"Sebastian","m"
|
||||||
|
"Evan","m"
|
||||||
|
"Julian","m"
|
||||||
|
"Tyler","m"
|
||||||
|
"Aaron","m"
|
||||||
|
"Jordan","m"
|
||||||
|
"Eli","m"
|
||||||
|
"Oliver","m"
|
||||||
|
"Levi","m"
|
||||||
|
"Connor","m"
|
||||||
|
"Jeremiah","m"
|
||||||
|
"Cameron","m"
|
||||||
|
"Charles","m"
|
||||||
|
"Angel","m"
|
||||||
|
"Thomas","m"
|
||||||
|
"Adrian","m"
|
||||||
|
"Robert","m"
|
||||||
|
"Brandon","m"
|
||||||
|
"Austin","m"
|
||||||
|
"Jaxon","m"
|
||||||
|
"Kevin","m"
|
||||||
|
"Jose","m"
|
||||||
|
"Colton","m"
|
||||||
|
"Zachary","m"
|
||||||
|
"Josiah","m"
|
||||||
|
"Dominic","m"
|
||||||
|
"Chase","m"
|
||||||
|
"Ayden","m"
|
||||||
|
"Jason","m"
|
||||||
|
"Justin","m"
|
||||||
|
"Ian","m"
|
||||||
|
"Parker","m"
|
||||||
|
"Grayson","m"
|
||||||
|
"Adam","m"
|
||||||
|
"Blake","m"
|
||||||
|
"Xavier","m"
|
||||||
|
"Cooper","m"
|
||||||
|
"Bentley","m"
|
||||||
|
"Jace","m"
|
||||||
|
"Carson","m"
|
||||||
|
"Nolan","m"
|
||||||
|
"Nathaniel","m"
|
||||||
|
"Brody","m"
|
||||||
|
"Hudson","m"
|
||||||
|
"Tristan","m"
|
||||||
|
"Luis","m"
|
||||||
|
"Juan","m"
|
||||||
|
"Easton","m"
|
||||||
|
"Kayden","m"
|
||||||
|
"Carlos","m"
|
||||||
|
"Jaxson","m"
|
||||||
|
"Asher","m"
|
||||||
|
"Cole","m"
|
||||||
|
"Jesus","m"
|
||||||
|
"Ryder","m"
|
||||||
|
"Vincent","m"
|
||||||
|
"Alex","m"
|
||||||
|
"Micah","m"
|
||||||
|
"Max","m"
|
||||||
|
"Lincoln","m"
|
||||||
|
"Bryson","m"
|
||||||
|
"Damian","m"
|
||||||
|
"Diego","m"
|
||||||
|
"Eric","m"
|
||||||
|
"Hayden","m"
|
||||||
|
"Elias","m"
|
||||||
|
"Miles","m"
|
||||||
|
"Maxwell","m"
|
||||||
|
"Bryce","m"
|
||||||
|
"Giovanni","m"
|
||||||
|
"Leo","m"
|
||||||
|
"Mateo","m"
|
||||||
|
"Santiago","m"
|
||||||
|
"Camden","m"
|
||||||
|
"Bryan","m"
|
||||||
|
"Timothy","m"
|
||||||
|
"Antonio","m"
|
||||||
|
"Aidan","m"
|
||||||
|
"Jaden","m"
|
||||||
|
"Steven","m"
|
||||||
|
"Sawyer","m"
|
||||||
|
"Colin","m"
|
||||||
|
"Leonardo","m"
|
||||||
|
"Ivan","m"
|
||||||
|
"Ashton","m"
|
||||||
|
"Kaleb","m"
|
||||||
|
"Miguel","m"
|
||||||
|
"Richard","m"
|
||||||
|
"Braxton","m"
|
||||||
|
"Jonah","m"
|
||||||
|
"Kaden","m"
|
||||||
|
"Roman","m"
|
||||||
|
"Brian","m"
|
||||||
|
"Kyle","m"
|
||||||
|
"Riley","m"
|
||||||
|
"Alejandro","m"
|
||||||
|
"Victor","m"
|
||||||
|
"Preston","m"
|
||||||
|
"Joel","m"
|
||||||
|
"Kaiden","m"
|
||||||
|
"Wesley","m"
|
||||||
|
"Patrick","m"
|
||||||
|
"Jesse","m"
|
||||||
|
"Marcus","m"
|
||||||
|
"Declan","m"
|
||||||
|
"Edward","m"
|
||||||
|
"Axel","m"
|
||||||
|
"Sean","m"
|
||||||
|
"Ezra","m"
|
||||||
|
"Jake","m"
|
||||||
|
"Silas","m"
|
||||||
|
"George","m"
|
||||||
|
"Jeremy","m"
|
||||||
|
"Brady","m"
|
||||||
|
"Caden","m"
|
||||||
|
"Emmanuel","m"
|
||||||
|
"Jude","m"
|
||||||
|
"Grant","m"
|
||||||
|
"Alan","m"
|
||||||
|
"Greyson","m"
|
||||||
|
"Theodore","m"
|
||||||
|
"Harrison","m"
|
||||||
|
"Maddox","m"
|
||||||
|
"Weston","m"
|
||||||
|
"Malachi","m"
|
||||||
|
"Oscar","m"
|
||||||
|
"Cayden","m"
|
||||||
|
"Brantley","m"
|
||||||
|
"Bradley","m"
|
||||||
|
"Mark","m"
|
||||||
|
"Kenneth","m"
|
||||||
|
"Jayce","m"
|
||||||
|
"Nicolas","m"
|
||||||
|
"Emmett","m"
|
||||||
|
"Gage","m"
|
||||||
|
"Abraham","m"
|
||||||
|
"Ezekiel","m"
|
||||||
|
"Kai","m"
|
||||||
|
"Kingston","m"
|
||||||
|
"Abel","m"
|
||||||
|
"Jase","m"
|
||||||
|
"Tucker","m"
|
||||||
|
"Jameson","m"
|
||||||
|
"Devin","m"
|
||||||
|
"Paul","m"
|
||||||
|
"Derek","m"
|
||||||
|
"Rylan","m"
|
||||||
|
"Calvin","m"
|
||||||
|
"Peyton","m"
|
||||||
|
"Tanner","m"
|
||||||
|
"Avery","m"
|
||||||
|
"Everett","m"
|
||||||
|
"Bennett","m"
|
||||||
|
"Ryker","m"
|
||||||
|
"Sophia","f"
|
||||||
|
"Emma","f"
|
||||||
|
"Isabella","f"
|
||||||
|
"Olivia","f"
|
||||||
|
"Ava","f"
|
||||||
|
"Emily","f"
|
||||||
|
"Abigail","f"
|
||||||
|
"Mia","f"
|
||||||
|
"Madison","f"
|
||||||
|
"Elizabeth","f"
|
||||||
|
"Chloe","f"
|
||||||
|
"Ella","f"
|
||||||
|
"Avery","f"
|
||||||
|
"Charlotte","f"
|
||||||
|
"Sofia","f"
|
||||||
|
"Addison","f"
|
||||||
|
"Natalie","f"
|
||||||
|
"Amelia","f"
|
||||||
|
"Grace","f"
|
||||||
|
"Evelyn","f"
|
||||||
|
"Lily","f"
|
||||||
|
"Aubrey","f"
|
||||||
|
"Victoria","f"
|
||||||
|
"Harper","f"
|
||||||
|
"Lillian","f"
|
||||||
|
"Hannah","f"
|
||||||
|
"Zoey","f"
|
||||||
|
"Samantha","f"
|
||||||
|
"Brooklyn","f"
|
||||||
|
"Layla","f"
|
||||||
|
"Zoe","f"
|
||||||
|
"Leah","f"
|
||||||
|
"Anna","f"
|
||||||
|
"Hailey","f"
|
||||||
|
"Allison","f"
|
||||||
|
"Gabriella","f"
|
||||||
|
"Alexis","f"
|
||||||
|
"Audrey","f"
|
||||||
|
"Savannah","f"
|
||||||
|
"Kaylee","f"
|
||||||
|
"Sarah","f"
|
||||||
|
"Riley","f"
|
||||||
|
"Nevaeh","f"
|
||||||
|
"Aaliyah","f"
|
||||||
|
"Camila","f"
|
||||||
|
"Alyssa","f"
|
||||||
|
"Claire","f"
|
||||||
|
"Arianna","f"
|
||||||
|
"Scarlett","f"
|
||||||
|
"Alexa","f"
|
||||||
|
"Taylor","f"
|
||||||
|
"Ashley","f"
|
||||||
|
"Brianna","f"
|
||||||
|
"Peyton","f"
|
||||||
|
"Bella","f"
|
||||||
|
"Ariana","f"
|
||||||
|
"Kylie","f"
|
||||||
|
"Khloe","f"
|
||||||
|
"Serenity","f"
|
||||||
|
"Stella","f"
|
||||||
|
"Lucy","f"
|
||||||
|
"Maya","f"
|
||||||
|
"Sophie","f"
|
||||||
|
"Madelyn","f"
|
||||||
|
"Genesis","f"
|
||||||
|
"Julia","f"
|
||||||
|
"Aria","f"
|
||||||
|
"Mackenzie","f"
|
||||||
|
"Autumn","f"
|
||||||
|
"Katherine","f"
|
||||||
|
"Caroline","f"
|
||||||
|
"Ellie","f"
|
||||||
|
"Kennedy","f"
|
||||||
|
"Kayla","f"
|
||||||
|
"Sadie","f"
|
||||||
|
"Makayla","f"
|
||||||
|
"Violet","f"
|
||||||
|
"Lauren","f"
|
||||||
|
"Faith","f"
|
||||||
|
"Gianna","f"
|
||||||
|
"Penelope","f"
|
||||||
|
"Skylar","f"
|
||||||
|
"Eva","f"
|
||||||
|
"Alexandra","f"
|
||||||
|
"Melanie","f"
|
||||||
|
"Aubree","f"
|
||||||
|
"Nora","f"
|
||||||
|
"Naomi","f"
|
||||||
|
"Sydney","f"
|
||||||
|
"Madeline","f"
|
||||||
|
"Jasmine","f"
|
||||||
|
"Morgan","f"
|
||||||
|
"Kimberly","f"
|
||||||
|
"Annabelle","f"
|
||||||
|
"Lydia","f"
|
||||||
|
"Jocelyn","f"
|
||||||
|
"Piper","f"
|
||||||
|
"Bailey","f"
|
||||||
|
"Paisley","f"
|
||||||
|
"London","f"
|
||||||
|
"Trinity","f"
|
||||||
|
"Ruby","f"
|
||||||
|
"Andrea","f"
|
||||||
|
"Molly","f"
|
||||||
|
"Maria","f"
|
||||||
|
"Mila","f"
|
||||||
|
"Eleanor","f"
|
||||||
|
"Brooke","f"
|
||||||
|
"Reagan","f"
|
||||||
|
"Isabelle","f"
|
||||||
|
"Rylee","f"
|
||||||
|
"Payton","f"
|
||||||
|
"Natalia","f"
|
||||||
|
"Mariah","f"
|
||||||
|
"Mary","f"
|
||||||
|
"Paige","f"
|
||||||
|
"Lilly","f"
|
||||||
|
"Alice","f"
|
||||||
|
"Nicole","f"
|
||||||
|
"Destiny","f"
|
||||||
|
"Mya","f"
|
||||||
|
"Jade","f"
|
||||||
|
"Liliana","f"
|
||||||
|
"Jordyn","f"
|
||||||
|
"Vivian","f"
|
||||||
|
"Kaitlyn","f"
|
||||||
|
"Brielle","f"
|
||||||
|
"Kendall","f"
|
||||||
|
"Clara","f"
|
||||||
|
"Angelina","f"
|
||||||
|
"Hadley","f"
|
||||||
|
"Eliana","f"
|
||||||
|
"Rachel","f"
|
||||||
|
"Isabel","f"
|
||||||
|
"Valentina","f"
|
||||||
|
"Elena","f"
|
||||||
|
"Gabrielle","f"
|
||||||
|
"Vanessa","f"
|
||||||
|
"Cora","f"
|
||||||
|
"Hazel","f"
|
||||||
|
"Katelyn","f"
|
||||||
|
"Lyla","f"
|
||||||
|
"Aurora","f"
|
||||||
|
"Valeria","f"
|
||||||
|
"Jessica","f"
|
||||||
|
"Quinn","f"
|
||||||
|
"Sara","f"
|
||||||
|
"Amy","f"
|
||||||
|
"Delilah","f"
|
||||||
|
"Mckenzie","f"
|
||||||
|
"Brooklynn","f"
|
||||||
|
"Reese","f"
|
||||||
|
"Laila","f"
|
||||||
|
"Aliyah","f"
|
||||||
|
"Adriana","f"
|
||||||
|
"Gracie","f"
|
||||||
|
"Juliana","f"
|
||||||
|
"Josephine","f"
|
||||||
|
"Michelle","f"
|
||||||
|
"Willow","f"
|
||||||
|
"Rebecca","f"
|
||||||
|
"Eden","f"
|
||||||
|
"Makenzie","f"
|
||||||
|
"Ariel","f"
|
||||||
|
"Valerie","f"
|
||||||
|
"Elise","f"
|
||||||
|
"Kinsley","f"
|
||||||
|
"Stephanie","f"
|
||||||
|
"Kylee","f"
|
||||||
|
"Jennifer","f"
|
||||||
|
"Izabella","f"
|
||||||
|
"Jayla","f"
|
||||||
|
"Catherine","f"
|
||||||
|
"Ximena","f"
|
||||||
|
"Melody","f"
|
||||||
|
"Margaret","f"
|
||||||
|
"Ivy","f"
|
||||||
|
"Daisy","f"
|
||||||
|
"Alaina","f"
|
||||||
|
"Lila","f"
|
||||||
|
"Adalyn","f"
|
||||||
|
"Summer","f"
|
||||||
|
"Giselle","f"
|
||||||
|
"Luna","f"
|
||||||
|
"Julianna","f"
|
||||||
|
"Alana","f"
|
||||||
|
"Londyn","f"
|
||||||
|
"Hayden","f"
|
||||||
|
"Ryleigh","f"
|
||||||
|
"Daniela","f"
|
||||||
|
"Angela","f"
|
||||||
|
"Isla","f"
|
||||||
|
"Alivia","f"
|
||||||
|
"Adalynn","f"
|
||||||
|
"Emery","f"
|
||||||
|
"Melissa","f"
|
||||||
|
"Kate","f"
|
||||||
|
"Gabriela","f"
|
||||||
|
"Keira","f"
|
||||||
|
"Norah","f"
|
||||||
|
1
extras/dummy_generator/csv/last_names_usa.README
Normal file
1
extras/dummy_generator/csv/last_names_usa.README
Normal file
@@ -0,0 +1 @@
|
|||||||
|
https://www.census.gov/topics/population/genealogy/data/2010_surnames.html
|
||||||
500
extras/dummy_generator/csv/last_names_usa.csv
Normal file
500
extras/dummy_generator/csv/last_names_usa.csv
Normal file
@@ -0,0 +1,500 @@
|
|||||||
|
Smith
|
||||||
|
Johnson
|
||||||
|
Williams
|
||||||
|
Brown
|
||||||
|
Jones
|
||||||
|
Garcia
|
||||||
|
Miller
|
||||||
|
Davis
|
||||||
|
Rodriguez
|
||||||
|
Martinez
|
||||||
|
Hernandez
|
||||||
|
Lopez
|
||||||
|
Gonzalez
|
||||||
|
Wilson
|
||||||
|
Anderson
|
||||||
|
Thomas
|
||||||
|
Taylor
|
||||||
|
Moore
|
||||||
|
Jackson
|
||||||
|
Martin
|
||||||
|
Lee
|
||||||
|
Perez
|
||||||
|
Thompson
|
||||||
|
White
|
||||||
|
Harris
|
||||||
|
Sanchez
|
||||||
|
Clark
|
||||||
|
Ramirez
|
||||||
|
Lewis
|
||||||
|
Robinson
|
||||||
|
Walker
|
||||||
|
Young
|
||||||
|
Allen
|
||||||
|
King
|
||||||
|
Wright
|
||||||
|
Scott
|
||||||
|
Torres
|
||||||
|
Nguyen
|
||||||
|
Hill
|
||||||
|
Flores
|
||||||
|
Green
|
||||||
|
Adams
|
||||||
|
Nelson
|
||||||
|
Baker
|
||||||
|
Hall
|
||||||
|
Rivera
|
||||||
|
Campbell
|
||||||
|
Mitchell
|
||||||
|
Carter
|
||||||
|
Roberts
|
||||||
|
Gomez
|
||||||
|
Phillips
|
||||||
|
Evans
|
||||||
|
Turner
|
||||||
|
Diaz
|
||||||
|
Parker
|
||||||
|
Cruz
|
||||||
|
Edwards
|
||||||
|
Collins
|
||||||
|
Reyes
|
||||||
|
Stewart
|
||||||
|
Morris
|
||||||
|
Morales
|
||||||
|
Murphy
|
||||||
|
Cook
|
||||||
|
Rogers
|
||||||
|
Gutierrez
|
||||||
|
Ortiz
|
||||||
|
Morgan
|
||||||
|
Cooper
|
||||||
|
Peterson
|
||||||
|
Bailey
|
||||||
|
Reed
|
||||||
|
Kelly
|
||||||
|
Howard
|
||||||
|
Ramos
|
||||||
|
Kim
|
||||||
|
Cox
|
||||||
|
Ward
|
||||||
|
Richardson
|
||||||
|
Watson
|
||||||
|
Brooks
|
||||||
|
Chavez
|
||||||
|
Wood
|
||||||
|
James
|
||||||
|
Bennett
|
||||||
|
Gray
|
||||||
|
Mendoza
|
||||||
|
Ruiz
|
||||||
|
Hughes
|
||||||
|
Price
|
||||||
|
Alvarez
|
||||||
|
Castillo
|
||||||
|
Sanders
|
||||||
|
Patel
|
||||||
|
Myers
|
||||||
|
Long
|
||||||
|
Ross
|
||||||
|
Foster
|
||||||
|
Jimenez
|
||||||
|
Powell
|
||||||
|
Jenkins
|
||||||
|
Perry
|
||||||
|
Russell
|
||||||
|
Sullivan
|
||||||
|
Bell
|
||||||
|
Coleman
|
||||||
|
Butler
|
||||||
|
Henderson
|
||||||
|
Barnes
|
||||||
|
Gonzales
|
||||||
|
Fisher
|
||||||
|
Vasquez
|
||||||
|
Simmons
|
||||||
|
Romero
|
||||||
|
Jordan
|
||||||
|
Patterson
|
||||||
|
Alexander
|
||||||
|
Hamilton
|
||||||
|
Graham
|
||||||
|
Reynolds
|
||||||
|
Griffin
|
||||||
|
Wallace
|
||||||
|
Moreno
|
||||||
|
West
|
||||||
|
Cole
|
||||||
|
Hayes
|
||||||
|
Bryant
|
||||||
|
Herrera
|
||||||
|
Gibson
|
||||||
|
Ellis
|
||||||
|
Tran
|
||||||
|
Medina
|
||||||
|
Aguilar
|
||||||
|
Stevens
|
||||||
|
Murray
|
||||||
|
Ford
|
||||||
|
Castro
|
||||||
|
Marshall
|
||||||
|
Owens
|
||||||
|
Harrison
|
||||||
|
Fernandez
|
||||||
|
Mcdonald
|
||||||
|
Woods
|
||||||
|
Washington
|
||||||
|
Kennedy
|
||||||
|
Wells
|
||||||
|
Vargas
|
||||||
|
Henry
|
||||||
|
Chen
|
||||||
|
Freeman
|
||||||
|
Webb
|
||||||
|
Tucker
|
||||||
|
Guzman
|
||||||
|
Burns
|
||||||
|
Crawford
|
||||||
|
Olson
|
||||||
|
Simpson
|
||||||
|
Porter
|
||||||
|
Hunter
|
||||||
|
Gordon
|
||||||
|
Mendez
|
||||||
|
Silva
|
||||||
|
Shaw
|
||||||
|
Snyder
|
||||||
|
Mason
|
||||||
|
Dixon
|
||||||
|
Munoz
|
||||||
|
Hunt
|
||||||
|
Hicks
|
||||||
|
Holmes
|
||||||
|
Palmer
|
||||||
|
Wagner
|
||||||
|
Black
|
||||||
|
Robertson
|
||||||
|
Boyd
|
||||||
|
Rose
|
||||||
|
Stone
|
||||||
|
Salazar
|
||||||
|
Fox
|
||||||
|
Warren
|
||||||
|
Mills
|
||||||
|
Meyer
|
||||||
|
Rice
|
||||||
|
Schmidt
|
||||||
|
Garza
|
||||||
|
Daniels
|
||||||
|
Ferguson
|
||||||
|
Nichols
|
||||||
|
Stephens
|
||||||
|
Soto
|
||||||
|
Weaver
|
||||||
|
Ryan
|
||||||
|
Gardner
|
||||||
|
Payne
|
||||||
|
Grant
|
||||||
|
Dunn
|
||||||
|
Kelley
|
||||||
|
Spencer
|
||||||
|
Hawkins
|
||||||
|
Arnold
|
||||||
|
Pierce
|
||||||
|
Vazquez
|
||||||
|
Hansen
|
||||||
|
Peters
|
||||||
|
Santos
|
||||||
|
Hart
|
||||||
|
Bradley
|
||||||
|
Knight
|
||||||
|
Elliott
|
||||||
|
Cunningham
|
||||||
|
Duncan
|
||||||
|
Armstrong
|
||||||
|
Hudson
|
||||||
|
Carroll
|
||||||
|
Lane
|
||||||
|
Riley
|
||||||
|
Andrews
|
||||||
|
Alvarado
|
||||||
|
Ray
|
||||||
|
Delgado
|
||||||
|
Berry
|
||||||
|
Perkins
|
||||||
|
Hoffman
|
||||||
|
Johnston
|
||||||
|
Matthews
|
||||||
|
Pena
|
||||||
|
Richards
|
||||||
|
Contreras
|
||||||
|
Willis
|
||||||
|
Carpenter
|
||||||
|
Lawrence
|
||||||
|
Sandoval
|
||||||
|
Guerrero
|
||||||
|
George
|
||||||
|
Chapman
|
||||||
|
Rios
|
||||||
|
Estrada
|
||||||
|
Ortega
|
||||||
|
Watkins
|
||||||
|
Greene
|
||||||
|
Nunez
|
||||||
|
Wheeler
|
||||||
|
Valdez
|
||||||
|
Harper
|
||||||
|
Burke
|
||||||
|
Larson
|
||||||
|
Santiago
|
||||||
|
Maldonado
|
||||||
|
Morrison
|
||||||
|
Franklin
|
||||||
|
Carlson
|
||||||
|
Austin
|
||||||
|
Dominguez
|
||||||
|
Carr
|
||||||
|
Lawson
|
||||||
|
Jacobs
|
||||||
|
Obrien
|
||||||
|
Lynch
|
||||||
|
Singh
|
||||||
|
Vega
|
||||||
|
Bishop
|
||||||
|
Montgomery
|
||||||
|
Oliver
|
||||||
|
Jensen
|
||||||
|
Harvey
|
||||||
|
Williamson
|
||||||
|
Gilbert
|
||||||
|
Dean
|
||||||
|
Sims
|
||||||
|
Espinoza
|
||||||
|
Howell
|
||||||
|
Li
|
||||||
|
Wong
|
||||||
|
Reid
|
||||||
|
Hanson
|
||||||
|
Le
|
||||||
|
Mccoy
|
||||||
|
Garrett
|
||||||
|
Burton
|
||||||
|
Fuller
|
||||||
|
Wang
|
||||||
|
Weber
|
||||||
|
Welch
|
||||||
|
Rojas
|
||||||
|
Lucas
|
||||||
|
Marquez
|
||||||
|
Fields
|
||||||
|
Park
|
||||||
|
Yang
|
||||||
|
Little
|
||||||
|
Banks
|
||||||
|
Padilla
|
||||||
|
Day
|
||||||
|
Walsh
|
||||||
|
Bowman
|
||||||
|
Schultz
|
||||||
|
Luna
|
||||||
|
Fowler
|
||||||
|
Mejia
|
||||||
|
Davidson
|
||||||
|
Acosta
|
||||||
|
Brewer
|
||||||
|
May
|
||||||
|
Holland
|
||||||
|
Juarez
|
||||||
|
Newman
|
||||||
|
Pearson
|
||||||
|
Curtis
|
||||||
|
Cortez
|
||||||
|
Douglas
|
||||||
|
Schneider
|
||||||
|
Joseph
|
||||||
|
Barrett
|
||||||
|
Navarro
|
||||||
|
Figueroa
|
||||||
|
Keller
|
||||||
|
Avila
|
||||||
|
Wade
|
||||||
|
Molina
|
||||||
|
Stanley
|
||||||
|
Hopkins
|
||||||
|
Campos
|
||||||
|
Barnett
|
||||||
|
Bates
|
||||||
|
Chambers
|
||||||
|
Caldwell
|
||||||
|
Beck
|
||||||
|
Lambert
|
||||||
|
Miranda
|
||||||
|
Byrd
|
||||||
|
Craig
|
||||||
|
Ayala
|
||||||
|
Lowe
|
||||||
|
Frazier
|
||||||
|
Powers
|
||||||
|
Neal
|
||||||
|
Leonard
|
||||||
|
Gregory
|
||||||
|
Carrillo
|
||||||
|
Sutton
|
||||||
|
Fleming
|
||||||
|
Rhodes
|
||||||
|
Shelton
|
||||||
|
Schwartz
|
||||||
|
Norris
|
||||||
|
Jennings
|
||||||
|
Watts
|
||||||
|
Duran
|
||||||
|
Walters
|
||||||
|
Cohen
|
||||||
|
Mcdaniel
|
||||||
|
Moran
|
||||||
|
Parks
|
||||||
|
Steele
|
||||||
|
Vaughn
|
||||||
|
Becker
|
||||||
|
Holt
|
||||||
|
Deleon
|
||||||
|
Barker
|
||||||
|
Terry
|
||||||
|
Hale
|
||||||
|
Leon
|
||||||
|
Hail
|
||||||
|
Benson
|
||||||
|
Haynes
|
||||||
|
Horton
|
||||||
|
Miles
|
||||||
|
Lyons
|
||||||
|
Pham
|
||||||
|
Graves
|
||||||
|
Bush
|
||||||
|
Thornton
|
||||||
|
Wolfe
|
||||||
|
Warner
|
||||||
|
Cabrera
|
||||||
|
Mckinney
|
||||||
|
Mann
|
||||||
|
Zimmerman
|
||||||
|
Dawson
|
||||||
|
Lara
|
||||||
|
Fletcher
|
||||||
|
Page
|
||||||
|
Mccarthy
|
||||||
|
Love
|
||||||
|
Robles
|
||||||
|
Cervantes
|
||||||
|
Solis
|
||||||
|
Erickson
|
||||||
|
Reeves
|
||||||
|
Chang
|
||||||
|
Klein
|
||||||
|
Salinas
|
||||||
|
Fuentes
|
||||||
|
Baldwin
|
||||||
|
Daniel
|
||||||
|
Simon
|
||||||
|
Velasquez
|
||||||
|
Hardy
|
||||||
|
Higgins
|
||||||
|
Aguirre
|
||||||
|
Lin
|
||||||
|
Cummings
|
||||||
|
Chandler
|
||||||
|
Sharp
|
||||||
|
Barber
|
||||||
|
Bowen
|
||||||
|
Ochoa
|
||||||
|
Dennis
|
||||||
|
Robbins
|
||||||
|
Liu
|
||||||
|
Ramsey
|
||||||
|
Francis
|
||||||
|
Griffith
|
||||||
|
Paul
|
||||||
|
Blair
|
||||||
|
Oconnor
|
||||||
|
Cardenas
|
||||||
|
Pacheco
|
||||||
|
Cross
|
||||||
|
Calderon
|
||||||
|
Quinn
|
||||||
|
Moss
|
||||||
|
Swanson
|
||||||
|
Chan
|
||||||
|
Rivas
|
||||||
|
Khan
|
||||||
|
Rodgers
|
||||||
|
Serrano
|
||||||
|
Fitzgerald
|
||||||
|
Rosales
|
||||||
|
Stevenson
|
||||||
|
Christensen
|
||||||
|
Manning
|
||||||
|
Gill
|
||||||
|
Curry
|
||||||
|
Mclaughlin
|
||||||
|
Harmon
|
||||||
|
Mcgee
|
||||||
|
Gross
|
||||||
|
Doyle
|
||||||
|
Garner
|
||||||
|
Newton
|
||||||
|
Burgess
|
||||||
|
Reese
|
||||||
|
Walton
|
||||||
|
Blake
|
||||||
|
Trujillo
|
||||||
|
Adkins
|
||||||
|
Brady
|
||||||
|
Goodman
|
||||||
|
Roman
|
||||||
|
Webster
|
||||||
|
Goodwin
|
||||||
|
Fischer
|
||||||
|
Huang
|
||||||
|
Potter
|
||||||
|
Delacruz
|
||||||
|
Montoya
|
||||||
|
Todd
|
||||||
|
Wu
|
||||||
|
Hines
|
||||||
|
Mullins
|
||||||
|
Castaneda
|
||||||
|
Malone
|
||||||
|
Cannon
|
||||||
|
Tate
|
||||||
|
Mack
|
||||||
|
Sherman
|
||||||
|
Hubbard
|
||||||
|
Hodges
|
||||||
|
Zhang
|
||||||
|
Guerra
|
||||||
|
Wolf
|
||||||
|
Valencia
|
||||||
|
Saunders
|
||||||
|
Franco
|
||||||
|
Rowe
|
||||||
|
Gallagher
|
||||||
|
Farmer
|
||||||
|
Hammond
|
||||||
|
Hampton
|
||||||
|
Townsend
|
||||||
|
Ingram
|
||||||
|
Wise
|
||||||
|
Gallegos
|
||||||
|
Clarke
|
||||||
|
Barton
|
||||||
|
Schroeder
|
||||||
|
Maxwell
|
||||||
|
Waters
|
||||||
|
Logan
|
||||||
|
Camacho
|
||||||
|
Strickland
|
||||||
|
Norman
|
||||||
|
Person
|
||||||
|
Colon
|
||||||
|
Parsons
|
||||||
|
Frank
|
||||||
|
Harrington
|
||||||
|
@@ -1,4 +1,5 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
# flake8: noqa
|
||||||
|
|
||||||
# This file is part of wger Workout Manager.
|
# This file is part of wger Workout Manager.
|
||||||
#
|
#
|
||||||
@@ -80,7 +81,7 @@ user_parser.add_argument('--country',
|
|||||||
action='store',
|
action='store',
|
||||||
default='germany',
|
default='germany',
|
||||||
help='What country the generated users should belong to. Default: Germany',
|
help='What country the generated users should belong to. Default: Germany',
|
||||||
choices=['germany', 'ukraine', 'spain'])
|
choices=['germany', 'ukraine', 'spain', 'usa'])
|
||||||
|
|
||||||
# Workout options
|
# Workout options
|
||||||
workouts_parser = subparsers.add_parser('workouts', help='Create workouts')
|
workouts_parser = subparsers.add_parser('workouts', help='Create workouts')
|
||||||
@@ -452,7 +453,7 @@ if hasattr(args, 'number_nutrition_plans'):
|
|||||||
|
|
||||||
# Total meals per plan
|
# Total meals per plan
|
||||||
total_meals = 4
|
total_meals = 4
|
||||||
|
|
||||||
for user in userlist:
|
for user in userlist:
|
||||||
print(' - generating for {0}'.format(user.username))
|
print(' - generating for {0}'.format(user.username))
|
||||||
|
|
||||||
|
|||||||
@@ -14,24 +14,26 @@
|
|||||||
#
|
#
|
||||||
# You should have received a copy of the GNU Affero General Public License
|
# You should have received a copy of the GNU Affero General Public License
|
||||||
|
|
||||||
'''
|
"""
|
||||||
Simple script that filters the output of django's dumpdata command into more
|
Simple script that filters the output of django's dumpdata command into more
|
||||||
manageable chunks.
|
manageable chunks.
|
||||||
|
|
||||||
Create the data.json e.g. with:
|
Create the data.json e.g. with:
|
||||||
python ../../manage.py dumpdata --indent 4 --natural-foreign > data.json
|
python ../../manage.py dumpdata --indent 4 --natural-foreign > data.json
|
||||||
'''
|
"""
|
||||||
|
|
||||||
import json
|
import json
|
||||||
|
|
||||||
|
|
||||||
def filter_dump(data, model_list, filename):
|
def filter_dump(data, model_list, filename):
|
||||||
'''
|
"""
|
||||||
Helper function
|
Helper function
|
||||||
'''
|
"""
|
||||||
filter_data = [i for i in data if i['model'] in model_list]
|
filter_data = [i for i in data if i['model'] in model_list]
|
||||||
with open(filename, 'w') as outfile:
|
if filter_data:
|
||||||
json.dump(filter_data, outfile, indent=4)
|
with open(filename, 'w') as outfile:
|
||||||
|
json.dump(filter_data, outfile, indent=4)
|
||||||
|
|
||||||
|
|
||||||
# This is a full dump of the DB
|
# This is a full dump of the DB
|
||||||
fixture = open('data.json')
|
fixture = open('data.json')
|
||||||
@@ -44,6 +46,7 @@ fixture.close()
|
|||||||
filter_dump(data, ('nutrition.ingredient',), 'ingredients.json')
|
filter_dump(data, ('nutrition.ingredient',), 'ingredients.json')
|
||||||
filter_dump(data, ('nutrition.weightunit',), 'weight_units.json')
|
filter_dump(data, ('nutrition.weightunit',), 'weight_units.json')
|
||||||
filter_dump(data, ('nutrition.ingredientweightunit',), 'ingredient_units.json')
|
filter_dump(data, ('nutrition.ingredientweightunit',), 'ingredient_units.json')
|
||||||
|
filter_dump(data, ('nutrition.logitem',), 'nutrition_diary.json')
|
||||||
|
|
||||||
#
|
#
|
||||||
# Exercises
|
# Exercises
|
||||||
|
|||||||
25
gulpfile.js
25
gulpfile.js
@@ -1,25 +0,0 @@
|
|||||||
const gulp = require('gulp');
|
|
||||||
const eslint = require('gulp-eslint');
|
|
||||||
|
|
||||||
gulp.task('lint-js', function () {
|
|
||||||
// ESLint ignores files with "node_modules" paths.
|
|
||||||
// So, it's best to have gulp ignore the directory as well.
|
|
||||||
// Also, Be sure to return the stream from the task;
|
|
||||||
// Otherwise, the task may end before the stream has finished.
|
|
||||||
return gulp.src(['**/*.js'])
|
|
||||||
// eslint() attaches the lint output to the "eslint" property
|
|
||||||
// of the file object so it can be used by other modules.
|
|
||||||
.pipe(eslint())
|
|
||||||
// eslint.format() outputs the lint results to the console.
|
|
||||||
// Alternatively use eslint.formatEach() (see Docs).
|
|
||||||
.pipe(eslint.format())
|
|
||||||
// To have the process exit with an error code (1) on
|
|
||||||
// lint error, return the stream and pipe to failAfterError last.
|
|
||||||
.pipe(eslint.failAfterError());
|
|
||||||
});
|
|
||||||
|
|
||||||
gulp.task('lint', ['lint-js']);
|
|
||||||
|
|
||||||
gulp.task('default', ['lint'], function () {
|
|
||||||
// This will only run if the lint task is successful...
|
|
||||||
});
|
|
||||||
11
manage.py
11
manage.py
@@ -1,13 +1,18 @@
|
|||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
# Standard Library
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
|
# Django
|
||||||
from django.core.management import execute_from_command_line
|
from django.core.management import execute_from_command_line
|
||||||
|
|
||||||
from tasks import (
|
# wger
|
||||||
setup_django_environment,
|
from wger.tasks import (
|
||||||
get_user_config_path
|
get_user_config_path,
|
||||||
|
setup_django_environment
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|
||||||
# If user passed the settings flag ignore the default wger settings
|
# If user passed the settings flag ignore the default wger settings
|
||||||
|
|||||||
28
package.json
28
package.json
@@ -1,13 +1,10 @@
|
|||||||
{
|
{
|
||||||
"name": "wger",
|
"name": "wger",
|
||||||
"version": "1.8.0",
|
"version": "2.0.dev1",
|
||||||
"description": "Self hosted FLOSS fitness/workout and weight tracker",
|
"description": "Self hosted FLOSS fitness/workout and weight tracker",
|
||||||
"directories": {
|
"directories": {
|
||||||
"doc": "docs"
|
"doc": "docs"
|
||||||
},
|
},
|
||||||
"scripts": {
|
|
||||||
"test": "echo \"Error: no test specified\" && exit 1"
|
|
||||||
},
|
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "git+https://github.com/wger-project/wger/wger.git"
|
"url": "git+https://github.com/wger-project/wger/wger.git"
|
||||||
@@ -18,13 +15,20 @@
|
|||||||
"url": "https://github.com/wger-project/wger/issues"
|
"url": "https://github.com/wger-project/wger/issues"
|
||||||
},
|
},
|
||||||
"homepage": "https://github.com/wger-project/wger",
|
"homepage": "https://github.com/wger-project/wger",
|
||||||
"devDependencies": {
|
"dependencies": {
|
||||||
"eslint": "^3.3.1",
|
"yarn": "^1.22.5",
|
||||||
"eslint-config-airbnb-base": "^5.0.2",
|
"Sortable": "RubaXa/Sortable#1.10.2",
|
||||||
"eslint-plugin-import": "^1.13.0",
|
"bootstrap": "twbs/bootstrap#4.x",
|
||||||
"eslint-plugin-jsx-a11y": "^2.1.0",
|
"components-font-awesome": "components/font-awesome#5.14.0",
|
||||||
"eslint-plugin-react": "^6.1.2",
|
"d3": "mbostock-bower/d3-bower#>=5",
|
||||||
"gulp": "^3.9.1",
|
"datatables": "DataTables/DataTables#1.10.x",
|
||||||
"gulp-eslint": "^3.0.1"
|
"devbridge-autocomplete": "^1.4.11",
|
||||||
|
"jquery": "^3.5.0",
|
||||||
|
"metrics-graphics": "mozilla/metrics-graphics#2.15.x",
|
||||||
|
"shariff": "^3.2.1",
|
||||||
|
"tinymce": "^5.4.2"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"yarn": ">= 1.0.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,30 +2,49 @@
|
|||||||
# Requirements for wger for production
|
# Requirements for wger for production
|
||||||
#
|
#
|
||||||
|
|
||||||
bleach
|
# Building/installing
|
||||||
|
wheel
|
||||||
|
|
||||||
|
# Application
|
||||||
|
bleach~=3.1
|
||||||
django-activity-stream
|
django-activity-stream
|
||||||
django-bootstrap-breadcrumbs
|
django-bootstrap-breadcrumbs~=0.9
|
||||||
django-bower
|
django-formtools~=2.2
|
||||||
django-formtools>=1.0,<1.1
|
django-recaptcha==2.0.6
|
||||||
django-recaptcha
|
Django~=3.1
|
||||||
django-sortedm2m
|
django-crispy-forms~=1.9
|
||||||
Django>=1.9,<1.10
|
django_compressor~=2.4
|
||||||
django_compressor
|
django_extensions~=3.0
|
||||||
django_mobile
|
django-sortedm2m~=3.0
|
||||||
easy-thumbnails
|
django-storages~=1.9
|
||||||
icalendar
|
easy-thumbnails~=2.7
|
||||||
invoke>=0.14,<0.15
|
icalendar==4.0.6
|
||||||
pillow
|
invoke~=1.4
|
||||||
|
pillow~=7.2
|
||||||
python-mimeparse
|
python-mimeparse
|
||||||
reportlab>=3.3,<3.4
|
reportlab==3.5.48
|
||||||
|
matplotlib>=3.1
|
||||||
requests
|
requests
|
||||||
|
setuptools>=18.5
|
||||||
sphinx
|
sphinx
|
||||||
|
|
||||||
# REST API
|
# AWS
|
||||||
django-cors-headers
|
#boto3
|
||||||
django-filter
|
|
||||||
django-tastypie>=0.13,<0.14
|
# Production
|
||||||
djangorestframework>=3.2,<3.3
|
#psycopg2
|
||||||
|
#python-memcached
|
||||||
|
|
||||||
|
# REST API
|
||||||
|
django-cors-headers>=3.0
|
||||||
|
django-filter==2.3.0
|
||||||
|
djangorestframework~=3.11
|
||||||
|
|
||||||
|
|
||||||
|
# Explicitly set versions as a workaround for CI/Devel.
|
||||||
|
# This is just intended to make life easier, has no deeper meaning and
|
||||||
|
# can be removed if needed.
|
||||||
|
docutils>=0.10,<0.17 # for botocore
|
||||||
|
six>=1.12.0 # for django-compressor
|
||||||
|
|
||||||
|
|
||||||
# Python3 compatibility
|
|
||||||
six
|
|
||||||
|
|||||||
@@ -6,6 +6,8 @@
|
|||||||
-r requirements.txt
|
-r requirements.txt
|
||||||
|
|
||||||
# Development packages
|
# Development packages
|
||||||
pep8
|
coverage
|
||||||
django-debug-toolbar
|
django-debug-toolbar
|
||||||
coverage
|
tblib
|
||||||
|
transifex-client
|
||||||
|
isort
|
||||||
|
|||||||
70
setup.cfg
70
setup.cfg
@@ -1,7 +1,69 @@
|
|||||||
[bdist_wheel]
|
[bdist_wheel]
|
||||||
universal = 1
|
universal = 1
|
||||||
|
|
||||||
[pep8]
|
[isort]
|
||||||
exclude = urls.py,tasks.py,*migrations*,*bower_components*
|
sections = FUTURE,STDLIB,DJANGO,THIRDPARTY,FIRSTPARTY,LOCALFOLDER
|
||||||
max-line-length = 100
|
skip: extras,build,dist,node_modules,migrations,docs,settings.py,apps.py
|
||||||
ignore = W503
|
|
||||||
|
# If set to true - ensures that if a star import is present, nothing else is
|
||||||
|
# imported from that namespace.
|
||||||
|
combine_star=False
|
||||||
|
|
||||||
|
# If set to true - imports will be sorted by their length instead of
|
||||||
|
# alphabetically.
|
||||||
|
length_sort=False
|
||||||
|
|
||||||
|
# An integer that represents the longest line-length you want a single import to
|
||||||
|
# take. Defaults to 80.
|
||||||
|
line_length=119
|
||||||
|
|
||||||
|
# A comment to consistently place directly above future imports.
|
||||||
|
import_heading_future=Future
|
||||||
|
|
||||||
|
# A comment to consistently place directly above django imports.
|
||||||
|
import_heading_django=Django
|
||||||
|
|
||||||
|
# A comment to consistently place directly above imports from the standard library.
|
||||||
|
import_heading_stdlib=Standard Library
|
||||||
|
|
||||||
|
# A comment to consistently place directly above thirdparty imports.
|
||||||
|
import_heading_thirdparty=Third Party
|
||||||
|
|
||||||
|
# A comment to consistently place directly above wger imports.
|
||||||
|
import_heading_firstparty=wger
|
||||||
|
|
||||||
|
# A comment to consistently place directly above imports that start with '.'.
|
||||||
|
import_heading_localfolder=Local
|
||||||
|
|
||||||
|
# An integer that represents the number of spaces you would like to indent by or
|
||||||
|
# Tab to indent by a single tab.
|
||||||
|
indent=' '
|
||||||
|
|
||||||
|
# A list of imports that will be forced to display withing the first party
|
||||||
|
# category.
|
||||||
|
known_first_party=wger
|
||||||
|
known_django=django
|
||||||
|
|
||||||
|
# An integer that represents how you want imports to be displayed if their long
|
||||||
|
# enough to span multiple lines. A full definition of all possible modes can be
|
||||||
|
# found in isort's README.
|
||||||
|
multi_line_output=3
|
||||||
|
force_grid_wrap=True
|
||||||
|
|
||||||
|
# If set to true - isort will create separate sections withing "from" imports
|
||||||
|
# for CONSTANTS, Classes, and modules/functions.
|
||||||
|
order_by_type=True
|
||||||
|
|
||||||
|
# Forces a certain number of lines after the imports and before the first line
|
||||||
|
# of functional code. By default this is 2 lines if the first line of code is a
|
||||||
|
# class or function. Otherwise it's 1.
|
||||||
|
lines_after_imports=2
|
||||||
|
|
||||||
|
# If set to true - isort will combine as imports on the same line within for
|
||||||
|
# import statements. By default isort forces all as imports to display on their
|
||||||
|
# own lines.
|
||||||
|
combine_as_imports=True
|
||||||
|
|
||||||
|
# If set to true - isort will add imports even if the file specified is
|
||||||
|
# currently completely empty.
|
||||||
|
force_adds=False
|
||||||
|
|||||||
18
setup.py
18
setup.py
@@ -7,10 +7,13 @@
|
|||||||
:license: GNU GPL, see LICENSE for more details.
|
:license: GNU GPL, see LICENSE for more details.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
# Third Party
|
||||||
from setuptools import (
|
from setuptools import (
|
||||||
setup,
|
find_packages,
|
||||||
find_packages
|
setup
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# wger
|
||||||
from wger import get_version
|
from wger import get_version
|
||||||
|
|
||||||
|
|
||||||
@@ -24,6 +27,7 @@ setup(
|
|||||||
name='wger',
|
name='wger',
|
||||||
description='FLOSS workout, fitness and weight manager/tracker written with Django',
|
description='FLOSS workout, fitness and weight manager/tracker written with Django',
|
||||||
long_description=long_description,
|
long_description=long_description,
|
||||||
|
long_description_content_type='text/x-rst',
|
||||||
version=get_version(),
|
version=get_version(),
|
||||||
url='https://github.com/wger-project',
|
url='https://github.com/wger-project',
|
||||||
author='Roland Geider',
|
author='Roland Geider',
|
||||||
@@ -39,13 +43,13 @@ setup(
|
|||||||
'Framework :: Django',
|
'Framework :: Django',
|
||||||
'License :: OSI Approved :: GNU Affero General Public License v3 or later (AGPLv3+)',
|
'License :: OSI Approved :: GNU Affero General Public License v3 or later (AGPLv3+)',
|
||||||
'Operating System :: OS Independent',
|
'Operating System :: OS Independent',
|
||||||
'Programming Language :: Python :: 2',
|
|
||||||
'Programming Language :: Python :: 2.7',
|
|
||||||
'Programming Language :: Python :: 3',
|
'Programming Language :: Python :: 3',
|
||||||
'Programming Language :: Python :: 3.4',
|
'Programming Language :: Python :: 3.6',
|
||||||
'Programming Language :: Python :: 3.5',
|
'Programming Language :: Python :: 3.7',
|
||||||
|
'Programming Language :: Python :: 3.8',
|
||||||
],
|
],
|
||||||
install_requires=install_requires,
|
|
||||||
|
nstall_requires=install_requires,
|
||||||
entry_points={
|
entry_points={
|
||||||
'console_scripts': [
|
'console_scripts': [
|
||||||
'wger = wger.__main__:main',
|
'wger = wger.__main__:main',
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
:license: GNU GPL, see LICENSE for more details.
|
:license: GNU GPL, see LICENSE for more details.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
VERSION = (1, 8, 0, 'beta', 1)
|
VERSION = (2, 0, 0, 'alpha', 1)
|
||||||
RELEASE = False
|
RELEASE = False
|
||||||
|
|
||||||
|
|
||||||
@@ -33,6 +33,6 @@ def get_version(version=None, release=None):
|
|||||||
else:
|
else:
|
||||||
sub = ''
|
sub = ''
|
||||||
if not release:
|
if not release:
|
||||||
sub += '-dev'
|
sub += '.dev0'
|
||||||
|
|
||||||
return main + sub
|
return main + sub
|
||||||
|
|||||||
@@ -14,20 +14,27 @@
|
|||||||
#
|
#
|
||||||
# You should have received a copy of the GNU Affero General Public License
|
# You should have received a copy of the GNU Affero General Public License
|
||||||
|
|
||||||
|
# Standard Library
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
|
# Third Party
|
||||||
from invoke import run
|
from invoke import run
|
||||||
|
|
||||||
'''
|
|
||||||
|
"""
|
||||||
This simple wrapper script is used as a console entry point in the packaged
|
This simple wrapper script is used as a console entry point in the packaged
|
||||||
version of the application. It simply redirects all arguments to the invoke
|
version of the application. It simply redirects all arguments to the invoke
|
||||||
command, which does all the work.
|
command, which does all the work.
|
||||||
'''
|
"""
|
||||||
|
|
||||||
invoke_cmd = 'invoke '
|
invoke_cmd = 'invoke '
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
|
# Change the working directory so that invoke can find the tasks fiel
|
||||||
|
os.chdir(os.path.dirname(os.path.abspath(__file__)))
|
||||||
|
|
||||||
args = sys.argv[1:]
|
args = sys.argv[1:]
|
||||||
if len(args):
|
if len(args):
|
||||||
run(invoke_cmd + ' '.join(args), pty=True)
|
run(invoke_cmd + ' '.join(args), pty=True)
|
||||||
|
|||||||
@@ -16,7 +16,9 @@
|
|||||||
# along with Workout Manager. If not, see <http://www.gnu.org/licenses/>.
|
# along with Workout Manager. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
|
||||||
|
# wger
|
||||||
from wger import get_version
|
from wger import get_version
|
||||||
|
|
||||||
|
|
||||||
VERSION = get_version()
|
VERSION = get_version()
|
||||||
default_app_config = 'wger.config.apps.ConfigConfig'
|
default_app_config = 'wger.config.apps.ConfigConfig'
|
||||||
|
|||||||
@@ -14,6 +14,7 @@
|
|||||||
#
|
#
|
||||||
# You should have received a copy of the GNU Affero General Public License
|
# You should have received a copy of the GNU Affero General Public License
|
||||||
|
|
||||||
|
# Django
|
||||||
from django.apps import AppConfig
|
from django.apps import AppConfig
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
[
|
[
|
||||||
{
|
{
|
||||||
"pk": 1,
|
"pk": 1,
|
||||||
"model": "config.gymconfig",
|
"model": "config.gymconfig",
|
||||||
"fields": {
|
"fields": {
|
||||||
"default_gym": null
|
"default_gym": null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1,4 +1,5 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
# flake8: noqa
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
from django.db import models, migrations
|
from django.db import models, migrations
|
||||||
@@ -16,7 +17,9 @@ class Migration(migrations.Migration):
|
|||||||
name='GymConfig',
|
name='GymConfig',
|
||||||
fields=[
|
fields=[
|
||||||
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
|
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
|
||||||
('default_gym', models.ForeignKey(blank=True, to='gym.Gym', help_text='Select the default gym for this installation. This will assign all new registered users to this gym and update all existing users without a gym.', null=True, verbose_name='Default gym')),
|
('default_gym', models.ForeignKey(blank=True, to='gym.Gym',
|
||||||
|
help_text='Select the default gym for this installation. This will assign all new registered users to this gym and update all existing users without a gym.',
|
||||||
|
null=True, verbose_name='Default gym', on_delete=models.CASCADE)),
|
||||||
],
|
],
|
||||||
options={
|
options={
|
||||||
},
|
},
|
||||||
@@ -28,8 +31,8 @@ class Migration(migrations.Migration):
|
|||||||
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
|
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
|
||||||
('item', models.CharField(max_length=2, editable=False, choices=[(b'1', 'Exercises'), (b'2', 'Ingredients')])),
|
('item', models.CharField(max_length=2, editable=False, choices=[(b'1', 'Exercises'), (b'2', 'Ingredients')])),
|
||||||
('show', models.BooleanField(default=1)),
|
('show', models.BooleanField(default=1)),
|
||||||
('language', models.ForeignKey(related_name='language_source', editable=False, to='core.Language')),
|
('language', models.ForeignKey(related_name='language_source', editable=False, to='core.Language', on_delete=models.CASCADE)),
|
||||||
('language_target', models.ForeignKey(related_name='language_target', editable=False, to='core.Language')),
|
('language_target', models.ForeignKey(related_name='language_target', editable=False, to='core.Language', on_delete=models.CASCADE)),
|
||||||
],
|
],
|
||||||
options={
|
options={
|
||||||
'ordering': ['item', 'language_target'],
|
'ordering': ['item', 'language_target'],
|
||||||
|
|||||||
22
wger/config/migrations/0002_auto_20190618_1617.py
Normal file
22
wger/config/migrations/0002_auto_20190618_1617.py
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# flake8: noqa
|
||||||
|
# Generated by Django 1.11.21 on 2019-06-18 16:17
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('config', '0001_initial'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='languageconfig',
|
||||||
|
name='item',
|
||||||
|
field=models.CharField(
|
||||||
|
choices=[('1', 'Exercises'), ('2', 'Ingredients')], editable=False, max_length=2),
|
||||||
|
),
|
||||||
|
]
|
||||||
@@ -15,30 +15,39 @@
|
|||||||
# You should have received a copy of the GNU Affero General Public License
|
# You should have received a copy of the GNU Affero General Public License
|
||||||
# along with Workout Manager. If not, see <http://www.gnu.org/licenses/>.
|
# along with Workout Manager. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
# Standard Library
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
from django.db import models
|
# Django
|
||||||
from django.utils.encoding import python_2_unicode_compatible
|
|
||||||
from django.utils.translation import ugettext_lazy as _
|
|
||||||
from django.core.cache import cache
|
from django.core.cache import cache
|
||||||
from wger.core.models import Language, UserProfile
|
from django.db import models
|
||||||
from wger.gym.helpers import is_any_gym_admin
|
from django.utils.translation import ugettext_lazy as _
|
||||||
from wger.gym.models import Gym, GymUserConfig
|
|
||||||
|
|
||||||
from wger.utils.cache import delete_template_fragment_cache
|
# wger
|
||||||
from wger.utils.cache import cache_mapper
|
from wger.core.models import (
|
||||||
|
Language,
|
||||||
|
UserProfile
|
||||||
|
)
|
||||||
|
from wger.gym.helpers import is_any_gym_admin
|
||||||
|
from wger.gym.models import (
|
||||||
|
Gym,
|
||||||
|
GymUserConfig
|
||||||
|
)
|
||||||
|
from wger.utils.cache import (
|
||||||
|
cache_mapper,
|
||||||
|
delete_template_fragment_cache
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
@python_2_unicode_compatible
|
|
||||||
class LanguageConfig(models.Model):
|
class LanguageConfig(models.Model):
|
||||||
'''
|
"""
|
||||||
Configuration for languages
|
Configuration for languages
|
||||||
|
|
||||||
Allows to specify what exercises and ingredients are shown for each language
|
Allows to specify what exercises and ingredients are shown for each language
|
||||||
'''
|
"""
|
||||||
SHOW_ITEM_EXERCISES = '1'
|
SHOW_ITEM_EXERCISES = '1'
|
||||||
SHOW_ITEM_INGREDIENTS = '2'
|
SHOW_ITEM_INGREDIENTS = '2'
|
||||||
SHOW_ITEM_LIST = (
|
SHOW_ITEM_LIST = (
|
||||||
@@ -48,31 +57,33 @@ class LanguageConfig(models.Model):
|
|||||||
|
|
||||||
language = models.ForeignKey(Language,
|
language = models.ForeignKey(Language,
|
||||||
related_name='language_source',
|
related_name='language_source',
|
||||||
editable=False)
|
editable=False,
|
||||||
|
on_delete=models.CASCADE)
|
||||||
language_target = models.ForeignKey(Language,
|
language_target = models.ForeignKey(Language,
|
||||||
related_name='language_target',
|
related_name='language_target',
|
||||||
editable=False)
|
editable=False,
|
||||||
|
on_delete=models.CASCADE)
|
||||||
item = models.CharField(max_length=2,
|
item = models.CharField(max_length=2,
|
||||||
choices=SHOW_ITEM_LIST,
|
choices=SHOW_ITEM_LIST,
|
||||||
editable=False)
|
editable=False)
|
||||||
show = models.BooleanField(default=1)
|
show = models.BooleanField(default=1)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
'''
|
"""
|
||||||
Set some other properties
|
Set some other properties
|
||||||
'''
|
"""
|
||||||
ordering = ["item", "language_target", ]
|
ordering = ["item", "language_target", ]
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
'''
|
"""
|
||||||
Return a more human-readable representation
|
Return a more human-readable representation
|
||||||
'''
|
"""
|
||||||
return u"Config for language {0}".format(self.language)
|
return u"Config for language {0}".format(self.language)
|
||||||
|
|
||||||
def save(self, *args, **kwargs):
|
def save(self, *args, **kwargs):
|
||||||
'''
|
"""
|
||||||
Reset all cached infos
|
Reset all cached infos
|
||||||
'''
|
"""
|
||||||
|
|
||||||
super(LanguageConfig, self).save(*args, **kwargs)
|
super(LanguageConfig, self).save(*args, **kwargs)
|
||||||
|
|
||||||
@@ -84,9 +95,9 @@ class LanguageConfig(models.Model):
|
|||||||
delete_template_fragment_cache('exercise-overview', self.language_id)
|
delete_template_fragment_cache('exercise-overview', self.language_id)
|
||||||
|
|
||||||
def delete(self, *args, **kwargs):
|
def delete(self, *args, **kwargs):
|
||||||
'''
|
"""
|
||||||
Reset all cached infos
|
Reset all cached infos
|
||||||
'''
|
"""
|
||||||
|
|
||||||
# Cached objects
|
# Cached objects
|
||||||
cache.delete(cache_mapper.get_language_config_key(self.language, self.item))
|
cache.delete(cache_mapper.get_language_config_key(self.language, self.item))
|
||||||
@@ -98,14 +109,13 @@ class LanguageConfig(models.Model):
|
|||||||
super(LanguageConfig, self).delete(*args, **kwargs)
|
super(LanguageConfig, self).delete(*args, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
@python_2_unicode_compatible
|
|
||||||
class GymConfig(models.Model):
|
class GymConfig(models.Model):
|
||||||
'''
|
"""
|
||||||
System wide configuration for gyms
|
System wide configuration for gyms
|
||||||
|
|
||||||
At the moment this only allows to set one gym as the default
|
At the moment this only allows to set one gym as the default
|
||||||
TODO: close registration (users can only become members thorough an admin)
|
TODO: close registration (users can only become members thorough an admin)
|
||||||
'''
|
"""
|
||||||
|
|
||||||
default_gym = models.ForeignKey(Gym,
|
default_gym = models.ForeignKey(Gym,
|
||||||
verbose_name=_('Default gym'),
|
verbose_name=_('Default gym'),
|
||||||
@@ -114,21 +124,22 @@ class GymConfig(models.Model):
|
|||||||
'gym and update all existing users without a '
|
'gym and update all existing users without a '
|
||||||
'gym.'),
|
'gym.'),
|
||||||
null=True,
|
null=True,
|
||||||
blank=True)
|
blank=True,
|
||||||
'''
|
on_delete=models.CASCADE)
|
||||||
|
"""
|
||||||
Default gym for the wger installation
|
Default gym for the wger installation
|
||||||
'''
|
"""
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
'''
|
"""
|
||||||
Return a more human-readable representation
|
Return a more human-readable representation
|
||||||
'''
|
"""
|
||||||
return u"Default gym {0}".format(self.default_gym)
|
return u"Default gym {0}".format(self.default_gym)
|
||||||
|
|
||||||
def save(self, *args, **kwargs):
|
def save(self, *args, **kwargs):
|
||||||
'''
|
"""
|
||||||
Perform additional tasks
|
Perform additional tasks
|
||||||
'''
|
"""
|
||||||
if self.default_gym:
|
if self.default_gym:
|
||||||
|
|
||||||
# All users that have no gym set in the profile are edited
|
# All users that have no gym set in the profile are edited
|
||||||
|
|||||||
@@ -15,19 +15,21 @@
|
|||||||
# You should have received a copy of the GNU Affero General Public License
|
# You should have received a copy of the GNU Affero General Public License
|
||||||
|
|
||||||
|
|
||||||
|
# Django
|
||||||
from django.db.models.signals import post_save
|
from django.db.models.signals import post_save
|
||||||
from django.dispatch import receiver
|
from django.dispatch import receiver
|
||||||
|
|
||||||
|
# wger
|
||||||
from wger.config.models import LanguageConfig
|
from wger.config.models import LanguageConfig
|
||||||
from wger.core.models import Language
|
from wger.core.models import Language
|
||||||
|
|
||||||
|
|
||||||
@receiver(post_save, sender=Language)
|
@receiver(post_save, sender=Language)
|
||||||
def init_language_config(sender, instance, created, **kwargs):
|
def init_language_config(sender, instance, created, **kwargs):
|
||||||
'''
|
"""
|
||||||
Creates language config entries when new languages are created
|
Creates language config entries when new languages are created
|
||||||
(all combinations of all languages)
|
(all combinations of all languages)
|
||||||
'''
|
"""
|
||||||
for language_source in Language.objects.all():
|
for language_source in Language.objects.all():
|
||||||
for language_target in Language.objects.all():
|
for language_target in Language.objects.all():
|
||||||
if not LanguageConfig.objects.filter(language=language_source)\
|
if not LanguageConfig.objects.filter(language=language_source)\
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
{% extends "base.html" %}
|
{% extends "base.html" %}
|
||||||
{% load i18n staticfiles wger_extras %}
|
{% load i18n static wger_extras %}
|
||||||
|
|
||||||
{% block title %}{% trans "Languages" %}{% endblock %}
|
{% block title %}{% trans "Languages" %}{% endblock %}
|
||||||
|
|
||||||
@@ -8,7 +8,7 @@
|
|||||||
<div class="list-group">
|
<div class="list-group">
|
||||||
{% for language in language_list %}
|
{% for language in language_list %}
|
||||||
<a href="{% url 'core:language:view' language.id %}" class="list-group-item">
|
<a href="{% url 'core:language:view' language.id %}" class="list-group-item">
|
||||||
<span class="glyphicon glyphicon-chevron-right pull-right"></span>
|
<span class="glyphicon glyphicon-chevron-right float-right"></span>
|
||||||
{{ language.full_name }}
|
{{ language.full_name }}
|
||||||
</a>
|
</a>
|
||||||
{% empty %}
|
{% empty %}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
{% extends "base.html" %}
|
{% extends "base.html" %}
|
||||||
{% load i18n staticfiles wger_extras django_bootstrap_breadcrumbs %}
|
{% load i18n static wger_extras django_bootstrap_breadcrumbs %}
|
||||||
|
|
||||||
{% block title %}{{ view_language }}{% endblock %}
|
{% block title %}{{ view_language }}{% endblock %}
|
||||||
|
|
||||||
@@ -85,24 +85,22 @@ in A).{% endblocktrans %}</p>
|
|||||||
{# #}
|
{# #}
|
||||||
{% block options %}
|
{% block options %}
|
||||||
<div class="btn-group">
|
<div class="btn-group">
|
||||||
<button type="button" class="btn btn-primary btn-sm dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
<div class="btn-group">
|
||||||
<span class="{% fa_class 'cog' %}"></span>
|
<button type="button" class="btn btn-primary btn-sm dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||||
{% trans "Options" %}
|
<span class="{% fa_class 'cog' %}"></span>
|
||||||
</button>
|
{% trans "Options" %}
|
||||||
<ul class="dropdown-menu">
|
</button>
|
||||||
<li>
|
<div class="dropdown-menu">
|
||||||
<a href="{% url 'core:language:edit' view_language.id %}" class="wger-modal-dialog">
|
<a href="{% url 'core:language:edit' view_language.id %}" class="wger-modal-dialog dropdown-item">
|
||||||
<span class="{% fa_class 'pencil-square-o' %}"></span>
|
<span class="{% fa_class 'edit' %}"></span>
|
||||||
{% trans "Edit" %}
|
{% trans "Edit" %}
|
||||||
</a>
|
</a>
|
||||||
</li>
|
<div role="separator" class="dropdown-divider"></div>
|
||||||
<li role="separator" class="divider"></li>
|
<a href="{% url 'core:language:delete' view_language.id %}" class="wger-modal-dialog dropdown-item">
|
||||||
<li>
|
|
||||||
<a href="{% url 'core:language:delete' view_language.id %}" class="wger-modal-dialog">
|
|
||||||
<span class="{% fa_class 'trash' %}"></span>
|
<span class="{% fa_class 'trash' %}"></span>
|
||||||
{% trans "Delete" %}
|
{% trans "Delete" %}
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</div>
|
||||||
</ul>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|||||||
@@ -15,16 +15,18 @@
|
|||||||
# You should have received a copy of the GNU Affero General Public License
|
# You should have received a copy of the GNU Affero General Public License
|
||||||
# along with Workout Manager. If not, see <http://www.gnu.org/licenses/>.
|
# along with Workout Manager. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
from django.core.urlresolvers import reverse
|
# Django
|
||||||
|
from django.urls import reverse
|
||||||
|
|
||||||
|
# wger
|
||||||
|
from wger.core.tests.base_testcase import WgerTestCase
|
||||||
from wger.gym.models import Gym
|
from wger.gym.models import Gym
|
||||||
from wger.core.tests.base_testcase import WorkoutManagerTestCase
|
|
||||||
|
|
||||||
|
|
||||||
class GymNameHeaderTestCase(WorkoutManagerTestCase):
|
class GymNameHeaderTestCase(WgerTestCase):
|
||||||
'''
|
"""
|
||||||
Test case for showing gym name on application header
|
Test case for showing gym name on application header
|
||||||
'''
|
"""
|
||||||
|
|
||||||
def check_header(self, gym=None):
|
def check_header(self, gym=None):
|
||||||
|
|
||||||
@@ -32,9 +34,9 @@ class GymNameHeaderTestCase(WorkoutManagerTestCase):
|
|||||||
self.assertEqual(response.context['custom_header'], gym)
|
self.assertEqual(response.context['custom_header'], gym)
|
||||||
|
|
||||||
def test_custom_header_gym_members(self):
|
def test_custom_header_gym_members(self):
|
||||||
'''
|
"""
|
||||||
Test the custom header for gym members
|
Test the custom header for gym members
|
||||||
'''
|
"""
|
||||||
|
|
||||||
# Gym 1, custom header activated
|
# Gym 1, custom header activated
|
||||||
gym = Gym.objects.get(pk=1)
|
gym = Gym.objects.get(pk=1)
|
||||||
@@ -60,7 +62,7 @@ class GymNameHeaderTestCase(WorkoutManagerTestCase):
|
|||||||
self.check_header(gym=None)
|
self.check_header(gym=None)
|
||||||
|
|
||||||
def test_custom_header_anonymous_user(self):
|
def test_custom_header_anonymous_user(self):
|
||||||
'''
|
"""
|
||||||
Test the custom header for logged out users
|
Test the custom header for logged out users
|
||||||
'''
|
"""
|
||||||
self.check_header(gym=None)
|
self.check_header(gym=None)
|
||||||
|
|||||||
@@ -15,24 +15,29 @@
|
|||||||
# You should have received a copy of the GNU Affero General Public License
|
# You should have received a copy of the GNU Affero General Public License
|
||||||
# along with Workout Manager. If not, see <http://www.gnu.org/licenses/>.
|
# along with Workout Manager. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
# Django
|
||||||
from django.contrib.auth.models import User
|
from django.contrib.auth.models import User
|
||||||
from django.core.urlresolvers import reverse
|
from django.urls import reverse
|
||||||
|
|
||||||
|
# wger
|
||||||
from wger.config.models import GymConfig
|
from wger.config.models import GymConfig
|
||||||
from wger.core.models import UserProfile
|
from wger.core.models import UserProfile
|
||||||
from wger.core.tests.base_testcase import WorkoutManagerTestCase
|
from wger.core.tests.base_testcase import WgerTestCase
|
||||||
from wger.gym.models import Gym, GymUserConfig
|
from wger.gym.models import (
|
||||||
|
Gym,
|
||||||
|
GymUserConfig
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class GymConfigTestCase(WorkoutManagerTestCase):
|
class GymConfigTestCase(WgerTestCase):
|
||||||
'''
|
"""
|
||||||
Test the system wide gym configuration
|
Test the system wide gym configuration
|
||||||
'''
|
"""
|
||||||
|
|
||||||
def test_default_gym(self):
|
def test_default_gym(self):
|
||||||
'''
|
"""
|
||||||
Test that newly registered users get a gym
|
Test that newly registered users get a gym
|
||||||
'''
|
"""
|
||||||
|
|
||||||
gym = Gym.objects.get(pk=2)
|
gym = Gym.objects.get(pk=2)
|
||||||
gym_config = GymConfig.objects.get(pk=1)
|
gym_config = GymConfig.objects.get(pk=1)
|
||||||
@@ -41,20 +46,21 @@ class GymConfigTestCase(WorkoutManagerTestCase):
|
|||||||
|
|
||||||
# Register
|
# Register
|
||||||
registration_data = {'username': 'myusername',
|
registration_data = {'username': 'myusername',
|
||||||
'password1': 'secret',
|
'password1': 'Aerieth4yuv5',
|
||||||
'password2': 'secret',
|
'password2': 'Aerieth4yuv5',
|
||||||
'email': 'my.email@example.com',
|
'email': 'my.email@example.com',
|
||||||
'g-recaptcha-response': 'PASSED', }
|
'g-recaptcha-response': 'PASSED', }
|
||||||
self.client.post(reverse('core:user:registration'), registration_data)
|
response = self.client.post(reverse('core:user:registration'), registration_data)
|
||||||
|
self.assertEqual(response.status_code, 302)
|
||||||
new_user = User.objects.all().last()
|
new_user = User.objects.all().last()
|
||||||
|
|
||||||
self.assertEqual(new_user.userprofile.gym, gym)
|
self.assertEqual(new_user.userprofile.gym, gym)
|
||||||
self.assertEqual(new_user.gymuserconfig.gym, gym)
|
self.assertEqual(new_user.gymuserconfig.gym, gym)
|
||||||
|
|
||||||
def test_no_default_gym(self):
|
def test_no_default_gym(self):
|
||||||
'''
|
"""
|
||||||
Test the user registration without a default gym
|
Test the user registration without a default gym
|
||||||
'''
|
"""
|
||||||
|
|
||||||
gym_config = GymConfig.objects.get(pk=1)
|
gym_config = GymConfig.objects.get(pk=1)
|
||||||
gym_config.default_gym = None
|
gym_config.default_gym = None
|
||||||
@@ -62,20 +68,21 @@ class GymConfigTestCase(WorkoutManagerTestCase):
|
|||||||
|
|
||||||
# Register
|
# Register
|
||||||
registration_data = {'username': 'myusername',
|
registration_data = {'username': 'myusername',
|
||||||
'password1': 'secret',
|
'password1': 'Iem2ahl1eizo',
|
||||||
'password2': 'secret',
|
'password2': 'Iem2ahl1eizo',
|
||||||
'email': 'my.email@example.com',
|
'email': 'my.email@example.com',
|
||||||
'g-recaptcha-response': 'PASSED', }
|
'g-recaptcha-response': 'PASSED', }
|
||||||
self.client.post(reverse('core:user:registration'), registration_data)
|
response = self.client.post(reverse('core:user:registration'), registration_data)
|
||||||
|
self.assertEqual(response.status_code, 302)
|
||||||
|
|
||||||
new_user = User.objects.all().last()
|
new_user = User.objects.all().last()
|
||||||
self.assertEqual(new_user.userprofile.gym_id, None)
|
self.assertEqual(new_user.userprofile.gym_id, None)
|
||||||
self.assertRaises(GymUserConfig.DoesNotExist, GymUserConfig.objects.get, user=new_user)
|
self.assertRaises(GymUserConfig.DoesNotExist, GymUserConfig.objects.get, user=new_user)
|
||||||
|
|
||||||
def test_update_userprofile(self):
|
def test_update_userprofile(self):
|
||||||
'''
|
"""
|
||||||
Test setting the gym for users when setting a default gym
|
Test setting the gym for users when setting a default gym
|
||||||
'''
|
"""
|
||||||
|
|
||||||
UserProfile.objects.update(gym=None)
|
UserProfile.objects.update(gym=None)
|
||||||
GymUserConfig.objects.all().delete()
|
GymUserConfig.objects.all().delete()
|
||||||
|
|||||||
@@ -15,15 +15,15 @@
|
|||||||
# You should have received a copy of the GNU Affero General Public License
|
# You should have received a copy of the GNU Affero General Public License
|
||||||
# along with Workout Manager. If not, see <http://www.gnu.org/licenses/>.
|
# along with Workout Manager. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
# wger
|
||||||
from wger.config.models import LanguageConfig
|
from wger.config.models import LanguageConfig
|
||||||
|
from wger.core.tests.base_testcase import WgerEditTestCase
|
||||||
from wger.core.tests.base_testcase import WorkoutManagerEditTestCase
|
|
||||||
|
|
||||||
|
|
||||||
class EditLanguageConfigTestCase(WorkoutManagerEditTestCase):
|
class EditLanguageConfigTestCase(WgerEditTestCase):
|
||||||
'''
|
"""
|
||||||
Tests editing a language config
|
Tests editing a language config
|
||||||
'''
|
"""
|
||||||
|
|
||||||
object_class = LanguageConfig
|
object_class = LanguageConfig
|
||||||
url = 'config:language_config:edit'
|
url = 'config:language_config:edit'
|
||||||
|
|||||||
@@ -15,25 +15,32 @@
|
|||||||
# You should have received a copy of the GNU Affero General Public License
|
# You should have received a copy of the GNU Affero General Public License
|
||||||
# along with Workout Manager. If not, see <http://www.gnu.org/licenses/>.
|
# along with Workout Manager. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
from django.conf.urls import patterns, url, include
|
# Django
|
||||||
|
from django.conf.urls import (
|
||||||
|
include,
|
||||||
|
url
|
||||||
|
)
|
||||||
|
|
||||||
from wger.config.views import language_config
|
# wger
|
||||||
from wger.config.views import gym_config
|
from wger.config.views import (
|
||||||
|
gym_config,
|
||||||
|
language_config
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
# sub patterns for language configs
|
# sub patterns for language configs
|
||||||
patterns_language_config = [
|
patterns_language_config = [
|
||||||
url(r'^(?P<pk>\d+)/edit',
|
url(r'^(?P<pk>\d+)/edit',
|
||||||
language_config.LanguageConfigUpdateView.as_view(),
|
language_config.LanguageConfigUpdateView.as_view(),
|
||||||
name='edit'),
|
name='edit'),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
# sub patterns for default gym
|
# sub patterns for default gym
|
||||||
patterns_gym_config = [
|
patterns_gym_config = [
|
||||||
url(r'^edit$',
|
url(r'^edit$',
|
||||||
gym_config.GymConfigUpdateView.as_view(),
|
gym_config.GymConfigUpdateView.as_view(),
|
||||||
name='edit'),
|
name='edit'),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
@@ -41,6 +48,6 @@ patterns_gym_config = [
|
|||||||
# Actual patterns
|
# Actual patterns
|
||||||
#
|
#
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
url(r'^language-config/', include(patterns_language_config, namespace="language_config")),
|
url(r'^language-config/', include((patterns_language_config, 'language_config'), namespace="language_config")),
|
||||||
url(r'^gym-config/', include(patterns_gym_config, namespace="gym_config")),
|
url(r'^gym-config/', include((patterns_gym_config, 'gym_config'), namespace="gym_config")),
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -14,12 +14,15 @@
|
|||||||
#
|
#
|
||||||
# You should have received a copy of the GNU Affero General Public License
|
# You should have received a copy of the GNU Affero General Public License
|
||||||
|
|
||||||
|
# Standard Library
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
from django.core.urlresolvers import reverse, reverse_lazy
|
# Django
|
||||||
from django.utils.translation import ugettext as _
|
from django.urls import reverse_lazy
|
||||||
|
from django.utils.translation import ugettext_lazy
|
||||||
from django.views.generic import UpdateView
|
from django.views.generic import UpdateView
|
||||||
|
|
||||||
|
# wger
|
||||||
from wger.config.models import GymConfig
|
from wger.config.models import GymConfig
|
||||||
from wger.utils.generic_views import WgerFormMixin
|
from wger.utils.generic_views import WgerFormMixin
|
||||||
|
|
||||||
@@ -28,22 +31,17 @@ logger = logging.getLogger(__name__)
|
|||||||
|
|
||||||
|
|
||||||
class GymConfigUpdateView(WgerFormMixin, UpdateView):
|
class GymConfigUpdateView(WgerFormMixin, UpdateView):
|
||||||
'''
|
"""
|
||||||
Generic view to edit the gym config table
|
Generic view to edit the gym config table
|
||||||
'''
|
"""
|
||||||
model = GymConfig
|
model = GymConfig
|
||||||
fields = '__all__'
|
fields = '__all__'
|
||||||
permission_required = 'config.change_gymconfig'
|
permission_required = 'config.change_gymconfig'
|
||||||
success_url = reverse_lazy('gym:gym:list')
|
success_url = reverse_lazy('gym:gym:list')
|
||||||
|
title = ugettext_lazy('Edit')
|
||||||
|
|
||||||
def get_object(self):
|
def get_object(self):
|
||||||
'''
|
"""
|
||||||
Return the only gym config object
|
Return the only gym config object
|
||||||
'''
|
"""
|
||||||
return GymConfig.objects.get(pk=1)
|
return GymConfig.objects.get(pk=1)
|
||||||
|
|
||||||
def get_context_data(self, **kwargs):
|
|
||||||
context = super(GymConfigUpdateView, self).get_context_data(**kwargs)
|
|
||||||
context['form_action'] = reverse('config:gym_config:edit')
|
|
||||||
context['title'] = _('Edit')
|
|
||||||
return context
|
|
||||||
|
|||||||
@@ -14,13 +14,19 @@
|
|||||||
#
|
#
|
||||||
# You should have received a copy of the GNU Affero General Public License
|
# You should have received a copy of the GNU Affero General Public License
|
||||||
|
|
||||||
|
# Standard Library
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
from django.contrib.auth.mixins import LoginRequiredMixin, PermissionRequiredMixin
|
# Django
|
||||||
from django.core.urlresolvers import reverse, reverse_lazy
|
from django.contrib.auth.mixins import (
|
||||||
from django.utils.translation import ugettext as _
|
LoginRequiredMixin,
|
||||||
|
PermissionRequiredMixin
|
||||||
|
)
|
||||||
|
from django.urls import reverse_lazy
|
||||||
|
from django.utils.translation import ugettext_lazy
|
||||||
from django.views.generic import UpdateView
|
from django.views.generic import UpdateView
|
||||||
|
|
||||||
|
# wger
|
||||||
from wger.config.models import LanguageConfig
|
from wger.config.models import LanguageConfig
|
||||||
from wger.utils.generic_views import WgerFormMixin
|
from wger.utils.generic_views import WgerFormMixin
|
||||||
|
|
||||||
@@ -32,23 +38,16 @@ class LanguageConfigUpdateView(WgerFormMixin,
|
|||||||
LoginRequiredMixin,
|
LoginRequiredMixin,
|
||||||
PermissionRequiredMixin,
|
PermissionRequiredMixin,
|
||||||
UpdateView):
|
UpdateView):
|
||||||
'''
|
"""
|
||||||
Generic view to edit a language config
|
Generic view to edit a language config
|
||||||
'''
|
"""
|
||||||
model = LanguageConfig
|
model = LanguageConfig
|
||||||
fields = ['show']
|
fields = ['show']
|
||||||
permission_required = 'config.change_languageconfig'
|
permission_required = 'config.change_languageconfig'
|
||||||
|
title = ugettext_lazy('Edit')
|
||||||
|
|
||||||
def get_success_url(self):
|
def get_success_url(self):
|
||||||
'''
|
"""
|
||||||
Return to the language page
|
Return to the language page
|
||||||
'''
|
"""
|
||||||
return reverse_lazy('core:language:view', kwargs={'pk': self.object.language_id})
|
return reverse_lazy('core:language:view', kwargs={'pk': self.object.language_id})
|
||||||
|
|
||||||
def get_context_data(self, **kwargs):
|
|
||||||
context = super(LanguageConfigUpdateView, self).get_context_data(**kwargs)
|
|
||||||
context['form_action'] = reverse('config:language_config:edit',
|
|
||||||
kwargs={'pk': self.object.id})
|
|
||||||
context['title'] = _('Edit')
|
|
||||||
|
|
||||||
return context
|
|
||||||
|
|||||||
@@ -16,7 +16,9 @@
|
|||||||
# along with Workout Manager. If not, see <http://www.gnu.org/licenses/>.
|
# along with Workout Manager. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
|
||||||
|
# wger
|
||||||
from wger import get_version
|
from wger import get_version
|
||||||
|
|
||||||
|
|
||||||
VERSION = get_version()
|
VERSION = get_version()
|
||||||
default_app_config = 'wger.core.apps.CoreConfig'
|
default_app_config = 'wger.core.apps.CoreConfig'
|
||||||
|
|||||||
@@ -1,79 +0,0 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
# This file is part of wger Workout Manager.
|
|
||||||
#
|
|
||||||
# wger Workout Manager is free software: you can redistribute it and/or modify
|
|
||||||
# it under the terms of the GNU Affero General Public License as published by
|
|
||||||
# the Free Software Foundation, either version 3 of the License, or
|
|
||||||
# (at your option) any later version.
|
|
||||||
#
|
|
||||||
# wger Workout Manager is distributed in the hope that it will be useful,
|
|
||||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
# GNU General Public License for more details.
|
|
||||||
#
|
|
||||||
# You should have received a copy of the GNU Affero General Public License
|
|
||||||
|
|
||||||
from tastypie.authentication import ApiKeyAuthentication
|
|
||||||
from tastypie.constants import ALL
|
|
||||||
from tastypie.resources import ModelResource
|
|
||||||
|
|
||||||
from wger.utils.resources import UserObjectsOnlyAuthorization
|
|
||||||
from wger.core.models import (
|
|
||||||
UserProfile,
|
|
||||||
Language,
|
|
||||||
DaysOfWeek,
|
|
||||||
License
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
class UserProfileResource(ModelResource):
|
|
||||||
'''
|
|
||||||
Resource for user profiles
|
|
||||||
'''
|
|
||||||
|
|
||||||
def authorized_read_list(self, object_list, bundle):
|
|
||||||
'''
|
|
||||||
Filter to own objects
|
|
||||||
'''
|
|
||||||
return object_list.filter(user=bundle.request.user)
|
|
||||||
|
|
||||||
class Meta:
|
|
||||||
excludes = ('is_temporary', )
|
|
||||||
queryset = UserProfile.objects.all()
|
|
||||||
authentication = ApiKeyAuthentication()
|
|
||||||
authorization = UserObjectsOnlyAuthorization()
|
|
||||||
|
|
||||||
|
|
||||||
class LanguageResource(ModelResource):
|
|
||||||
'''
|
|
||||||
Resource for languages
|
|
||||||
'''
|
|
||||||
class Meta:
|
|
||||||
queryset = Language.objects.all()
|
|
||||||
filtering = {'id': ALL,
|
|
||||||
"full_name": ALL,
|
|
||||||
"short_name": ALL}
|
|
||||||
|
|
||||||
|
|
||||||
class DaysOfWeekResource(ModelResource):
|
|
||||||
'''
|
|
||||||
Resource for days of the week
|
|
||||||
'''
|
|
||||||
|
|
||||||
class Meta:
|
|
||||||
queryset = DaysOfWeek.objects.all()
|
|
||||||
filtering = {'id': ALL,
|
|
||||||
'day_of_week': ALL}
|
|
||||||
|
|
||||||
|
|
||||||
class LicenseResource(ModelResource):
|
|
||||||
'''
|
|
||||||
Resource for licenses
|
|
||||||
'''
|
|
||||||
class Meta:
|
|
||||||
queryset = License.objects.all()
|
|
||||||
filtering = {'id': ALL,
|
|
||||||
"full_name": ALL,
|
|
||||||
"short_name": ALL,
|
|
||||||
"url": ALL}
|
|
||||||
|
|||||||
@@ -15,67 +15,76 @@
|
|||||||
# You should have received a copy of the GNU Affero General Public License
|
# You should have received a copy of the GNU Affero General Public License
|
||||||
# along with Workout Manager. If not, see <http://www.gnu.org/licenses/>.
|
# along with Workout Manager. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
# Third Party
|
||||||
from rest_framework import serializers
|
from rest_framework import serializers
|
||||||
|
|
||||||
|
# wger
|
||||||
from wger.core.models import (
|
from wger.core.models import (
|
||||||
UserProfile,
|
|
||||||
Language,
|
|
||||||
DaysOfWeek,
|
DaysOfWeek,
|
||||||
|
Language,
|
||||||
License,
|
License,
|
||||||
RepetitionUnit,
|
RepetitionUnit,
|
||||||
WeightUnit)
|
UserProfile,
|
||||||
|
WeightUnit
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class UserprofileSerializer(serializers.ModelSerializer):
|
class UserprofileSerializer(serializers.ModelSerializer):
|
||||||
'''
|
"""
|
||||||
Workout session serializer
|
Workout session serializer
|
||||||
'''
|
"""
|
||||||
class Meta:
|
class Meta:
|
||||||
model = UserProfile
|
model = UserProfile
|
||||||
|
fields = '__all__'
|
||||||
|
|
||||||
|
|
||||||
class UsernameSerializer(serializers.Serializer):
|
class UsernameSerializer(serializers.Serializer):
|
||||||
'''
|
"""
|
||||||
Serializer to extract the username
|
Serializer to extract the username
|
||||||
'''
|
"""
|
||||||
username = serializers.CharField()
|
username = serializers.CharField()
|
||||||
|
|
||||||
|
|
||||||
class LanguageSerializer(serializers.ModelSerializer):
|
class LanguageSerializer(serializers.ModelSerializer):
|
||||||
'''
|
"""
|
||||||
Language serializer
|
Language serializer
|
||||||
'''
|
"""
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Language
|
model = Language
|
||||||
|
fields = '__all__'
|
||||||
|
|
||||||
|
|
||||||
class DaysOfWeekSerializer(serializers.ModelSerializer):
|
class DaysOfWeekSerializer(serializers.ModelSerializer):
|
||||||
'''
|
"""
|
||||||
DaysOfWeek serializer
|
DaysOfWeek serializer
|
||||||
'''
|
"""
|
||||||
class Meta:
|
class Meta:
|
||||||
model = DaysOfWeek
|
model = DaysOfWeek
|
||||||
|
fields = '__all__'
|
||||||
|
|
||||||
|
|
||||||
class LicenseSerializer(serializers.ModelSerializer):
|
class LicenseSerializer(serializers.ModelSerializer):
|
||||||
'''
|
"""
|
||||||
License serializer
|
License serializer
|
||||||
'''
|
"""
|
||||||
class Meta:
|
class Meta:
|
||||||
model = License
|
model = License
|
||||||
|
fields = '__all__'
|
||||||
|
|
||||||
|
|
||||||
class RepetitionUnitSerializer(serializers.ModelSerializer):
|
class RepetitionUnitSerializer(serializers.ModelSerializer):
|
||||||
'''
|
"""
|
||||||
Repetition unit serializer
|
Repetition unit serializer
|
||||||
'''
|
"""
|
||||||
class Meta:
|
class Meta:
|
||||||
model = RepetitionUnit
|
model = RepetitionUnit
|
||||||
|
fields = '__all__'
|
||||||
|
|
||||||
|
|
||||||
class WeightUnitSerializer(serializers.ModelSerializer):
|
class WeightUnitSerializer(serializers.ModelSerializer):
|
||||||
'''
|
"""
|
||||||
Weight unit serializer
|
Weight unit serializer
|
||||||
'''
|
"""
|
||||||
class Meta:
|
class Meta:
|
||||||
model = WeightUnit
|
model = WeightUnit
|
||||||
|
fields = '__all__'
|
||||||
|
|||||||
@@ -15,109 +15,117 @@
|
|||||||
# You should have received a copy of the GNU Affero General Public License
|
# You should have received a copy of the GNU Affero General Public License
|
||||||
# along with Workout Manager. If not, see <http://www.gnu.org/licenses/>.
|
# along with Workout Manager. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
# Django
|
||||||
from django.contrib.auth.models import User
|
from django.contrib.auth.models import User
|
||||||
from rest_framework import viewsets
|
|
||||||
from rest_framework.response import Response
|
|
||||||
from rest_framework.decorators import detail_route
|
|
||||||
|
|
||||||
from wger.core.models import (
|
# Third Party
|
||||||
UserProfile,
|
from rest_framework import viewsets
|
||||||
Language,
|
from rest_framework.decorators import action
|
||||||
DaysOfWeek,
|
from rest_framework.response import Response
|
||||||
License,
|
|
||||||
RepetitionUnit,
|
# wger
|
||||||
WeightUnit)
|
|
||||||
from wger.core.api.serializers import (
|
from wger.core.api.serializers import (
|
||||||
UsernameSerializer,
|
|
||||||
LanguageSerializer,
|
|
||||||
DaysOfWeekSerializer,
|
DaysOfWeekSerializer,
|
||||||
|
LanguageSerializer,
|
||||||
LicenseSerializer,
|
LicenseSerializer,
|
||||||
RepetitionUnitSerializer,
|
RepetitionUnitSerializer,
|
||||||
|
UsernameSerializer,
|
||||||
|
UserprofileSerializer,
|
||||||
WeightUnitSerializer
|
WeightUnitSerializer
|
||||||
)
|
)
|
||||||
from wger.core.api.serializers import UserprofileSerializer
|
from wger.core.models import (
|
||||||
from wger.utils.permissions import UpdateOnlyPermission, WgerPermission
|
DaysOfWeek,
|
||||||
|
Language,
|
||||||
|
License,
|
||||||
|
RepetitionUnit,
|
||||||
|
UserProfile,
|
||||||
|
WeightUnit
|
||||||
|
)
|
||||||
|
from wger.utils.permissions import (
|
||||||
|
UpdateOnlyPermission,
|
||||||
|
WgerPermission
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class UserProfileViewSet(viewsets.ModelViewSet):
|
class UserProfileViewSet(viewsets.ModelViewSet):
|
||||||
'''
|
"""
|
||||||
API endpoint for workout objects
|
API endpoint for workout objects
|
||||||
'''
|
"""
|
||||||
is_private = True
|
is_private = True
|
||||||
serializer_class = UserprofileSerializer
|
serializer_class = UserprofileSerializer
|
||||||
permission_classes = (WgerPermission, UpdateOnlyPermission)
|
permission_classes = (WgerPermission, UpdateOnlyPermission)
|
||||||
ordering_fields = '__all__'
|
ordering_fields = '__all__'
|
||||||
|
|
||||||
def get_queryset(self):
|
def get_queryset(self):
|
||||||
'''
|
"""
|
||||||
Only allow access to appropriate objects
|
Only allow access to appropriate objects
|
||||||
'''
|
"""
|
||||||
return UserProfile.objects.filter(user=self.request.user)
|
return UserProfile.objects.filter(user=self.request.user)
|
||||||
|
|
||||||
def get_owner_objects(self):
|
def get_owner_objects(self):
|
||||||
'''
|
"""
|
||||||
Return objects to check for ownership permission
|
Return objects to check for ownership permission
|
||||||
'''
|
"""
|
||||||
return [(User, 'user')]
|
return [(User, 'user')]
|
||||||
|
|
||||||
@detail_route()
|
@action(detail=True)
|
||||||
def username(self, request, pk):
|
def username(self, request, pk):
|
||||||
'''
|
"""
|
||||||
Return the username
|
Return the username
|
||||||
'''
|
"""
|
||||||
|
|
||||||
user = self.get_object().user
|
user = self.get_object().user
|
||||||
return Response(UsernameSerializer(user).data)
|
return Response(UsernameSerializer(user).data)
|
||||||
|
|
||||||
|
|
||||||
class LanguageViewSet(viewsets.ReadOnlyModelViewSet):
|
class LanguageViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
'''
|
"""
|
||||||
API endpoint for workout objects
|
API endpoint for workout objects
|
||||||
'''
|
"""
|
||||||
queryset = Language.objects.all()
|
queryset = Language.objects.all()
|
||||||
serializer_class = LanguageSerializer
|
serializer_class = LanguageSerializer
|
||||||
ordering_fields = '__all__'
|
ordering_fields = '__all__'
|
||||||
filter_fields = ('full_name',
|
filterset_fields = ('full_name',
|
||||||
'short_name')
|
'short_name')
|
||||||
|
|
||||||
|
|
||||||
class DaysOfWeekViewSet(viewsets.ReadOnlyModelViewSet):
|
class DaysOfWeekViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
'''
|
"""
|
||||||
API endpoint for workout objects
|
API endpoint for workout objects
|
||||||
'''
|
"""
|
||||||
queryset = DaysOfWeek.objects.all()
|
queryset = DaysOfWeek.objects.all()
|
||||||
serializer_class = DaysOfWeekSerializer
|
serializer_class = DaysOfWeekSerializer
|
||||||
ordering_fields = '__all__'
|
ordering_fields = '__all__'
|
||||||
filter_fields = ('day_of_week', )
|
filterset_fields = ('day_of_week', )
|
||||||
|
|
||||||
|
|
||||||
class LicenseViewSet(viewsets.ReadOnlyModelViewSet):
|
class LicenseViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
'''
|
"""
|
||||||
API endpoint for workout objects
|
API endpoint for workout objects
|
||||||
'''
|
"""
|
||||||
queryset = License.objects.all()
|
queryset = License.objects.all()
|
||||||
serializer_class = LicenseSerializer
|
serializer_class = LicenseSerializer
|
||||||
ordering_fields = '__all__'
|
ordering_fields = '__all__'
|
||||||
filter_fields = ('full_name',
|
filterset_fields = ('full_name',
|
||||||
'short_name',
|
'short_name',
|
||||||
'url')
|
'url')
|
||||||
|
|
||||||
|
|
||||||
class RepetitionUnitViewSet(viewsets.ReadOnlyModelViewSet):
|
class RepetitionUnitViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
'''
|
"""
|
||||||
API endpoint for repetition units objects
|
API endpoint for repetition units objects
|
||||||
'''
|
"""
|
||||||
queryset = RepetitionUnit.objects.all()
|
queryset = RepetitionUnit.objects.all()
|
||||||
serializer_class = RepetitionUnitSerializer
|
serializer_class = RepetitionUnitSerializer
|
||||||
ordering_fields = '__all__'
|
ordering_fields = '__all__'
|
||||||
filter_fields = ('name', )
|
filterset_fields = ('name', )
|
||||||
|
|
||||||
|
|
||||||
class WeightUnitViewSet(viewsets.ReadOnlyModelViewSet):
|
class WeightUnitViewSet(viewsets.ReadOnlyModelViewSet):
|
||||||
'''
|
"""
|
||||||
API endpoint for weight units objects
|
API endpoint for weight units objects
|
||||||
'''
|
"""
|
||||||
queryset = WeightUnit.objects.all()
|
queryset = WeightUnit.objects.all()
|
||||||
serializer_class = WeightUnitSerializer
|
serializer_class = WeightUnitSerializer
|
||||||
ordering_fields = '__all__'
|
ordering_fields = '__all__'
|
||||||
filter_fields = ('name', )
|
filterset_fields = ('name', )
|
||||||
|
|||||||
@@ -14,6 +14,7 @@
|
|||||||
#
|
#
|
||||||
# You should have received a copy of the GNU Affero General Public License
|
# You should have received a copy of the GNU Affero General Public License
|
||||||
|
|
||||||
|
# Django
|
||||||
from django.apps import AppConfig, apps
|
from django.apps import AppConfig, apps
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -14,44 +14,47 @@
|
|||||||
#
|
#
|
||||||
# You should have received a copy of the GNU Affero General Public License
|
# You should have received a copy of the GNU Affero General Public License
|
||||||
|
|
||||||
|
# Standard Library
|
||||||
|
import datetime
|
||||||
import logging
|
import logging
|
||||||
import random
|
import random
|
||||||
import datetime
|
|
||||||
import uuid
|
import uuid
|
||||||
|
|
||||||
from django.contrib.auth.models import User
|
# Django
|
||||||
from django.contrib.auth import authenticate
|
from django.contrib.auth import authenticate
|
||||||
|
from django.contrib.auth.models import User
|
||||||
from django.utils.translation import ugettext as _
|
from django.utils.translation import ugettext as _
|
||||||
|
|
||||||
from wger.weight.models import WeightEntry
|
# wger
|
||||||
from wger.exercises.models import Exercise
|
|
||||||
from wger.core.models import DaysOfWeek
|
from wger.core.models import DaysOfWeek
|
||||||
|
from wger.exercises.models import Exercise
|
||||||
from wger.manager.models import (
|
from wger.manager.models import (
|
||||||
Workout,
|
|
||||||
Day,
|
Day,
|
||||||
|
Schedule,
|
||||||
|
ScheduleStep,
|
||||||
Set,
|
Set,
|
||||||
Setting,
|
Setting,
|
||||||
WorkoutLog,
|
Workout,
|
||||||
Schedule,
|
WorkoutLog
|
||||||
ScheduleStep
|
|
||||||
)
|
)
|
||||||
from wger.nutrition.models import (
|
from wger.nutrition.models import (
|
||||||
NutritionPlan,
|
Ingredient,
|
||||||
|
IngredientWeightUnit,
|
||||||
Meal,
|
Meal,
|
||||||
MealItem,
|
MealItem,
|
||||||
Ingredient,
|
NutritionPlan
|
||||||
IngredientWeightUnit
|
|
||||||
)
|
)
|
||||||
|
|
||||||
from wger.utils.language import load_language
|
from wger.utils.language import load_language
|
||||||
|
from wger.weight.models import WeightEntry
|
||||||
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
def create_temporary_user():
|
def create_temporary_user():
|
||||||
'''
|
"""
|
||||||
Creates a temporary user
|
Creates a temporary user
|
||||||
'''
|
"""
|
||||||
username = uuid.uuid4().hex[:-2]
|
username = uuid.uuid4().hex[:-2]
|
||||||
password = uuid.uuid4().hex[:-2]
|
password = uuid.uuid4().hex[:-2]
|
||||||
email = ''
|
email = ''
|
||||||
@@ -68,9 +71,9 @@ def create_temporary_user():
|
|||||||
|
|
||||||
|
|
||||||
def create_demo_entries(user):
|
def create_demo_entries(user):
|
||||||
'''
|
"""
|
||||||
Creates some demo data for temporary users
|
Creates some demo data for temporary users
|
||||||
'''
|
"""
|
||||||
|
|
||||||
# (this is a bit ugly and long...)
|
# (this is a bit ugly and long...)
|
||||||
language = load_language()
|
language = load_language()
|
||||||
|
|||||||
@@ -1,51 +1,51 @@
|
|||||||
[
|
[
|
||||||
{
|
{
|
||||||
"pk": 1,
|
"pk": 1,
|
||||||
"model": "core.daysofweek",
|
"model": "core.daysofweek",
|
||||||
"fields": {
|
"fields": {
|
||||||
"day_of_week": "Monday"
|
"day_of_week": "Monday"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"pk": 2,
|
"pk": 2,
|
||||||
"model": "core.daysofweek",
|
"model": "core.daysofweek",
|
||||||
"fields": {
|
"fields": {
|
||||||
"day_of_week": "Tuesday"
|
"day_of_week": "Tuesday"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"pk": 3,
|
"pk": 3,
|
||||||
"model": "core.daysofweek",
|
"model": "core.daysofweek",
|
||||||
"fields": {
|
"fields": {
|
||||||
"day_of_week": "Wednesday"
|
"day_of_week": "Wednesday"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"pk": 4,
|
"pk": 4,
|
||||||
"model": "core.daysofweek",
|
"model": "core.daysofweek",
|
||||||
"fields": {
|
"fields": {
|
||||||
"day_of_week": "Thursday"
|
"day_of_week": "Thursday"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"pk": 5,
|
"pk": 5,
|
||||||
"model": "core.daysofweek",
|
"model": "core.daysofweek",
|
||||||
"fields": {
|
"fields": {
|
||||||
"day_of_week": "Friday"
|
"day_of_week": "Friday"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"pk": 6,
|
"pk": 6,
|
||||||
"model": "core.daysofweek",
|
"model": "core.daysofweek",
|
||||||
"fields": {
|
"fields": {
|
||||||
"day_of_week": "Saturday"
|
"day_of_week": "Saturday"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"pk": 7,
|
"pk": 7,
|
||||||
"model": "core.daysofweek",
|
"model": "core.daysofweek",
|
||||||
"fields": {
|
"fields": {
|
||||||
"day_of_week": "Sunday"
|
"day_of_week": "Sunday"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -323,12 +323,12 @@
|
|||||||
"permissions": [
|
"permissions": [
|
||||||
[
|
[
|
||||||
"add_log",
|
"add_log",
|
||||||
"email",
|
"mailer",
|
||||||
"log"
|
"log"
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
"change_log",
|
"change_log",
|
||||||
"email",
|
"mailer",
|
||||||
"log"
|
"log"
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
@@ -562,4 +562,4 @@
|
|||||||
"model": "auth.group",
|
"model": "auth.group",
|
||||||
"pk": 6
|
"pk": 6
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -1,90 +1,98 @@
|
|||||||
[
|
[
|
||||||
{
|
{
|
||||||
|
"model": "core.language",
|
||||||
|
"pk": 1,
|
||||||
"fields": {
|
"fields": {
|
||||||
"short_name": "de",
|
"short_name": "de",
|
||||||
"full_name": "Deutsch"
|
"full_name": "Deutsch"
|
||||||
},
|
}
|
||||||
"model": "core.language",
|
|
||||||
"pk": 1
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"model": "core.language",
|
||||||
|
"pk": 2,
|
||||||
"fields": {
|
"fields": {
|
||||||
"short_name": "en",
|
"short_name": "en",
|
||||||
"full_name": "English"
|
"full_name": "English"
|
||||||
},
|
}
|
||||||
"model": "core.language",
|
|
||||||
"pk": 2
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"model": "core.language",
|
||||||
|
"pk": 3,
|
||||||
"fields": {
|
"fields": {
|
||||||
"short_name": "bg",
|
"short_name": "bg",
|
||||||
"full_name": "\u0431\u044a\u043b\u0433\u0430\u0440\u0441\u043a\u0438 \u0435\u0437\u0438\u043a"
|
"full_name": "\u0431\u044a\u043b\u0433\u0430\u0440\u0441\u043a\u0438 \u0435\u0437\u0438\u043a"
|
||||||
},
|
}
|
||||||
"model": "core.language",
|
|
||||||
"pk": 3
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"model": "core.language",
|
||||||
|
"pk": 4,
|
||||||
"fields": {
|
"fields": {
|
||||||
"short_name": "es",
|
"short_name": "es",
|
||||||
"full_name": "Espa\u00f1ol"
|
"full_name": "Espa\u00f1ol"
|
||||||
},
|
}
|
||||||
"model": "core.language",
|
|
||||||
"pk": 4
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"model": "core.language",
|
||||||
|
"pk": 5,
|
||||||
"fields": {
|
"fields": {
|
||||||
"short_name": "ru",
|
"short_name": "ru",
|
||||||
"full_name": "\u0420\u0443\u0441\u0441\u043a\u0438\u0439"
|
"full_name": "\u0420\u0443\u0441\u0441\u043a\u0438\u0439"
|
||||||
},
|
}
|
||||||
"model": "core.language",
|
|
||||||
"pk": 5
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"model": "core.language",
|
||||||
|
"pk": 6,
|
||||||
"fields": {
|
"fields": {
|
||||||
"short_name": "nl",
|
"short_name": "nl",
|
||||||
"full_name": "Nederlands"
|
"full_name": "Nederlands"
|
||||||
},
|
}
|
||||||
"model": "core.language",
|
|
||||||
"pk": 6
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"model": "core.language",
|
||||||
|
"pk": 7,
|
||||||
"fields": {
|
"fields": {
|
||||||
"short_name": "pt",
|
"short_name": "pt",
|
||||||
"full_name": "Portugu\u00eas"
|
"full_name": "Portugu\u00eas"
|
||||||
},
|
}
|
||||||
"model": "core.language",
|
|
||||||
"pk": 7
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"model": "core.language",
|
||||||
|
"pk": 8,
|
||||||
"fields": {
|
"fields": {
|
||||||
"short_name": "el",
|
"short_name": "el",
|
||||||
"full_name": "\u03b5\u03bb\u03bb\u03b7\u03bd\u03b9\u03ba\u03ac"
|
"full_name": "\u03b5\u03bb\u03bb\u03b7\u03bd\u03b9\u03ba\u03ac"
|
||||||
},
|
}
|
||||||
"model": "core.language",
|
|
||||||
"pk": 8
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"model": "core.language",
|
||||||
|
"pk": 9,
|
||||||
"fields": {
|
"fields": {
|
||||||
"short_name": "cs",
|
"short_name": "cs",
|
||||||
"full_name": "\u010de\u0161tina"
|
"full_name": "\u010de\u0161tina"
|
||||||
},
|
}
|
||||||
"model": "core.language",
|
|
||||||
"pk": 9
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"model": "core.language",
|
||||||
|
"pk": 10,
|
||||||
"fields": {
|
"fields": {
|
||||||
"short_name": "sv",
|
"short_name": "sv",
|
||||||
"full_name": "Svenska"
|
"full_name": "Svenska"
|
||||||
},
|
}
|
||||||
"model": "core.language",
|
|
||||||
"pk": 10
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"model": "core.language",
|
||||||
|
"pk": 11,
|
||||||
"fields": {
|
"fields": {
|
||||||
"short_name": "no",
|
"short_name": "no",
|
||||||
"full_name": "Norsk"
|
"full_name": "Norsk"
|
||||||
},
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
"model": "core.language",
|
"model": "core.language",
|
||||||
"pk": 11
|
"pk": 12,
|
||||||
|
"fields": {
|
||||||
|
"short_name": "fr",
|
||||||
|
"full_name": "Fran\u00e7ais"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -1,37 +1,37 @@
|
|||||||
[
|
[
|
||||||
{
|
{
|
||||||
"pk": 1,
|
"pk": 1,
|
||||||
"model": "core.license",
|
"model": "core.license",
|
||||||
"fields": {
|
"fields": {
|
||||||
"url": "https://creativecommons.org/licenses/by-sa/3.0/deed.en",
|
"url": "https://creativecommons.org/licenses/by-sa/3.0/deed.en",
|
||||||
"full_name": " Creative Commons Attribution Share Alike 3",
|
"full_name": " Creative Commons Attribution Share Alike 3",
|
||||||
"short_name": "CC-BY-SA 3"
|
"short_name": "CC-BY-SA 3"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"pk": 2,
|
"pk": 2,
|
||||||
"model": "core.license",
|
"model": "core.license",
|
||||||
"fields": {
|
"fields": {
|
||||||
"url": "https://creativecommons.org/licenses/by-sa/4.0/deed.en",
|
"url": "https://creativecommons.org/licenses/by-sa/4.0/deed.en",
|
||||||
"full_name": "Creative Commons Attribution Share Alike 4",
|
"full_name": "Creative Commons Attribution Share Alike 4",
|
||||||
"short_name": "CC-BY-SA 4"
|
"short_name": "CC-BY-SA 4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"pk": 3,
|
"pk": 3,
|
||||||
"model": "core.license",
|
"model": "core.license",
|
||||||
"fields": {
|
"fields": {
|
||||||
"url": "http://creativecommons.org/publicdomain/zero/1.0/",
|
"url": "http://creativecommons.org/publicdomain/zero/1.0/",
|
||||||
"full_name": "Creative Commons Public Domain 1.0",
|
"full_name": "Creative Commons Public Domain 1.0",
|
||||||
"short_name": "CC0"
|
"short_name": "CC0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"pk": 4,
|
"pk": 4,
|
||||||
"model": "core.license",
|
"model": "core.license",
|
||||||
"fields": {
|
"fields": {
|
||||||
"url": "http://creativecommons.org/licenses/by/4.0/",
|
"url": "http://creativecommons.org/licenses/by/4.0/",
|
||||||
"full_name": "Creative Commons Attribution 4",
|
"full_name": "Creative Commons Attribution 4",
|
||||||
"short_name": "CC-BY 4"
|
"short_name": "CC-BY 4"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,19 +1,19 @@
|
|||||||
[
|
[
|
||||||
{
|
{
|
||||||
"pk": 1,
|
"pk": 1,
|
||||||
"model": "core.license",
|
"model": "core.license",
|
||||||
"fields": {
|
"fields": {
|
||||||
"url": "",
|
"url": "",
|
||||||
"full_name": "A cool and free license - Germany",
|
"full_name": "A cool and free license - Germany",
|
||||||
"short_name": "ACAFL - DE"
|
"short_name": "ACAFL - DE"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"pk": 2,
|
"pk": 2,
|
||||||
"model": "core.license",
|
"model": "core.license",
|
||||||
"fields": {
|
"fields": {
|
||||||
"url": "https://another-cool-license.org/acl-2.1",
|
"url": "https://another-cool-license.org/acl-2.1",
|
||||||
"full_name": "Another cool license 2.1",
|
"full_name": "Another cool license 2.1",
|
||||||
"short_name": "ACL 2.1"
|
"short_name": "ACL 2.1"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,6 @@
|
|||||||
[
|
[
|
||||||
{
|
{
|
||||||
"pk": 1,
|
"pk": 1,
|
||||||
"model": "auth.user",
|
"model": "auth.user",
|
||||||
"fields": {
|
"fields": {
|
||||||
"username": "admin",
|
"username": "admin",
|
||||||
@@ -34,12 +34,12 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"pk": 1,
|
"pk": 1,
|
||||||
"model": "core.userprofile",
|
"model": "core.userprofile",
|
||||||
"fields": {
|
"fields": {
|
||||||
"is_temporary": false,
|
"is_temporary": false,
|
||||||
"show_comments": false,
|
"show_comments": false,
|
||||||
"show_english_ingredients": false,
|
"show_english_ingredients": false,
|
||||||
"user": 1,
|
"user": 1,
|
||||||
"gym": 1
|
"gym": 1
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,32 +14,71 @@
|
|||||||
#
|
#
|
||||||
# You should have received a copy of the GNU Affero General Public License
|
# You should have received a copy of the GNU Affero General Public License
|
||||||
|
|
||||||
from captcha.fields import ReCaptchaField
|
# Django
|
||||||
from django.contrib.auth.forms import UserCreationForm, AuthenticationForm
|
from django import forms
|
||||||
|
from django.contrib.auth.forms import (
|
||||||
|
AuthenticationForm,
|
||||||
|
UserCreationForm
|
||||||
|
)
|
||||||
from django.contrib.auth.models import User
|
from django.contrib.auth.models import User
|
||||||
from django.core.exceptions import ValidationError
|
from django.core.exceptions import ValidationError
|
||||||
from django import forms
|
|
||||||
from django.forms import (
|
from django.forms import (
|
||||||
|
CharField,
|
||||||
EmailField,
|
EmailField,
|
||||||
Form,
|
Form,
|
||||||
CharField,
|
PasswordInput,
|
||||||
widgets,
|
widgets
|
||||||
PasswordInput
|
|
||||||
)
|
)
|
||||||
from django.utils.translation import ugettext as _
|
from django.utils.translation import ugettext as _
|
||||||
|
|
||||||
|
# Third Party
|
||||||
|
from captcha.fields import ReCaptchaField
|
||||||
|
from crispy_forms.bootstrap import (
|
||||||
|
Accordion,
|
||||||
|
AccordionGroup
|
||||||
|
)
|
||||||
|
from crispy_forms.helper import FormHelper
|
||||||
|
from crispy_forms.layout import (
|
||||||
|
ButtonHolder,
|
||||||
|
Column,
|
||||||
|
Layout,
|
||||||
|
Row,
|
||||||
|
Submit
|
||||||
|
)
|
||||||
|
|
||||||
|
# wger
|
||||||
from wger.core.models import UserProfile
|
from wger.core.models import UserProfile
|
||||||
|
|
||||||
|
|
||||||
class UserLoginForm(AuthenticationForm):
|
class UserLoginForm(AuthenticationForm):
|
||||||
'''
|
"""
|
||||||
Form for logins
|
Form for logins
|
||||||
|
"""
|
||||||
|
|
||||||
Overwritten here just to change the label on the 'username' field
|
def __init__(self, *args, **kwargs):
|
||||||
'''
|
super(UserLoginForm, self).__init__(*args, **kwargs)
|
||||||
username = forms.CharField(label=_("Username or email"), max_length=254)
|
|
||||||
|
self.helper = FormHelper()
|
||||||
|
self.helper.add_input(Submit('submit', _('Login'), css_class='btn-success btn-block'))
|
||||||
|
self.helper.form_class = 'wger-form'
|
||||||
|
self.helper.layout = Layout(
|
||||||
|
Row(
|
||||||
|
Column('username', css_class='form-group col-6 mb-0'),
|
||||||
|
Column('password', css_class='form-group col-6 mb-0'),
|
||||||
|
css_class='form-row'
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class UserPreferencesForm(forms.ModelForm):
|
class UserPreferencesForm(forms.ModelForm):
|
||||||
|
first_name = forms.CharField(label=_('First name'),
|
||||||
|
required=False)
|
||||||
|
last_name = forms.CharField(label=_('Last name'),
|
||||||
|
required=False)
|
||||||
|
email = EmailField(label=_("Email"),
|
||||||
|
help_text=_("Used for password resets and, optionally, email reminders."),
|
||||||
|
required=False)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = UserProfile
|
model = UserProfile
|
||||||
fields = ('show_comments',
|
fields = ('show_comments',
|
||||||
@@ -52,7 +91,43 @@ class UserPreferencesForm(forms.ModelForm):
|
|||||||
'timer_active',
|
'timer_active',
|
||||||
'timer_pause',
|
'timer_pause',
|
||||||
'ro_access',
|
'ro_access',
|
||||||
'num_days_weight_reminder')
|
'num_days_weight_reminder',
|
||||||
|
'birthdate'
|
||||||
|
)
|
||||||
|
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
super(UserPreferencesForm, self).__init__(*args, **kwargs)
|
||||||
|
self.helper = FormHelper()
|
||||||
|
self.helper.form_class = 'wger-form'
|
||||||
|
self.helper.layout = Layout(
|
||||||
|
Accordion(
|
||||||
|
AccordionGroup(_("Personal data"),
|
||||||
|
'email',
|
||||||
|
Row(Column('first_name', css_class='form-group col-6 mb-0'),
|
||||||
|
Column('last_name', css_class='form-group col-6 mb-0'),
|
||||||
|
css_class='form-row'),
|
||||||
|
),
|
||||||
|
AccordionGroup(_("Workout reminders"),
|
||||||
|
'workout_reminder_active',
|
||||||
|
'workout_reminder',
|
||||||
|
'workout_duration',
|
||||||
|
),
|
||||||
|
AccordionGroup("{} ({})".format(_("Gym mode"), _("mobile version only")),
|
||||||
|
"timer_active",
|
||||||
|
"timer_pause"
|
||||||
|
),
|
||||||
|
AccordionGroup(_("Other settings"),
|
||||||
|
"ro_access",
|
||||||
|
"notification_language",
|
||||||
|
"weight_unit",
|
||||||
|
"show_comments",
|
||||||
|
"show_english_ingredients",
|
||||||
|
"num_days_weight_reminder",
|
||||||
|
"birthdate",
|
||||||
|
)
|
||||||
|
),
|
||||||
|
ButtonHolder(Submit('submit', _("Save"), css_class='btn-success btn-block'))
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class UserEmailForm(forms.ModelForm):
|
class UserEmailForm(forms.ModelForm):
|
||||||
@@ -65,14 +140,14 @@ class UserEmailForm(forms.ModelForm):
|
|||||||
fields = ('email', )
|
fields = ('email', )
|
||||||
|
|
||||||
def clean_email(self):
|
def clean_email(self):
|
||||||
'''
|
"""
|
||||||
Email must be unique system wide
|
Email must be unique system wide
|
||||||
|
|
||||||
However, this check should only be performed when the user changes his
|
However, this check should only be performed when the user changes his
|
||||||
email, otherwise the uniqueness check will because it will find one user
|
email, otherwise the uniqueness check will because it will find one user
|
||||||
(the current one) using the same email. Only when the user changes it, do
|
(the current one) using the same email. Only when the user changes it, do
|
||||||
we want to check that nobody else has that email
|
we want to check that nobody else has that email
|
||||||
'''
|
"""
|
||||||
|
|
||||||
email = self.cleaned_data["email"]
|
email = self.cleaned_data["email"]
|
||||||
if not email:
|
if not email:
|
||||||
@@ -99,12 +174,12 @@ class UserPersonalInformationForm(UserEmailForm):
|
|||||||
|
|
||||||
|
|
||||||
class PasswordConfirmationForm(Form):
|
class PasswordConfirmationForm(Form):
|
||||||
'''
|
"""
|
||||||
A simple password confirmation form.
|
A simple password confirmation form.
|
||||||
|
|
||||||
This can be used to make sure the user really wants to perform a dangerous
|
This can be used to make sure the user really wants to perform a dangerous
|
||||||
action. The form must be initialised with a user object.
|
action. The form must be initialised with a user object.
|
||||||
'''
|
"""
|
||||||
password = CharField(label=_("Password"),
|
password = CharField(label=_("Password"),
|
||||||
widget=PasswordInput,
|
widget=PasswordInput,
|
||||||
help_text=_('Please enter your current password.'))
|
help_text=_('Please enter your current password.'))
|
||||||
@@ -112,11 +187,16 @@ class PasswordConfirmationForm(Form):
|
|||||||
def __init__(self, user, data=None):
|
def __init__(self, user, data=None):
|
||||||
self.user = user
|
self.user = user
|
||||||
super(PasswordConfirmationForm, self).__init__(data=data)
|
super(PasswordConfirmationForm, self).__init__(data=data)
|
||||||
|
self.helper = FormHelper()
|
||||||
|
self.helper.layout = Layout(
|
||||||
|
'password',
|
||||||
|
ButtonHolder(Submit('submit', _("Delete"), css_class='btn-danger btn-block'))
|
||||||
|
)
|
||||||
|
|
||||||
def clean_password(self):
|
def clean_password(self):
|
||||||
'''
|
"""
|
||||||
Check that the password supplied matches the one for the user
|
Check that the password supplied matches the one for the user
|
||||||
'''
|
"""
|
||||||
password = self.cleaned_data.get('password', None)
|
password = self.cleaned_data.get('password', None)
|
||||||
if not self.user.check_password(password):
|
if not self.user.check_password(password):
|
||||||
raise ValidationError(_('Invalid password'))
|
raise ValidationError(_('Invalid password'))
|
||||||
@@ -124,34 +204,43 @@ class PasswordConfirmationForm(Form):
|
|||||||
|
|
||||||
|
|
||||||
class RegistrationForm(UserCreationForm, UserEmailForm):
|
class RegistrationForm(UserCreationForm, UserEmailForm):
|
||||||
'''
|
"""
|
||||||
Registration form
|
Registration form
|
||||||
'''
|
"""
|
||||||
|
|
||||||
# Manually set the language to 'en', otherwise the language used seems to
|
# Manually set the language to 'en', otherwise the language used seems to
|
||||||
# randomly one of the application languages. This also appears to happen
|
# randomly one of the application languages. This also appears to happen
|
||||||
# only on wger.de, perhaps because there the application is behind a reverse
|
# only on wger.de, perhaps because there the application is behind a reverse
|
||||||
# proxy. See #281.
|
# proxy. See #281.
|
||||||
captcha = ReCaptchaField(attrs={'theme': 'clean', 'lang': 'en'},
|
captcha = ReCaptchaField(label=_('Confirmation text'),
|
||||||
label=_('Confirmation text'),
|
|
||||||
help_text=_('As a security measure, please enter the previous words'))
|
help_text=_('As a security measure, please enter the previous words'))
|
||||||
|
|
||||||
|
|
||||||
class RegistrationFormNoCaptcha(UserCreationForm, UserEmailForm):
|
class RegistrationFormNoCaptcha(UserCreationForm, UserEmailForm):
|
||||||
'''
|
"""
|
||||||
Registration form without captcha field
|
Registration form without captcha field
|
||||||
|
"""
|
||||||
|
|
||||||
This is used when registering through an app, in that case there is not
|
def __init__(self, *args, **kwargs):
|
||||||
such a spam danger and simplifies the registration process on a mobile
|
super(RegistrationFormNoCaptcha, self).__init__(*args, **kwargs)
|
||||||
device.
|
self.helper = FormHelper()
|
||||||
'''
|
self.helper.form_class = 'wger-form'
|
||||||
pass
|
self.helper.layout = Layout(
|
||||||
|
'username',
|
||||||
|
'email',
|
||||||
|
Row(
|
||||||
|
Column('password1', css_class='form-group col-6 mb-0'),
|
||||||
|
Column('password2', css_class='form-group col-6 mb-0'),
|
||||||
|
css_class='form-row'
|
||||||
|
),
|
||||||
|
ButtonHolder(Submit('submit', _("Register"), css_class='btn-success btn-block'))
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class FeedbackRegisteredForm(forms.Form):
|
class FeedbackRegisteredForm(forms.Form):
|
||||||
'''
|
"""
|
||||||
Feedback form used for logged in users
|
Feedback form used for logged in users
|
||||||
'''
|
"""
|
||||||
contact = forms.CharField(max_length=50,
|
contact = forms.CharField(max_length=50,
|
||||||
min_length=10,
|
min_length=10,
|
||||||
label=_('Contact'),
|
label=_('Contact'),
|
||||||
@@ -167,9 +256,8 @@ class FeedbackRegisteredForm(forms.Form):
|
|||||||
|
|
||||||
|
|
||||||
class FeedbackAnonymousForm(FeedbackRegisteredForm):
|
class FeedbackAnonymousForm(FeedbackRegisteredForm):
|
||||||
'''
|
"""
|
||||||
Feedback form used for anonymous users (has additionally a reCaptcha field)
|
Feedback form used for anonymous users (has additionally a reCaptcha field)
|
||||||
'''
|
"""
|
||||||
captcha = ReCaptchaField(attrs={'theme': 'clean'},
|
captcha = ReCaptchaField(label=_('Confirmation text'),
|
||||||
label=_('Confirmation text'),
|
|
||||||
help_text=_('As a security measure, please enter the previous words'),)
|
help_text=_('As a security measure, please enter the previous words'),)
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user