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
|
||||
trim_trailing_whitespace = true
|
||||
|
||||
# Docstrings and comments use max_line_length = 79
|
||||
[*.py]
|
||||
max_line_length = 100
|
||||
|
||||
#
|
||||
# Javascript
|
||||
#
|
||||
[*.js]
|
||||
indent_size = 2
|
||||
|
||||
[.eslintignore]
|
||||
[{.eslintrc,.eslintignore}]
|
||||
indent_size = 2
|
||||
|
||||
#
|
||||
# Python
|
||||
#
|
||||
[*.py]
|
||||
max_line_length = 100
|
||||
|
||||
#
|
||||
# JSON File
|
||||
#
|
||||
[*.json]
|
||||
indent_size = 2
|
||||
|
||||
#
|
||||
# YAML File
|
||||
#
|
||||
[*.yml]
|
||||
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
|
||||
* text=auto
|
||||
# Bash scripts (e.g. in Docker) make problems when the line ending is not LF
|
||||
* 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": {
|
||||
"browser": 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
|
||||
.idea/
|
||||
|
||||
# External Libraries
|
||||
wger/core/static/bower_components
|
||||
# External Libraries
|
||||
wger/core/static/yarn
|
||||
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
|
||||
dist: bionic
|
||||
|
||||
services:
|
||||
- postgresql
|
||||
|
||||
# Cache the pip files
|
||||
cache:
|
||||
@@ -8,60 +12,43 @@ cache:
|
||||
- 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:
|
||||
- "2.7"
|
||||
- "3.4"
|
||||
- "3.5"
|
||||
- "3.6"
|
||||
- "3.7"
|
||||
- "3.8"
|
||||
|
||||
node_js: 10
|
||||
|
||||
# Manually define here the combinations environment variables to test
|
||||
# https://github.com/travis-ci/travis-ci/issues/1519
|
||||
env:
|
||||
- TEST_MOBILE=True DB=postgresql TRAVIS_NODE_VERSION="4"
|
||||
- TEST_MOBILE=True DB=sqlite TRAVIS_NODE_VERSION="4"
|
||||
- TEST_MOBILE=False DB=postgresql TRAVIS_NODE_VERSION="4"
|
||||
- TEST_MOBILE=False DB=sqlite TRAVIS_NODE_VERSION="4"
|
||||
- DB=postgresql
|
||||
- DB=sqlite
|
||||
|
||||
# Install the application
|
||||
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
|
||||
- pip install -r requirements_devel.txt
|
||||
- npm install
|
||||
- python setup.py develop
|
||||
- cd wger
|
||||
- if [[ "$DB" = "postgresql" ]]; then pip install psycopg2; fi
|
||||
|
||||
# Setup application
|
||||
- if [[ "$DB" = "sqlite" ]]; then invoke create_settings; fi
|
||||
- if [[ "$DB" = "postgresql" ]]; then invoke create_settings --database-type postgresql; fi
|
||||
- if [[ "$DB" = "sqlite" ]]; then wger create-settings; fi
|
||||
- if [[ "$DB" = "postgresql" ]]; then wger create-settings --database-type postgresql; fi
|
||||
|
||||
# change back to the source folder
|
||||
- cd ..
|
||||
|
||||
# Create test databases
|
||||
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
|
||||
|
||||
# Do the tests
|
||||
script:
|
||||
# Formatting
|
||||
- pep8 wger
|
||||
|
||||
# Javascript linting
|
||||
- gulp lint
|
||||
|
||||
# Regular application
|
||||
- coverage run --source='.' ./manage.py test
|
||||
|
||||
- coverage run --source='.' ./manage.py test --parallel
|
||||
|
||||
# Code coverage
|
||||
- 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
|
||||
* Malcolm Jones: https://github.com/DevloperMal
|
||||
* Boniface Mwenda: https://github.com/andela-bmwenda
|
||||
* Scott Peshak: https://github.com/speshak
|
||||
|
||||
Translators
|
||||
-----------
|
||||
|
||||
15
MANIFEST.in
15
MANIFEST.in
@@ -1,24 +1,21 @@
|
||||
# Files in root folder
|
||||
include README.rst
|
||||
include AUTHORS.txt
|
||||
include AGPL.txt
|
||||
include CC-BY-SA.txt
|
||||
include requirements.txt
|
||||
include tasks.py
|
||||
include requirements_devel.txt
|
||||
|
||||
# Application folder as well as extras
|
||||
recursive-include extras *.*
|
||||
recursive-include wger *.*
|
||||
recursive-exclude wger *.pyc
|
||||
recursive-exclude wger *.swp
|
||||
recursive-exclude wger *~
|
||||
include extras/docker/*/Dockerfile
|
||||
|
||||
# added by check_manifest.py
|
||||
include *.rst
|
||||
include *.txt
|
||||
# Documentation
|
||||
recursive-include docs *.bat
|
||||
recursive-include docs *.py
|
||||
recursive-include docs *.rst
|
||||
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
|
||||
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.
|
||||
wger
|
||||
====
|
||||
|
||||
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
|
||||
============
|
||||
|
||||
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
|
||||
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
|
||||
_build/index.html).
|
||||
in your code repository in the docs folder.
|
||||
|
||||
Please consult the commands' help for further information and available
|
||||
parameters.
|
||||
@@ -25,7 +24,8 @@ parameters.
|
||||
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
|
||||
|
||||
@@ -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::
|
||||
|
||||
$ virtualenv --python python3 venv-django
|
||||
$ source venv-django/bin/activate
|
||||
$ python3 -m venv venv-wger
|
||||
$ source venv-wger/bin/activate
|
||||
|
||||
|
||||
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
|
||||
$ cd wger
|
||||
$ pip install -r requirements.txt # or requirements_devel.txt to develop
|
||||
$ 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
|
||||
$ pip install -r requirements.txt
|
||||
$ python setup.py develop
|
||||
$ wger create-settings --settings-path $(pwd)/settings.py --database-path $(pwd)/database.sqlite
|
||||
$ wger bootstrap --settings-path $(pwd)/settings.py --no-start-server
|
||||
$ python manage.py runserver
|
||||
|
||||
3) Log in as: **admin**, password **admin**
|
||||
|
||||
After the first run you can just use django's development server. You will
|
||||
probably want to move the settings and sqlite files to your git folder, see
|
||||
the comments in the documentation (development chapter) about this::
|
||||
After the first run you just start django's development server::
|
||||
|
||||
$ 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)
|
||||
--------------------------
|
||||
@@ -119,38 +80,45 @@ Stable version (from PyPI)
|
||||
|
||||
::
|
||||
|
||||
$ sudo apt-get install python3-dev python-virtualenv nodejs nodejs-legacy npm libjpeg8-dev zlib1g-dev
|
||||
$ virtualenv venv-django
|
||||
$ source venv-django/bin/activate
|
||||
$ sudo apt-get install python3-dev nodejs npm git
|
||||
$ sudo npm install -g yarn
|
||||
$ python3 -m venv venv-wger
|
||||
$ source venv-wger/bin/activate
|
||||
$ pip install wger
|
||||
|
||||
|
||||
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.
|
||||
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
|
||||
--------------------
|
||||
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
|
||||
``invoke`` (if installed from source) are the following (use e.g. ``wger
|
||||
<command>``::
|
||||
Available tasks:
|
||||
|
||||
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
|
||||
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
|
||||
You can also get help on a specific command with ``wger --help <command>``.
|
||||
|
||||
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
|
||||
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
|
||||
* **gitter:** https://gitter.im/wger-project/wger
|
||||
* **issue tracker:** https://github.com/wger-project/wger/issues
|
||||
* **twitter:** https://twitter.com/wger_project
|
||||
|
||||
|
||||
Sources
|
||||
@@ -173,29 +139,28 @@ Sources
|
||||
All the code and the content is freely available:
|
||||
|
||||
* **Main repository:** https://github.com/wger-project/wger
|
||||
* **Mirror:** https://bitbucket.org/rolandgeider/wger
|
||||
|
||||
|
||||
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
|
||||
your choice.
|
||||
|
||||
.. 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
|
||||
|
||||
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+).
|
||||
|
||||
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,
|
||||
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
|
||||
Some images were taken from Wikipedia, see the SOURCES file in their respective
|
||||
folders for more details.
|
||||
|
||||
@@ -1,9 +1,113 @@
|
||||
Changelog
|
||||
=========
|
||||
|
||||
1.8 - IN DEVELOPMENT
|
||||
--------------------
|
||||
**2016-XX-XX**
|
||||
2.0 - IN DEVELOPMENT
|
||||
**2020-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:
|
||||
|
||||
@@ -22,6 +126,7 @@ Upgrade steps from 1.7:
|
||||
New languages:
|
||||
|
||||
* Norwegian (many thanks to Kjetil Elde `@w00p`_ `#304`_)
|
||||
* French (many thanks to all translators)
|
||||
|
||||
New features:
|
||||
|
||||
@@ -43,6 +148,7 @@ Improvements:
|
||||
* Give feedback when autocompleter didn't find any results `#293`_
|
||||
* Make exercise names links to their detail page in training log pages `#350`_
|
||||
* 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`_
|
||||
* New, more verbose, API endpoint for exercises, (thanks `@andela-bmwenda`_)
|
||||
* 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
|
||||
.. _#248: https://github.com/wger-project/wger/issues/248
|
||||
.. _#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
|
||||
.. _#269: https://github.com/wger-project/wger/issues/269
|
||||
.. _#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
|
||||
.. _@w00p: https://github.com/w00p
|
||||
.. _@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
|
||||
------
|
||||
|
||||
* Code according to PEP8
|
||||
|
||||
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.
|
||||
Code according to PEP8, but with but with a maximum line length of 100.
|
||||
|
||||
|
||||
Javascript
|
||||
@@ -29,12 +20,8 @@ Javascript
|
||||
* 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
|
||||
files you can run the following commands:
|
||||
|
||||
* 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)
|
||||
The coding style is automatically checked by GitHub actions after sending a
|
||||
pull request.
|
||||
|
||||
@@ -8,56 +8,47 @@ running application (to e.g. delete guest users, send emails, etc.).
|
||||
Administration Commands
|
||||
-----------------------
|
||||
|
||||
The application provides several administration and bootstraping commands. They
|
||||
are all available with ``wger`` (if installed from PyPI) or ``invoke`` (if
|
||||
installed from source)::
|
||||
The application provides several administration and bootstraping commands that
|
||||
can be passed to the ``wger`` command::
|
||||
|
||||
wger <command>
|
||||
|
||||
or ::
|
||||
|
||||
invoke <command>
|
||||
|
||||
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::
|
||||
You can get a list of all available commands by calling ``wger`` without any
|
||||
arguments::
|
||||
|
||||
Available tasks:
|
||||
|
||||
bootstrap_wger 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_wger Start the application using django's built in webserver
|
||||
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
|
||||
|
||||
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::
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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: inv[oke] [--core-opts] bootstrap_wger [--options] [other tasks here ...]
|
||||
Usage: inv[oke] [--core-opts] bootstrap [--options] [other tasks here ...]
|
||||
|
||||
Docstring:
|
||||
Performs all steps necessary to bootstrap the application
|
||||
@@ -81,11 +72,11 @@ Usage::
|
||||
Start wger
|
||||
~~~~~~~~~~
|
||||
|
||||
Command: **start_wger**
|
||||
Command: **start**
|
||||
|
||||
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*,
|
||||
it simply calls django's development server and (optionally) opens a browser
|
||||
@@ -94,7 +85,7 @@ is probably better.
|
||||
|
||||
Usage::
|
||||
|
||||
Usage: inv[oke] [--core-opts] start_wger [--options] [other tasks here ...]
|
||||
Usage: inv[oke] [--core-opts] start [--options] [other tasks here ...]
|
||||
|
||||
Docstring:
|
||||
Start the application using django's built in webserver
|
||||
@@ -111,7 +102,7 @@ Usage::
|
||||
Default locations
|
||||
~~~~~~~~~~~~~~~~~
|
||||
|
||||
Command: **config_location**
|
||||
Command: **config-location**
|
||||
|
||||
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
|
||||
@@ -121,21 +112,21 @@ files.
|
||||
Create settings
|
||||
~~~~~~~~~~~~~~~
|
||||
|
||||
Command: **create_settings**
|
||||
Command: **create-settings**
|
||||
|
||||
Creates a new settings file based. If you call it without further arguments it
|
||||
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::
|
||||
|
||||
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: inv[oke] [--core-opts] create_settings [--options] [other tasks here ...]
|
||||
Usage: inv[oke] [--core-opts] create-settings [--options] [other tasks here ...]
|
||||
|
||||
Docstring:
|
||||
Creates a local settings file
|
||||
@@ -152,7 +143,7 @@ Usage::
|
||||
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
|
||||
it is reset.
|
||||
@@ -160,7 +151,7 @@ it is reset.
|
||||
|
||||
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:
|
||||
Creates an admin user or resets the password for an existing one
|
||||
@@ -173,7 +164,7 @@ Usage::
|
||||
Migrate database
|
||||
~~~~~~~~~~~~~~~~
|
||||
|
||||
Command: **migrate_db**
|
||||
Command: **migrate-db**
|
||||
|
||||
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
|
||||
@@ -185,7 +176,7 @@ will happen.
|
||||
|
||||
Usage::
|
||||
|
||||
Usage: inv[oke] [--core-opts] migrate_db [--options] [other tasks here ...]
|
||||
Usage: inv[oke] [--core-opts] migrate-db [--options] [other tasks here ...]
|
||||
|
||||
Docstring:
|
||||
Run all database migrations
|
||||
@@ -198,7 +189,7 @@ Usage::
|
||||
Load all fixtures
|
||||
~~~~~~~~~~~~~~~~~
|
||||
|
||||
Command: **load_fixtures**
|
||||
Command: **load-fixtures**
|
||||
|
||||
Loads all fixture file with the default data. This data includes all data necessary
|
||||
for the application to work such as:
|
||||
@@ -215,7 +206,7 @@ as workouts are *not* reset with this, only the application data.
|
||||
|
||||
Usage::
|
||||
|
||||
Usage: inv[oke] [--core-opts] load_fixtures [--options] [other tasks here ...]
|
||||
Usage: inv[oke] [--core-opts] load-fixtures [--options] [other tasks here ...]
|
||||
|
||||
Docstring:
|
||||
Loads all fixtures
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# flake8: noqa
|
||||
#
|
||||
# wger Workout Manager documentation build configuration file, created by
|
||||
# sphinx-quickstart on Mon Dec 1 22:22:02 2014.
|
||||
@@ -47,16 +48,16 @@ master_doc = 'index'
|
||||
|
||||
# General information about the project.
|
||||
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
|
||||
# |version| and |release|, also used in various other places throughout the
|
||||
# built documents.
|
||||
#
|
||||
# The short X.Y version.
|
||||
version = '1.8'
|
||||
version = '2.0'
|
||||
# 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
|
||||
# for a list of supported languages.
|
||||
|
||||
@@ -3,210 +3,63 @@
|
||||
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
|
||||
~~~~~~~~~~~~
|
||||
::
|
||||
|
||||
The code is available on Github::
|
||||
|
||||
$ git clone https://github.com/wger-project/wger.git
|
||||
|
||||
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
|
||||
|
||||
$ git clone https://github.com/wger-project/wger.git src
|
||||
$ cd src
|
||||
$ WGER_PATH=$(pwd)
|
||||
|
||||
Install Requirements
|
||||
~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
To install the Python requirements::
|
||||
::
|
||||
|
||||
$ pip install -r requirements_devel.txt
|
||||
$ npm install -g yarn sass
|
||||
$ python setup.py develop
|
||||
|
||||
Install NodeJS and npm::
|
||||
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 application
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Install the npm modules::
|
||||
|
||||
$ npm install
|
||||
This will download the required JS and CSS libraries and create a SQlite
|
||||
database and populate it with data on the first run::
|
||||
|
||||
|
||||
Install site
|
||||
~~~~~~~~~~~~
|
||||
|
||||
To install the server::
|
||||
|
||||
$ 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 \
|
||||
$ wger create-settings \
|
||||
--settings-path $WGER_PATH/settings.py \
|
||||
--database-path $WGER_PATH/database.sqlite
|
||||
$ wger bootstrap \
|
||||
--settings-path $WGER_PATH/settings.py \
|
||||
--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
|
||||
----------------
|
||||
|
||||
To start the server::
|
||||
After the first run you can just use django's development server::
|
||||
|
||||
$ 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
|
||||
* **passsword**: admin
|
||||
* **password**: admin
|
||||
|
||||
You can start the application again with the django server with
|
||||
``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
|
||||
running. They are all located under ``extras/docker`` if you want to build
|
||||
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
|
||||
-----------
|
||||
@@ -12,10 +33,9 @@ Development
|
||||
This image installs the application using virtualenv, uses a sqlite database
|
||||
and serves it with django's development server.
|
||||
|
||||
Get the image::
|
||||
|
||||
First build the image::
|
||||
|
||||
docker build -t wger/devel .
|
||||
docker pull wger/devel
|
||||
|
||||
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) python manage.py runserver 0.0.0.0:8000
|
||||
|
||||
Now you can access the application on port 8000 of your host (probably just
|
||||
http://localhost:8000).
|
||||
Then just open http://localhost:8000 and log in as: **admin**, password **admin**
|
||||
|
||||
Depending on what you intend to do with it, you might want to map a local folder
|
||||
to the container. This is interesting if e.g. you want to keep the wger source
|
||||
code on your host machine and use docker only to serve it. Then you can do this::
|
||||
As an alternative you might want to map a local folder to the container.
|
||||
This is interesting if e.g. you want to keep the wger source code on
|
||||
your host machine and use docker only to serve it. Then do this::
|
||||
|
||||
docker run -ti \
|
||||
--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 \
|
||||
wger/devel
|
||||
|
||||
It will mount the local path *on top* of the folder in the container, basically
|
||||
exchanging one for the other. Please note that for this to work you need to
|
||||
manually checkout the code to ``/path/to/local/wger/`` and create a settings file
|
||||
as well.
|
||||
It will mount the local path *on top* of the folder in the container. For this to
|
||||
work you obviously need to manually checkout the code to ``/path/to/local/wger/``
|
||||
and create a settings file 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.
|
||||
|
||||
|
||||
Installation and development
|
||||
----------------------------
|
||||
Installation and administration
|
||||
-------------------------------
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
install
|
||||
commands
|
||||
installation
|
||||
|
||||
|
||||
Development
|
||||
-------------------------------
|
||||
.. toctree::
|
||||
|
||||
tips_and_tricks
|
||||
codingstyle
|
||||
i18n
|
||||
|
||||
|
||||
|
||||
Administration guide
|
||||
--------------------
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
commands
|
||||
settings
|
||||
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
|
||||
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,
|
||||
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
|
||||
@@ -85,11 +90,3 @@ folders for more details.
|
||||
.. include the authors file from the root folder
|
||||
.. 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
|
||||
|
||||
REM Command file for Sphinx documentation
|
||||
|
||||
if "%SPHINXBUILD%" == "" (
|
||||
set SPHINXBUILD=sphinx-build
|
||||
)
|
||||
set BUILDDIR=_build
|
||||
set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% .
|
||||
set I18NSPHINXOPTS=%SPHINXOPTS% .
|
||||
if NOT "%PAPER%" == "" (
|
||||
set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS%
|
||||
set I18NSPHINXOPTS=-D latex_paper_size=%PAPER% %I18NSPHINXOPTS%
|
||||
)
|
||||
|
||||
if "%1" == "" goto help
|
||||
|
||||
if "%1" == "help" (
|
||||
:help
|
||||
echo.Please use `make ^<target^>` where ^<target^> is one of
|
||||
echo. html to make standalone HTML files
|
||||
echo. dirhtml to make HTML files named index.html in directories
|
||||
echo. singlehtml to make a single large HTML file
|
||||
echo. pickle to make pickle files
|
||||
echo. json to make JSON files
|
||||
echo. htmlhelp to make HTML files and a HTML help project
|
||||
echo. qthelp to make HTML files and a qthelp project
|
||||
echo. devhelp to make HTML files and a Devhelp project
|
||||
echo. epub to make an epub
|
||||
echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter
|
||||
echo. text to make text files
|
||||
echo. man to make manual pages
|
||||
echo. texinfo to make Texinfo files
|
||||
echo. gettext to make PO message catalogs
|
||||
echo. changes to make an overview over all changed/added/deprecated items
|
||||
echo. xml to make Docutils-native XML files
|
||||
echo. pseudoxml to make pseudoxml-XML files for display purposes
|
||||
echo. linkcheck to check all external links for integrity
|
||||
echo. doctest to run all doctests embedded in the documentation if enabled
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "clean" (
|
||||
for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i
|
||||
del /q /s %BUILDDIR%\*
|
||||
goto end
|
||||
)
|
||||
|
||||
|
||||
%SPHINXBUILD% 2> nul
|
||||
if errorlevel 9009 (
|
||||
echo.
|
||||
echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
|
||||
echo.installed, then set the SPHINXBUILD environment variable to point
|
||||
echo.to the full path of the 'sphinx-build' executable. Alternatively you
|
||||
echo.may add the Sphinx directory to PATH.
|
||||
echo.
|
||||
echo.If you don't have Sphinx installed, grab it from
|
||||
echo.http://sphinx-doc.org/
|
||||
exit /b 1
|
||||
)
|
||||
|
||||
if "%1" == "html" (
|
||||
%SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished. The HTML pages are in %BUILDDIR%/html.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "dirhtml" (
|
||||
%SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "singlehtml" (
|
||||
%SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "pickle" (
|
||||
%SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished; now you can process the pickle files.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "json" (
|
||||
%SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished; now you can process the JSON files.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "htmlhelp" (
|
||||
%SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished; now you can run HTML Help Workshop with the ^
|
||||
.hhp project file in %BUILDDIR%/htmlhelp.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "qthelp" (
|
||||
%SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished; now you can run "qcollectiongenerator" with the ^
|
||||
.qhcp project file in %BUILDDIR%/qthelp, like this:
|
||||
echo.^> qcollectiongenerator %BUILDDIR%\qthelp\wgerWorkoutManager.qhcp
|
||||
echo.To view the help file:
|
||||
echo.^> assistant -collectionFile %BUILDDIR%\qthelp\wgerWorkoutManager.ghc
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "devhelp" (
|
||||
%SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "epub" (
|
||||
%SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished. The epub file is in %BUILDDIR%/epub.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "latex" (
|
||||
%SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished; the LaTeX files are in %BUILDDIR%/latex.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "latexpdf" (
|
||||
%SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
|
||||
cd %BUILDDIR%/latex
|
||||
make all-pdf
|
||||
cd %BUILDDIR%/..
|
||||
echo.
|
||||
echo.Build finished; the PDF files are in %BUILDDIR%/latex.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "latexpdfja" (
|
||||
%SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
|
||||
cd %BUILDDIR%/latex
|
||||
make all-pdf-ja
|
||||
cd %BUILDDIR%/..
|
||||
echo.
|
||||
echo.Build finished; the PDF files are in %BUILDDIR%/latex.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "text" (
|
||||
%SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished. The text files are in %BUILDDIR%/text.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "man" (
|
||||
%SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished. The manual pages are in %BUILDDIR%/man.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "texinfo" (
|
||||
%SPHINXBUILD% -b texinfo %ALLSPHINXOPTS% %BUILDDIR%/texinfo
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished. The Texinfo files are in %BUILDDIR%/texinfo.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "gettext" (
|
||||
%SPHINXBUILD% -b gettext %I18NSPHINXOPTS% %BUILDDIR%/locale
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished. The message catalogs are in %BUILDDIR%/locale.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "changes" (
|
||||
%SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.The overview file is in %BUILDDIR%/changes.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "linkcheck" (
|
||||
%SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Link check complete; look for any errors in the above output ^
|
||||
or in %BUILDDIR%/linkcheck/output.txt.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "doctest" (
|
||||
%SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Testing of doctests in the sources finished, look at the ^
|
||||
results in %BUILDDIR%/doctest/output.txt.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "xml" (
|
||||
%SPHINXBUILD% -b xml %ALLSPHINXOPTS% %BUILDDIR%/xml
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished. The XML files are in %BUILDDIR%/xml.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "pseudoxml" (
|
||||
%SPHINXBUILD% -b pseudoxml %ALLSPHINXOPTS% %BUILDDIR%/pseudoxml
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished. The pseudo-XML files are in %BUILDDIR%/pseudoxml.
|
||||
goto end
|
||||
)
|
||||
|
||||
:end
|
||||
@ECHO OFF
|
||||
|
||||
REM Command file for Sphinx documentation
|
||||
|
||||
if "%SPHINXBUILD%" == "" (
|
||||
set SPHINXBUILD=sphinx-build
|
||||
)
|
||||
set BUILDDIR=_build
|
||||
set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% .
|
||||
set I18NSPHINXOPTS=%SPHINXOPTS% .
|
||||
if NOT "%PAPER%" == "" (
|
||||
set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS%
|
||||
set I18NSPHINXOPTS=-D latex_paper_size=%PAPER% %I18NSPHINXOPTS%
|
||||
)
|
||||
|
||||
if "%1" == "" goto help
|
||||
|
||||
if "%1" == "help" (
|
||||
:help
|
||||
echo.Please use `make ^<target^>` where ^<target^> is one of
|
||||
echo. html to make standalone HTML files
|
||||
echo. dirhtml to make HTML files named index.html in directories
|
||||
echo. singlehtml to make a single large HTML file
|
||||
echo. pickle to make pickle files
|
||||
echo. json to make JSON files
|
||||
echo. htmlhelp to make HTML files and a HTML help project
|
||||
echo. qthelp to make HTML files and a qthelp project
|
||||
echo. devhelp to make HTML files and a Devhelp project
|
||||
echo. epub to make an epub
|
||||
echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter
|
||||
echo. text to make text files
|
||||
echo. man to make manual pages
|
||||
echo. texinfo to make Texinfo files
|
||||
echo. gettext to make PO message catalogs
|
||||
echo. changes to make an overview over all changed/added/deprecated items
|
||||
echo. xml to make Docutils-native XML files
|
||||
echo. pseudoxml to make pseudoxml-XML files for display purposes
|
||||
echo. linkcheck to check all external links for integrity
|
||||
echo. doctest to run all doctests embedded in the documentation if enabled
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "clean" (
|
||||
for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i
|
||||
del /q /s %BUILDDIR%\*
|
||||
goto end
|
||||
)
|
||||
|
||||
|
||||
%SPHINXBUILD% 2> nul
|
||||
if errorlevel 9009 (
|
||||
echo.
|
||||
echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
|
||||
echo.installed, then set the SPHINXBUILD environment variable to point
|
||||
echo.to the full path of the 'sphinx-build' executable. Alternatively you
|
||||
echo.may add the Sphinx directory to PATH.
|
||||
echo.
|
||||
echo.If you don't have Sphinx installed, grab it from
|
||||
echo.http://sphinx-doc.org/
|
||||
exit /b 1
|
||||
)
|
||||
|
||||
if "%1" == "html" (
|
||||
%SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished. The HTML pages are in %BUILDDIR%/html.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "dirhtml" (
|
||||
%SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "singlehtml" (
|
||||
%SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "pickle" (
|
||||
%SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished; now you can process the pickle files.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "json" (
|
||||
%SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished; now you can process the JSON files.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "htmlhelp" (
|
||||
%SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished; now you can run HTML Help Workshop with the ^
|
||||
.hhp project file in %BUILDDIR%/htmlhelp.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "qthelp" (
|
||||
%SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished; now you can run "qcollectiongenerator" with the ^
|
||||
.qhcp project file in %BUILDDIR%/qthelp, like this:
|
||||
echo.^> qcollectiongenerator %BUILDDIR%\qthelp\wgerWorkoutManager.qhcp
|
||||
echo.To view the help file:
|
||||
echo.^> assistant -collectionFile %BUILDDIR%\qthelp\wgerWorkoutManager.ghc
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "devhelp" (
|
||||
%SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "epub" (
|
||||
%SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished. The epub file is in %BUILDDIR%/epub.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "latex" (
|
||||
%SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished; the LaTeX files are in %BUILDDIR%/latex.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "latexpdf" (
|
||||
%SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
|
||||
cd %BUILDDIR%/latex
|
||||
make all-pdf
|
||||
cd %BUILDDIR%/..
|
||||
echo.
|
||||
echo.Build finished; the PDF files are in %BUILDDIR%/latex.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "latexpdfja" (
|
||||
%SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
|
||||
cd %BUILDDIR%/latex
|
||||
make all-pdf-ja
|
||||
cd %BUILDDIR%/..
|
||||
echo.
|
||||
echo.Build finished; the PDF files are in %BUILDDIR%/latex.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "text" (
|
||||
%SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished. The text files are in %BUILDDIR%/text.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "man" (
|
||||
%SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished. The manual pages are in %BUILDDIR%/man.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "texinfo" (
|
||||
%SPHINXBUILD% -b texinfo %ALLSPHINXOPTS% %BUILDDIR%/texinfo
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished. The Texinfo files are in %BUILDDIR%/texinfo.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "gettext" (
|
||||
%SPHINXBUILD% -b gettext %I18NSPHINXOPTS% %BUILDDIR%/locale
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished. The message catalogs are in %BUILDDIR%/locale.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "changes" (
|
||||
%SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.The overview file is in %BUILDDIR%/changes.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "linkcheck" (
|
||||
%SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Link check complete; look for any errors in the above output ^
|
||||
or in %BUILDDIR%/linkcheck/output.txt.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "doctest" (
|
||||
%SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Testing of doctests in the sources finished, look at the ^
|
||||
results in %BUILDDIR%/doctest/output.txt.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "xml" (
|
||||
%SPHINXBUILD% -b xml %ALLSPHINXOPTS% %BUILDDIR%/xml
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished. The XML files are in %BUILDDIR%/xml.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "pseudoxml" (
|
||||
%SPHINXBUILD% -b pseudoxml %ALLSPHINXOPTS% %BUILDDIR%/pseudoxml
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished. The pseudo-XML files are in %BUILDDIR%/pseudoxml.
|
||||
goto end
|
||||
)
|
||||
|
||||
:end
|
||||
|
||||
@@ -30,7 +30,7 @@ Configure apache to serve the application::
|
||||
|
||||
|
||||
<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
|
||||
WSGIScriptAlias / /home/wger/src/wger/wsgi.py
|
||||
|
||||
@@ -44,13 +44,13 @@ Configure apache to serve the application::
|
||||
Require all granted
|
||||
</Directory>
|
||||
|
||||
ErrorLog ${APACHE_LOG_DIR}/error.log
|
||||
CustomLog ${APACHE_LOG_DIR}/access.log combined
|
||||
ErrorLog ${APACHE_LOG_DIR}/wger-error.log
|
||||
CustomLog ${APACHE_LOG_DIR}/wger-access.log combined
|
||||
</VirtualHost>
|
||||
|
||||
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
|
||||
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 LC_ALL='en_US.UTF-8'
|
||||
@@ -63,14 +63,15 @@ Activate the settings and disable apache's default::
|
||||
sudo service apache2 reload
|
||||
|
||||
Database
|
||||
---------
|
||||
--------
|
||||
|
||||
.. _prod_postgres:
|
||||
postgreSQL
|
||||
~~~~~~~~~~
|
||||
|
||||
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
|
||||
createdb wger
|
||||
psql wger -c "CREATE USER wger WITH PASSWORD 'wger'";
|
||||
@@ -94,7 +95,7 @@ Application
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
cd /home/wger/src
|
||||
npm install bower
|
||||
pip install -r requirements.txt
|
||||
npm install -g yarn sass
|
||||
python setup.py develop
|
||||
pip install psycopg2 # Only if using postgres
|
||||
invoke create_settings \
|
||||
wger create-settings \
|
||||
--settings-path /home/wger/src/settings.py \
|
||||
--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
|
||||
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::
|
||||
|
||||
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
|
||||
'''
|
||||
"""
|
||||
import unittest
|
||||
from random import random
|
||||
from funkload.FunkLoadTestCase import FunkLoadTestCase
|
||||
|
||||
class Simple(FunkLoadTestCase):
|
||||
'''
|
||||
"""
|
||||
This test uses the configuration file Simple.conf.
|
||||
'''
|
||||
"""
|
||||
|
||||
def setUp(self):
|
||||
'''
|
||||
"""
|
||||
Setting up test.
|
||||
'''
|
||||
"""
|
||||
self.server_url = self.conf_get('main', 'url')
|
||||
|
||||
def test_simple(self):
|
||||
# The description should be set in the configuration file
|
||||
server_url = self.server_url
|
||||
|
||||
# Exercises
|
||||
# Exercises
|
||||
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 + '/de/exercise/79/view/', description='Get exercise page')
|
||||
|
||||
@@ -1,55 +1,109 @@
|
||||
#
|
||||
# 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
|
||||
# docker build --tag 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>
|
||||
EXPOSE 80
|
||||
|
||||
# Install dependencies
|
||||
RUN apt-get install -y apache2 libapache2-mod-wsgi-py3
|
||||
|
||||
# Configure apache
|
||||
RUN a2dissite 000-default.conf
|
||||
ADD wger.conf /etc/apache2/sites-available/
|
||||
RUN a2ensite wger
|
||||
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/*
|
||||
|
||||
# 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
|
||||
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 git clone https://github.com/wger-project/wger.git
|
||||
RUN python3 -m venv /home/wger/venv
|
||||
RUN . /home/wger/venv/bin/activate \
|
||||
&& pip install --upgrade pip \
|
||||
&& pip install -r requirements.txt \
|
||||
&& invoke create_settings \
|
||||
&& pip install wheel \
|
||||
&& 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 \
|
||||
&& invoke bootstrap_wger \
|
||||
&& wger bootstrap \
|
||||
--settings-path /home/wger/src/settings.py \
|
||||
--no-start-server
|
||||
|
||||
|
||||
# Change permissions of some files and folders so the apache process
|
||||
# can access them.
|
||||
RUN chmod o+w -R ~/db/ \
|
||||
&& . /home/wger/venv/bin/activate \
|
||||
&& mkdir ~/static \
|
||||
&& mkdir ~/media \
|
||||
&& chmod o+w ~/media \
|
||||
RUN mkdir -p ~/static/CACHE ~/media \
|
||||
&& ln -s /home/wger/static/CACHE /home/wger/src/CACHE \
|
||||
&& chmod g+w /home/wger/static/CACHE \
|
||||
&& 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 \
|
||||
&& python manage.py collectstatic --noinput
|
||||
&& echo STATIC_ROOT=\'/home/wger/static\' >> settings.py
|
||||
|
||||
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"]
|
||||
CMD ["-D", "FOREGROUND"]
|
||||
ENTRYPOINT ["/home/wger/entrypoint.sh"]
|
||||
|
||||
@@ -18,7 +18,25 @@ play around. To start it:
|
||||
|
||||
```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
|
||||
-------
|
||||
@@ -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
|
||||
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
|
||||
* 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
|
||||
* Mirror: https://bitbucket.org/rolandgeider/wger
|
||||
|
||||
* Main repository: <https://github.com/wger-project/wger>
|
||||
|
||||
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>
|
||||
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
|
||||
WSGIScriptAlias / /home/wger/src/wger/wsgi.py
|
||||
WSGIPassAuthorization On
|
||||
|
||||
Alias /static/ /home/wger/static/
|
||||
<Directory /home/wger/static>
|
||||
Require all granted
|
||||
Require all granted
|
||||
Header set Cache-Control "max-age=604800, public"
|
||||
</Directory>
|
||||
|
||||
Alias /media/ /home/wger/media/
|
||||
<Directory /home/wger//media>
|
||||
Require all granted
|
||||
<Directory /home/wger/media>
|
||||
Require all granted
|
||||
Header set Cache-Control "max-age=604800, public"
|
||||
</Directory>
|
||||
|
||||
ErrorLog ${APACHE_LOG_DIR}/error.log
|
||||
CustomLog ${APACHE_LOG_DIR}/access.log combined
|
||||
ErrorLog ${APACHE_LOG_DIR}/wger-error.log
|
||||
CustomLog ${APACHE_LOG_DIR}/wger-access.log combined
|
||||
</VirtualHost>
|
||||
|
||||
ServerSignature Off
|
||||
ServerTokens Prod
|
||||
|
||||
@@ -8,17 +8,34 @@
|
||||
# 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
|
||||
RUN apt-get update;\
|
||||
apt-get install -y nodejs nodejs-legacy npm git \
|
||||
python-virtualenv python3-dev \
|
||||
libjpeg8-dev zlib1g-dev libwebp-dev \
|
||||
sudo
|
||||
ENV DEBIAN_FRONTEND=noninteractive
|
||||
RUN apt-get update \
|
||||
&& apt-get install --no-install-recommends -y \
|
||||
git \
|
||||
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
|
||||
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
|
||||
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
|
||||
@@ -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
|
||||
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
|
||||
* 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
|
||||
* Mirror: https://bitbucket.org/rolandgeider/wger
|
||||
* Main repository: <https://github.com/wger-project/wger>
|
||||
|
||||
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
|
||||
#
|
||||
# Please consult the documentation 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
|
||||
# Please consult the README 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 -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
|
||||
|
||||
# Install dependencies
|
||||
RUN apt-get install -y vim tmux sqlite3
|
||||
|
||||
# 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
|
||||
COPY --chown=wger:wger . /home/wger/src
|
||||
COPY --from=builder /wheels /wheels
|
||||
COPY ${DOCKER_DIR}/settings.py /home/wger/src
|
||||
COPY ${DOCKER_DIR}/settings.py /tmp/
|
||||
COPY ${DOCKER_DIR}/entrypoint.sh /home/wger/entrypoint.sh
|
||||
RUN chmod +x /home/wger/entrypoint.sh
|
||||
RUN pip3 install --no-cache /wheels/* \
|
||||
&& pip3 install psycopg2-binary \
|
||||
&& pip3 install django-redis \
|
||||
&& python3 setup.py develop
|
||||
|
||||
# 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
|
||||
RUN chown -R wger:wger .
|
||||
|
||||
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
|
||||
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
|
||||
------------
|
||||
## Usage
|
||||
|
||||
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):
|
||||
This docker image is meant to provide a quick development environment using
|
||||
django's development server and an sqlite database from your current code
|
||||
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
|
||||
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
|
||||
* 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
|
||||
-------
|
||||
## Sources
|
||||
|
||||
All the code and the content is freely available:
|
||||
|
||||
* Main repository: https://github.com/wger-project/wger
|
||||
* Mirror: https://bitbucket.org/rolandgeider/wger
|
||||
* Main repository: <https://github.com/wger-project/wger>
|
||||
|
||||
Licence
|
||||
-------
|
||||
## Licence
|
||||
|
||||
The application is licenced under the Affero GNU General Public License 3 or
|
||||
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 -*-
|
||||
# flake8: noqa
|
||||
|
||||
# This file is part of wger Workout Manager.
|
||||
#
|
||||
@@ -80,7 +81,7 @@ user_parser.add_argument('--country',
|
||||
action='store',
|
||||
default='germany',
|
||||
help='What country the generated users should belong to. Default: Germany',
|
||||
choices=['germany', 'ukraine', 'spain'])
|
||||
choices=['germany', 'ukraine', 'spain', 'usa'])
|
||||
|
||||
# Workout options
|
||||
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 = 4
|
||||
|
||||
|
||||
for user in userlist:
|
||||
print(' - generating for {0}'.format(user.username))
|
||||
|
||||
|
||||
@@ -14,24 +14,26 @@
|
||||
#
|
||||
# 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
|
||||
manageable chunks.
|
||||
|
||||
Create the data.json e.g. with:
|
||||
python ../../manage.py dumpdata --indent 4 --natural-foreign > data.json
|
||||
'''
|
||||
"""
|
||||
|
||||
import json
|
||||
|
||||
|
||||
def filter_dump(data, model_list, filename):
|
||||
'''
|
||||
"""
|
||||
Helper function
|
||||
'''
|
||||
"""
|
||||
filter_data = [i for i in data if i['model'] in model_list]
|
||||
with open(filename, 'w') as outfile:
|
||||
json.dump(filter_data, outfile, indent=4)
|
||||
if filter_data:
|
||||
with open(filename, 'w') as outfile:
|
||||
json.dump(filter_data, outfile, indent=4)
|
||||
|
||||
|
||||
# This is a full dump of the DB
|
||||
fixture = open('data.json')
|
||||
@@ -44,6 +46,7 @@ fixture.close()
|
||||
filter_dump(data, ('nutrition.ingredient',), 'ingredients.json')
|
||||
filter_dump(data, ('nutrition.weightunit',), 'weight_units.json')
|
||||
filter_dump(data, ('nutrition.ingredientweightunit',), 'ingredient_units.json')
|
||||
filter_dump(data, ('nutrition.logitem',), 'nutrition_diary.json')
|
||||
|
||||
#
|
||||
# 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
|
||||
|
||||
# Standard Library
|
||||
import sys
|
||||
|
||||
# Django
|
||||
from django.core.management import execute_from_command_line
|
||||
|
||||
from tasks import (
|
||||
setup_django_environment,
|
||||
get_user_config_path
|
||||
# wger
|
||||
from wger.tasks import (
|
||||
get_user_config_path,
|
||||
setup_django_environment
|
||||
)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
# If user passed the settings flag ignore the default wger settings
|
||||
|
||||
28
package.json
28
package.json
@@ -1,13 +1,10 @@
|
||||
{
|
||||
"name": "wger",
|
||||
"version": "1.8.0",
|
||||
"version": "2.0.dev1",
|
||||
"description": "Self hosted FLOSS fitness/workout and weight tracker",
|
||||
"directories": {
|
||||
"doc": "docs"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/wger-project/wger/wger.git"
|
||||
@@ -18,13 +15,20 @@
|
||||
"url": "https://github.com/wger-project/wger/issues"
|
||||
},
|
||||
"homepage": "https://github.com/wger-project/wger",
|
||||
"devDependencies": {
|
||||
"eslint": "^3.3.1",
|
||||
"eslint-config-airbnb-base": "^5.0.2",
|
||||
"eslint-plugin-import": "^1.13.0",
|
||||
"eslint-plugin-jsx-a11y": "^2.1.0",
|
||||
"eslint-plugin-react": "^6.1.2",
|
||||
"gulp": "^3.9.1",
|
||||
"gulp-eslint": "^3.0.1"
|
||||
"dependencies": {
|
||||
"yarn": "^1.22.5",
|
||||
"Sortable": "RubaXa/Sortable#1.10.2",
|
||||
"bootstrap": "twbs/bootstrap#4.x",
|
||||
"components-font-awesome": "components/font-awesome#5.14.0",
|
||||
"d3": "mbostock-bower/d3-bower#>=5",
|
||||
"datatables": "DataTables/DataTables#1.10.x",
|
||||
"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
|
||||
#
|
||||
|
||||
bleach
|
||||
# Building/installing
|
||||
wheel
|
||||
|
||||
# Application
|
||||
bleach~=3.1
|
||||
django-activity-stream
|
||||
django-bootstrap-breadcrumbs
|
||||
django-bower
|
||||
django-formtools>=1.0,<1.1
|
||||
django-recaptcha
|
||||
django-sortedm2m
|
||||
Django>=1.9,<1.10
|
||||
django_compressor
|
||||
django_mobile
|
||||
easy-thumbnails
|
||||
icalendar
|
||||
invoke>=0.14,<0.15
|
||||
pillow
|
||||
django-bootstrap-breadcrumbs~=0.9
|
||||
django-formtools~=2.2
|
||||
django-recaptcha==2.0.6
|
||||
Django~=3.1
|
||||
django-crispy-forms~=1.9
|
||||
django_compressor~=2.4
|
||||
django_extensions~=3.0
|
||||
django-sortedm2m~=3.0
|
||||
django-storages~=1.9
|
||||
easy-thumbnails~=2.7
|
||||
icalendar==4.0.6
|
||||
invoke~=1.4
|
||||
pillow~=7.2
|
||||
python-mimeparse
|
||||
reportlab>=3.3,<3.4
|
||||
reportlab==3.5.48
|
||||
matplotlib>=3.1
|
||||
requests
|
||||
setuptools>=18.5
|
||||
sphinx
|
||||
|
||||
# REST API
|
||||
django-cors-headers
|
||||
django-filter
|
||||
django-tastypie>=0.13,<0.14
|
||||
djangorestframework>=3.2,<3.3
|
||||
# AWS
|
||||
#boto3
|
||||
|
||||
# Production
|
||||
#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
|
||||
|
||||
# Development packages
|
||||
pep8
|
||||
coverage
|
||||
django-debug-toolbar
|
||||
coverage
|
||||
tblib
|
||||
transifex-client
|
||||
isort
|
||||
|
||||
70
setup.cfg
70
setup.cfg
@@ -1,7 +1,69 @@
|
||||
[bdist_wheel]
|
||||
universal = 1
|
||||
|
||||
[pep8]
|
||||
exclude = urls.py,tasks.py,*migrations*,*bower_components*
|
||||
max-line-length = 100
|
||||
ignore = W503
|
||||
[isort]
|
||||
sections = FUTURE,STDLIB,DJANGO,THIRDPARTY,FIRSTPARTY,LOCALFOLDER
|
||||
skip: extras,build,dist,node_modules,migrations,docs,settings.py,apps.py
|
||||
|
||||
# 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.
|
||||
"""
|
||||
|
||||
# Third Party
|
||||
from setuptools import (
|
||||
setup,
|
||||
find_packages
|
||||
find_packages,
|
||||
setup
|
||||
)
|
||||
|
||||
# wger
|
||||
from wger import get_version
|
||||
|
||||
|
||||
@@ -24,6 +27,7 @@ setup(
|
||||
name='wger',
|
||||
description='FLOSS workout, fitness and weight manager/tracker written with Django',
|
||||
long_description=long_description,
|
||||
long_description_content_type='text/x-rst',
|
||||
version=get_version(),
|
||||
url='https://github.com/wger-project',
|
||||
author='Roland Geider',
|
||||
@@ -39,13 +43,13 @@ setup(
|
||||
'Framework :: Django',
|
||||
'License :: OSI Approved :: GNU Affero General Public License v3 or later (AGPLv3+)',
|
||||
'Operating System :: OS Independent',
|
||||
'Programming Language :: Python :: 2',
|
||||
'Programming Language :: Python :: 2.7',
|
||||
'Programming Language :: Python :: 3',
|
||||
'Programming Language :: Python :: 3.4',
|
||||
'Programming Language :: Python :: 3.5',
|
||||
'Programming Language :: Python :: 3.6',
|
||||
'Programming Language :: Python :: 3.7',
|
||||
'Programming Language :: Python :: 3.8',
|
||||
],
|
||||
install_requires=install_requires,
|
||||
|
||||
nstall_requires=install_requires,
|
||||
entry_points={
|
||||
'console_scripts': [
|
||||
'wger = wger.__main__:main',
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
:license: GNU GPL, see LICENSE for more details.
|
||||
"""
|
||||
|
||||
VERSION = (1, 8, 0, 'beta', 1)
|
||||
VERSION = (2, 0, 0, 'alpha', 1)
|
||||
RELEASE = False
|
||||
|
||||
|
||||
@@ -33,6 +33,6 @@ def get_version(version=None, release=None):
|
||||
else:
|
||||
sub = ''
|
||||
if not release:
|
||||
sub += '-dev'
|
||||
sub += '.dev0'
|
||||
|
||||
return main + sub
|
||||
|
||||
@@ -14,20 +14,27 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
|
||||
# Standard Library
|
||||
import os
|
||||
import sys
|
||||
|
||||
# Third Party
|
||||
from invoke import run
|
||||
|
||||
'''
|
||||
|
||||
"""
|
||||
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
|
||||
command, which does all the work.
|
||||
'''
|
||||
"""
|
||||
|
||||
invoke_cmd = 'invoke '
|
||||
|
||||
|
||||
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:]
|
||||
if len(args):
|
||||
run(invoke_cmd + ' '.join(args), pty=True)
|
||||
|
||||
@@ -16,7 +16,9 @@
|
||||
# along with Workout Manager. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
# wger
|
||||
from wger import get_version
|
||||
|
||||
|
||||
VERSION = get_version()
|
||||
default_app_config = 'wger.config.apps.ConfigConfig'
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
|
||||
# Django
|
||||
from django.apps import AppConfig
|
||||
|
||||
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
[
|
||||
{
|
||||
"pk": 1,
|
||||
"model": "config.gymconfig",
|
||||
"pk": 1,
|
||||
"model": "config.gymconfig",
|
||||
"fields": {
|
||||
"default_gym": null
|
||||
}
|
||||
}
|
||||
]
|
||||
]
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,4 +1,5 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# flake8: noqa
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import models, migrations
|
||||
@@ -16,7 +17,9 @@ class Migration(migrations.Migration):
|
||||
name='GymConfig',
|
||||
fields=[
|
||||
('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={
|
||||
},
|
||||
@@ -28,8 +31,8 @@ class Migration(migrations.Migration):
|
||||
('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')])),
|
||||
('show', models.BooleanField(default=1)),
|
||||
('language', models.ForeignKey(related_name='language_source', editable=False, to='core.Language')),
|
||||
('language_target', models.ForeignKey(related_name='language_target', 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', on_delete=models.CASCADE)),
|
||||
],
|
||||
options={
|
||||
'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
|
||||
# along with Workout Manager. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
# Standard Library
|
||||
import logging
|
||||
|
||||
from django.db import models
|
||||
from django.utils.encoding import python_2_unicode_compatible
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
# Django
|
||||
from django.core.cache import cache
|
||||
from wger.core.models import Language, UserProfile
|
||||
from wger.gym.helpers import is_any_gym_admin
|
||||
from wger.gym.models import Gym, GymUserConfig
|
||||
from django.db import models
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
from wger.utils.cache import delete_template_fragment_cache
|
||||
from wger.utils.cache import cache_mapper
|
||||
# wger
|
||||
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__)
|
||||
|
||||
|
||||
@python_2_unicode_compatible
|
||||
class LanguageConfig(models.Model):
|
||||
'''
|
||||
"""
|
||||
Configuration for languages
|
||||
|
||||
Allows to specify what exercises and ingredients are shown for each language
|
||||
'''
|
||||
"""
|
||||
SHOW_ITEM_EXERCISES = '1'
|
||||
SHOW_ITEM_INGREDIENTS = '2'
|
||||
SHOW_ITEM_LIST = (
|
||||
@@ -48,31 +57,33 @@ class LanguageConfig(models.Model):
|
||||
|
||||
language = models.ForeignKey(Language,
|
||||
related_name='language_source',
|
||||
editable=False)
|
||||
editable=False,
|
||||
on_delete=models.CASCADE)
|
||||
language_target = models.ForeignKey(Language,
|
||||
related_name='language_target',
|
||||
editable=False)
|
||||
editable=False,
|
||||
on_delete=models.CASCADE)
|
||||
item = models.CharField(max_length=2,
|
||||
choices=SHOW_ITEM_LIST,
|
||||
editable=False)
|
||||
show = models.BooleanField(default=1)
|
||||
|
||||
class Meta:
|
||||
'''
|
||||
"""
|
||||
Set some other properties
|
||||
'''
|
||||
"""
|
||||
ordering = ["item", "language_target", ]
|
||||
|
||||
def __str__(self):
|
||||
'''
|
||||
"""
|
||||
Return a more human-readable representation
|
||||
'''
|
||||
"""
|
||||
return u"Config for language {0}".format(self.language)
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
'''
|
||||
"""
|
||||
Reset all cached infos
|
||||
'''
|
||||
"""
|
||||
|
||||
super(LanguageConfig, self).save(*args, **kwargs)
|
||||
|
||||
@@ -84,9 +95,9 @@ class LanguageConfig(models.Model):
|
||||
delete_template_fragment_cache('exercise-overview', self.language_id)
|
||||
|
||||
def delete(self, *args, **kwargs):
|
||||
'''
|
||||
"""
|
||||
Reset all cached infos
|
||||
'''
|
||||
"""
|
||||
|
||||
# Cached objects
|
||||
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)
|
||||
|
||||
|
||||
@python_2_unicode_compatible
|
||||
class GymConfig(models.Model):
|
||||
'''
|
||||
"""
|
||||
System wide configuration for gyms
|
||||
|
||||
At the moment this only allows to set one gym as the default
|
||||
TODO: close registration (users can only become members thorough an admin)
|
||||
'''
|
||||
"""
|
||||
|
||||
default_gym = models.ForeignKey(Gym,
|
||||
verbose_name=_('Default gym'),
|
||||
@@ -114,21 +124,22 @@ class GymConfig(models.Model):
|
||||
'gym and update all existing users without a '
|
||||
'gym.'),
|
||||
null=True,
|
||||
blank=True)
|
||||
'''
|
||||
blank=True,
|
||||
on_delete=models.CASCADE)
|
||||
"""
|
||||
Default gym for the wger installation
|
||||
'''
|
||||
"""
|
||||
|
||||
def __str__(self):
|
||||
'''
|
||||
"""
|
||||
Return a more human-readable representation
|
||||
'''
|
||||
"""
|
||||
return u"Default gym {0}".format(self.default_gym)
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
'''
|
||||
"""
|
||||
Perform additional tasks
|
||||
'''
|
||||
"""
|
||||
if self.default_gym:
|
||||
|
||||
# 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
|
||||
|
||||
|
||||
# Django
|
||||
from django.db.models.signals import post_save
|
||||
from django.dispatch import receiver
|
||||
|
||||
# wger
|
||||
from wger.config.models import LanguageConfig
|
||||
from wger.core.models import Language
|
||||
|
||||
|
||||
@receiver(post_save, sender=Language)
|
||||
def init_language_config(sender, instance, created, **kwargs):
|
||||
'''
|
||||
"""
|
||||
Creates language config entries when new languages are created
|
||||
(all combinations of all languages)
|
||||
'''
|
||||
"""
|
||||
for language_source in Language.objects.all():
|
||||
for language_target in Language.objects.all():
|
||||
if not LanguageConfig.objects.filter(language=language_source)\
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{% extends "base.html" %}
|
||||
{% load i18n staticfiles wger_extras %}
|
||||
{% load i18n static wger_extras %}
|
||||
|
||||
{% block title %}{% trans "Languages" %}{% endblock %}
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
<div class="list-group">
|
||||
{% for language in language_list %}
|
||||
<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 }}
|
||||
</a>
|
||||
{% empty %}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{% extends "base.html" %}
|
||||
{% load i18n staticfiles wger_extras django_bootstrap_breadcrumbs %}
|
||||
{% load i18n static wger_extras django_bootstrap_breadcrumbs %}
|
||||
|
||||
{% block title %}{{ view_language }}{% endblock %}
|
||||
|
||||
@@ -85,24 +85,22 @@ in A).{% endblocktrans %}</p>
|
||||
{# #}
|
||||
{% block options %}
|
||||
<div class="btn-group">
|
||||
<button type="button" class="btn btn-primary btn-sm dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||
<span class="{% fa_class 'cog' %}"></span>
|
||||
{% trans "Options" %}
|
||||
</button>
|
||||
<ul class="dropdown-menu">
|
||||
<li>
|
||||
<a href="{% url 'core:language:edit' view_language.id %}" class="wger-modal-dialog">
|
||||
<span class="{% fa_class 'pencil-square-o' %}"></span>
|
||||
<div class="btn-group">
|
||||
<button type="button" class="btn btn-primary btn-sm dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||
<span class="{% fa_class 'cog' %}"></span>
|
||||
{% trans "Options" %}
|
||||
</button>
|
||||
<div class="dropdown-menu">
|
||||
<a href="{% url 'core:language:edit' view_language.id %}" class="wger-modal-dialog dropdown-item">
|
||||
<span class="{% fa_class 'edit' %}"></span>
|
||||
{% trans "Edit" %}
|
||||
</a>
|
||||
</li>
|
||||
<li role="separator" class="divider"></li>
|
||||
<li>
|
||||
<a href="{% url 'core:language:delete' view_language.id %}" class="wger-modal-dialog">
|
||||
<div role="separator" class="dropdown-divider"></div>
|
||||
<a href="{% url 'core:language:delete' view_language.id %}" class="wger-modal-dialog dropdown-item">
|
||||
<span class="{% fa_class 'trash' %}"></span>
|
||||
{% trans "Delete" %}
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
@@ -15,16 +15,18 @@
|
||||
# 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/>.
|
||||
|
||||
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.core.tests.base_testcase import WorkoutManagerTestCase
|
||||
|
||||
|
||||
class GymNameHeaderTestCase(WorkoutManagerTestCase):
|
||||
'''
|
||||
class GymNameHeaderTestCase(WgerTestCase):
|
||||
"""
|
||||
Test case for showing gym name on application header
|
||||
'''
|
||||
"""
|
||||
|
||||
def check_header(self, gym=None):
|
||||
|
||||
@@ -32,9 +34,9 @@ class GymNameHeaderTestCase(WorkoutManagerTestCase):
|
||||
self.assertEqual(response.context['custom_header'], gym)
|
||||
|
||||
def test_custom_header_gym_members(self):
|
||||
'''
|
||||
"""
|
||||
Test the custom header for gym members
|
||||
'''
|
||||
"""
|
||||
|
||||
# Gym 1, custom header activated
|
||||
gym = Gym.objects.get(pk=1)
|
||||
@@ -60,7 +62,7 @@ class GymNameHeaderTestCase(WorkoutManagerTestCase):
|
||||
self.check_header(gym=None)
|
||||
|
||||
def test_custom_header_anonymous_user(self):
|
||||
'''
|
||||
"""
|
||||
Test the custom header for logged out users
|
||||
'''
|
||||
"""
|
||||
self.check_header(gym=None)
|
||||
|
||||
@@ -15,24 +15,29 @@
|
||||
# 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/>.
|
||||
|
||||
# Django
|
||||
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.core.models import UserProfile
|
||||
from wger.core.tests.base_testcase import WorkoutManagerTestCase
|
||||
from wger.gym.models import Gym, GymUserConfig
|
||||
from wger.core.tests.base_testcase import WgerTestCase
|
||||
from wger.gym.models import (
|
||||
Gym,
|
||||
GymUserConfig
|
||||
)
|
||||
|
||||
|
||||
class GymConfigTestCase(WorkoutManagerTestCase):
|
||||
'''
|
||||
class GymConfigTestCase(WgerTestCase):
|
||||
"""
|
||||
Test the system wide gym configuration
|
||||
'''
|
||||
"""
|
||||
|
||||
def test_default_gym(self):
|
||||
'''
|
||||
"""
|
||||
Test that newly registered users get a gym
|
||||
'''
|
||||
"""
|
||||
|
||||
gym = Gym.objects.get(pk=2)
|
||||
gym_config = GymConfig.objects.get(pk=1)
|
||||
@@ -41,20 +46,21 @@ class GymConfigTestCase(WorkoutManagerTestCase):
|
||||
|
||||
# Register
|
||||
registration_data = {'username': 'myusername',
|
||||
'password1': 'secret',
|
||||
'password2': 'secret',
|
||||
'password1': 'Aerieth4yuv5',
|
||||
'password2': 'Aerieth4yuv5',
|
||||
'email': 'my.email@example.com',
|
||||
'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()
|
||||
|
||||
self.assertEqual(new_user.userprofile.gym, gym)
|
||||
self.assertEqual(new_user.gymuserconfig.gym, gym)
|
||||
|
||||
def test_no_default_gym(self):
|
||||
'''
|
||||
"""
|
||||
Test the user registration without a default gym
|
||||
'''
|
||||
"""
|
||||
|
||||
gym_config = GymConfig.objects.get(pk=1)
|
||||
gym_config.default_gym = None
|
||||
@@ -62,20 +68,21 @@ class GymConfigTestCase(WorkoutManagerTestCase):
|
||||
|
||||
# Register
|
||||
registration_data = {'username': 'myusername',
|
||||
'password1': 'secret',
|
||||
'password2': 'secret',
|
||||
'password1': 'Iem2ahl1eizo',
|
||||
'password2': 'Iem2ahl1eizo',
|
||||
'email': 'my.email@example.com',
|
||||
'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()
|
||||
self.assertEqual(new_user.userprofile.gym_id, None)
|
||||
self.assertRaises(GymUserConfig.DoesNotExist, GymUserConfig.objects.get, user=new_user)
|
||||
|
||||
def test_update_userprofile(self):
|
||||
'''
|
||||
"""
|
||||
Test setting the gym for users when setting a default gym
|
||||
'''
|
||||
"""
|
||||
|
||||
UserProfile.objects.update(gym=None)
|
||||
GymUserConfig.objects.all().delete()
|
||||
|
||||
@@ -15,15 +15,15 @@
|
||||
# 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/>.
|
||||
|
||||
# wger
|
||||
from wger.config.models import LanguageConfig
|
||||
|
||||
from wger.core.tests.base_testcase import WorkoutManagerEditTestCase
|
||||
from wger.core.tests.base_testcase import WgerEditTestCase
|
||||
|
||||
|
||||
class EditLanguageConfigTestCase(WorkoutManagerEditTestCase):
|
||||
'''
|
||||
class EditLanguageConfigTestCase(WgerEditTestCase):
|
||||
"""
|
||||
Tests editing a language config
|
||||
'''
|
||||
"""
|
||||
|
||||
object_class = LanguageConfig
|
||||
url = 'config:language_config:edit'
|
||||
|
||||
@@ -15,25 +15,32 @@
|
||||
# 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/>.
|
||||
|
||||
from django.conf.urls import patterns, url, include
|
||||
# Django
|
||||
from django.conf.urls import (
|
||||
include,
|
||||
url
|
||||
)
|
||||
|
||||
from wger.config.views import language_config
|
||||
from wger.config.views import gym_config
|
||||
# wger
|
||||
from wger.config.views import (
|
||||
gym_config,
|
||||
language_config
|
||||
)
|
||||
|
||||
|
||||
# sub patterns for language configs
|
||||
patterns_language_config = [
|
||||
url(r'^(?P<pk>\d+)/edit',
|
||||
language_config.LanguageConfigUpdateView.as_view(),
|
||||
name='edit'),
|
||||
url(r'^(?P<pk>\d+)/edit',
|
||||
language_config.LanguageConfigUpdateView.as_view(),
|
||||
name='edit'),
|
||||
]
|
||||
|
||||
|
||||
# sub patterns for default gym
|
||||
patterns_gym_config = [
|
||||
url(r'^edit$',
|
||||
gym_config.GymConfigUpdateView.as_view(),
|
||||
name='edit'),
|
||||
url(r'^edit$',
|
||||
gym_config.GymConfigUpdateView.as_view(),
|
||||
name='edit'),
|
||||
]
|
||||
|
||||
|
||||
@@ -41,6 +48,6 @@ patterns_gym_config = [
|
||||
# Actual patterns
|
||||
#
|
||||
urlpatterns = [
|
||||
url(r'^language-config/', include(patterns_language_config, namespace="language_config")),
|
||||
url(r'^gym-config/', include(patterns_gym_config, namespace="gym_config")),
|
||||
url(r'^language-config/', include((patterns_language_config, 'language_config'), namespace="language_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
|
||||
|
||||
# Standard Library
|
||||
import logging
|
||||
|
||||
from django.core.urlresolvers import reverse, reverse_lazy
|
||||
from django.utils.translation import ugettext as _
|
||||
# Django
|
||||
from django.urls import reverse_lazy
|
||||
from django.utils.translation import ugettext_lazy
|
||||
from django.views.generic import UpdateView
|
||||
|
||||
# wger
|
||||
from wger.config.models import GymConfig
|
||||
from wger.utils.generic_views import WgerFormMixin
|
||||
|
||||
@@ -28,22 +31,17 @@ logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class GymConfigUpdateView(WgerFormMixin, UpdateView):
|
||||
'''
|
||||
"""
|
||||
Generic view to edit the gym config table
|
||||
'''
|
||||
"""
|
||||
model = GymConfig
|
||||
fields = '__all__'
|
||||
permission_required = 'config.change_gymconfig'
|
||||
success_url = reverse_lazy('gym:gym:list')
|
||||
title = ugettext_lazy('Edit')
|
||||
|
||||
def get_object(self):
|
||||
'''
|
||||
"""
|
||||
Return the only gym config object
|
||||
'''
|
||||
"""
|
||||
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
|
||||
|
||||
# Standard Library
|
||||
import logging
|
||||
|
||||
from django.contrib.auth.mixins import LoginRequiredMixin, PermissionRequiredMixin
|
||||
from django.core.urlresolvers import reverse, reverse_lazy
|
||||
from django.utils.translation import ugettext as _
|
||||
# Django
|
||||
from django.contrib.auth.mixins import (
|
||||
LoginRequiredMixin,
|
||||
PermissionRequiredMixin
|
||||
)
|
||||
from django.urls import reverse_lazy
|
||||
from django.utils.translation import ugettext_lazy
|
||||
from django.views.generic import UpdateView
|
||||
|
||||
# wger
|
||||
from wger.config.models import LanguageConfig
|
||||
from wger.utils.generic_views import WgerFormMixin
|
||||
|
||||
@@ -32,23 +38,16 @@ class LanguageConfigUpdateView(WgerFormMixin,
|
||||
LoginRequiredMixin,
|
||||
PermissionRequiredMixin,
|
||||
UpdateView):
|
||||
'''
|
||||
"""
|
||||
Generic view to edit a language config
|
||||
'''
|
||||
"""
|
||||
model = LanguageConfig
|
||||
fields = ['show']
|
||||
permission_required = 'config.change_languageconfig'
|
||||
title = ugettext_lazy('Edit')
|
||||
|
||||
def get_success_url(self):
|
||||
'''
|
||||
"""
|
||||
Return to the language page
|
||||
'''
|
||||
"""
|
||||
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/>.
|
||||
|
||||
|
||||
# wger
|
||||
from wger import get_version
|
||||
|
||||
|
||||
VERSION = get_version()
|
||||
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
|
||||
# along with Workout Manager. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
# Third Party
|
||||
from rest_framework import serializers
|
||||
|
||||
# wger
|
||||
from wger.core.models import (
|
||||
UserProfile,
|
||||
Language,
|
||||
DaysOfWeek,
|
||||
Language,
|
||||
License,
|
||||
RepetitionUnit,
|
||||
WeightUnit)
|
||||
UserProfile,
|
||||
WeightUnit
|
||||
)
|
||||
|
||||
|
||||
class UserprofileSerializer(serializers.ModelSerializer):
|
||||
'''
|
||||
"""
|
||||
Workout session serializer
|
||||
'''
|
||||
"""
|
||||
class Meta:
|
||||
model = UserProfile
|
||||
fields = '__all__'
|
||||
|
||||
|
||||
class UsernameSerializer(serializers.Serializer):
|
||||
'''
|
||||
"""
|
||||
Serializer to extract the username
|
||||
'''
|
||||
"""
|
||||
username = serializers.CharField()
|
||||
|
||||
|
||||
class LanguageSerializer(serializers.ModelSerializer):
|
||||
'''
|
||||
"""
|
||||
Language serializer
|
||||
'''
|
||||
"""
|
||||
class Meta:
|
||||
model = Language
|
||||
fields = '__all__'
|
||||
|
||||
|
||||
class DaysOfWeekSerializer(serializers.ModelSerializer):
|
||||
'''
|
||||
"""
|
||||
DaysOfWeek serializer
|
||||
'''
|
||||
"""
|
||||
class Meta:
|
||||
model = DaysOfWeek
|
||||
fields = '__all__'
|
||||
|
||||
|
||||
class LicenseSerializer(serializers.ModelSerializer):
|
||||
'''
|
||||
"""
|
||||
License serializer
|
||||
'''
|
||||
"""
|
||||
class Meta:
|
||||
model = License
|
||||
fields = '__all__'
|
||||
|
||||
|
||||
class RepetitionUnitSerializer(serializers.ModelSerializer):
|
||||
'''
|
||||
"""
|
||||
Repetition unit serializer
|
||||
'''
|
||||
"""
|
||||
class Meta:
|
||||
model = RepetitionUnit
|
||||
fields = '__all__'
|
||||
|
||||
|
||||
class WeightUnitSerializer(serializers.ModelSerializer):
|
||||
'''
|
||||
"""
|
||||
Weight unit serializer
|
||||
'''
|
||||
"""
|
||||
class Meta:
|
||||
model = WeightUnit
|
||||
fields = '__all__'
|
||||
|
||||
@@ -15,109 +15,117 @@
|
||||
# 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/>.
|
||||
|
||||
# Django
|
||||
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 (
|
||||
UserProfile,
|
||||
Language,
|
||||
DaysOfWeek,
|
||||
License,
|
||||
RepetitionUnit,
|
||||
WeightUnit)
|
||||
# Third Party
|
||||
from rest_framework import viewsets
|
||||
from rest_framework.decorators import action
|
||||
from rest_framework.response import Response
|
||||
|
||||
# wger
|
||||
from wger.core.api.serializers import (
|
||||
UsernameSerializer,
|
||||
LanguageSerializer,
|
||||
DaysOfWeekSerializer,
|
||||
LanguageSerializer,
|
||||
LicenseSerializer,
|
||||
RepetitionUnitSerializer,
|
||||
UsernameSerializer,
|
||||
UserprofileSerializer,
|
||||
WeightUnitSerializer
|
||||
)
|
||||
from wger.core.api.serializers import UserprofileSerializer
|
||||
from wger.utils.permissions import UpdateOnlyPermission, WgerPermission
|
||||
from wger.core.models import (
|
||||
DaysOfWeek,
|
||||
Language,
|
||||
License,
|
||||
RepetitionUnit,
|
||||
UserProfile,
|
||||
WeightUnit
|
||||
)
|
||||
from wger.utils.permissions import (
|
||||
UpdateOnlyPermission,
|
||||
WgerPermission
|
||||
)
|
||||
|
||||
|
||||
class UserProfileViewSet(viewsets.ModelViewSet):
|
||||
'''
|
||||
"""
|
||||
API endpoint for workout objects
|
||||
'''
|
||||
"""
|
||||
is_private = True
|
||||
serializer_class = UserprofileSerializer
|
||||
permission_classes = (WgerPermission, UpdateOnlyPermission)
|
||||
ordering_fields = '__all__'
|
||||
|
||||
def get_queryset(self):
|
||||
'''
|
||||
"""
|
||||
Only allow access to appropriate objects
|
||||
'''
|
||||
"""
|
||||
return UserProfile.objects.filter(user=self.request.user)
|
||||
|
||||
def get_owner_objects(self):
|
||||
'''
|
||||
"""
|
||||
Return objects to check for ownership permission
|
||||
'''
|
||||
"""
|
||||
return [(User, 'user')]
|
||||
|
||||
@detail_route()
|
||||
@action(detail=True)
|
||||
def username(self, request, pk):
|
||||
'''
|
||||
"""
|
||||
Return the username
|
||||
'''
|
||||
"""
|
||||
|
||||
user = self.get_object().user
|
||||
return Response(UsernameSerializer(user).data)
|
||||
|
||||
|
||||
class LanguageViewSet(viewsets.ReadOnlyModelViewSet):
|
||||
'''
|
||||
"""
|
||||
API endpoint for workout objects
|
||||
'''
|
||||
"""
|
||||
queryset = Language.objects.all()
|
||||
serializer_class = LanguageSerializer
|
||||
ordering_fields = '__all__'
|
||||
filter_fields = ('full_name',
|
||||
'short_name')
|
||||
filterset_fields = ('full_name',
|
||||
'short_name')
|
||||
|
||||
|
||||
class DaysOfWeekViewSet(viewsets.ReadOnlyModelViewSet):
|
||||
'''
|
||||
"""
|
||||
API endpoint for workout objects
|
||||
'''
|
||||
"""
|
||||
queryset = DaysOfWeek.objects.all()
|
||||
serializer_class = DaysOfWeekSerializer
|
||||
ordering_fields = '__all__'
|
||||
filter_fields = ('day_of_week', )
|
||||
filterset_fields = ('day_of_week', )
|
||||
|
||||
|
||||
class LicenseViewSet(viewsets.ReadOnlyModelViewSet):
|
||||
'''
|
||||
"""
|
||||
API endpoint for workout objects
|
||||
'''
|
||||
"""
|
||||
queryset = License.objects.all()
|
||||
serializer_class = LicenseSerializer
|
||||
ordering_fields = '__all__'
|
||||
filter_fields = ('full_name',
|
||||
'short_name',
|
||||
'url')
|
||||
filterset_fields = ('full_name',
|
||||
'short_name',
|
||||
'url')
|
||||
|
||||
|
||||
class RepetitionUnitViewSet(viewsets.ReadOnlyModelViewSet):
|
||||
'''
|
||||
"""
|
||||
API endpoint for repetition units objects
|
||||
'''
|
||||
"""
|
||||
queryset = RepetitionUnit.objects.all()
|
||||
serializer_class = RepetitionUnitSerializer
|
||||
ordering_fields = '__all__'
|
||||
filter_fields = ('name', )
|
||||
filterset_fields = ('name', )
|
||||
|
||||
|
||||
class WeightUnitViewSet(viewsets.ReadOnlyModelViewSet):
|
||||
'''
|
||||
"""
|
||||
API endpoint for weight units objects
|
||||
'''
|
||||
"""
|
||||
queryset = WeightUnit.objects.all()
|
||||
serializer_class = WeightUnitSerializer
|
||||
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
|
||||
|
||||
# Django
|
||||
from django.apps import AppConfig, apps
|
||||
|
||||
|
||||
|
||||
@@ -14,44 +14,47 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
|
||||
# Standard Library
|
||||
import datetime
|
||||
import logging
|
||||
import random
|
||||
import datetime
|
||||
import uuid
|
||||
|
||||
from django.contrib.auth.models import User
|
||||
# Django
|
||||
from django.contrib.auth import authenticate
|
||||
from django.contrib.auth.models import User
|
||||
from django.utils.translation import ugettext as _
|
||||
|
||||
from wger.weight.models import WeightEntry
|
||||
from wger.exercises.models import Exercise
|
||||
# wger
|
||||
from wger.core.models import DaysOfWeek
|
||||
from wger.exercises.models import Exercise
|
||||
from wger.manager.models import (
|
||||
Workout,
|
||||
Day,
|
||||
Schedule,
|
||||
ScheduleStep,
|
||||
Set,
|
||||
Setting,
|
||||
WorkoutLog,
|
||||
Schedule,
|
||||
ScheduleStep
|
||||
Workout,
|
||||
WorkoutLog
|
||||
)
|
||||
from wger.nutrition.models import (
|
||||
NutritionPlan,
|
||||
Ingredient,
|
||||
IngredientWeightUnit,
|
||||
Meal,
|
||||
MealItem,
|
||||
Ingredient,
|
||||
IngredientWeightUnit
|
||||
NutritionPlan
|
||||
)
|
||||
|
||||
from wger.utils.language import load_language
|
||||
from wger.weight.models import WeightEntry
|
||||
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def create_temporary_user():
|
||||
'''
|
||||
"""
|
||||
Creates a temporary user
|
||||
'''
|
||||
"""
|
||||
username = uuid.uuid4().hex[:-2]
|
||||
password = uuid.uuid4().hex[:-2]
|
||||
email = ''
|
||||
@@ -68,9 +71,9 @@ def create_temporary_user():
|
||||
|
||||
|
||||
def create_demo_entries(user):
|
||||
'''
|
||||
"""
|
||||
Creates some demo data for temporary users
|
||||
'''
|
||||
"""
|
||||
|
||||
# (this is a bit ugly and long...)
|
||||
language = load_language()
|
||||
|
||||
@@ -1,51 +1,51 @@
|
||||
[
|
||||
{
|
||||
"pk": 1,
|
||||
"model": "core.daysofweek",
|
||||
"pk": 1,
|
||||
"model": "core.daysofweek",
|
||||
"fields": {
|
||||
"day_of_week": "Monday"
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
"pk": 2,
|
||||
"model": "core.daysofweek",
|
||||
"pk": 2,
|
||||
"model": "core.daysofweek",
|
||||
"fields": {
|
||||
"day_of_week": "Tuesday"
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
"pk": 3,
|
||||
"model": "core.daysofweek",
|
||||
"pk": 3,
|
||||
"model": "core.daysofweek",
|
||||
"fields": {
|
||||
"day_of_week": "Wednesday"
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
"pk": 4,
|
||||
"model": "core.daysofweek",
|
||||
"pk": 4,
|
||||
"model": "core.daysofweek",
|
||||
"fields": {
|
||||
"day_of_week": "Thursday"
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
"pk": 5,
|
||||
"model": "core.daysofweek",
|
||||
"pk": 5,
|
||||
"model": "core.daysofweek",
|
||||
"fields": {
|
||||
"day_of_week": "Friday"
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
"pk": 6,
|
||||
"model": "core.daysofweek",
|
||||
"pk": 6,
|
||||
"model": "core.daysofweek",
|
||||
"fields": {
|
||||
"day_of_week": "Saturday"
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
"pk": 7,
|
||||
"model": "core.daysofweek",
|
||||
"pk": 7,
|
||||
"model": "core.daysofweek",
|
||||
"fields": {
|
||||
"day_of_week": "Sunday"
|
||||
}
|
||||
}
|
||||
]
|
||||
]
|
||||
|
||||
@@ -323,12 +323,12 @@
|
||||
"permissions": [
|
||||
[
|
||||
"add_log",
|
||||
"email",
|
||||
"mailer",
|
||||
"log"
|
||||
],
|
||||
[
|
||||
"change_log",
|
||||
"email",
|
||||
"mailer",
|
||||
"log"
|
||||
],
|
||||
[
|
||||
@@ -562,4 +562,4 @@
|
||||
"model": "auth.group",
|
||||
"pk": 6
|
||||
}
|
||||
]
|
||||
]
|
||||
|
||||
@@ -1,90 +1,98 @@
|
||||
[
|
||||
{
|
||||
"model": "core.language",
|
||||
"pk": 1,
|
||||
"fields": {
|
||||
"short_name": "de",
|
||||
"full_name": "Deutsch"
|
||||
},
|
||||
"model": "core.language",
|
||||
"pk": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"model": "core.language",
|
||||
"pk": 2,
|
||||
"fields": {
|
||||
"short_name": "en",
|
||||
"full_name": "English"
|
||||
},
|
||||
"model": "core.language",
|
||||
"pk": 2
|
||||
}
|
||||
},
|
||||
{
|
||||
"model": "core.language",
|
||||
"pk": 3,
|
||||
"fields": {
|
||||
"short_name": "bg",
|
||||
"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": {
|
||||
"short_name": "es",
|
||||
"full_name": "Espa\u00f1ol"
|
||||
},
|
||||
"model": "core.language",
|
||||
"pk": 4
|
||||
}
|
||||
},
|
||||
{
|
||||
"model": "core.language",
|
||||
"pk": 5,
|
||||
"fields": {
|
||||
"short_name": "ru",
|
||||
"full_name": "\u0420\u0443\u0441\u0441\u043a\u0438\u0439"
|
||||
},
|
||||
"model": "core.language",
|
||||
"pk": 5
|
||||
}
|
||||
},
|
||||
{
|
||||
"model": "core.language",
|
||||
"pk": 6,
|
||||
"fields": {
|
||||
"short_name": "nl",
|
||||
"full_name": "Nederlands"
|
||||
},
|
||||
"model": "core.language",
|
||||
"pk": 6
|
||||
}
|
||||
},
|
||||
{
|
||||
"model": "core.language",
|
||||
"pk": 7,
|
||||
"fields": {
|
||||
"short_name": "pt",
|
||||
"full_name": "Portugu\u00eas"
|
||||
},
|
||||
"model": "core.language",
|
||||
"pk": 7
|
||||
}
|
||||
},
|
||||
{
|
||||
"model": "core.language",
|
||||
"pk": 8,
|
||||
"fields": {
|
||||
"short_name": "el",
|
||||
"full_name": "\u03b5\u03bb\u03bb\u03b7\u03bd\u03b9\u03ba\u03ac"
|
||||
},
|
||||
"model": "core.language",
|
||||
"pk": 8
|
||||
}
|
||||
},
|
||||
{
|
||||
"model": "core.language",
|
||||
"pk": 9,
|
||||
"fields": {
|
||||
"short_name": "cs",
|
||||
"full_name": "\u010de\u0161tina"
|
||||
},
|
||||
"model": "core.language",
|
||||
"pk": 9
|
||||
}
|
||||
},
|
||||
{
|
||||
"model": "core.language",
|
||||
"pk": 10,
|
||||
"fields": {
|
||||
"short_name": "sv",
|
||||
"full_name": "Svenska"
|
||||
},
|
||||
"model": "core.language",
|
||||
"pk": 10
|
||||
}
|
||||
},
|
||||
{
|
||||
"model": "core.language",
|
||||
"pk": 11,
|
||||
"fields": {
|
||||
"short_name": "no",
|
||||
"full_name": "Norsk"
|
||||
},
|
||||
}
|
||||
},
|
||||
{
|
||||
"model": "core.language",
|
||||
"pk": 11
|
||||
"pk": 12,
|
||||
"fields": {
|
||||
"short_name": "fr",
|
||||
"full_name": "Fran\u00e7ais"
|
||||
}
|
||||
}
|
||||
]
|
||||
]
|
||||
|
||||
@@ -1,37 +1,37 @@
|
||||
[
|
||||
{
|
||||
"pk": 1,
|
||||
"model": "core.license",
|
||||
"pk": 1,
|
||||
"model": "core.license",
|
||||
"fields": {
|
||||
"url": "https://creativecommons.org/licenses/by-sa/3.0/deed.en",
|
||||
"full_name": " Creative Commons Attribution Share Alike 3",
|
||||
"url": "https://creativecommons.org/licenses/by-sa/3.0/deed.en",
|
||||
"full_name": " Creative Commons Attribution Share Alike 3",
|
||||
"short_name": "CC-BY-SA 3"
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
"pk": 2,
|
||||
"model": "core.license",
|
||||
"pk": 2,
|
||||
"model": "core.license",
|
||||
"fields": {
|
||||
"url": "https://creativecommons.org/licenses/by-sa/4.0/deed.en",
|
||||
"full_name": "Creative Commons Attribution Share Alike 4",
|
||||
"url": "https://creativecommons.org/licenses/by-sa/4.0/deed.en",
|
||||
"full_name": "Creative Commons Attribution Share Alike 4",
|
||||
"short_name": "CC-BY-SA 4"
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
"pk": 3,
|
||||
"model": "core.license",
|
||||
"pk": 3,
|
||||
"model": "core.license",
|
||||
"fields": {
|
||||
"url": "http://creativecommons.org/publicdomain/zero/1.0/",
|
||||
"full_name": "Creative Commons Public Domain 1.0",
|
||||
"url": "http://creativecommons.org/publicdomain/zero/1.0/",
|
||||
"full_name": "Creative Commons Public Domain 1.0",
|
||||
"short_name": "CC0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"pk": 4,
|
||||
"model": "core.license",
|
||||
"pk": 4,
|
||||
"model": "core.license",
|
||||
"fields": {
|
||||
"url": "http://creativecommons.org/licenses/by/4.0/",
|
||||
"full_name": "Creative Commons Attribution 4",
|
||||
"url": "http://creativecommons.org/licenses/by/4.0/",
|
||||
"full_name": "Creative Commons Attribution 4",
|
||||
"short_name": "CC-BY 4"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
[
|
||||
{
|
||||
"pk": 1,
|
||||
"model": "core.license",
|
||||
"pk": 1,
|
||||
"model": "core.license",
|
||||
"fields": {
|
||||
"url": "",
|
||||
"full_name": "A cool and free license - Germany",
|
||||
"url": "",
|
||||
"full_name": "A cool and free license - Germany",
|
||||
"short_name": "ACAFL - DE"
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
"pk": 2,
|
||||
"model": "core.license",
|
||||
"pk": 2,
|
||||
"model": "core.license",
|
||||
"fields": {
|
||||
"url": "https://another-cool-license.org/acl-2.1",
|
||||
"full_name": "Another cool license 2.1",
|
||||
"url": "https://another-cool-license.org/acl-2.1",
|
||||
"full_name": "Another cool license 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",
|
||||
"fields": {
|
||||
"username": "admin",
|
||||
@@ -34,12 +34,12 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"pk": 1,
|
||||
"model": "core.userprofile",
|
||||
"pk": 1,
|
||||
"model": "core.userprofile",
|
||||
"fields": {
|
||||
"is_temporary": false,
|
||||
"show_comments": false,
|
||||
"show_english_ingredients": false,
|
||||
"is_temporary": false,
|
||||
"show_comments": false,
|
||||
"show_english_ingredients": false,
|
||||
"user": 1,
|
||||
"gym": 1
|
||||
}
|
||||
|
||||
@@ -14,32 +14,71 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
|
||||
from captcha.fields import ReCaptchaField
|
||||
from django.contrib.auth.forms import UserCreationForm, AuthenticationForm
|
||||
# Django
|
||||
from django import forms
|
||||
from django.contrib.auth.forms import (
|
||||
AuthenticationForm,
|
||||
UserCreationForm
|
||||
)
|
||||
from django.contrib.auth.models import User
|
||||
from django.core.exceptions import ValidationError
|
||||
from django import forms
|
||||
from django.forms import (
|
||||
CharField,
|
||||
EmailField,
|
||||
Form,
|
||||
CharField,
|
||||
widgets,
|
||||
PasswordInput
|
||||
PasswordInput,
|
||||
widgets
|
||||
)
|
||||
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
|
||||
|
||||
|
||||
class UserLoginForm(AuthenticationForm):
|
||||
'''
|
||||
"""
|
||||
Form for logins
|
||||
"""
|
||||
|
||||
Overwritten here just to change the label on the 'username' field
|
||||
'''
|
||||
username = forms.CharField(label=_("Username or email"), max_length=254)
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(UserLoginForm, self).__init__(*args, **kwargs)
|
||||
|
||||
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):
|
||||
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:
|
||||
model = UserProfile
|
||||
fields = ('show_comments',
|
||||
@@ -52,7 +91,43 @@ class UserPreferencesForm(forms.ModelForm):
|
||||
'timer_active',
|
||||
'timer_pause',
|
||||
'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):
|
||||
@@ -65,14 +140,14 @@ class UserEmailForm(forms.ModelForm):
|
||||
fields = ('email', )
|
||||
|
||||
def clean_email(self):
|
||||
'''
|
||||
"""
|
||||
Email must be unique system wide
|
||||
|
||||
However, this check should only be performed when the user changes his
|
||||
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
|
||||
we want to check that nobody else has that email
|
||||
'''
|
||||
"""
|
||||
|
||||
email = self.cleaned_data["email"]
|
||||
if not email:
|
||||
@@ -99,12 +174,12 @@ class UserPersonalInformationForm(UserEmailForm):
|
||||
|
||||
|
||||
class PasswordConfirmationForm(Form):
|
||||
'''
|
||||
"""
|
||||
A simple password confirmation form.
|
||||
|
||||
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.
|
||||
'''
|
||||
"""
|
||||
password = CharField(label=_("Password"),
|
||||
widget=PasswordInput,
|
||||
help_text=_('Please enter your current password.'))
|
||||
@@ -112,11 +187,16 @@ class PasswordConfirmationForm(Form):
|
||||
def __init__(self, user, data=None):
|
||||
self.user = user
|
||||
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):
|
||||
'''
|
||||
"""
|
||||
Check that the password supplied matches the one for the user
|
||||
'''
|
||||
"""
|
||||
password = self.cleaned_data.get('password', None)
|
||||
if not self.user.check_password(password):
|
||||
raise ValidationError(_('Invalid password'))
|
||||
@@ -124,34 +204,43 @@ class PasswordConfirmationForm(Form):
|
||||
|
||||
|
||||
class RegistrationForm(UserCreationForm, UserEmailForm):
|
||||
'''
|
||||
"""
|
||||
Registration form
|
||||
'''
|
||||
"""
|
||||
|
||||
# Manually set the language to 'en', otherwise the language used seems to
|
||||
# randomly one of the application languages. This also appears to happen
|
||||
# only on wger.de, perhaps because there the application is behind a reverse
|
||||
# proxy. See #281.
|
||||
captcha = ReCaptchaField(attrs={'theme': 'clean', 'lang': 'en'},
|
||||
label=_('Confirmation text'),
|
||||
captcha = ReCaptchaField(label=_('Confirmation text'),
|
||||
help_text=_('As a security measure, please enter the previous words'))
|
||||
|
||||
|
||||
class RegistrationFormNoCaptcha(UserCreationForm, UserEmailForm):
|
||||
'''
|
||||
"""
|
||||
Registration form without captcha field
|
||||
"""
|
||||
|
||||
This is used when registering through an app, in that case there is not
|
||||
such a spam danger and simplifies the registration process on a mobile
|
||||
device.
|
||||
'''
|
||||
pass
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(RegistrationFormNoCaptcha, self).__init__(*args, **kwargs)
|
||||
self.helper = FormHelper()
|
||||
self.helper.form_class = 'wger-form'
|
||||
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):
|
||||
'''
|
||||
"""
|
||||
Feedback form used for logged in users
|
||||
'''
|
||||
"""
|
||||
contact = forms.CharField(max_length=50,
|
||||
min_length=10,
|
||||
label=_('Contact'),
|
||||
@@ -167,9 +256,8 @@ class FeedbackRegisteredForm(forms.Form):
|
||||
|
||||
|
||||
class FeedbackAnonymousForm(FeedbackRegisteredForm):
|
||||
'''
|
||||
"""
|
||||
Feedback form used for anonymous users (has additionally a reCaptcha field)
|
||||
'''
|
||||
captcha = ReCaptchaField(attrs={'theme': 'clean'},
|
||||
label=_('Confirmation text'),
|
||||
"""
|
||||
captcha = ReCaptchaField(label=_('Confirmation text'),
|
||||
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