Regroup everything here
							
								
								
									
										10
									
								
								.coveragerc
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,10 @@ | ||||
| [run] | ||||
| source = | ||||
|     note_kfet | ||||
|     note_theme | ||||
|     note_adherents | ||||
| omit = | ||||
|     note_theme/tests/*.py | ||||
|     note_theme/migrations/*.py | ||||
|     note_adherents/tests/*.py | ||||
|     note_adherents/migrations/*.py | ||||
							
								
								
									
										21
									
								
								.gitlab-ci.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,21 @@ | ||||
| image: python:3.6 | ||||
|  | ||||
| stages: | ||||
|   - test | ||||
|  | ||||
| before_script: | ||||
|   - pip install tox | ||||
|  | ||||
| python36: | ||||
|   image: python:3.6 | ||||
|   stage: test | ||||
|   script: tox -e py36 | ||||
|  | ||||
| python37: | ||||
|   image: python:3.7 | ||||
|   stage: test | ||||
|   script: tox -e py37 | ||||
|  | ||||
| linters: | ||||
|   stage: test | ||||
|   script: tox -e linters | ||||
							
								
								
									
										379
									
								
								.pylintrc
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,379 @@ | ||||
| [MASTER] | ||||
|  | ||||
| # Specify a configuration file. | ||||
| #rcfile= | ||||
|  | ||||
| # Python code to execute, usually for sys.path manipulation such as | ||||
| # pygtk.require(). | ||||
| #init-hook= | ||||
|  | ||||
| # Add files or directories to the blacklist. They should be base names, not | ||||
| # paths. | ||||
| ignore=CVS,.git | ||||
|  | ||||
| # Pickle collected data for later comparisons. | ||||
| persistent=yes | ||||
|  | ||||
| # List of plugins (as comma separated values of python modules names) to load, | ||||
| # usually to register additional checkers. | ||||
| load-plugins= | ||||
|  | ||||
| # Use multiple processes to speed up Pylint. | ||||
| jobs=4 | ||||
|  | ||||
| # Allow loading of arbitrary C extensions. Extensions are imported into the | ||||
| # active Python interpreter and may run arbitrary code. | ||||
| unsafe-load-any-extension=no | ||||
|  | ||||
| # 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= | ||||
|  | ||||
| # Allow optimization of some AST trees. This will activate a peephole AST | ||||
| # optimizer, which will apply various small optimizations. For instance, it can | ||||
| # be used to obtain the result of joining multiple strings with the addition | ||||
| # operator. Joining a lot of strings can lead to a maximum recursion error in | ||||
| # Pylint and this flag can prevent that. It has one side effect, the resulting | ||||
| # AST will be different than the one from reality. | ||||
| optimize-ast=no | ||||
|  | ||||
|  | ||||
| [MESSAGES CONTROL] | ||||
|  | ||||
| # Only show warnings with the listed confidence levels. Leave empty to show | ||||
| # all. Valid levels: HIGH, INFERENCE, INFERENCE_FAILURE, UNDEFINED | ||||
| confidence=INFERENCE_FAILURE | ||||
|  | ||||
| # 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. See also the "--disable" option for examples. | ||||
| #enable= | ||||
|  | ||||
| # 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=intern-builtin,nonzero-method,parameter-unpacking,backtick,raw_input-builtin,dict-view-method,filter-builtin-not-iterating,long-builtin,unichr-builtin,input-builtin,unicode-builtin,file-builtin,map-builtin-not-iterating,delslice-method,apply-builtin,cmp-method,setslice-method,coerce-method,long-suffix,raising-string,import-star-module-level,buffer-builtin,reload-builtin,unpacking-in-except,print-statement,hex-method,old-octal-literal,metaclass-assignment,dict-iter-method,range-builtin-not-iterating,using-cmp-argument,indexing-exception,no-absolute-import,coerce-builtin,getslice-method,suppressed-message,execfile-builtin,round-builtin,useless-suppression,reduce-builtin,old-raise-syntax,zip-builtin-not-iterating,cmp-builtin,xrange-builtin,standarderror-builtin,old-division,oct-method,next-method-called,old-ne-operator,basestring-builtin | ||||
|  | ||||
|  | ||||
| [REPORTS] | ||||
|  | ||||
| # Set the output format. Available formats are text, parseable, colorized, msvs | ||||
| # (visual studio) and html. You can also give a reporter class, eg | ||||
| # mypackage.mymodule.MyReporterClass. | ||||
| output-format=text | ||||
|  | ||||
| # Put messages in a separate file for each module / package specified on the | ||||
| # command line instead of printing them on stdout. Reports (if any) will be | ||||
| # written in a file name "pylint_global.[txt|html]". | ||||
| files-output=no | ||||
|  | ||||
| # Tells whether to display a full report or only the messages | ||||
| reports=no | ||||
|  | ||||
| # Python expression which should return a note less than 10 (10 is the highest | ||||
| # note). You have access to the variables errors warning, statement which | ||||
| # respectively contain the number of errors / warnings messages and the total | ||||
| # number of statements analyzed. This 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= | ||||
|  | ||||
|  | ||||
| [BASIC] | ||||
|  | ||||
| # List of builtins function names that should not be used, separated by a comma | ||||
| bad-functions=map,filter | ||||
|  | ||||
| # Good variable names which should always be accepted, separated by a comma | ||||
| good-names=i,j,k,ex,Run,_ | ||||
|  | ||||
| # Bad variable names which should always be refused, separated by a comma | ||||
| bad-names=foo,bar,baz,toto,tutu,tata | ||||
|  | ||||
| # Colon-delimited sets of names that determine each other's naming style when | ||||
| # the name regexes allow several styles. | ||||
| name-group= | ||||
|  | ||||
| # Include a hint for the correct naming format with invalid-name | ||||
| include-naming-hint=yes | ||||
|  | ||||
| # Regular expression matching correct argument names | ||||
| argument-rgx=[a-z_][a-z0-9_]{2,30}$ | ||||
|  | ||||
| # Naming hint for argument names | ||||
| argument-name-hint=[a-z_][a-z0-9_]{2,30}$ | ||||
|  | ||||
| # Regular expression matching correct attribute names | ||||
| attr-rgx=[a-z_][a-z0-9_]{2,30}$ | ||||
|  | ||||
| # Naming hint for attribute names | ||||
| attr-name-hint=[a-z_][a-z0-9_]{2,30}$ | ||||
|  | ||||
| # Regular expression matching correct constant names | ||||
| const-rgx=(([A-Z_][A-Z0-9_]*)|(__.*__))$ | ||||
|  | ||||
| # Naming hint for constant names | ||||
| const-name-hint=(([A-Z_][A-Z0-9_]*)|(__.*__))$ | ||||
|  | ||||
| # Regular expression matching correct class names | ||||
| class-rgx=[A-Z_][a-zA-Z0-9]+$ | ||||
|  | ||||
| # Naming hint for class names | ||||
| class-name-hint=[A-Z_][a-zA-Z0-9]+$ | ||||
|  | ||||
| # Regular expression matching correct inline iteration names | ||||
| inlinevar-rgx=[A-Za-z_][A-Za-z0-9_]*$ | ||||
|  | ||||
| # Naming hint for inline iteration names | ||||
| inlinevar-name-hint=[A-Za-z_][A-Za-z0-9_]*$ | ||||
|  | ||||
| # Regular expression matching correct class attribute names | ||||
| class-attribute-rgx=([A-Za-z_][A-Za-z0-9_]{2,30}|(__.*__))$ | ||||
|  | ||||
| # Naming hint for class attribute names | ||||
| class-attribute-name-hint=([A-Za-z_][A-Za-z0-9_]{2,30}|(__.*__))$ | ||||
|  | ||||
| # Regular expression matching correct function names | ||||
| function-rgx=[a-z_][a-z0-9_]{2,30}$ | ||||
|  | ||||
| # Naming hint for function names | ||||
| function-name-hint=[a-z_][a-z0-9_]{2,30}$ | ||||
|  | ||||
| # Regular expression matching correct module names | ||||
| module-rgx=(([a-z_][a-z0-9_]*)|([A-Z][a-zA-Z0-9]+))$ | ||||
|  | ||||
| # Naming hint for module names | ||||
| module-name-hint=(([a-z_][a-z0-9_]*)|([A-Z][a-zA-Z0-9]+))$ | ||||
|  | ||||
| # Regular expression matching correct method names | ||||
| method-rgx=[a-z_][a-z0-9_]{2,30}$ | ||||
|  | ||||
| # Naming hint for method names | ||||
| method-name-hint=[a-z_][a-z0-9_]{2,30}$ | ||||
|  | ||||
| # Regular expression matching correct variable names | ||||
| variable-rgx=[a-z_][a-z0-9_]{2,30}$ | ||||
|  | ||||
| # Naming hint for variable names | ||||
| variable-name-hint=[a-z_][a-z0-9_]{2,30}$ | ||||
|  | ||||
| # Regular expression which should only match function or class names that do | ||||
| # not require a docstring. | ||||
| no-docstring-rgx=^_ | ||||
|  | ||||
| # Minimum line length for functions/classes that require docstrings, shorter | ||||
| # ones are exempt. | ||||
| docstring-min-length=-1 | ||||
|  | ||||
|  | ||||
| [ELIF] | ||||
|  | ||||
| # Maximum number of nested blocks for function / method body | ||||
| max-nested-blocks=5 | ||||
|  | ||||
|  | ||||
| [FORMAT] | ||||
|  | ||||
| # Maximum number of characters on a single line. | ||||
| max-line-length=100 | ||||
|  | ||||
| # Regexp for a line that is allowed to be longer than the limit. | ||||
| ignore-long-lines=^\s*(# )?<?https?://\S+>?$ | ||||
|  | ||||
| # 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 | ||||
|  | ||||
| # 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 | ||||
|  | ||||
| # Maximum number of lines in a module | ||||
| max-module-lines=1000 | ||||
|  | ||||
| # String used as indentation unit. This is usually "    " (4 spaces) or "\t" (1 | ||||
| # tab). | ||||
| indent-string='    ' | ||||
|  | ||||
| # Number of spaces of indent required inside a hanging  or continued line. | ||||
| indent-after-paren=4 | ||||
|  | ||||
| # Expected format of line ending, e.g. empty (any line ending), LF or CRLF. | ||||
| expected-line-ending-format= | ||||
|  | ||||
|  | ||||
| [LOGGING] | ||||
|  | ||||
| # Logging modules to check that the string format arguments are in logging | ||||
| # function parameter format | ||||
| logging-modules=logging | ||||
|  | ||||
|  | ||||
| [MISCELLANEOUS] | ||||
|  | ||||
| # List of note tags to take in consideration, separated by a comma. | ||||
| notes=FIXME,XXX,TODO | ||||
|  | ||||
|  | ||||
| [SIMILARITIES] | ||||
|  | ||||
| # Minimum lines number of a similarity. | ||||
| min-similarity-lines=4 | ||||
|  | ||||
| # Ignore comments when computing similarities. | ||||
| ignore-comments=yes | ||||
|  | ||||
| # Ignore docstrings when computing similarities. | ||||
| ignore-docstrings=yes | ||||
|  | ||||
| # Ignore imports when computing similarities. | ||||
| ignore-imports=no | ||||
|  | ||||
|  | ||||
| [SPELLING] | ||||
|  | ||||
| # Spelling dictionary name. Available dictionaries: none. To make it working | ||||
| # install 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 private dictionary; one word per line. | ||||
| spelling-private-dict-file= | ||||
|  | ||||
| # Tells whether to store unknown words to indicated private dictionary in | ||||
| # --spelling-private-dict-file option instead of raising a message. | ||||
| spelling-store-unknown-words=no | ||||
|  | ||||
|  | ||||
| [TYPECHECK] | ||||
|  | ||||
| # 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 | ||||
|  | ||||
| # 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= | ||||
|  | ||||
| # List of classes names for which member attributes should not be checked | ||||
| # (useful for classes with attributes dynamically set). This supports can work | ||||
| # with qualified names. | ||||
| ignored-classes= | ||||
|  | ||||
| # 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= | ||||
|  | ||||
|  | ||||
| [VARIABLES] | ||||
|  | ||||
| # Tells whether we should check for unused import in __init__ files. | ||||
| init-import=no | ||||
|  | ||||
| # A regular expression matching the name of dummy variables (i.e. expectedly | ||||
| # not used). | ||||
| dummy-variables-rgx=_$|dummy | ||||
|  | ||||
| # List of additional names supposed to be defined in builtins. Remember that | ||||
| # you should avoid to define new builtins when possible. | ||||
| additional-builtins= | ||||
|  | ||||
| # 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 | ||||
|  | ||||
|  | ||||
| [CLASSES] | ||||
|  | ||||
| # List of method names used to declare (i.e. assign) instance attributes. | ||||
| defining-attr-methods=__init__,__new__,setUp | ||||
|  | ||||
| # 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=mcs | ||||
|  | ||||
| # List of member names, which should be excluded from the protected access | ||||
| # warning. | ||||
| exclude-protected=_asdict,_fields,_replace,_source,_make | ||||
|  | ||||
|  | ||||
| [DESIGN] | ||||
|  | ||||
| # Maximum number of arguments for function / method | ||||
| max-args=20 | ||||
|  | ||||
| # Argument names that match this expression will be ignored. Default to name | ||||
| # with leading underscore | ||||
| ignored-argument-names=_.* | ||||
|  | ||||
| # Maximum number of locals for function / method body | ||||
| max-locals=20 | ||||
|  | ||||
| # Maximum number of return / yield for function / method body | ||||
| max-returns=6 | ||||
|  | ||||
| # Maximum number of branch for function / method body | ||||
| max-branches=12 | ||||
|  | ||||
| # Maximum number of statements in function / method body | ||||
| max-statements=50 | ||||
|  | ||||
| # Maximum number of parents for a class (see R0901). | ||||
| max-parents=7 | ||||
|  | ||||
| # Maximum number of attributes for a class (see R0902). | ||||
| max-attributes=10 | ||||
|  | ||||
| # Minimum number of public methods for a class (see R0903). | ||||
| min-public-methods=2 | ||||
|  | ||||
| # Maximum number of public methods for a class (see R0904). | ||||
| max-public-methods=20 | ||||
|  | ||||
| # Maximum number of boolean expressions in an if statement | ||||
| max-bool-expr=5 | ||||
|  | ||||
|  | ||||
| [IMPORTS] | ||||
|  | ||||
| # Deprecated modules which should not be used, separated by a comma | ||||
| deprecated-modules=optparse | ||||
|  | ||||
| # 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 external dependencies in the given file (report RP0402 must | ||||
| # not be disabled) | ||||
| ext-import-graph= | ||||
|  | ||||
| # Create a graph of internal dependencies in the given file (report RP0402 must | ||||
| # not be disabled) | ||||
| int-import-graph= | ||||
|  | ||||
|  | ||||
| [EXCEPTIONS] | ||||
|  | ||||
| # Exceptions that will emit a warning when being caught. Defaults to | ||||
| # "Exception" | ||||
| overgeneral-exceptions=Exception | ||||
|  | ||||
							
								
								
									
										0
									
								
								note_adherents/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
							
								
								
									
										75
									
								
								note_adherents/models.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,75 @@ | ||||
| # -*- mode: python; coding: utf-8 -*- | ||||
| # Copyright (C) 2016-2019 by BDE | ||||
| # SPDX-License-Identifier: GPL-3.0-or-later | ||||
|  | ||||
| from django.conf import settings | ||||
| from django.contrib.auth.models import User | ||||
| from django.db import models | ||||
| from django.db.models.signals import post_save | ||||
| from django.dispatch import receiver | ||||
| from django.utils.translation import gettext_lazy as _ | ||||
|  | ||||
|  | ||||
| class Profile(models.Model): | ||||
|     """ | ||||
|     An user profile | ||||
|  | ||||
|     We do not want to patch the Django Contrib Auth User class | ||||
|     so this model add an user profile with additional information. | ||||
|     """ | ||||
|     user = models.OneToOneField( | ||||
|         settings.AUTH_USER_MODEL, | ||||
|         on_delete=models.CASCADE, | ||||
|     ) | ||||
|     phone_number = models.CharField( | ||||
|         max_length=255, | ||||
|         verbose_name=_('phone number'), | ||||
|     ) | ||||
|     section = models.CharField( | ||||
|         max_length=255, | ||||
|         verbose_name=_('section'), | ||||
|         help_text=_('e.g. "1A0", "9A♥", "SAPHIRE"'), | ||||
|     ) | ||||
|  | ||||
|     class Meta: | ||||
|         verbose_name = _('user profile') | ||||
|         verbose_name_plural = _('user profile') | ||||
|  | ||||
|     def __str__(self): | ||||
|         return self.user.get_username() | ||||
|  | ||||
|  | ||||
| class MembershipFee(models.Model): | ||||
|     """ | ||||
|     TODO | ||||
|     """ | ||||
|     user = models.ForeignKey( | ||||
|         settings.AUTH_USER_MODEL, | ||||
|         on_delete=models.PROTECT, | ||||
|     ) | ||||
|     date = models.CharField( | ||||
|         max_length=255, | ||||
|         verbose_name=_('phone number'), | ||||
|     ) | ||||
|     amount = models.CharField( | ||||
|         max_length=255, | ||||
|         verbose_name=_('section'), | ||||
|         help_text=_('e.g. "1A0", "9A♥", "SAPHIRE"'), | ||||
|     ) | ||||
|  | ||||
|     class Meta: | ||||
|         verbose_name = _('user profile') | ||||
|         verbose_name_plural = _('user profile') | ||||
|  | ||||
|     def __str__(self): | ||||
|         return self.user.get_username() | ||||
|  | ||||
|  | ||||
| @receiver(post_save, sender=User) | ||||
| def save_user_profile(sender, instance, created, **_kwargs): | ||||
|     """ | ||||
|     Hook to save an user profile when an user is updated | ||||
|     """ | ||||
|     if created: | ||||
|         Profile.objects.create(user=instance) | ||||
|     instance.profile.save() | ||||
							
								
								
									
										0
									
								
								note_adherents/tests/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
							
								
								
									
										0
									
								
								note_theme/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
							
								
								
									
										104
									
								
								note_theme/locale/fr/LC_MESSAGES/django.po
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,104 @@ | ||||
| #, fuzzy | ||||
| msgid "" | ||||
| msgstr "" | ||||
| "Project-Id-Version: PACKAGE VERSION\n" | ||||
| "Report-Msgid-Bugs-To: \n" | ||||
| "POT-Creation-Date: 2019-06-30 16:26+0200\n" | ||||
| "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" | ||||
| "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" | ||||
| "Language-Team: LANGUAGE <LL@li.org>\n" | ||||
| "Language: \n" | ||||
| "MIME-Version: 1.0\n" | ||||
| "Content-Type: text/plain; charset=UTF-8\n" | ||||
| "Content-Transfer-Encoding: 8bit\n" | ||||
| "Plural-Forms: nplurals=2; plural=(n > 1);\n" | ||||
|  | ||||
| #: templates/admin/base_site.html:22 templates/base.html:48 | ||||
| msgid "Welcome," | ||||
| msgstr "" | ||||
|  | ||||
| #: templates/admin/base_site.html:27 | ||||
| msgid "View site" | ||||
| msgstr "Retour au site" | ||||
|  | ||||
| #: templates/admin/base_site.html:32 templates/admin/base_site.html:51 | ||||
| #: templates/base.html:52 | ||||
| msgid "View admin" | ||||
| msgstr "Administration" | ||||
|  | ||||
| #: templates/admin/base_site.html:44 | ||||
| msgid "Documentation" | ||||
| msgstr "" | ||||
|  | ||||
| #: templates/admin/base_site.html:53 templates/base.html:56 | ||||
| msgid "Log out" | ||||
| msgstr "" | ||||
|  | ||||
| #: templates/base.html:62 templates/registration/login.html:9 | ||||
| #: templates/registration/login.html:56 | ||||
| msgid "Log in" | ||||
| msgstr "" | ||||
|  | ||||
| #: templates/registration/logged_out.html:9 | ||||
| #: templates/registration/password_change_done.html:9 | ||||
| #: templates/registration/password_change_form.html:9 | ||||
| #: templates/registration/password_reset_complete.html:9 | ||||
| #: templates/registration/password_reset_confirm.html:9 | ||||
| #: templates/registration/password_reset_done.html:9 | ||||
| #: templates/registration/password_reset_form.html:9 | ||||
| msgid "Home" | ||||
| msgstr "" | ||||
|  | ||||
| #: templates/registration/login.html:14 | ||||
| msgid "Please correct the error below." | ||||
| msgstr "" | ||||
|  | ||||
| #: templates/registration/login.html:15 | ||||
| msgid "Please correct the errors below." | ||||
| msgstr "" | ||||
|  | ||||
| #: templates/registration/login.html:31 | ||||
| #, python-format | ||||
| msgid "" | ||||
| "You are authenticated as %(username)s, but are not authorized to access this " | ||||
| "page. Would you like to login to a different account?" | ||||
| msgstr "" | ||||
|  | ||||
| #: templates/registration/login.html:52 | ||||
| msgid "Forgotten your password?" | ||||
| msgstr "Mot de passe oublié ?" | ||||
|  | ||||
| #: templates/registration/password_change_done.html:9 | ||||
| #: templates/registration/password_change_form.html:9 | ||||
| msgid "Password change" | ||||
| msgstr "" | ||||
|  | ||||
| #: templates/registration/password_reset_complete.html:9 | ||||
| #: templates/registration/password_reset_done.html:9 | ||||
| #: templates/registration/password_reset_form.html:9 | ||||
| msgid "Password reset" | ||||
| msgstr "" | ||||
|  | ||||
| #: templates/registration/password_reset_confirm.html:9 | ||||
| msgid "Password reset confirmation" | ||||
| msgstr "" | ||||
|  | ||||
| #: templates/registration/password_reset_email.html:2 | ||||
| #, python-format | ||||
| msgid "" | ||||
| "You're receiving this email because you requested a password reset for your " | ||||
| "user account at %(site_name)s." | ||||
| msgstr "" | ||||
|  | ||||
| #: templates/registration/password_reset_email.html:4 | ||||
| msgid "Please go to the following page and choose a new password:" | ||||
| msgstr "" | ||||
|  | ||||
| #: templates/registration/password_reset_email.html:9 | ||||
| msgid "Thanks for using our site!" | ||||
| msgstr "" | ||||
|  | ||||
| #: templates/registration/password_reset_email.html:11 | ||||
| #, python-format | ||||
| msgid "The %(site_name)s team" | ||||
| msgstr "" | ||||
							
								
								
									
										141
									
								
								note_theme/static/css/admin.css
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,141 @@ | ||||
| /* | ||||
|  * SPDX-License-Identifier: GPL-3.0-or-later | ||||
|  * | ||||
|  * Copyright © 2019  Alexandre Iooss | ||||
|  * | ||||
|  * This is the custom style for Django Contrib Admin | ||||
|  */ | ||||
|  | ||||
| /* Colors */ | ||||
| #header { | ||||
|     background-color: #151515; | ||||
|     border-bottom: solid 5px #d80029; | ||||
|     padding: 10px 40px; | ||||
| } | ||||
|  | ||||
| .module h2, .module caption, .inline-group h2 { | ||||
|     background: #e6e0d8; | ||||
|     color: #222; | ||||
| } | ||||
|  | ||||
| a.section:link, a.section:visited { | ||||
|     color: #222; | ||||
| } | ||||
|  | ||||
| #user-tools a { | ||||
|     border-bottom: none; | ||||
|     font-weight: bold; | ||||
| } | ||||
|  | ||||
| div.breadcrumbs { | ||||
|     background: #3c3c3c; | ||||
| } | ||||
|  | ||||
| .button, input[type=submit], input[type=button], .submit-row input, a.button { | ||||
|     background: #d8a456; | ||||
| } | ||||
|  | ||||
| .button:active, input[type=submit]:active, input[type=button]:active, .button:focus, input[type=submit]:focus, | ||||
| input[type=button]:focus, .button:hover, input[type=submit]:hover, input[type=button]:hover { | ||||
|     background: #b98d4a; | ||||
| } | ||||
|  | ||||
| .button.default, input[type=submit].default, .submit-row input.default { | ||||
|     background: #b98d4a; | ||||
| } | ||||
|  | ||||
| .button.default:active, input[type=submit].default:active, .button.default:focus, input[type=submit].default:focus, | ||||
| .button.default:hover, input[type=submit].default:hover { | ||||
|     background: #a7752b; | ||||
| } | ||||
|  | ||||
| /* User tools top menu */ | ||||
| #user-tools .dropdown:hover > a, #user-tools .dropdown:focus > a { | ||||
|     color: #79aec8; | ||||
| } | ||||
|  | ||||
| #user-tools .dropdown { | ||||
|     position: relative; /* needed to position the dropdown content */ | ||||
|     display: inline-block; | ||||
| } | ||||
|  | ||||
| #user-tools .dropdown-content { | ||||
|     display: block; | ||||
|     position: absolute; | ||||
|     background-color: #444444; | ||||
|     min-width: 180px; | ||||
|     box-shadow: 0 8px 16px 0 rgba(0, 0, 0, 0.2); | ||||
|     z-index: 2000; | ||||
|     text-align: left; | ||||
|  | ||||
|     /* Hide menu by making it transparent */ | ||||
|     transition: opacity 100ms, visibility 100ms; | ||||
|     opacity: 0; | ||||
|     visibility: hidden; | ||||
| } | ||||
|  | ||||
| #user-tools .dropdown-content a { | ||||
|     color: #fff; | ||||
|     padding: 7px 8px; | ||||
|     text-decoration: none; | ||||
|     display: block; | ||||
|     line-height: 16px; | ||||
| } | ||||
|  | ||||
| #user-tools .dropdown-content a:hover { | ||||
|     background-color: #636363; | ||||
| } | ||||
|  | ||||
| #user-tools .dropdown:hover .dropdown-content { | ||||
|     opacity: 1; | ||||
|     visibility: visible; | ||||
| } | ||||
|  | ||||
| /* Fix navigation hidden */ | ||||
| #header { | ||||
|     overflow: visible; | ||||
| } | ||||
|  | ||||
| .login #header { | ||||
|     overflow: hidden; | ||||
| } | ||||
|  | ||||
| /* Footer */ | ||||
| #footer { | ||||
|     padding: 20px 40px; | ||||
|     color: #999; | ||||
| } | ||||
|  | ||||
| .login #footer { | ||||
|     padding: 10px; | ||||
|     font-size: 10pt; | ||||
| } | ||||
|  | ||||
| #footer a { | ||||
|     color: #777; | ||||
| } | ||||
|  | ||||
| #footer select { | ||||
|     height: 24px; | ||||
|     padding: 0; | ||||
| } | ||||
|  | ||||
| /* Pull footer to bottom */ | ||||
| #content { | ||||
|     min-height: calc(100vh - 190px); | ||||
| } | ||||
|  | ||||
| .login #content { | ||||
|     min-height: 0; | ||||
| } | ||||
|  | ||||
| /* Recenter login button */ | ||||
| .login .submit-row { | ||||
|     padding: 1em 0 0 0 !important; | ||||
|     text-align: center !important; | ||||
| } | ||||
|  | ||||
| /* Dashboard should take all page */ | ||||
| .dashboard #content { | ||||
|     width: auto; | ||||
| } | ||||
							
								
								
									
										
											BIN
										
									
								
								note_theme/static/favicon/android-chrome-192x192.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 9.7 KiB | 
							
								
								
									
										
											BIN
										
									
								
								note_theme/static/favicon/android-chrome-512x512.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 26 KiB | 
							
								
								
									
										
											BIN
										
									
								
								note_theme/static/favicon/apple-touch-icon.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 6.4 KiB | 
							
								
								
									
										9
									
								
								note_theme/static/favicon/browserconfig.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,9 @@ | ||||
| <?xml version="1.0" encoding="utf-8"?> | ||||
| <browserconfig> | ||||
|     <msapplication> | ||||
|         <tile> | ||||
|             <square150x150logo src="/static/favicon/mstile-150x150.png"/> | ||||
|             <TileColor>#da532c</TileColor> | ||||
|         </tile> | ||||
|     </msapplication> | ||||
| </browserconfig> | ||||
							
								
								
									
										
											BIN
										
									
								
								note_theme/static/favicon/favicon-16x16.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 690 B | 
							
								
								
									
										
											BIN
										
									
								
								note_theme/static/favicon/favicon-32x32.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 1.4 KiB | 
							
								
								
									
										
											BIN
										
									
								
								note_theme/static/favicon/favicon.ico
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 15 KiB | 
							
								
								
									
										
											BIN
										
									
								
								note_theme/static/favicon/mstile-150x150.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 5.5 KiB | 
							
								
								
									
										1
									
								
								note_theme/static/favicon/safari-pinned-tab.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 28 KiB | 
							
								
								
									
										19
									
								
								note_theme/static/favicon/site.webmanifest
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,19 @@ | ||||
| { | ||||
|     "name": "", | ||||
|     "short_name": "", | ||||
|     "icons": [ | ||||
|         { | ||||
|             "src": "/static/favicon/android-chrome-192x192.png", | ||||
|             "sizes": "192x192", | ||||
|             "type": "image/png" | ||||
|         }, | ||||
|         { | ||||
|             "src": "/static/favicon/android-chrome-512x512.png", | ||||
|             "sizes": "512x512", | ||||
|             "type": "image/png" | ||||
|         } | ||||
|     ], | ||||
|     "theme_color": "#ffffff", | ||||
|     "background_color": "#ffffff", | ||||
|     "display": "standalone" | ||||
| } | ||||
							
								
								
									
										96
									
								
								note_theme/templates/admin/base_site.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,96 @@ | ||||
| {% extends "admin/base.html" %} | ||||
| {% comment %} | ||||
| SPDX-License-Identifier: GPL-3.0-or-later | ||||
| {% endcomment %} | ||||
|  | ||||
| {% load i18n staticfiles %} | ||||
|  | ||||
| {% block title %}{{ title }} | {{ request.site.name }}{% endblock %} | ||||
|  | ||||
| {% block branding %} | ||||
|     <strong id="site-name"> | ||||
|         <a href="{{ site_url }}"> | ||||
|             {{ request.site.name }} | ||||
|         </a> | ||||
|     </strong> | ||||
| {% endblock %} | ||||
|  | ||||
| {% block usertools %} | ||||
|     {% if user.is_authenticated %} | ||||
|         <div id="user-tools"> | ||||
|             {% block welcome-msg %} | ||||
|                 {% trans 'Welcome,' %} | ||||
|                 <strong>{% firstof user.get_short_name user.get_username %}</strong>. | ||||
|             {% endblock %} | ||||
|             {% block userlinks %} | ||||
|                 {% if site_url %} | ||||
|                     <a href="{{ site_url }}">{% trans 'View site' %}</a> / | ||||
|                 {% endif %} | ||||
|                 {% if available_apps %} | ||||
|                     {# When in admin site, list all admin pages and documentation #} | ||||
|                     <span class="dropdown"> | ||||
|                         <a href="{% url 'admin:index' %}">{% trans 'View admin' %}</a> | ||||
|                         <span class="dropdown-content"> | ||||
|                             {% for app in available_apps %} | ||||
|                                 {% for model in app.models %} | ||||
|                                     {% if model.admin_url %} | ||||
|                                         <a href="{{ model.admin_url }}">{{ model.name }}</a> | ||||
|                                     {% endif %} | ||||
|                                 {% endfor %} | ||||
|                             {% endfor %} | ||||
|                             {% if user.is_active and user.is_superuser %} | ||||
|                                 {% url 'django-admindocs-docroot' as docsroot %} | ||||
|                                 {% if docsroot %} | ||||
|                                     <a href="{{ docsroot }}">{% trans 'Documentation' %}</a> | ||||
|                                 {% endif %} | ||||
|                             {% endif %} | ||||
|                          </span> | ||||
|                     </span> / | ||||
|                 {% elif user.is_staff %} | ||||
|                     {# When not in admin site, but user is staff then add a link #} | ||||
|                     <a href="{% url 'admin:index' %}">{% trans 'View admin' %}</a> / | ||||
|                 {% endif %} | ||||
|                 <a href="{% url 'logout' %}">{% trans 'Log out' %}</a> | ||||
|             {% endblock %} | ||||
|         </div> | ||||
|     {% endif %} | ||||
| {% endblock %} | ||||
|  | ||||
| {% block extrastyle %} | ||||
|     <link rel="stylesheet" type="text/css" href="{% static "css/admin.css" %}"/> | ||||
|  | ||||
|     {# Favicon #} | ||||
|     <link rel="apple-touch-icon" sizes="180x180" href="{% static "favicon/apple-touch-icon.png" %}"> | ||||
|     <link rel="icon" type="image/png" sizes="32x32" href="{% static "favicon/favicon-32x32.png" %}"> | ||||
|     <link rel="icon" type="image/png" sizes="16x16" href="{% static "favicon/favicon-16x16.png" %}"> | ||||
|     <link rel="manifest" href="{% static "favicon/site.webmanifest" %}"> | ||||
|     <link rel="mask-icon" href="{% static "favicon/safari-pinned-tab.svg" %}" color="#5bbad5"> | ||||
|     <link rel="shortcut icon" href="{% static "favicon/favicon.ico" %}"> | ||||
|     <meta name="msapplication-TileColor" content="#da532c"> | ||||
|     <meta name="msapplication-config" content="{% static "favicon/browserconfig.xml" %}"> | ||||
|     <meta name="theme-color" content="#ffffff"> | ||||
| {% endblock %} | ||||
|  | ||||
| {% block footer %} | ||||
|     {% if not is_popup %} | ||||
|         <div id="footer"> | ||||
|             <form action="{% url 'set_language' %}" method="post"> | ||||
|                 {% csrf_token %} | ||||
|                 <select title="language" name="language" onchange="this.form.submit()"> | ||||
|                     {% get_current_language as LANGUAGE_CODE %} | ||||
|                     {% get_available_languages as LANGUAGES %} | ||||
|                     {% get_language_info_list for LANGUAGES as languages %} | ||||
|                     {% for language in languages %} | ||||
|                         <option value="{{ language.code }}"{% if language.code == LANGUAGE_CODE %} selected{% endif %}> | ||||
|                             {{ language.name_local }} ({{ language.code }}) | ||||
|                         </option> | ||||
|                     {% endfor %} | ||||
|                 </select> | ||||
|                 <noscript> | ||||
|                     <input type="submit"> | ||||
|                 </noscript> | ||||
|                 Note Kfet 2018-2020 — <a href="mailto:tresorerie.bde@lists.crans.org">Nous contactez</a> | ||||
|             </form> | ||||
|         </div> | ||||
|     {% endif %} | ||||
| {% endblock %} | ||||
							
								
								
									
										11
									
								
								note_theme/templates/registration/logged_out.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,11 @@ | ||||
| {% extends "registration/logged_out.html" %} | ||||
| {% comment %} | ||||
| SPDX-License-Identifier: GPL-3.0-or-later | ||||
| {% endcomment %} | ||||
| {% load i18n %} | ||||
|  | ||||
| {% block breadcrumbs %} | ||||
|     <div class="breadcrumbs"> | ||||
|         <a href="{% url 'index' %}">{% trans 'Home' %}</a> | ||||
|     </div> | ||||
| {% endblock %} | ||||
							
								
								
									
										11
									
								
								note_theme/templates/registration/password_change_done.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,11 @@ | ||||
| {% extends "registration/password_change_done.html" %} | ||||
| {% comment %} | ||||
| SPDX-License-Identifier: GPL-3.0-or-later | ||||
| {% endcomment %} | ||||
| {% load i18n %} | ||||
|  | ||||
| {% block breadcrumbs %} | ||||
|     <div class="breadcrumbs"> | ||||
|         <a href="{% url 'index' %}">{% trans 'Home' %}</a> › {% trans 'Password change' %} | ||||
|     </div> | ||||
| {% endblock %} | ||||
							
								
								
									
										11
									
								
								note_theme/templates/registration/password_change_form.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,11 @@ | ||||
| {% extends "registration/password_change_form.html" %} | ||||
| {% comment %} | ||||
| SPDX-License-Identifier: GPL-3.0-or-later | ||||
| {% endcomment %} | ||||
| {% load i18n %} | ||||
|  | ||||
| {% block breadcrumbs %} | ||||
|     <div class="breadcrumbs"> | ||||
|         <a href="{% url 'index' %}">{% trans 'Home' %}</a> › {% trans 'Password change' %} | ||||
|     </div> | ||||
| {% endblock %} | ||||
| @@ -0,0 +1,11 @@ | ||||
| {% extends "registration/password_reset_complete.html" %} | ||||
| {% comment %} | ||||
| SPDX-License-Identifier: GPL-3.0-or-later | ||||
| {% endcomment %} | ||||
| {% load i18n %} | ||||
|  | ||||
| {% block breadcrumbs %} | ||||
|     <div class="breadcrumbs"> | ||||
|         <a href="{% url 'index' %}">{% trans 'Home' %}</a> › {% trans 'Password reset' %} | ||||
|     </div> | ||||
| {% endblock %} | ||||
| @@ -0,0 +1,11 @@ | ||||
| {% extends "registration/password_reset_confirm.html" %} | ||||
| {% comment %} | ||||
| SPDX-License-Identifier: GPL-3.0-or-later | ||||
| {% endcomment %} | ||||
| {% load i18n %} | ||||
|  | ||||
| {% block breadcrumbs %} | ||||
|     <div class="breadcrumbs"> | ||||
|         <a href="{% url 'index' %}">{% trans 'Home' %}</a> › {% trans 'Password reset confirmation' %} | ||||
|     </div> | ||||
| {% endblock %} | ||||
							
								
								
									
										11
									
								
								note_theme/templates/registration/password_reset_done.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,11 @@ | ||||
| {% extends "registration/password_reset_done.html" %} | ||||
| {% comment %} | ||||
| SPDX-License-Identifier: GPL-3.0-or-later | ||||
| {% endcomment %} | ||||
| {% load i18n %} | ||||
|  | ||||
| {% block breadcrumbs %} | ||||
|     <div class="breadcrumbs"> | ||||
|         <a href="{% url 'index' %}">{% trans 'Home' %}</a> › {% trans 'Password reset' %} | ||||
|     </div> | ||||
| {% endblock %} | ||||
							
								
								
									
										13
									
								
								note_theme/templates/registration/password_reset_email.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,13 @@ | ||||
| {% load i18n %}{% autoescape off %} | ||||
| {% blocktrans %}You're receiving this email because you requested a password reset for your user account at {{ site_name }}.{% endblocktrans %} | ||||
|  | ||||
| {% trans "Please go to the following page and choose a new password:" %} | ||||
| {% block reset_link %} | ||||
| {{ protocol }}://{{ domain }}{% url 'password_reset_confirm' uidb64=uid token=token %} | ||||
| {% endblock %} | ||||
|  | ||||
| {% trans "Thanks for using our site!" %} | ||||
|  | ||||
| {% blocktrans %}The {{ site_name }} team{% endblocktrans %} | ||||
|  | ||||
| {% endautoescape %} | ||||
							
								
								
									
										11
									
								
								note_theme/templates/registration/password_reset_form.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,11 @@ | ||||
| {% extends "registration/password_reset_form.html" %} | ||||
| {% comment %} | ||||
| SPDX-License-Identifier: GPL-3.0-or-later | ||||
| {% endcomment %} | ||||
| {% load i18n %} | ||||
|  | ||||
| {% block breadcrumbs %} | ||||
|     <div class="breadcrumbs"> | ||||
|         <a href="{% url 'index' %}">{% trans 'Home' %}</a> › {% trans 'Password reset' %} | ||||
|     </div> | ||||
| {% endblock %} | ||||
							
								
								
									
										0
									
								
								note_theme/tests/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
							
								
								
									
										44
									
								
								note_theme/tests/test_templates.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,44 @@ | ||||
| # -*- mode: python; coding: utf-8 -*- | ||||
| # SPDX-License-Identifier: GPL-3.0-or-later | ||||
|  | ||||
| from django.contrib.auth.models import User | ||||
| from django.test import TestCase | ||||
|  | ||||
| """ | ||||
| Test that every themed page still works | ||||
| """ | ||||
|  | ||||
|  | ||||
| class TemplateLoggedOutTests(TestCase): | ||||
|     def test_login_page(self): | ||||
|         response = self.client.get('/admin/login/') | ||||
|         self.assertEqual(response.status_code, 200) | ||||
|  | ||||
|  | ||||
| class TemplateLoggedInTests(TestCase): | ||||
|     def setUp(self): | ||||
|         self.user = User.objects.create_superuser( | ||||
|             username="admin", | ||||
|             password="adminadmin", | ||||
|             email="admin@example.com", | ||||
|         ) | ||||
|         self.client.force_login(self.user) | ||||
|  | ||||
|     def test_login_page(self): | ||||
|         """ | ||||
|         Login page should redirect | ||||
|         """ | ||||
|         response = self.client.get('/admin/login/') | ||||
|         self.assertEqual(response.status_code, 302) | ||||
|  | ||||
|     def test_admin_index(self): | ||||
|         response = self.client.get('/admin/') | ||||
|         self.assertEqual(response.status_code, 200) | ||||
|  | ||||
|     def test_accounts_password_reset(self): | ||||
|         response = self.client.get('/accounts/password_reset/') | ||||
|         self.assertEqual(response.status_code, 200) | ||||
|  | ||||
|     def test_logout_page(self): | ||||
|         response = self.client.get('/accounts/logout/') | ||||
|         self.assertEqual(response.status_code, 200) | ||||
							
								
								
									
										49
									
								
								tox.ini
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,49 @@ | ||||
| [tox] | ||||
| envlist = py36,py37,linters | ||||
| skipsdist = True | ||||
|  | ||||
| [testenv] | ||||
| basepython = python3 | ||||
| deps = | ||||
|     -r{toxinidir}/requirements.txt | ||||
|     coverage | ||||
| commands = | ||||
|     coverage run ./manage.py test {posargs} | ||||
|     coverage report -m | ||||
|  | ||||
| [testenv:pre-commit] | ||||
| deps = pre-commit | ||||
| commands = | ||||
|     pre-commit run --all-files --show-diff-on-failure | ||||
|  | ||||
| [testenv:linters] | ||||
| deps = | ||||
|     -r{toxinidir}/requirements.txt | ||||
|     flake8 | ||||
|     flake8-colors | ||||
|     flake8-import-order | ||||
|     flake8-typing-imports | ||||
|     pep8-naming | ||||
|     pyflakes | ||||
|     pylint | ||||
| commands = | ||||
|     flake8 note_* | ||||
|     pylint . | ||||
|  | ||||
| [flake8] | ||||
| ignore = D203, W503, E203 | ||||
| exclude = | ||||
|     .tox, | ||||
|     .git, | ||||
|     __pycache__, | ||||
|     build, | ||||
|     dist, | ||||
|     *.pyc, | ||||
|     *.egg-info, | ||||
|     .cache, | ||||
|     .eggs | ||||
| max-complexity = 10 | ||||
| import-order-style = google | ||||
| application-import-names = flake8 | ||||
| format = ${cyan}%(path)s${reset}:${yellow_bold}%(row)d${reset}:${green_bold}%(col)d${reset}: ${red_bold}%(code)s${reset} %(text)s | ||||
|  | ||||