diff --git a/docs/programmer_manual.rst b/docs/programmer_manual.rst index 81fa0f345dad86a3c54c3f46673cfc2e873bcfe9..a69a7818829a5d861eeaadfcafe652c6cfdf10bf 100644 --- a/docs/programmer_manual.rst +++ b/docs/programmer_manual.rst @@ -5,27 +5,35 @@ programmer manual the programmer manual describes not only how to install, setup, deploy this website project. you also find here the programming conventions of this website project and how to adapt it to the needs of your association. +to simplify the maintenance and deployment of this website project install the ``grm`` tool on your local machine. -installation/setup -================== +.. hint:: + install the ``grm`` tool with pip (`pip install aedev-git-repo-manager`). check their documentation in + `the grm user manual `__. + + +installation +============ Django CMS 3.8 -------------- -inspired by youtube video tutorial https://www.youtube.com/watch?v=NbsRVfLCE1U +the following installation steps are inspired by the youtube video tutorial at +``__ * on a new OS/system ensure the system/apt/non-python libs needed by Django CMS are installed (see - https://djangocms-installer.readthedocs.io/en/latest/libraries.html). -* create a new python virtual environment (web39) and activate it + ``__). +* create a new python virtual environment (e.g. kairos-web39) and activate it * pip install djangocms-installer (version 2.0) * cd to your projects parent folder then run: * djangocms --permissions=yes --languages=en,es,de --bootstrap=yes --parent-dir=kairos kairos * cd kairos -* pyenv local web39 -* open the project in PyCharm and then: -* set the projects python interpreter to the virtual env (web39) +* pyenv local kairos-web39 +* open the project in PyCharm, and then: +* set the projects python interpreter to the virtual env (kairos-web39) * edit requirements.txt downgrading the version of django-treebeard to 4.4 to prevent an exception on publishing - (VeshRaazThapa recommends even using 4.3.1 instead of 4.4 in https://github.com/django-cms/django-cms/issues/6980) + (VeshRaazThapa recommends even using 4.3.1 instead of 4.4 in + ``__) * open kairos/settings.py and to (1) fix the 4 inspections “Missed locally stored library for HTTP link” by downloading the external libraries and (2) reformat long lines with the hot-fix “Put attributes on separate lines” * open kairos/templates/base.html and replace the tag with @@ -68,14 +76,16 @@ Reset database and migrations * stop the server -* run the script kairos/management/commands/_members_and_announcements_data_loader.py. +* if you want to migrate members, their notifications and announcements, adapt and run the script + kairos/management/commands/_members_and_announcements_data_loader.py. * run ./manage.py generate_thumbnails (not sure on that, because they are not displayed in filer admin). * run the server again and start adding the CMS pages. -inspired by https://stackoverflow.com/questions/34576004 and -https://simpleisbetterthancomplex.com/tutorial/2016/07/26/how-to-reset-migrations.html +.. hint:: + for more details on database reset see by ``__ and + ``__. configuration and maintenance @@ -103,7 +113,7 @@ adding or removing languages, to adapt it to the needs of your association, can `GNU gettext message file `__ has to be provided (stored in this project underneath the kairos/locale folder). -some examples of multi-language messages, that may be set for your association individually in each language, are: +multi-language messages that may be adapted for your association individually in each language, are: * `"KairosBrandName"`: brand name of your association. * `"Time exchange * Goods exchange * Rental exchange"`: sub title of the website. @@ -214,6 +224,23 @@ delete all database migrations: DELETE from django_migrations +add static and media folders to repo by running locally +------------------------------------------------------- + +this is only needed if you have added new CMS pages and new media files (pictures, PDFs, ...) to your website +and you want to include them into your own repository. for that execute the following shell commands:: + +.. code-block:: shell + + git add -f media + git add -f static + git add -f project.db + +(if you see warning on CRLF/LF conversions then correct them conversion e.g. with: +:code:`git add -f -u --renormalize static`) + + + modules and django apps ======================= @@ -232,69 +259,122 @@ modules and django apps deployment ========== -the deployment of this website differs on the used hosting service company. +the following instructions describing the deployment of this website to pythonanywhere.com. + + +authentication +-------------- + +on the pythonanywhere host navigate to ``account`` and ``API Token`` to create a new API token for the authentication. +this token has then to be provided to the ``grm`` tool either via the ``--token`` command line option, +or in the OS environment variable AE_OPTIONS_WEB_TOKEN. +.. hint:: + to support the specification of multiple tokens on your local machine, the name of the AE_OPTIONS_WEB_TOKEN + environment variable name can be extended with hosting domain, sub-domain names and user name, in the format + ``AE_OPTIONS_WEB_TOKEN[_AT_[_]]``. domain and user names are converted to a valid variable + name with the :func:`~ae.base.env_str` function (to upper-case, replacing invalid characters with underscore + and prefixing upper-case characters with an underscore). -initial deployment on pythonanywhere +.. note:: + the instructions in this section are using ``kairosgomera`` as the user name and ``kairos-web39`` as + the name of the virtual environment. these names can be changed to your needs. + + +initial deployment and configuration ------------------------------------ -the following steps are explained in more detail in the django tutorials of pythonanywhere, which are available -as a `guided tour (the eu version) -`_ as well as in a -`separate web-page `_: +this section is explaining the initial steps to prepare the new fresh pythonanywhere server for this Django project. +for more details see the django tutorials of pythonanywhere, available at +``__: -* add static and media folders to repo by running locally: +* to create a new virtual environment (e.g. kairos-web39), open a bash shell on your host and execute:: - this step is only needed if added new CMS pages and new media files (pictures, PDFs, ...) to your website - and you want to include them into your own repository. + mkvirtualenv --python=/usr/bin/python3.9 kairos-web39 - .. code-block:: shell +* open via the ``Files`` tab the virtualenv script at ~/.virtualenvs/kairos-web39/bin/postactivate on your host + and add the following line to it (and Save it):: - git add -f media - git add -f static - git add -f project.db + set -a; source ~/.env; set +a - (if you see warning on CRLF/LF conversions then correct them conversion e.g. with: - :code:`git add -f -u --renormalize static`) +* optionally correct/complete the file ~/.bashrc on your host with:: -* log into your pythonanywhere account and then open bash console to run: + HISTCONTROL=ignorespace:erasedups + shopt -s histappend + HISTSIZE=3000 + HISTFILESIZE=6000 - .. code-block:: shell +* there are various ways to deploy the kairos web app server code onto your hosting server. - git clone https://gitlab.com/ae-group/kairos - cd kairos - mkvirtualenv --python=/usr/bin/python3.9 kairos-web39 - pip install -r requirements.txt - pip freeze > requirements_yymmdd.txt + if you plan to maintain, debug or change the server code, then first + :ref:`follow the instructions above to install this project onto your local machine `. + the deployment of the server code onto your host will then be done by executing the following command + in a local bash shell and the projects working tree root folder:: -* create new app and WSGI file (see "Setting up your Web app and WSGI file" in - https://help.pythonanywhere.com/pages/DeployExistingDjangoProject/) + grm deploy WORKTREE -* add a superuser/admin to your django database by running: python manage.py createsuperuser + .. hint:: + other project versions can be deployed by specifying instead of ``WORKTREE`` + a project version git tag (e.g. ``v1.2.3``) or ``LATEST`` (for the latest stable project version). -* upload/create a .env file to/in hosts home folder (~ or /home/user_name) containing the env vars for django (DJANGO_*) - the change notification settings (MCN_*) and the data import (MEMBERS_DATA_FILE_PATH, ...). + alternatively you could initially deploy this web app project by cloning the + project repository directly onto your host. for this execute + in a bash shell on your host the following commands: + + .. code-block:: shell + + cd /home/kairosgomera + git clone https://gitlab.com/ae-group/kairos + cd kairos + pip install -r requirements_frozen.txt + + .. hint:: the first installation method will occupy much less space on your host. + +* open the ``Web`` tab in the interface of your pythonanywhere host and click the button + ``manual configuration (including virtualenvs)`` to start a new web app. + +* in the now upcoming page under the ``Web`` tab, navigate to the ``Code`` section and specify there the + paths of the ``Source code`` to ``/home/kairosgomera/kairos`` and + of the ``Working directory`` to ``/home/kairosgomera``. also specify there the used ``Python version`` (3.9). -* add at the top of your WSGI file (available via the Web tab) the following lines - (see also ``__):: +* in the same page (``Web``), in the section ``Code`` click on the link next to ``WSGI configuration file`` to adapt the + WSGI file template. replace file content with the following:: + + import os + import sys + + from ae.base import load_dotenvs # type: ignore + + + path = os.path.expanduser('~/kairos') # results in '/home/your-username/kairos' + if path not in sys.path: + sys.path.append(path) - from ae.base import load_dotenvs load_dotenvs() -* add to the virtualenv script at ~/.virtualenvs/kairos-web39/bin/postactivate the following line (and Save it): + os.environ['DJANGO_SETTINGS_MODULE'] = 'kairos.settings' - .. code-block:: shell + from django.core.wsgi import get_wsgi_application + application = get_wsgi_application() - set -a; source ~/.env; set +a -* correct/complete ~/.bashrc with: + .. hint:: + more info see the section "Setting up your Web app and WSGI file" in + ``__. - .. code-block:: shell +* specify the path of your new virtual environment in the ``Web`` tab under the section ``Virtualenv`` + as ``/home/kairosgomera/.virtualenvs/kairos-web39``. - HISTCONTROL=ignorespace:erasedups - shopt -s histappend - HISTSIZE=3000 - HISTFILESIZE=6000 +* add a superuser/admin to your django database by running on your host in bash shell + with virtual environment activated the command:: + + python manage.py createsuperuser + +* upload/create a .env file to/in hosts home folder (~ or /home/user_name) containing the env vars for django (DJANGO_*) + the change notification settings (MCN_*) and the data import (MEMBERS_DATA_FILE_PATH, ...). + + +after finishing all these steps your Django site will be available at your-username.pythonanywhere.com. update from version Vx.x.xx to Vx.x.yy on pythonanywhere @@ -309,8 +389,8 @@ update from version Vx.x.xx to Vx.x.yy on pythonanywhere grm commit grm push grm request - grm deploy LATEST grm release LATEST + grm deploy LATEST .. hint:: use the grm options --domain diff --git a/kairos/__init__.py b/kairos/__init__.py index 2e26d674c40ca605fc64235fb148fad4807e4e56..cad0778f24dd7d3a8e1c1a46859981b28c3a294d 100644 --- a/kairos/__init__.py +++ b/kairos/__init__.py @@ -62,4 +62,4 @@ TODO: """ -__version__ = '0.3.106' +__version__ = '0.3.107' diff --git a/kairos/settings.py b/kairos/settings.py index 436042d19fc1fd416e7b770d5a9325549f223138..b5cb833f170a56019fccc817bb43275f8303f77b 100644 --- a/kairos/settings.py +++ b/kairos/settings.py @@ -11,6 +11,7 @@ from django.contrib.messages import constants as messages # type: from ae.base import load_dotenvs # type: ignore + load_dotenvs() diff --git a/kairos/views.py b/kairos/views.py index 17dea6c7680f7589c48a26790e9ecafe3fb00b44..aae94f89e8dd613dde450ea9b51ad4c2a7a9f4b3 100644 --- a/kairos/views.py +++ b/kairos/views.py @@ -32,7 +32,7 @@ SIGNUP_ADMINS = os.environ.get( def _member_lang_toggle(request: HttpRequest, lang: str, show: bool): - hidden_languages = request.session[HIDDEN_LANG_SESSION_KEY] + hidden_languages = request.session.get(HIDDEN_LANG_SESSION_KEY, []) last_url = request.META.get('HTTP_REFERER', '/') if show: hidden_languages = [l_ for l_ in hidden_languages if l_ != lang] @@ -124,6 +124,7 @@ def _activate_member(member_pk: int, request: HttpRequest, token: Optional[str] current_user = request.user rec = MemberMessage.objects.create( mm_author=current_user, + mm_language=request.LANGUAGE_CODE, mm_text=_("A 'warm welcome' to our new member {name}").format(name=member_full_name(member_rec)), mm_public=False, ) diff --git a/mbr_announcements/views.py b/mbr_announcements/views.py index b5e1dc7ba3ae629a9160bdb48eff6fbf08ca1c50..25c8dc5d8672ab247cbd27dd9d40e7231cad7844 100644 --- a/mbr_announcements/views.py +++ b/mbr_announcements/views.py @@ -92,7 +92,7 @@ def get_queryset(request: HttpRequest): last_year_datetime = timezone.now() - datetime.timedelta(days=365) obj_list = obj_list.exclude(Q(ma_user__last_login=None) | Q(ma_user__last_login__lt=last_year_datetime)) - if hidden_languages := request.session[HIDDEN_LANG_SESSION_KEY]: + if hidden_languages := request.session.get(HIDDEN_LANG_SESSION_KEY, []): obj_list = obj_list.exclude(ma_language__in=hidden_languages) return obj_list.order_by("ma_announce_category__ac_name", "ma_action", "-ma_last_updated") diff --git a/mbr_meeting_plugin/cms_plugins.py b/mbr_meeting_plugin/cms_plugins.py index bfa5fbdc72888b9dd7c06194ee991be9ee0696a4..6bf02d0b47e427c554075c952ab5be109bccbd63 100644 --- a/mbr_meeting_plugin/cms_plugins.py +++ b/mbr_meeting_plugin/cms_plugins.py @@ -25,7 +25,7 @@ class MemberMeetingsPlugin(CMSPluginBase): context['MBR_MEET_ANCHOR_ID_PREFIX'] = MBR_MEET_ANCHOR_ID_PREFIX context['mt_texts'] = mtt = {} - hidden_languages = context['request'].session[HIDDEN_LANG_SESSION_KEY] + hidden_languages = context['request'].session.get(HIDDEN_LANG_SESSION_KEY, []) for lang, _lang_name in settings.LANGUAGES: if lang not in hidden_languages: mts = MemberMeeting.objects.filter(mt_language=lang).order_by('-mt_created').first() diff --git a/mbr_messages/views.py b/mbr_messages/views.py index 54e593285a9ad6520298a680d26afdbeedbacc4d..91b6599408d52772afa1fd3e67ec265803c32fc9 100644 --- a/mbr_messages/views.py +++ b/mbr_messages/views.py @@ -97,7 +97,7 @@ def get_queryset(request: HttpRequest): elif not current_user.is_staff: # only admins are seeing records added/owned by other users obj_list = obj_list.exclude(Q(mm_text__contains=MSG_ADD_MARKER) & ~Q(mm_author=current_user)) - if hidden_languages := request.session[HIDDEN_LANG_SESSION_KEY]: + if hidden_languages := request.session.get(HIDDEN_LANG_SESSION_KEY, []): obj_list = obj_list.exclude(mm_language__in=hidden_languages) return obj_list.order_by("-mm_created") diff --git a/mbr_news_plugin/cms_plugins.py b/mbr_news_plugin/cms_plugins.py index fb41609e01d440f07033f09193ca178befb6250c..7a366137523a7cca85a6bbc542d2673310f0051a 100644 --- a/mbr_news_plugin/cms_plugins.py +++ b/mbr_news_plugin/cms_plugins.py @@ -29,7 +29,7 @@ class MemberNewsPlugin(CMSPluginBase): """ add object_list to context """ context = super().render(context, instance, placeholder) - hidden_languages = context['request'].session[HIDDEN_LANG_SESSION_KEY] + hidden_languages = context['request'].session.get(HIDDEN_LANG_SESSION_KEY, []) mes = MemberAnnouncement.objects \ .exclude(Q(ma_language__in=hidden_languages) | Q(ma_description__contains=EXC_ADD_MARKER)) diff --git a/requirements_frozen.txt b/requirements_frozen.txt new file mode 100644 index 0000000000000000000000000000000000000000..0222c3b5bec30d87a8bf10622760caf260277795 --- /dev/null +++ b/requirements_frozen.txt @@ -0,0 +1,27 @@ +ae_base==0.3.38 +ae-django-utils==0.3.1 +ae_notify==0.3.5 +django-cms==3.8.0 +djangocms-admin-style==2.0.2 +django-treebeard==4.4 +djangocms-text-ckeditor==4.0.0 +djangocms-link==3.1.0 +djangocms-icon==2.0.0 +djangocms-style==3.0.0 +djangocms-googlemap==2.0.0 +djangocms-video==3.0.0 +djangocms-file==3.0.0 +djangocms-picture==3.0.0 +djangocms-bootstrap4==2.0.0 +django-filer==2.2.4 +Django==3.1.14 +django-classy-tags==3.0.1 +django-sekizai==3.0.1 +django-mptt==0.14.0 +django-crispy-forms==1.14.0 +easy-thumbnails==2.8.5 +html5lib==1.1 +Pillow==9.3.0 +pytz==2022.6 +requests==2.32.3 +six==1.16.0