diff --git a/check_process.default b/check_process.default new file mode 100644 index 0000000..4c705fe --- /dev/null +++ b/check_process.default @@ -0,0 +1,43 @@ +# See here for more informations +# https://github.com/YunoHost/package_check#syntax-check_process-file + +# Move this file from check_process.default to check_process when you have filled it. + +;; Test complet + ; Manifest + domain="domain.tld" (DOMAIN) + path="/path" (PATH) + admin="john" (USER) + language="fr" + is_public=1 (PUBLIC|public=1|private=0) + password="pass" + port="666" (PORT) + ; Checks + pkg_linter=1 + setup_sub_dir=1 + setup_root=1 + setup_nourl=0 + setup_private=1 + setup_public=1 + upgrade=1 + backup_restore=1 + multi_instance=1 + incorrect_path=1 + port_already_use=1 + change_url=0 +;;; Levels + Level 1=auto + Level 2=auto + Level 3=auto +# Level 4: + Level 4=0 +# Level 5: + Level 5=auto + Level 6=auto + Level 7=auto + Level 8=0 + Level 9=0 + Level 10=0 +;;; Options +Email= +Notification=none diff --git a/conf/app.src b/conf/app.src new file mode 100644 index 0000000..c2ad4dc --- /dev/null +++ b/conf/app.src @@ -0,0 +1,6 @@ +SOURCE_URL=https://dl.cihar.com/weblate/Weblate-2.16.tar.xz +SOURCE_SUM=0cd67d3eef8fb414c55d9447a361feb9718e39460c85de51fc0c636838625c70 +SOURCE_SUM_PRG=sha256 +SOURCE_FORMAT=tar.xz +SOURCE_IN_SUBDIR=true +SOURCE_FILENAME=Weblate-2.16.tar.xz diff --git a/conf/cron_weblate b/conf/cron_weblate new file mode 100644 index 0000000..6b5febf --- /dev/null +++ b/conf/cron_weblate @@ -0,0 +1,3 @@ +# https://docs.weblate.org/en/latest/admin/management.html#update-index +# every 10 minutes +10 * * * * www-data cd "__FINALPATH__" && python3 ./manage.py update_index diff --git a/conf/nginx.conf b/conf/nginx.conf new file mode 100644 index 0000000..6eda5c8 --- /dev/null +++ b/conf/nginx.conf @@ -0,0 +1,46 @@ +location __PATH__ { + #Source: https://docs.weblate.org/en/latest/admin/install.html#sample-configuration-for-nginx-and-uwsgi + #TODO:https://docs.weblate.org/en/latest/admin/install.html#id2 + # Path to source + alias __FINALPATH__/ ; + + if ($scheme = http) { + rewrite ^ https://$server_name$request_uri? permanent; + } + + location /favicon.ico { + # DATA_DIR/static/favicon.ico + alias __FINALPATH__/static/favicon.ico; + expires 30d; + } + + location /robots.txt { + # DATA_DIR/static/robots.txt + alias __FINALPATH__/static/robots.txt; + expires 30d; + } + + location /static { + # DATA_DIR/static/ + alias __FINALPATH__/static/; + expires 30d; + } + + location /media { + # DATA_DIR/media/ + alias __FINALPATH__/media/; + expires 30d; + } + + location / { + include uwsgi_params; + # Needed for long running operations in admin interface + uwsgi_read_timeout 3600; + # Adjust based to uwsgi configuration: + uwsgi_pass unix:///run/uwsgi/app/weblate/socket; + # uwsgi_pass 127.0.0.1:8080; + } + + # Include SSOWAT user panel. + include conf.d/yunohost_panel.conf.inc; +} diff --git a/conf/settings.py b/conf/settings.py new file mode 100644 index 0000000..f1ca838 --- /dev/null +++ b/conf/settings.py @@ -0,0 +1,705 @@ +# -*- coding: utf-8 -*- +# +# Copyright © 2012 - 2017 Michal Čihař +# +# This file is part of Weblate +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program 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 General Public License +# along with this program. If not, see . +# + +from __future__ import unicode_literals +import platform +import os +from logging.handlers import SysLogHandler + +# +# Django settings for Weblate project. +# + +DEBUG = True + +ADMINS = ( + ('__ADMIN__', '__ADMINMAIL__'), +) + +MANAGERS = ADMINS + +DATABASES = { + 'default': { + # Database engine + 'ENGINE': 'django.db.backends.mysql', + # Database name + 'NAME': '__APP__', + # Database user + 'USER': '__APP__', + # Database password + 'PASSWORD': '__DB_PWD__', + # Set to empty string for localhost + 'HOST': '', + # Set to empty string for default + 'PORT': '', + # Additional database options + 'OPTIONS': { + # In case of older MySQL server which has default MariaDB + # 'init_command': 'SET storage_engine=INNODB', + # If your server supports it, see Unicode issues above + 'charset': 'utf8mb4', + } + + } +} + +BASE_DIR = os.path.dirname(os.path.abspath(__file__)) + +# Data directory +DATA_DIR = os.path.join(BASE_DIR, '..', 'data') + +# Local time zone for this installation. Choices can be found here: +# http://en.wikipedia.org/wiki/List_of_tz_zones_by_name +# although not all choices may be available on all operating systems. +# On Unix systems, a value of None will cause Django to use the same +# timezone as the operating system. +# If running in a Windows environment this must be set to the same as your +# system time zone. +TIME_ZONE = 'UTC' + +# Language code for this installation. All choices can be found here: +# http://www.i18nguy.com/unicode/language-identifiers.html +LANGUAGE_CODE = 'en-us' + +LANGUAGES = ( + ('az', 'Azərbaycan'), + ('be', 'Беларуская'), + ('be@latin', 'Biełaruskaja'), + ('bg', 'Български'), + ('br', 'Brezhoneg'), + ('ca', 'Català'), + ('cs', 'Čeština'), + ('da', 'Dansk'), + ('de', 'Deutsch'), + ('en', 'English'), + ('en-gb', 'English (United Kingdom)'), + ('el', 'Ελληνικά'), + ('es', 'Español'), + ('fi', 'Suomi'), + ('fr', 'Français'), + ('fy', 'Frysk'), + ('gl', 'Galego'), + ('he', 'עברית'), + ('hu', 'Magyar'), + ('id', 'Indonesia'), + ('it', 'Italiano'), + ('ja', '日本語'), + ('ko', '한국어'), + ('ksh', 'Kölsch'), + ('nb', 'Norsk bokmål'), + ('nl', 'Nederlands'), + ('pl', 'Polski'), + ('pt', 'Português'), + ('pt-br', 'Português brasileiro'), + ('ru', 'Русский'), + ('sk', 'Slovenčina'), + ('sl', 'Slovenščina'), + ('sr', 'Српски'), + ('sv', 'Svenska'), + ('tr', 'Türkçe'), + ('uk', 'Українська'), + ('zh-hans', '简体字'), + ('zh-hant', '正體字'), +) + +SITE_ID = 1 + +# If you set this to False, Django will make some optimizations so as not +# to load the internationalization machinery. +USE_I18N = True + +# If you set this to False, Django will not format dates, numbers and +# calendars according to the current locale. +USE_L10N = True + +# If you set this to False, Django will not use timezone-aware datetimes. +USE_TZ = True + +# URL prefix to use, please see documentation for more details +URL_PREFIX = '' + +# Absolute filesystem path to the directory that will hold user-uploaded files. +# Example: "/home/media/media.lawrence.com/media/" +MEDIA_ROOT = os.path.join(DATA_DIR, 'media') + +# URL that handles the media served from MEDIA_ROOT. Make sure to use a +# trailing slash. +# Examples: "http://media.lawrence.com/media/", "http://example.com/media/" +MEDIA_URL = '{0}/media/'.format(URL_PREFIX) + +# Absolute path to the directory static files should be collected to. +# Don't put anything in this directory yourself; store your static files +# in apps' "static/" subdirectories and in STATICFILES_DIRS. +# Example: "/home/media/media.lawrence.com/static/" +STATIC_ROOT = os.path.join(DATA_DIR, 'static') + +# URL prefix for static files. +# Example: "http://media.lawrence.com/static/" +STATIC_URL = '{0}/static/'.format(URL_PREFIX) + +# Additional locations of static files +STATICFILES_DIRS = ( + # Put strings here, like "/home/html/static" or "C:/www/django/static". + # Always use forward slashes, even on Windows. + # Don't forget to use absolute paths, not relative paths. +) + +# List of finder classes that know how to find static files in +# various locations. +STATICFILES_FINDERS = ( + 'django.contrib.staticfiles.finders.FileSystemFinder', + 'django.contrib.staticfiles.finders.AppDirectoriesFinder', + 'compressor.finders.CompressorFinder', +) + +# Make this unique, and don't share it with anybody. +# You can generate it using examples/generate-secret-key +SECRET_KEY = '__KEY__' # noqa + +TEMPLATES = [ + { + 'BACKEND': 'django.template.backends.django.DjangoTemplates', + 'OPTIONS': { + 'context_processors': [ + 'django.contrib.auth.context_processors.auth', + 'django.template.context_processors.debug', + 'django.template.context_processors.i18n', + 'django.template.context_processors.request', + 'django.template.context_processors.csrf', + 'django.contrib.messages.context_processors.messages', + 'weblate.trans.context_processors.weblate_context', + ], + 'loaders': [ + ('django.template.loaders.cached.Loader', [ + 'django.template.loaders.filesystem.Loader', + 'django.template.loaders.app_directories.Loader', + ]), + ], + }, + }, +] + + +# GitHub username for sending pull requests. +# Please see the documentation for more details. +GITHUB_USERNAME = None + +# Authentication configuration +AUTHENTICATION_BACKENDS = ( + 'social_core.backends.email.EmailAuth', + # 'social_core.backends.google.GoogleOAuth2', + # 'social_core.backends.github.GithubOAuth2', + # 'social_core.backends.bitbucket.BitbucketOAuth', + # 'social_core.backends.suse.OpenSUSEOpenId', + # 'social_core.backends.ubuntu.UbuntuOpenId', + # 'social_core.backends.fedora.FedoraOpenId', + # 'social_core.backends.facebook.FacebookOAuth2', + 'weblate.accounts.auth.WeblateUserBackend', +) + +# Social auth backends setup +SOCIAL_AUTH_GITHUB_KEY = '' +SOCIAL_AUTH_GITHUB_SECRET = '' +SOCIAL_AUTH_GITHUB_SCOPE = ['user:email'] + +SOCIAL_AUTH_BITBUCKET_KEY = '' +SOCIAL_AUTH_BITBUCKET_SECRET = '' +SOCIAL_AUTH_BITBUCKET_VERIFIED_EMAILS_ONLY = True + +SOCIAL_AUTH_FACEBOOK_KEY = '' +SOCIAL_AUTH_FACEBOOK_SECRET = '' +SOCIAL_AUTH_FACEBOOK_SCOPE = ['email', 'public_profile'] + +SOCIAL_AUTH_GOOGLE_OAUTH2_KEY = '' +SOCIAL_AUTH_GOOGLE_OAUTH2_SECRET = '' + +# Social auth settings +SOCIAL_AUTH_PIPELINE = ( + 'social_core.pipeline.social_auth.social_details', + 'social_core.pipeline.social_auth.social_uid', + 'social_core.pipeline.social_auth.auth_allowed', + 'social_core.pipeline.social_auth.social_user', + 'weblate.accounts.pipeline.store_params', + 'weblate.accounts.pipeline.verify_open', + 'social_core.pipeline.user.get_username', + 'weblate.accounts.pipeline.require_email', + 'social_core.pipeline.mail.mail_validation', + 'weblate.accounts.pipeline.revoke_mail_code', + 'weblate.accounts.pipeline.ensure_valid', + 'weblate.accounts.pipeline.reauthenticate', + 'social_core.pipeline.social_auth.associate_by_email', + 'weblate.accounts.pipeline.verify_username', + 'social_core.pipeline.user.create_user', + 'social_core.pipeline.social_auth.associate_user', + 'social_core.pipeline.social_auth.load_extra_data', + 'weblate.accounts.pipeline.cleanup_next', + 'weblate.accounts.pipeline.user_full_name', + 'weblate.accounts.pipeline.store_email', + 'weblate.accounts.pipeline.notify_connect', + 'weblate.accounts.pipeline.password_reset', +) +SOCIAL_AUTH_DISCONNECT_PIPELINE = ( + 'social_core.pipeline.disconnect.allowed_to_disconnect', + 'social_core.pipeline.disconnect.get_entries', + 'social_core.pipeline.disconnect.revoke_tokens', + 'weblate.accounts.pipeline.cycle_session', + 'weblate.accounts.pipeline.adjust_primary_mail', + 'weblate.accounts.pipeline.notify_disconnect', + 'social_core.pipeline.disconnect.disconnect', + 'weblate.accounts.pipeline.cleanup_next', +) + +# Custom authentication strategy +SOCIAL_AUTH_STRATEGY = 'weblate.accounts.strategy.WeblateStrategy' + +# Raise exceptions so that we can handle them later +SOCIAL_AUTH_RAISE_EXCEPTIONS = True + +SOCIAL_AUTH_EMAIL_VALIDATION_FUNCTION = \ + 'weblate.accounts.pipeline.send_validation' +SOCIAL_AUTH_EMAIL_VALIDATION_URL = \ + '{0}/accounts/email-sent/'.format(URL_PREFIX) +SOCIAL_AUTH_LOGIN_ERROR_URL = \ + '{0}/accounts/login/'.format(URL_PREFIX) +SOCIAL_AUTH_EMAIL_FORM_URL = \ + '{0}/accounts/email/'.format(URL_PREFIX) +SOCIAL_AUTH_NEW_ASSOCIATION_REDIRECT_URL = \ + '{0}/accounts/profile/#auth'.format(URL_PREFIX) +SOCIAL_AUTH_PROTECTED_USER_FIELDS = ('email',) +SOCIAL_AUTH_SLUGIFY_USERNAMES = True +SOCIAL_AUTH_SLUGIFY_FUNCTION = 'weblate.accounts.pipeline.slugify_username' + +# Password validation configuration +AUTH_PASSWORD_VALIDATORS = [ + { + 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', + }, + { + 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', + 'OPTIONS': { + 'min_length': 6, + } + }, + { + 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', + }, + { + 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', + }, + { + 'NAME': 'weblate.accounts.password_validation.CharsPasswordValidator', + }, +] + +# Middleware +MIDDLEWARE_CLASSES = ( + 'django.contrib.sessions.middleware.SessionMiddleware', + 'django.middleware.common.CommonMiddleware', + 'django.middleware.locale.LocaleMiddleware', + 'django.middleware.csrf.CsrfViewMiddleware', + 'weblate.accounts.middleware.AuthenticationMiddleware', + 'django.contrib.messages.middleware.MessageMiddleware', + 'django.middleware.clickjacking.XFrameOptionsMiddleware', + 'social_django.middleware.SocialAuthExceptionMiddleware', + 'weblate.accounts.middleware.RequireLoginMiddleware', + 'weblate.middleware.SecurityMiddleware', +) + +ROOT_URLCONF = 'weblate.urls' + +INSTALLED_APPS = ( + # Has to be first to override Django admin templates: + 'weblate.wladmin', + + 'django.contrib.auth', + 'django.contrib.contenttypes', + 'django.contrib.sessions', + 'django.contrib.sites', + 'django.contrib.messages', + 'django.contrib.staticfiles', + 'django.contrib.admin.apps.SimpleAdminConfig', + 'django.contrib.admindocs', + 'django.contrib.sitemaps', + 'social_django', + 'crispy_forms', + 'compressor', + 'rest_framework', + 'rest_framework.authtoken', + 'weblate.trans', + 'weblate.lang', + 'weblate.permissions', + 'weblate.screenshots', + 'weblate.accounts', + 'weblate.utils', + + # Optional: Git exporter + # 'weblate.gitexport', + + # This application has to be placed last! + 'weblate', +) + +# Path to locales +LOCALE_PATHS = (os.path.join(BASE_DIR, 'locale'), ) + +# Custom exception reporter to include some details +DEFAULT_EXCEPTION_REPORTER_FILTER = \ + 'weblate.trans.debug.WeblateExceptionReporterFilter' + +# Default logging of Weblate messages +# - to syslog in production (if available) +# - otherwise to console +# - you can also choose 'logfile' to log into separate file +# after configuring it below + +# Detect if we can connect to syslog +HAVE_SYSLOG = False +if platform.system() != 'Windows': + try: + SysLogHandler(address='/dev/log', facility=SysLogHandler.LOG_LOCAL2) + HAVE_SYSLOG = True + except IOError: + HAVE_SYSLOG = False + +if DEBUG or not HAVE_SYSLOG: + DEFAULT_LOG = 'console' +else: + DEFAULT_LOG = 'syslog' + +# A sample logging configuration. The only tangible logging +# performed by this configuration is to send an email to +# the site admins on every HTTP 500 error when DEBUG=False. +# See http://docs.djangoproject.com/en/stable/topics/logging for +# more details on how to customize your logging configuration. +LOGGING = { + 'version': 1, + 'disable_existing_loggers': False, + 'filters': { + 'require_debug_false': { + '()': 'django.utils.log.RequireDebugFalse' + } + }, + 'formatters': { + 'syslog': { + 'format': 'weblate[%(process)d]: %(levelname)s %(message)s' + }, + 'simple': { + 'format': '%(levelname)s %(message)s' + }, + 'logfile': { + 'format': '%(asctime)s %(levelname)s %(message)s' + }, + }, + 'handlers': { + 'mail_admins': { + 'level': 'ERROR', + 'filters': ['require_debug_false'], + 'class': 'django.utils.log.AdminEmailHandler', + 'include_html': True, + }, + 'console': { + 'level': 'DEBUG', + 'class': 'logging.StreamHandler', + 'formatter': 'simple' + }, + 'syslog': { + 'level': 'DEBUG', + 'class': 'logging.handlers.SysLogHandler', + 'formatter': 'syslog', + 'address': '/dev/log', + 'facility': SysLogHandler.LOG_LOCAL2, + }, + # Logging to a file + # 'logfile': { + # 'level':'DEBUG', + # 'class':'logging.handlers.RotatingFileHandler', + # 'filename': "/var/log/weblate/weblate.log", + # 'maxBytes': 100000, + # 'backupCount': 3, + # 'formatter': 'logfile', + # }, + }, + 'loggers': { + 'django.request': { + 'handlers': ['mail_admins', DEFAULT_LOG], + 'level': 'ERROR', + 'propagate': True, + }, + # Logging database queries + # 'django.db.backends': { + # 'handlers': [DEFAULT_LOG], + # 'level': 'DEBUG', + # }, + 'weblate': { + 'handlers': [DEFAULT_LOG], + 'level': 'DEBUG', + }, + # Logging VCS operations + # 'weblate-vcs': { + # 'handlers': [DEFAULT_LOG], + # 'level': 'DEBUG', + # }, + # Python Social Auth logging + # 'social': { + # 'handlers': [DEFAULT_LOG], + # 'level': 'DEBUG', + # }, + } +} + +# Logging of management commands to console +if (os.environ.get('DJANGO_IS_MANAGEMENT_COMMAND', False) and + 'console' not in LOGGING['loggers']['weblate']['handlers']): + LOGGING['loggers']['weblate']['handlers'].append('console') + +# Remove syslog setup if it's not present +if not HAVE_SYSLOG: + del LOGGING['handlers']['syslog'] + +# List of machine translations +# MACHINE_TRANSLATION_SERVICES = ( +# 'weblate.trans.machine.apertium.ApertiumAPYTranslation', +# 'weblate.trans.machine.glosbe.GlosbeTranslation', +# 'weblate.trans.machine.google.GoogleTranslation', +# 'weblate.trans.machine.microsoft.MicrosoftCognitiveTranslation', +# 'weblate.trans.machine.mymemory.MyMemoryTranslation', +# 'weblate.trans.machine.tmserver.AmagamaTranslation', +# 'weblate.trans.machine.tmserver.TMServerTranslation', +# 'weblate.trans.machine.yandex.YandexTranslation', +# 'weblate.trans.machine.weblatetm.WeblateSimilarTranslation', +# 'weblate.trans.machine.weblatetm.WeblateTranslation', +# ) + +# Machine translation API keys + +# URL of the Apertium APy server +MT_APERTIUM_APY = None + +# Microsoft Translator service, register at +# https://datamarket.azure.com/developer/applications/ +MT_MICROSOFT_ID = None +MT_MICROSOFT_SECRET = None + +# Microsoft Cognitive Services Translator API, register at +# https://portal.azure.com/ +MT_MICROSOFT_COGNITIVE_KEY = None + +# MyMemory identification email, see +# https://mymemory.translated.net/doc/spec.php +MT_MYMEMORY_EMAIL = None + +# Optional MyMemory credentials to access private translation memory +MT_MYMEMORY_USER = None +MT_MYMEMORY_KEY = None + +# Google API key for Google Translate API +MT_GOOGLE_KEY = None + +# API key for Yandex Translate API +MT_YANDEX_KEY = None + +# tmserver URL +MT_TMSERVER = None + +# Title of site to use +SITE_TITLE = 'Weblate' + +# Whether site uses https +ENABLE_HTTPS = True + +# Use HTTPS when creating redirect URLs for social authentication, see +# documentation for more details: +# http://python-social-auth-docs.readthedocs.io/en/latest/configuration/settings.html#processing-redirects-and-urlopen +SOCIAL_AUTH_REDIRECT_IS_HTTPS = ENABLE_HTTPS + +# Make CSRF cookie HttpOnly, see documentation for more details: +# https://docs.djangoproject.com/en/1.11/ref/settings/#csrf-cookie-httponly +CSRF_COOKIE_HTTPONLY = True +CSRF_COOKIE_SECURE = ENABLE_HTTPS +# Store CSRF token in session (since Django 1.11) +CSRF_USE_SESSIONS = True +SESSION_COOKIE_SECURE = ENABLE_HTTPS +# Session cookie age (in seconds) +SESSION_COOKIE_AGE = 1209600 + +# URL of login +LOGIN_URL = '{0}/accounts/login/'.format(URL_PREFIX) + +# URL of logout +LOGOUT_URL = '{0}/accounts/logout/'.format(URL_PREFIX) + +# Default location for login +LOGIN_REDIRECT_URL = '{0}/'.format(URL_PREFIX) + +# Anonymous user name +ANONYMOUS_USER_NAME = 'anonymous' + +# Reverse proxy settings +IP_BEHIND_REVERSE_PROXY = False +IP_PROXY_HEADER = 'HTTP_X_FORWARDED_FOR' +IP_PROXY_OFFSET = 0 + +# Sending HTML in mails +EMAIL_SEND_HTML = True + +# Subject of emails includes site title +EMAIL_SUBJECT_PREFIX = '[{0}] '.format(SITE_TITLE) + +# Enable remote hooks +ENABLE_HOOKS = True + +# Whether to run hooks in background +BACKGROUND_HOOKS = True + +# Number of nearby messages to show in each direction +NEARBY_MESSAGES = 5 + +# Enable lazy commits +LAZY_COMMITS = True + +# Offload indexing +OFFLOAD_INDEXING = True + +# Translation locking +AUTO_LOCK = True +AUTO_LOCK_TIME = 60 +LOCK_TIME = 15 * 60 + +# Render forms using bootstrap +CRISPY_TEMPLATE_PACK = 'bootstrap3' + +# List of quality checks +# CHECK_LIST = ( +# 'weblate.trans.checks.same.SameCheck', +# 'weblate.trans.checks.chars.BeginNewlineCheck', +# 'weblate.trans.checks.chars.EndNewlineCheck', +# 'weblate.trans.checks.chars.BeginSpaceCheck', +# 'weblate.trans.checks.chars.EndSpaceCheck', +# 'weblate.trans.checks.chars.EndStopCheck', +# 'weblate.trans.checks.chars.EndColonCheck', +# 'weblate.trans.checks.chars.EndQuestionCheck', +# 'weblate.trans.checks.chars.EndExclamationCheck', +# 'weblate.trans.checks.chars.EndEllipsisCheck', +# 'weblate.trans.checks.chars.EndSemicolonCheck', +# 'weblate.trans.checks.chars.MaxLengthCheck', +# 'weblate.trans.checks.format.PythonFormatCheck', +# 'weblate.trans.checks.format.PythonBraceFormatCheck', +# 'weblate.trans.checks.format.PHPFormatCheck', +# 'weblate.trans.checks.format.CFormatCheck', +# 'weblate.trans.checks.format.PerlFormatCheck', +# 'weblate.trans.checks.format.JavascriptFormatCheck', +# 'weblate.trans.checks.consistency.PluralsCheck', +# 'weblate.trans.checks.consistency.SamePluralsCheck', +# 'weblate.trans.checks.consistency.ConsistencyCheck', +# 'weblate.trans.checks.consistency.TranslatedCheck', +# 'weblate.trans.checks.chars.NewlineCountingCheck', +# 'weblate.trans.checks.markup.BBCodeCheck', +# 'weblate.trans.checks.chars.ZeroWidthSpaceCheck', +# 'weblate.trans.checks.markup.XMLValidityCheck', +# 'weblate.trans.checks.markup.XMLTagsCheck', +# 'weblate.trans.checks.source.OptionalPluralCheck', +# 'weblate.trans.checks.source.EllipsisCheck', +# 'weblate.trans.checks.source.MultipleFailingCheck', +# ) + +# List of automatic fixups +# AUTOFIX_LIST = ( +# 'weblate.trans.autofixes.whitespace.SameBookendingWhitespace', +# 'weblate.trans.autofixes.chars.ReplaceTrailingDotsWithEllipsis', +# 'weblate.trans.autofixes.chars.RemoveZeroSpace', +# 'weblate.trans.autofixes.chars.RemoveControlChars', +# ) + +# List of scripts to use in custom processing +# POST_UPDATE_SCRIPTS = ( +# ) +# PRE_COMMIT_SCRIPTS = ( +# ) + +# E-mail address that error messages come from. +SERVER_EMAIL = 'noreply@__DOMAIN__' + +# Default email address to use for various automated correspondence from +# the site managers. Used for registration emails. +DEFAULT_FROM_EMAIL = '__ADMINMAIL__' + +# List of URLs your site is supposed to serve +ALLOWED_HOSTS = ['__DOMAIN__'] + +# Example configuration to use memcached for caching +# CACHES = { +# 'default': { +# 'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache', +# 'LOCATION': '127.0.0.1:11211', +# }, +# 'avatar': { +# 'BACKEND': 'django.core.cache.backends.filebased.FileBasedCache', +# 'LOCATION': os.path.join(BASE_DIR, 'avatar-cache'), +# 'TIMEOUT': 3600, +# 'OPTIONS': { +# 'MAX_ENTRIES': 1000, +# }, +# } +# } + +# REST framework settings for API +REST_FRAMEWORK = { + # Use Django's standard `django.contrib.auth` permissions, + # or allow read-only access for unauthenticated users. + 'DEFAULT_PERMISSION_CLASSES': [ + 'rest_framework.permissions.IsAuthenticatedOrReadOnly' + ], + 'DEFAULT_AUTHENTICATION_CLASSES': ( + 'rest_framework.authentication.TokenAuthentication', + 'rest_framework.authentication.SessionAuthentication', + ), + 'DEFAULT_THROTTLE_CLASSES': ( + 'rest_framework.throttling.AnonRateThrottle', + 'rest_framework.throttling.UserRateThrottle' + ), + 'DEFAULT_THROTTLE_RATES': { + 'anon': '100/day', + 'user': '1000/day' + }, + 'DEFAULT_PAGINATION_CLASS': ( + 'rest_framework.pagination.PageNumberPagination' + ), + 'PAGE_SIZE': 20, + 'VIEW_DESCRIPTION_FUNCTION': 'weblate.api.views.get_view_description', + 'UNAUTHENTICATED_USER': 'weblate.accounts.models.get_anonymous', +} + +# Example for restricting access to logged in users +# LOGIN_REQUIRED_URLS = ( +# r'/(.*)$', +# ) + +# In such case you will want to include some of the exceptions +# LOGIN_REQUIRED_URLS_EXCEPTIONS = ( +# r'/accounts/(.*)$', # Required for login +# r'/static/(.*)$', # Required for development mode +# r'/widgets/(.*)$', # Allowing public access to widgets +# r'/data/(.*)$', # Allowing public access to data exports +# r'/hooks/(.*)$', # Allowing public access to notification hooks +# r'/api/(.*)$', # Allowing access to API +# ) + +# Force sane test runner +TEST_RUNNER = 'django.test.runner.DiscoverRunner' diff --git a/conf/uwsgi.ini b/conf/uwsgi.ini new file mode 100644 index 0000000..4eb5490 --- /dev/null +++ b/conf/uwsgi.ini @@ -0,0 +1,31 @@ +[uwsgi] +uid = __APP__ +gid = users + +protocol = uwsgi +wsgi-file = __FINALPATH__/weblate/wsgi.py +python-path = __FINALPATH__ +# Needed for OAuth/OpenID +buffer-size = 8192 +# Increase number of workers for heavily loaded sites +#workers = 6 +# Needed for background processing +enable-threads = true +# Child processes do not need file descriptors +close-on-exec = true +# Avoid default 0000 umask +umask = 0022 + +# process-related settings +# master +master = true +# maximum number of worker processes +processes = 4 +# the socket (use the full path to be safe +socket = /opt/__APP__/uwsgi.sock +# ... with appropriate permissions - may be needed +chmod-socket = 666 +stats = /opt/__APP__/stats.sock +# clear environment on exit +vacuum = true +plugins = python3 diff --git a/manifest.json b/manifest.json new file mode 100644 index 0000000..f54d1a2 --- /dev/null +++ b/manifest.json @@ -0,0 +1,42 @@ +{ + "name": "Weblate", + "id": "weblate", + "packaging_format": 1, + "requirements": { + "yunohost": ">= 2.7.0" + }, + "description": { + "en": "Instant messaging server who use matrix" + }, + "version": "2.16.0", + "url": "https://weblate.org", + "license": "GNU GPL-3, or any later version.", + "maintainer": { + "name": "Jean-Baptiste Holcroft", + "email": "jean-baptiste@holcroft.fr" + }, + "multi_instance": true, + "services": [ + "nginx" + ], + "arguments": { + "install" : [ + { + "name": "domain", + "type": "domain", + "ask": { + "en": "Choose a domain:", + }, + "example": "domain.org" + }, + { + "name": "is_public", + "type": "boolean", + "ask": { + "en": "Is it a public server ?" + }, + "default": "0" + } + ] + } +} diff --git a/scripts/_common.sh b/scripts/_common.sh new file mode 100644 index 0000000..f07a1be --- /dev/null +++ b/scripts/_common.sh @@ -0,0 +1,2 @@ +#!/bin/bash +# unused at the moment diff --git a/scripts/backup b/scripts/backup new file mode 100755 index 0000000..2c52551 --- /dev/null +++ b/scripts/backup @@ -0,0 +1,70 @@ +#!/bin/bash + +# TODO: https://docs.weblate.org/en/latest/admin/install.html#migrating-database + +#================================================= +# GENERIC START +#================================================= +# MANAGE SCRIPT FAILURE +#================================================= + +# Exit on command errors and treat access to unset variables as an error +set -eu + +#================================================= +# IMPORT GENERIC HELPERS +#================================================= + +if [ ! -e _common.sh ]; then + # Get the _common.sh file if it's not in the current directory + cp ../settings/scripts/_common.sh ./_common.sh + chmod a+rx _common.sh +fi +source _common.sh +source /usr/share/yunohost/helpers + +#================================================= +# LOAD SETTINGS +#================================================= + +app=$YNH_APP_INSTANCE_NAME + +final_path=$(ynh_app_setting_get $app final_path) +domain=$(ynh_app_setting_get $app domain) +db_name=$(ynh_app_setting_get $app db_name) +db_pwd=$(ynh_app_setting_get $app mysqlpwd) + +#================================================= +# STANDARD BACKUP STEPS +#================================================= +# BACKUP THE APP MAIN DIR +#================================================= + +ynh_backup "$final_path" "${backup_dir}$final_path" + +#================================================= +# BACKUP THE NGINX CONFIGURATION +#================================================= + +ynh_backup "/etc/nginx/conf.d/$domain.d/$app.conf" "${backup_dir}/etc/nginx/conf.d/$domain.d/$app.conf" + +#================================================= +# BACKUP THE MYSQL DATABASE +#================================================= + +ynh_mysql_dump_db "$db_name" > db.sql +ynh_backup "db.sql" "${backup_dir}/db.sql" + +#================================================= +# SPECIFIC BACKUP +#================================================= +# BACKUP LOGROTATE +#================================================= + +ynh_backup "/etc/logrotate.d/$app" "${backup_dir}/etc/logrotate.d/$app" + +#================================================= +# BACKUP THE CRON FILE +#================================================= + +ynh_backup "/etc/cron.d/$app" "${backup_dir}/etc/cron.d/$app" diff --git a/scripts/install b/scripts/install new file mode 100755 index 0000000..6567456 --- /dev/null +++ b/scripts/install @@ -0,0 +1,215 @@ +#!/bin/bash + +#================================================= +# GENERIC START +#================================================= +# IMPORT GENERIC HELPERS +#================================================= + +source _common.sh +source /usr/share/yunohost/helpers + +#================================================= +# MANAGE SCRIPT FAILURE +#================================================= + +# Exit if an error occurs during the execution of the script +ynh_abort_if_errors + +#================================================= +# RETRIEVE ARGUMENTS FROM THE MANIFEST +#================================================= + +domain=$YNH_APP_ARG_DOMAIN +path_url=$YNH_APP_ARG_PATH +admin=$YNH_APP_ARG_ADMIN +is_public=$YNH_APP_ARG_IS_PUBLIC +language=$YNH_APP_ARG_LANGUAGE + +# This is a multi-instance app, meaning it can be installed several times independently +# The id of the app as stated in the manifest is available as $YNH_APP_ID +# The instance number is available as $YNH_APP_INSTANCE_NUMBER (equals "1", "2", ...) +# The app instance name is available as $YNH_APP_INSTANCE_NAME +# - the first time the app is installed, YNH_APP_INSTANCE_NAME = ynhexample +# - the second time the app is installed, YNH_APP_INSTANCE_NAME = ynhexample__2 +# - ynhexample__{N} for the subsequent installations, with N=3,4, ... +# The app instance name is probably what you are interested the most, since this is +# guaranteed to be unique. This is a good unique identifier to define installation path, +# db names, ... +app=$YNH_APP_INSTANCE_NAME + +#================================================= +# CHECK IF THE APP CAN BE INSTALLED WITH THESE ARGS +#================================================= + +# Normalize the url path syntax +path_url=$(ynh_normalize_url_path $path_url) + +# Check web path availability +ynh_webpath_available $domain $path_url +# Register (book) web path +ynh_webpath_register $app $domain $path_url + +final_path=/var/www/$app +test ! -e "$final_path" || ynh_die "This path already contains a folder" + +#================================================= +# STORE SETTINGS FROM MANIFEST +#================================================= + +ynh_app_setting_set $app domain $domain +ynh_app_setting_set $app path $path_url +ynh_app_setting_set $app admin $admin +ynh_app_setting_set $app is_public $is_public +ynh_app_setting_set $app language $language + +#================================================= +# STANDARD MODIFICATIONS +#================================================= + +#================================================= +# INSTALL DEPENDENCIES +#================================================= + +ynh_install_app_dependencies python-django translate-toolkit \ + python-whoosh python-pil python-libravatar \ + python-babel git mercurial \ + python-django-compressor python-django-crispy-forms \ + python-djangorestframework python-dateutil + +#================================================= +# CREATE A MYSQL DATABASE +#================================================= +# If your app uses a MySQL database, you can use these lines to bootstrap +# a database, an associated user and save the password in app settings + +db_name=$(ynh_sanitize_dbid $app) +ynh_app_setting_set $app db_name $db_name +ynh_mysql_setup_db $db_name $db_name + +# https://docs.weblate.org/en/latest/admin/install.html#unicode-issues-in-mysql +ynh_mysql_execute_as_root "ALTER DATABASE weblate CHARACTER SET utf8mb4;" + +#================================================= +# DOWNLOAD, CHECK AND UNPACK SOURCE +#================================================= + +ynh_app_setting_set $app final_path $final_path +# Download, check integrity, uncompress and patch the source from app.src +ynh_setup_source "$final_path" + +#================================================= +# NGINX CONFIGURATION +#================================================= + +# Create a dedicated nginx config +ynh_add_nginx_config + +#================================================= +# CREATE DEDICATED USER +#================================================= + +# Create a system user +ynh_system_user_create $app + +#================================================= +# SPECIFIC SETUP +#================================================= +# SPECIFIC SETUP uwsgi +#================================================= + +# Copy Files +sudo cp ../conf/uwsgi.ini $final_path/uwsgi.ini +ynh_replace_string "__APP__" "$app" $final_path/uwsgi.ini +ynh_replace_string "__FINALPATH__" "$finalpath" $final_path/uwsgi.ini + +# Config service +sudo mkdir -p /etc/uwsgi/apps-enabled/ +sudo ln -s $final_path/uwsgi.ini /etc/uwsgi/apps-enabled/$app.uwsgi.ini + +# Start service +sudo systemctl enable uwsgi +sudo systemctl restart uwsgi + +# Add umap.uwsgi as a service +sudo yunohost service add $app.uwsgi + +#================================================= +# SPECIFIC SETUP settings.py +# https://docs.weblate.org/en/latest/admin/install.html#installation +#================================================= + +db_pwd=$(ynh_app_setting_get $app mysqlpwd) +admin_mail="$(ynh_user_get_info $admin mail)" +key=$(ynh_string_random 64) + +sudo cp $final_path/weblate/settings_example.py $final_path/weblate/settings.py +sudo cp ../conf/settings.py $final_path/weblate/settings.py + +ynh_replace_string "__APP__" "$app" $final_path/settings.py +ynh_replace_string "__DB_PWD__" "$db_pwd" $final_path/weblate/settings.py +ynh_replace_string "__ADMIN__" "$admin" $final_path/weblate/settings.py +ynh_replace_string "__ADMINMAIL__" "$admin_mail" $final_path/weblate/settings.py +ynh_replace_string "__DOMAIN__" "$domain" $final_path/weblate/settings.py +ynh_replace_string "__KEY__" "$key" $final_path/weblate/settings.py + + +#================================================= +# SPECIFIC SETUP Filling up the database +# https://docs.weblate.org/en/latest/admin/install.html#filling-up-the-database +#========================================== + +sudo $final_path/manage.py migrate --noinput + +#================================================= +# SETUP CRON +#================================================= + +cp ../conf/cron_weblate /etc/cron.d/$app +ynh_replace_string "__FINALPATH__" "$final_path/" /etc/cron.d/$app +chmod +x $final_path/script/lutim + +#================================================= +# STORE THE CHECKSUM OF THE CONFIG FILE +#================================================= + +# Calculate and store the config file checksum into the app settings +ynh_store_file_checksum "$final_path/CONFIG_FILE" + +#================================================= +# GENERIC FINALIZATION +#================================================= +# SECURE FILES AND DIRECTORIES +#================================================= + +# Set permissions to app files +chown -R root: $final_path + +#================================================= +# SETUP LOGROTATE +#================================================= + +# Use logrotate to manage application logfile(s) +ynh_use_logrotate + + +#================================================= +# SETUP SSOWAT +#================================================= + +if [ $is_public -eq 0 ] +then # Remove the public access + ynh_app_setting_delete $app skipped_uris +fi +# Make app public if necessary +if [ $is_public -eq 1 ] +then + # unprotected_uris allows SSO credentials to be passed anyway. + ynh_app_setting_set $app unprotected_uris "/" +fi + +#================================================= +# RELOAD NGINX +#================================================= + +systemctl reload nginx diff --git a/scripts/remove b/scripts/remove new file mode 100755 index 0000000..fbd8064 --- /dev/null +++ b/scripts/remove @@ -0,0 +1,115 @@ +#!/bin/bash + +#================================================= +# GENERIC START +#================================================= +# IMPORT GENERIC HELPERS +#================================================= + +source _common.sh +source /usr/share/yunohost/helpers + +#================================================= +# LOAD SETTINGS +#================================================= + +app=$YNH_APP_INSTANCE_NAME + +domain=$(ynh_app_setting_get $app domain) +port=$(ynh_app_setting_get $app port) +db_name=$(ynh_app_setting_get $app db_name) + +#================================================= +# STANDARD REMOVE +#================================================= +# STOP AND REMOVE SERVICE +#================================================= + +# Remove the dedicated systemd config +ynh_remove_systemd_config + +#================================================= +# REMOVE SERVICE FROM ADMIN PANEL +#================================================= + +if yunohost service status | grep -q $app +then + echo "Remove $app service" + yunohost service remove $app +fi + +#================================================= +# REMOVE DEPENDENCIES +#================================================= + +# Remove metapackage and its dependencies +ynh_remove_app_dependencies + +#================================================= +# REMOVE THE MYSQL DATABASE +#================================================= + +# Remove a database if it exists, along with the associated user +ynh_mysql_remove_db $db_name $db_name + +#================================================= +# REMOVE APP MAIN DIR +#================================================= + +# Remove the app directory securely +ynh_secure_remove "/var/www/$app" + +#================================================= +# REMOVE NGINX CONFIGURATION +#================================================= + +# Remove the dedicated nginx config +ynh_remove_nginx_config + +#================================================= +# REMOVE PHP-FPM CONFIGURATION +#================================================= + +# Remove the dedicated php-fpm config +ynh_remove_fpm_config + +#================================================= +# REMOVE LOGROTATE CONFIGURATION +#================================================= + +# Remove the app-specific logrotate config +ynh_remove_logrotate + +#================================================= +# CLOSE A PORT +#================================================= + +if yunohost firewall list | grep -q "\- $port$" +then + echo "Close port $port" + QUIET yunohost firewall disallow TCP $port +fi + +#================================================= +# SPECIFIC REMOVE +#================================================= +# REMOVE THE CRON FILE +#================================================= + +# Remove a cron file +ynh_secure_remove "/etc/cron.d/$app" + +# Remove a directory securely +ynh_secure_remove "/etc/$app/" + +# Remove the log files +ynh_secure_remove "/var/log/$app/" + +#================================================= +# GENERIC FINALIZATION +#================================================= +# REMOVE DEDICATED USER +#================================================= + +# Delete a system user +ynh_system_user_delete $app diff --git a/scripts/restore b/scripts/restore new file mode 100755 index 0000000..df59075 --- /dev/null +++ b/scripts/restore @@ -0,0 +1,117 @@ +#!/bin/bash + +#================================================= +# GENERIC START +#================================================= +# MANAGE SCRIPT FAILURE +#================================================= + +# Exit on command errors and treat access to unset variables as an error +set -eu + +#================================================= +# IMPORT GENERIC HELPERS +#================================================= + +if [ ! -e _common.sh ]; then + # Get the _common.sh file if it's not in the current directory + cp ../settings/scripts/_common.sh ./_common.sh + chmod a+rx _common.sh +fi +source _common.sh +source /usr/share/yunohost/helpers + +#================================================= +# LOAD SETTINGS +#================================================= + +app=$YNH_APP_INSTANCE_NAME + +domain=$(ynh_app_setting_get $app domain) +path_url=$(ynh_app_setting_get $app path) +final_path=$(ynh_app_setting_get $app final_path) +db_name=$(ynh_app_setting_get $app db_name) + +#================================================= +# CHECK IF THE APP CAN BE RESTORED +#================================================= + +yunohost app checkurl "${domain}${path_url}" -a "$app" \ + || ynh_die "Path not available: ${domain}${path_url}" +test ! -d $final_path \ + || ynh_die "There is already a directory: $final_path " + +#================================================= +# STANDARD RESTORATION STEPS +#================================================= +# RESTORE THE NGINX CONFIGURATION +#================================================= + +ynh_restore_file "/etc/nginx/conf.d/$domain.d/$app.conf" + +#================================================= +# RESTORE THE APP MAIN DIR +#================================================= + +ynh_restore_file "$final_path" + +#================================================= +# RESTORE THE MYSQL DATABASE +#================================================= + +db_pwd=$(ynh_app_setting_get $app mysqlpwd) +ynh_mysql_setup_db $db_name $db_name $db_pwd +ynh_mysql_connect_as $db_name $db_pwd $db_name < ./db.sql + +#================================================= +# RECREATE THE DEDICATED USER +#================================================= + +# Create the dedicated user (if not existing) +ynh_system_user_create $app + +#================================================= +# RESTORE USER RIGHTS +#================================================= + +# Restore permissions on app files +chown -R root: $final_path + +#================================================= +# SPECIFIC RESTORATION +#================================================= +# REINSTALL DEPENDENCIES +#================================================= + +# Define and install dependencies +ynh_install_app_dependencies python-django translate-toolkit \ + python-whoosh python-pil python-libravatar \ + python-babel git mercurial \ + python-django-compressor python-django-crispy-forms \ + python-djangorestframework python-dateutil + +#================================================= +# ADVERTISE SERVICE IN ADMIN PANEL +#================================================= + +yunohost service add $app --log "/var/log/$app/APP.log" + +#================================================= +# RESTORE THE CRON FILE +#================================================= + +ynh_restore_file "/etc/cron.d/$app" + +#================================================= +# BACKUP THE LOGROTATE CONFIGURATION +#================================================= + +ynh_restore_file "/etc/logrotate.d/$app" + +#================================================= +# GENERIC FINALIZATION +#================================================= +# RELOAD NGINX +#================================================= + +systemctl reload nginx diff --git a/scripts/upgrade b/scripts/upgrade new file mode 100755 index 0000000..c0b3296 --- /dev/null +++ b/scripts/upgrade @@ -0,0 +1,133 @@ +#!/bin/bash + +#================================================= +# GENERIC START +#================================================= +# IMPORT GENERIC HELPERS +#================================================= + +source _common.sh +source /usr/share/yunohost/helpers + +#================================================= +# LOAD SETTINGS +#================================================= + +app=$YNH_APP_INSTANCE_NAME + +domain=$(ynh_app_setting_get $app domain) +path_url=$(ynh_app_setting_get $app path) +admin=$(ynh_app_setting_get $app admin) +is_public=$(ynh_app_setting_get $app is_public) +final_path=$(ynh_app_setting_get $app final_path) +port=$(ynh_app_setting_get $app port) +db_name=$(ynh_app_setting_get $app db_name) + +#================================================= +# ENSURE DOWNWARD COMPATIBILITY +#================================================= + +if [ "$is_public" = "Yes" ]; then + ynh_app_setting_set $app is_public 1 # Fix is_public as a boolean value + is_public=1 +elif [ "$is_public" = "No" ]; then + ynh_app_setting_set $app is_public 0 + is_public=0 +fi + +if [ -z $db_name ]; then # If db_name doesn't exist, create it + db_name=$(ynh_sanitize_dbid $app) + ynh_app_setting_set $app db_name $db_name +fi + +#================================================= +# CHECK THE PATH +#================================================= + +# Normalize the URL path syntax +path_url=$(ynh_normalize_url_path $path_url) + +#================================================= +# STANDARD UPGRADE STEPS +#================================================= +# DOWNLOAD, CHECK AND UNPACK SOURCE +#================================================= + +# Download, check integrity, uncompress and patch the source from app.src +ynh_setup_source "$final_path" + +#================================================= +# NGINX CONFIGURATION +#================================================= + +# Create a dedicated nginx config +ynh_add_nginx_config + +#================================================= +# CREATE DEDICATED USER +#================================================= + +# Create a system user +ynh_system_user_create $app + +#================================================= +# PHP-FPM CONFIGURATION +#================================================= + +# Create a dedicated php-fpm config +ynh_fpm_config + +#================================================= +# SPECIFIC UPGRADE +#================================================= +# ... +#================================================= + +# Verify the checksum and backup the file if it's different +ynh_backup_if_checksum_is_different "$final_path/CONFIG_FILE" +# Recalculate and store the config file checksum into the app settings +ynh_store_file_checksum "$final_path/CONFIG_FILE" + +#================================================= +# SETUP LOGROTATE +#================================================= + +# Use logrotate to manage app-specific logfile(s) +ynh_use_logrotate + +#================================================= +# SETUP SYSTEMD +#================================================= + +# Create a dedicated systemd config +ynh_systemd_config + +#================================================= +# GENERIC FINALIZATION +#================================================= +# SECURE FILES AND DIRECTORIES +#================================================= + +# Set right permissions for curl installation +chown -R root: $final_path + +#================================================= +# SETUP SSOWAT +#================================================= + +if [ $is_public -eq 0 ] +then # Remove the public access + ynh_app_setting_delete $app skipped_uris +fi +# Make app public if necessary +if [ $is_public -eq 1 ] +then + # unprotected_uris allows SSO credentials to be passed anyway + ynh_app_setting_set $app unprotected_uris "/" +fi + +#================================================= +# RELOAD NGINX +#================================================= + +systemctl reload nginx diff --git a/sources/extra_files/app/.gitignore b/sources/extra_files/app/.gitignore new file mode 100644 index 0000000..783a4ae --- /dev/null +++ b/sources/extra_files/app/.gitignore @@ -0,0 +1,2 @@ +*~ +*.sw[op] diff --git a/sources/patches/.gitignore b/sources/patches/.gitignore new file mode 100644 index 0000000..783a4ae --- /dev/null +++ b/sources/patches/.gitignore @@ -0,0 +1,2 @@ +*~ +*.sw[op]