├── .gitignore
├── conf
├── local.example.json
├── reel2bits.target
├── front.src
├── audiowaveform.src
├── pythonz.src
├── googletest.src
├── app.src
├── reel2bits-worker.service
├── reel2bits-web.service
├── nginx.conf
└── prod_secret.py
├── .travis.yml
├── pull_request_template.md
├── check_process
├── scripts
├── _common.sh
├── ynh_add_swap
├── backup
├── remove
├── change_url
├── restore
├── upgrade
└── install
├── README.md
├── manifest.json
└── LICENSE
/.gitignore:
--------------------------------------------------------------------------------
1 | *~
2 | *.sw[op]
3 |
--------------------------------------------------------------------------------
/conf/local.example.json:
--------------------------------------------------------------------------------
1 | {
2 | "target": "http://127.0.0.1:5000/",
3 | "host": "__DOMAIN__"
4 | }
5 |
--------------------------------------------------------------------------------
/conf/reel2bits.target:
--------------------------------------------------------------------------------
1 | [Unit]
2 | Description=reel2bits
3 | Wants=reel2bits-web.service reel2bits-worker.service
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: python
2 |
3 | before_install:
4 | - git clone https://github.com/YunoHost/package_linter /tmp/package_linter
5 |
6 | script:
7 | - /tmp/package_linter/package_linter.py ./
--------------------------------------------------------------------------------
/conf/front.src:
--------------------------------------------------------------------------------
1 | SOURCE_URL=https://assets.reel2bits.org/front-dist-master.zip
2 | SOURCE_SUM=fa9f53337c2a4fddd82695922989e8c904007780874972390bc4f07406c33790
3 | SOURCE_SUM_PRG=sha256sum
4 | SOURCE_FORMAT=zip
5 | SOURCE_IN_SUBDIR=true
6 | SOURCE_FILENAME=
7 |
--------------------------------------------------------------------------------
/conf/audiowaveform.src:
--------------------------------------------------------------------------------
1 | SOURCE_URL=https://github.com/bbc/audiowaveform/archive/1.4.2.tar.gz
2 | SOURCE_SUM=3fc6b995d1ae0e5bf735a76e681e3e0df85eeabc06e7f253b5e28eff2c842354
3 | SOURCE_SUM_PRG=sha256sum
4 | SOURCE_FORMAT=tar.gz
5 | SOURCE_IN_SUBDIR=true
6 | SOURCE_FILENAME=
7 |
--------------------------------------------------------------------------------
/conf/pythonz.src:
--------------------------------------------------------------------------------
1 | SOURCE_URL=https://github.com/saghul/pythonz/archive/9067f35e0253b015eb51b8a4d60c0bd1a06dcc83.tar.gz
2 | SOURCE_SUM=ce9eb5400fff81e4877e04dd7166c764d8adc999d9ca6b06ce933ee9375b8652
3 | SOURCE_SUM_PRG=sha256sum
4 | SOURCE_FORMAT=tar.gz
5 | SOURCE_IN_SUBDIR=true
6 | SOURCE_FILENAME=
7 |
--------------------------------------------------------------------------------
/conf/googletest.src:
--------------------------------------------------------------------------------
1 | SOURCE_URL=https://github.com/google/googletest/archive/011959aafddcd30611003de96cfd8d7a7685c700.tar.gz
2 | SOURCE_SUM=0e34ac9e3aac3af3977a7ca45c27bb941fbf3a803877a7e440f93a6f9dc9235f
3 | SOURCE_SUM_PRG=sha256sum
4 | SOURCE_FORMAT=tar.gz
5 | SOURCE_IN_SUBDIR=true
6 | SOURCE_FILENAME=
7 |
--------------------------------------------------------------------------------
/conf/app.src:
--------------------------------------------------------------------------------
1 | SOURCE_URL=https://github.com/rhaamo/reel2bits/archive/680765b772ef394e225aa1cada315adef425e0cd.tar.gz
2 | SOURCE_SUM=5052c5ca938ee7f24b838947532e5a9d6a09f17a3a0d81c1c0ea5e0a3c1ed2c9
3 | SOURCE_SUM_PRG=sha256sum
4 | SOURCE_FORMAT=tar.gz
5 | SOURCE_IN_SUBDIR=true
6 | SOURCE_FILENAME=0.0.1-2020-02-04.tar.gz
7 |
--------------------------------------------------------------------------------
/conf/reel2bits-worker.service:
--------------------------------------------------------------------------------
1 | [Unit]
2 | Description=reel2bits-worker
3 | After=network.target
4 | PartOf=reel2bits.target
5 |
6 | [Service]
7 | Type=simple
8 | User=__APP__
9 | WorkingDirectory=__FINALPATH__/api
10 | Environment="FLASK_ENV=production"
11 | Environment="APP_SETTINGS=config.prod_secret.Config"
12 | ExecStart=__FINALPATH__/api/ve3/bin/celery worker -A tasks.celery -l INFO
13 | TimeoutSec=15
14 | Restart=always
15 |
16 | [Install]
17 | WantedBy=multi-user.target
18 |
--------------------------------------------------------------------------------
/conf/reel2bits-web.service:
--------------------------------------------------------------------------------
1 | [Unit]
2 | Description=reel2bits-web
3 | After=network.target
4 | PartOf=reel2bits.target
5 |
6 | [Service]
7 | Type=simple
8 | User=__APP__
9 | WorkingDirectory=__FINALPATH__/api
10 | Environment="FLASK_ENV=production"
11 | Environment="APP_SETTINGS=config.prod_secret.Config"
12 | ExecStart=__FINALPATH__/api/ve3/bin/waitress-serve --host 127.0.0.1 --port __PORT__ --call 'app:create_app'
13 | TimeoutSec=15
14 | Restart=always
15 |
16 | [Install]
17 | WantedBy=multi-user.target
18 |
--------------------------------------------------------------------------------
/pull_request_template.md:
--------------------------------------------------------------------------------
1 | ## Problem
2 | - *Description of why you made this PR*
3 |
4 | ## Solution
5 | - *And how do you fix that problem*
6 |
7 | ## PR Status
8 | - [ ] Code finished.
9 | - [ ] Tested with Package_check.
10 | - [ ] Fix or enhancement tested.
11 | - [ ] Upgrade from last version tested.
12 | - [ ] Can be reviewed and tested.
13 |
14 | ## Package_check results
15 | ---
16 | *If you have access to [App Continuous Integration for packagers](https://yunohost.org/#/packaging_apps_ci) you can provide a link to the package_check results like below, replacing '-NUM-' in this link by the PR number and USERNAME by your username on the ci-apps-dev. Or you provide a screenshot or a pastebin of the results*
17 |
18 | [/badge/icon)](https://ci-apps-dev.yunohost.org/jenkins/job/reel2bits_ynh%20PR-NUM-%20(USERNAME)/)
19 |
--------------------------------------------------------------------------------
/check_process:
--------------------------------------------------------------------------------
1 | ;; Test complet
2 | ; Manifest
3 | domain="domain.tld" (DOMAIN)
4 | admin="john" (USER)
5 | language="fr"
6 | is_public=1 (PUBLIC|public=1|private=0)
7 | password="pass"
8 | ; Checks
9 | pkg_linter=1
10 | setup_sub_dir=0
11 | setup_root=1
12 | setup_nourl=0
13 | setup_private=1
14 | setup_public=1
15 | upgrade=1
16 | # 0.0.1-2020-02-04~ynh1
17 | upgrade=1 from_commit=0fc25106736e824bd984b26f0c2146a6685904e0
18 | backup_restore=1
19 | multi_instance=1
20 | # This test is no longer necessary since the version 2.7 (PR: https://github.com/YunoHost/yunohost/pull/304), you can still do it if your app could be installed with this version.
21 | # incorrect_path=1
22 | port_already_use=0
23 | change_url=0
24 | ;;; Levels
25 | # If the level 5 (Package linter) is forced to 1. Please add justifications here.
26 | Level 5=auto
27 | ;;; Options
28 | Email=yalh@yahoo.com
29 | Notification=all
30 | ;;; Upgrade options
31 | ; commit=0fc25106736e824bd984b26f0c2146a6685904e0
32 | name=0.0.1-2020-02-04~ynh1
33 |
--------------------------------------------------------------------------------
/scripts/_common.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | #=================================================
4 | # COMMON VARIABLES
5 | #=================================================
6 |
7 | # dependencies used by the app
8 | pkg_dependencies="postgresql postgresql-contrib python-virtualenv libffi-dev libssl-dev zlib1g-dev libncurses5-dev libncursesw5-dev libreadline-dev libffi6 sox libtag1v5 libmagic1 tzdata libmad0 libboost-all-dev libsndfile1 libid3tag0 ffmpeg redis-server"
9 |
10 | build_dependencies="libffi-dev cmake make pkg-config git libboost-all-dev libgd-dev libmad0-dev libsndfile-dev libid3tag0-dev libffi-dev"
11 |
12 | swap_needed=2048
13 |
14 | python_version=3.8.3
15 |
16 | #=================================================
17 | # PERSONAL HELPERS
18 | #=================================================
19 |
20 | #=================================================
21 | # EXPERIMENTAL HELPERS
22 | #=================================================
23 |
24 | #=================================================
25 | # FUTURE OFFICIAL HELPERS
26 | #=================================================
27 |
--------------------------------------------------------------------------------
/conf/nginx.conf:
--------------------------------------------------------------------------------
1 | # add_header Content-Security-Policy "default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; font-src 'self' data:; object-src 'none'; media-src 'self' data:";
2 | # add_header Referrer-Policy "strict-origin-when-cross-origin";
3 |
4 | client_max_body_size 1G;
5 |
6 | location /static {
7 | alias __FINALPATH__/front/dist/static;
8 | try_files $uri $uri/ @proxy;
9 | }
10 |
11 | location / {
12 |
13 | try_files $request_uri @proxy;
14 |
15 | # Include SSOWAT user panel.
16 | include conf.d/yunohost_panel.conf.inc;
17 | }
18 |
19 | location @proxy {
20 | proxy_set_header Host $host;
21 | proxy_set_header X-Real-IP $remote_addr;
22 | proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
23 | proxy_set_header X-Forwarded-Proto $scheme;
24 | proxy_set_header X-Forwarded-Host $host:$server_port;
25 | proxy_set_header X-Forwarded-Port $server_port;
26 | proxy_redirect off;
27 |
28 | proxy_http_version 1.1;
29 | proxy_set_header Upgrade $http_upgrade;
30 | proxy_set_header Connection $connection_upgrade;
31 |
32 | proxy_pass http://127.0.0.1:__PORT__;
33 | }
34 |
35 | location /_protected/media/sounds {
36 | alias __DATADIR__/uploads/sounds;
37 | }
38 |
39 | location /_protected/media/artwork_sounds {
40 | alias __DATADIR__/uploads/artwork_sounds;
41 | }
42 |
43 | location /_protected/media/artwork_albums {
44 | alias __DATADIR__/uploads/artwork_albums;
45 | }
46 |
47 | location /_protected/media/avatars {
48 | alias __DATADIR__/uploads/avatars;
49 | }
50 |
--------------------------------------------------------------------------------
/conf/prod_secret.py:
--------------------------------------------------------------------------------
1 | from .development import Config as BaseConfig
2 |
3 |
4 | class Config(BaseConfig):
5 | # See the Configuration documentation at:
6 | # https://docs-develop.reel2bits.org/installation/configuration.html
7 | # For all the config keys you can use
8 |
9 | # Please generate me with: openssl rand -hex 42
10 | SECRET_KEY = "__SECRET_KEY__"
11 | # Please generate me with: openssl rand -hex 5
12 | SECURITY_PASSWORD_SALT = "__SECURITY_PASSWORD_SALT__"
13 | # Set your DB URI
14 | SQLALCHEMY_DATABASE_URI = "postgresql+psycopg2://__DB_USER__:__DB_PWD__@localhost/__DB_NAME__"
15 |
16 | # Don't forget that SOUNDS and ARTWORKS, etc. have to be under DEFAULT path folder
17 | UPLOADS_DEFAULT_DEST = "__DATADIR__/uploads"
18 | UPLOADED_SOUNDS_DEST = "__DATADIR__/uploads/sounds"
19 | UPLOADED_ARTWORKALBUMS_DEST = "__DATADIR__/uploads/artwork_albums"
20 | UPLOADED_ARTWORKSOUNDS_DEST = "__DATADIR__/uploads/artwork_sounds"
21 | UPLOADED_AVATARS_DEST = "__DATADIR__/uploads/avatars"
22 |
23 | # Where is the audiowaveform binary located
24 | AUDIOWAVEFORM_BIN = "__FINAL_PATH__/audiowaveform"
25 |
26 | # If you are using Sentry, otherwise, set to None
27 | SENTRY_DSN = None
28 |
29 | # The domain name your instance will be using
30 | REEL2BITS_HOSTNAME = "__DOMAIN__"
31 | # Is the ActivityPub backend active ?
32 | # Even at False, you needs to setup the AP_DOMAIN because it is used
33 | # by more things than just ActivityPub
34 | AP_DOMAIN = "__DOMAIN__"
35 | AP_ENABLED = True
36 |
37 | # Can the users register on your instance ?
38 | REGISTRATION_ENABLED = True
39 |
40 | # If you are using a modified instance, please set your own repository URL
41 | SOURCES_REPOSITORY_URL = "https://github.com/YunoHost-Apps/reel2bits_ynh"
42 |
43 | # Email settings
44 | MAIL_SERVER = "localhost"
45 | MAIL_PORT = 25
46 | MAIL_USE_TLS = False
47 | MAIL_USE_SSL = False
48 | # MAIL_USERNAME = None
49 | # MAIL_PASSWORD = None
50 |
51 | CELERY_BROKER_URL = 'redis://127.0.0.1:6379/0'
52 | CELERY_RESULT_BACKEND = 'redis://127.0.0.1:6379/0'
53 |
54 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Reel2Bits for YunoHost
2 |
3 | [](https://dash.yunohost.org/appci/app/reel2bits)
4 | [](https://install-app.yunohost.org/?app=reel2bits)
5 |
6 | > *This package allow you to install Reel2Bits quickly and simply on a YunoHost server.
7 | If you don't have YunoHost, please see [here](https://yunohost.org/#/install) to know how to install and enjoy it.*
8 |
9 | ## Overview
10 | Soundcloud-like but simple, easy and KISS (and ActivityPub).
11 |
12 | **Shipped version:** 0.0.1-2020-02-04
13 |
14 | ## Important points to read before installing
15 |
16 | 1. **Reel2Bits** is under development
17 | 1. **Reel2Bits** require a dedicated **root domain**, eg. reel2bits.domain.tld
18 | 1. Even if requested during installation: admin, language and password variables are not used
19 | 1. When your Reel2Bits instance is installed, you need to execute the following command to create a first user and give it admin rights: `(cd /var/www/reel2bits/api && export APP_SETTINGS=config.prod_secret.Config && ve3/bin/flask users create)`
20 |
21 | ## Screenshots
22 |
23 | 
24 |
25 | ## Demo
26 |
27 | * [Official demo](https://demo.reel2bits.org/)
28 |
29 | ## YunoHost specific features
30 |
31 | #### Supported architectures
32 |
33 | * x86-64b - [](https://ci-apps.yunohost.org/ci/apps/reel2bits/)
34 | * ARMv8-A - [](https://ci-apps-arm.yunohost.org/ci/apps/reel2bits/)
35 |
36 | ## Links
37 |
38 | * Report a bug: https://github.com/YunoHost-Apps/reel2bits_ynh/issues
39 | * Upstream app repository: https://github.com/rhaamo/reel2bits
40 | * YunoHost website: https://yunohost.org/
41 |
42 | ---
43 |
44 | Developers info
45 | ----------------
46 |
47 | Please do your pull request to the [testing branch](https://github.com/YunoHost-Apps/reel2bits_ynh/tree/testing).
48 |
49 | To try the testing branch, please proceed like that.
50 | ```
51 | sudo yunohost app install https://github.com/YunoHost-Apps/reel2bits_ynh/tree/testing --debug
52 | or
53 | sudo yunohost app upgrade reel2bits -u https://github.com/YunoHost-Apps/reel2bits_ynh/tree/testing --debug
54 | ```
55 |
--------------------------------------------------------------------------------
/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "Reel2bits",
3 | "id": "reel2bits",
4 | "packaging_format": 1,
5 | "description": {
6 | "en": "Soundcloud-like but simple, easy and KISS (and ActivityPub).",
7 | "fr": "Soundcloud-like mais simple, facile et KISS (et ActivityPub)."
8 | },
9 | "version": "0.0.1-2020-02-04~ynh2",
10 | "url": "https://sound.otter.sh/user/dashie",
11 | "license": "AGPL-3.0-or-later",
12 | "maintainer": {
13 | "name": ""
14 | },
15 | "previous_maintainer": {
16 | "name": "yalh76"
17 | },
18 | "requirements": {
19 | "yunohost": ">= 3.5"
20 | },
21 | "multi_instance": true,
22 | "services": [
23 | "nginx",
24 | "php7.0-fpm",
25 | "mysql"
26 | ],
27 | "arguments": {
28 | "install" : [
29 | {
30 | "name": "domain",
31 | "type": "domain",
32 | "ask": {
33 | "en": "Choose a domain name for Reel2Bits",
34 | "fr": "Choisissez un nom de domaine pour Reel2Bits"
35 | },
36 | "example": "example.com"
37 | },
38 | {
39 | "name": "admin",
40 | "type": "user",
41 | "ask": {
42 | "en": "Choose an admin user",
43 | "fr": "Choisissez l’administrateur"
44 | },
45 | "example": "johndoe"
46 | },
47 | {
48 | "name": "is_public",
49 | "type": "boolean",
50 | "ask": {
51 | "en": "Is it a public application?",
52 | "fr": "Est-ce une application publique ?"
53 | },
54 | "default": true
55 | },
56 | {
57 | "name": "language",
58 | "type": "string",
59 | "ask": {
60 | "en": "Choose the application language",
61 | "fr": "Choisissez la langue de l'application"
62 | },
63 | "choices": ["fr", "en"],
64 | "default": "en"
65 | },
66 | {
67 | "name": "password",
68 | "type": "password",
69 | "ask": {
70 | "en": "Set the administrator password",
71 | "fr": "Définissez le mot de passe administrateur"
72 | },
73 | "example": "Choose a password"
74 | }
75 | ]
76 | }
77 | }
78 |
--------------------------------------------------------------------------------
/scripts/ynh_add_swap:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # Add swap
4 | #
5 | # usage: ynh_add_swap --size=SWAP in Mb
6 | # | arg: -s, --size= - Amount of SWAP to add in Mb.
7 | ynh_add_swap () {
8 | # Declare an array to define the options of this helper.
9 | declare -Ar args_array=( [s]=size= )
10 | local size
11 | # Manage arguments with getopts
12 | ynh_handle_getopts_args "$@"
13 |
14 | local swap_max_size=$(( $size * 1024 ))
15 |
16 | local free_space=$(df --output=avail / | sed 1d)
17 | # Because we don't want to fill the disk with a swap file, divide by 2 the available space.
18 | local usable_space=$(( $free_space / 2 ))
19 |
20 | SD_CARD_CAN_SWAP=${SD_CARD_CAN_SWAP:-0}
21 |
22 | # Swap on SD card only if it's is specified
23 | if ynh_is_main_device_a_sd_card && [ "$SD_CARD_CAN_SWAP" == "0" ]
24 | then
25 | ynh_print_warn --message="The main mountpoint of your system '/' is on an SD card, swap will not be added to prevent some damage of this one, but that can cause troubles for the app $app. If you still want activate the swap, you can relaunch the command preceded by 'SD_CARD_CAN_SWAP=1'"
26 | return
27 | fi
28 |
29 | # Compare the available space with the size of the swap.
30 | # And set a acceptable size from the request
31 | if [ $usable_space -ge $swap_max_size ]
32 | then
33 | local swap_size=$swap_max_size
34 | elif [ $usable_space -ge $(( $swap_max_size / 2 )) ]
35 | then
36 | local swap_size=$(( $swap_max_size / 2 ))
37 | elif [ $usable_space -ge $(( $swap_max_size / 3 )) ]
38 | then
39 | local swap_size=$(( $swap_max_size / 3 ))
40 | elif [ $usable_space -ge $(( $swap_max_size / 4 )) ]
41 | then
42 | local swap_size=$(( $swap_max_size / 4 ))
43 | else
44 | echo "Not enough space left for a swap file" >&2
45 | local swap_size=0
46 | fi
47 |
48 | # If there's enough space for a swap, and no existing swap here
49 | if [ $swap_size -ne 0 ] && [ ! -e /swap_$app ]
50 | then
51 | # Preallocate space for the swap file, fallocate may sometime not be used, use dd instead in this case
52 | if ! fallocate -l ${swap_size}K /swap_$app
53 | then
54 | dd if=/dev/zero of=/swap_$app bs=1024 count=${swap_size}
55 | fi
56 | chmod 0600 /swap_$app
57 | # Create the swap
58 | mkswap /swap_$app
59 | # And activate it
60 | swapon /swap_$app
61 | # Then add an entry in fstab to load this swap at each boot.
62 | echo -e "/swap_$app swap swap defaults 0 0 #Swap added by $app" >> /etc/fstab
63 | fi
64 | }
65 |
66 | ynh_del_swap () {
67 | # If there a swap at this place
68 | if [ -e /swap_$app ]
69 | then
70 | # Clean the fstab
71 | sed -i "/#Swap added by $app/d" /etc/fstab
72 | # Desactive the swap file
73 | swapoff /swap_$app
74 | # And remove it
75 | rm /swap_$app
76 | fi
77 | }
78 |
79 | # Check if the device of the main mountpoint "/" is an SD card
80 | #
81 | # [internal]
82 | #
83 | # return 0 if it's an SD card, else 1
84 | ynh_is_main_device_a_sd_card () {
85 | local main_device=$(lsblk --output PKNAME --noheadings $(findmnt / --nofsroot --uniq --output source --noheadings --first-only))
86 |
87 | if echo $main_device | grep --quiet "mmc" && [ $(tail -n1 /sys/block/$main_device/queue/rotational) == "0" ]
88 | then
89 | return 0
90 | else
91 | return 1
92 | fi
93 | }
94 |
--------------------------------------------------------------------------------
/scripts/backup:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | #=================================================
4 | # GENERIC START
5 | #=================================================
6 | # IMPORT GENERIC HELPERS
7 | #=================================================
8 |
9 | #Keep this path for calling _common.sh inside the execution's context of backup and restore scripts
10 | source ../settings/scripts/_common.sh
11 | source /usr/share/yunohost/helpers
12 |
13 | #=================================================
14 | # MANAGE SCRIPT FAILURE
15 | #=================================================
16 | ynh_print_info --message="Managing script failure..."
17 |
18 | ynh_clean_setup () {
19 | ynh_clean_check_starting
20 | }
21 | # Exit if an error occurs during the execution of the script
22 | ynh_abort_if_errors
23 |
24 | #=================================================
25 | # LOAD SETTINGS
26 | #=================================================
27 | ynh_print_info --message="Loading installation settings..."
28 |
29 | app=$YNH_APP_INSTANCE_NAME
30 |
31 | final_path=$(ynh_app_setting_get --app=$app --key=final_path)
32 | domain=$(ynh_app_setting_get --app=$app --key=domain)
33 | db_name=$(ynh_app_setting_get --app=$app --key=db_name)
34 |
35 | #=================================================
36 | # STANDARD BACKUP STEPS
37 | #=================================================
38 | # STOP SYSTEMD SERVICE
39 | #=================================================
40 | ynh_print_info --message="Stopping a systemd service..."
41 |
42 | ynh_systemd_action --service_name=${app}-web --action="stop" --log_path=systemd --line_match="Stopped ${app}-web"
43 | ynh_systemd_action --service_name=${app}-worker --action="stop" --log_path=systemd --line_match="Stopped ${app}-worker"
44 |
45 | #=================================================
46 | # BACKUP THE APP MAIN DIR
47 | #=================================================
48 | ynh_print_info --message="Backing up the main app directory..."
49 |
50 | ynh_backup --src_path="$final_path"
51 |
52 | #=================================================
53 | # BACKUP THE NGINX CONFIGURATION
54 | #=================================================
55 | ynh_print_info --message="Backing up nginx web server configuration..."
56 |
57 | ynh_backup --src_path="/etc/nginx/conf.d/$domain.d/$app.conf"
58 |
59 | #=================================================
60 | # BACKUP THE POSTGRESQL DATABASE
61 | #=================================================
62 | ynh_print_info --message="Backing up the PostgreSQL database..."
63 |
64 | ynh_psql_dump_db --database="$db_name" > db.sql
65 |
66 | #=================================================
67 | # SPECIFIC BACKUP
68 | #=================================================
69 | # BACKUP SYSTEMD
70 | #=================================================
71 | ynh_print_info --message="Backing up systemd configuration..."
72 |
73 | ynh_backup --src_path="/etc/systemd/system/$app.target"
74 | ynh_backup --src_path="/etc/systemd/system/$app-web.service"
75 | ynh_backup --src_path="/etc/systemd/system/$app-worker.service"
76 |
77 | #=================================================
78 | # START SYSTEMD SERVICE
79 | #=================================================
80 | ynh_print_info --message="Starting a systemd service..."
81 |
82 | ynh_systemd_action --service_name=${app}-web --action="start" --log_path=systemd --line_match="Started ${app}-web"
83 | ynh_systemd_action --service_name=${app}-worker --action="start" --log_path=systemd --line_match="Started ${app}-worker"
84 | systemctl start $app.target
85 |
86 | #=================================================
87 | # END OF SCRIPT
88 | #=================================================
89 |
90 | ynh_print_info --message="Backup script completed for $app. (YunoHost will then actually copy those files to the archive)."
91 |
--------------------------------------------------------------------------------
/scripts/remove:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | #=================================================
4 | # GENERIC START
5 | #=================================================
6 | # IMPORT GENERIC HELPERS
7 | #=================================================
8 |
9 | source _common.sh
10 | source ynh_add_swap
11 | source /usr/share/yunohost/helpers
12 |
13 | #=================================================
14 | # LOAD SETTINGS
15 | #=================================================
16 | ynh_print_info --message="Loading installation settings..."
17 |
18 | app=$YNH_APP_INSTANCE_NAME
19 |
20 | domain=$(ynh_app_setting_get --app=$app --key=domain)
21 | port=$(ynh_app_setting_get --app=$app --key=port)
22 | db_name=$(ynh_app_setting_get --app=$app --key=db_name)
23 | db_user=$db_name
24 | final_path=$(ynh_app_setting_get --app=$app --key=final_path)
25 |
26 | #=================================================
27 | # STANDARD REMOVE
28 | #=================================================
29 | # REMOVE SERVICE INTEGRATION IN YUNOHOST
30 | #=================================================
31 | ynh_print_info --message="Removing service integration in YunoHost..."
32 |
33 | # Remove a service from the admin panel, added by `yunohost service add`
34 | if yunohost service status "$app-web" >/dev/null 2>&1
35 | then
36 | ynh_print_info --message="Removing $app-web service..."
37 | yunohost service remove "$app-web"
38 | fi
39 |
40 | if yunohost service status "$app-worker" >/dev/null 2>&1
41 | then
42 | ynh_print_info --message="Removing $app-worker service..."
43 | yunohost service remove "$app-worker"
44 | fi
45 |
46 | if yunohost service status "$app" >/dev/null 2>&1
47 | then
48 | ynh_print_info --message="Removing $app service..."
49 | yunohost service remove "$app"
50 | fi
51 |
52 | #=================================================
53 | # STOP AND REMOVE SERVICE
54 | #=================================================
55 | ynh_print_info --message="Stopping and removing the systemd service..."
56 |
57 | # Remove the dedicated systemd config
58 | ynh_remove_systemd_config --service="$app-web"
59 | ynh_remove_systemd_config --service="$app-worker"
60 | ynh_remove_systemd_config --service="$app"
61 |
62 | #=================================================
63 | # REMOVE THE POSTGRESQL DATABASE
64 | #=================================================
65 | ynh_print_info --message="Removing the PostgreSQL database..."
66 |
67 | # Remove a database if it exists, along with the associated user
68 | ynh_psql_remove_db --db_user="$db_user" --db_name="$db_name"
69 |
70 | #=================================================
71 | # REMOVE DEPENDENCIES
72 | #=================================================
73 | ynh_print_info --message="Removing dependencies..."
74 |
75 | # Remove metapackage and its dependencies
76 | ynh_remove_app_dependencies
77 |
78 | #=================================================
79 | # REMOVE SWAP
80 | #=================================================
81 | ynh_print_info --message="Removing $swap_needed Mo to swap..."
82 |
83 | ynh_del_swap
84 |
85 | #=================================================
86 | # REMOVE APP MAIN DIR
87 | #=================================================
88 | ynh_print_info --message="Removing app main directory..."
89 |
90 | # Remove the app directory securely
91 | ynh_secure_remove --file="$final_path"
92 |
93 | #=================================================
94 | # REMOVE NGINX CONFIGURATION
95 | #=================================================
96 | ynh_print_info --message="Removing nginx web server configuration..."
97 |
98 | # Remove the dedicated nginx config
99 | ynh_remove_nginx_config
100 |
101 | #=================================================
102 | # CLOSE A PORT
103 | #=================================================
104 | ynh_print_info --message="Closing a port"
105 |
106 | if yunohost firewall list | grep -q "\- $port$"
107 | then
108 | ynh_print_info --message="Closing port $port..."
109 | ynh_exec_warn_less yunohost firewall disallow TCP $port
110 | fi
111 |
112 | #=================================================
113 | # GENERIC FINALIZATION
114 | #=================================================
115 | # REMOVE DEDICATED USER
116 | #=================================================
117 | ynh_print_info --message="Removing the dedicated system user..."
118 |
119 | # Delete a system user
120 | ynh_system_user_delete --username=$app
121 |
122 | #=================================================
123 | # END OF SCRIPT
124 | #=================================================
125 |
126 | ynh_print_info --message="Removal of $app completed"
127 |
--------------------------------------------------------------------------------
/scripts/change_url:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | #=================================================
4 | # GENERIC STARTING
5 | #=================================================
6 | # IMPORT GENERIC HELPERS
7 | #=================================================
8 |
9 | source _common.sh
10 | source /usr/share/yunohost/helpers
11 |
12 | #=================================================
13 | # RETRIEVE ARGUMENTS
14 | #=================================================
15 |
16 | old_domain=$YNH_APP_OLD_DOMAIN
17 | old_path=$YNH_APP_OLD_PATH
18 |
19 | new_domain=$YNH_APP_NEW_DOMAIN
20 | new_path="/"
21 |
22 | app=$YNH_APP_INSTANCE_NAME
23 |
24 | #=================================================
25 | # LOAD SETTINGS
26 | #=================================================
27 | ynh_print_info --message="Loading installation settings..."
28 |
29 | # Needed for helper "ynh_add_nginx_config"
30 | final_path=$(ynh_app_setting_get --app=$app --key=final_path)
31 |
32 | # Add settings here as needed by your application
33 | #db_name=$(ynh_app_setting_get --app=$app --key=db_name)
34 | #db_user=$db_name
35 | #db_pwd=$(ynh_app_setting_get --app=$app --key=db_pwd)
36 |
37 | #=================================================
38 | # BACKUP BEFORE UPGRADE THEN ACTIVE TRAP
39 | #=================================================
40 | ynh_print_info --message="Backing up the app before changing its url (may take a while)..."
41 |
42 | # Backup the current version of the app
43 | ynh_backup_before_upgrade
44 | ynh_clean_setup () {
45 | # Remove the new domain config file, the remove script won't do it as it doesn't know yet its location.
46 | ynh_secure_remove --file="/etc/nginx/conf.d/$new_domain.d/$app.conf"
47 |
48 | # restore it if the upgrade fails
49 | ynh_restore_upgradebackup
50 | }
51 | # Exit if an error occurs during the execution of the script
52 | ynh_abort_if_errors
53 |
54 | #=================================================
55 | # CHECK WHICH PARTS SHOULD BE CHANGED
56 | #=================================================
57 |
58 | change_domain=0
59 | if [ "$old_domain" != "$new_domain" ]
60 | then
61 | change_domain=1
62 | fi
63 |
64 | change_path=0
65 | if [ "$old_path" != "$new_path" ]
66 | then
67 | change_path=1
68 | fi
69 |
70 | #=================================================
71 | # STANDARD MODIFICATIONS
72 | #=================================================
73 | # STOP SYSTEMD SERVICE
74 | #=================================================
75 | ynh_print_info --message="Stopping a systemd service..."
76 |
77 | ynh_systemd_action --service_name=${app}-web --action="stop" --log_path=systemd --line_match="Stopped ${app}-web"
78 | ynh_systemd_action --service_name=${app}-worker --action="stop" --log_path=systemd --line_match="Stopped ${app}-worker"
79 |
80 | #=================================================
81 | # MODIFY URL IN NGINX CONF
82 | #=================================================
83 | ynh_print_info --message="Updating nginx web server configuration..."
84 |
85 | nginx_conf_path=/etc/nginx/conf.d/$old_domain.d/$app.conf
86 |
87 | # Change the path in the nginx config file
88 | if [ $change_path -eq 1 ]
89 | then
90 | # Make a backup of the original nginx config file if modified
91 | ynh_backup_if_checksum_is_different --file="$nginx_conf_path"
92 | # Set global variables for nginx helper
93 | domain="$old_domain"
94 | path_url="$new_path"
95 | # Create a dedicated nginx config
96 | ynh_add_nginx_config
97 | fi
98 |
99 | # Change the domain for nginx
100 | if [ $change_domain -eq 1 ]
101 | then
102 | # Delete file checksum for the old conf file location
103 | ynh_delete_file_checksum --file="$nginx_conf_path"
104 | mv $nginx_conf_path /etc/nginx/conf.d/$new_domain.d/$app.conf
105 | # Store file checksum for the new config file location
106 | ynh_store_file_checksum --file="/etc/nginx/conf.d/$new_domain.d/$app.conf"
107 | fi
108 |
109 | #=================================================
110 | # SPECIFIC MODIFICATIONS
111 | #=================================================
112 | # MODIFY A CONFIG FILE
113 | #=================================================
114 |
115 | api_config="$final_path/config.py"
116 |
117 | ynh_replace_string --match_string="$old_domain" "--replace_string=$new_domain" --target_file="$api_config"
118 |
119 | ynh_backup_if_checksum_is_different --file="$api_config"
120 | # Recalculate and store the checksum of the file for the next upgrade.
121 | ynh_store_file_checksum --file="$api_config"
122 |
123 | #=================================================
124 | # GENERIC FINALISATION
125 | #=================================================
126 | # START SYSTEMD SERVICE
127 | #=================================================
128 | ynh_print_info --message="Starting a systemd service..."
129 |
130 | ynh_systemd_action --service_name=${app}-web --action="start" --log_path=systemd --line_match="Started ${app}-web"
131 | ynh_systemd_action --service_name=${app}-worker --action="start" --log_path=systemd --line_match="Started ${app}-worker"
132 | systemctl start $app.target
133 |
134 | #=================================================
135 | # RELOAD NGINX
136 | #=================================================
137 | ynh_print_info --message="Reloading nginx web server..."
138 |
139 | ynh_systemd_action --service_name=nginx --action=reload
140 |
141 | #=================================================
142 | # END OF SCRIPT
143 | #=================================================
144 |
145 | ynh_print_info --message="Change of URL completed for $app"
146 |
--------------------------------------------------------------------------------
/scripts/restore:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | #=================================================
4 | # GENERIC START
5 | #=================================================
6 | # IMPORT GENERIC HELPERS
7 | #=================================================
8 |
9 | #Keep this path for calling _common.sh inside the execution's context of backup and restore scripts
10 | source ../settings/scripts/_common.sh
11 | source ../settings/scripts/ynh_add_swap
12 | source /usr/share/yunohost/helpers
13 |
14 | #=================================================
15 | # MANAGE SCRIPT FAILURE
16 | #=================================================
17 | ynh_print_info --message="Managing script failure..."
18 |
19 | ynh_clean_setup () {
20 | ynh_clean_check_starting
21 | }
22 | # Exit if an error occurs during the execution of the script
23 | ynh_abort_if_errors
24 |
25 | #=================================================
26 | # LOAD SETTINGS
27 | #=================================================
28 | ynh_print_info --message="Loading settings..."
29 |
30 | app=$YNH_APP_INSTANCE_NAME
31 |
32 | domain=$(ynh_app_setting_get --app=$app --key=domain)
33 | path_url=$(ynh_app_setting_get --app=$app --key=path)
34 | final_path=$(ynh_app_setting_get --app=$app --key=final_path)
35 | db_name=$(ynh_app_setting_get --app=$app --key=db_name)
36 | db_user=$db_name
37 | db_pwd=$(ynh_app_setting_get --app=$app --key=db_pwd)
38 | datadir=$(ynh_app_setting_get --app=$app --key=datadir)
39 |
40 | #=================================================
41 | # CHECK IF THE APP CAN BE RESTORED
42 | #=================================================
43 | ynh_print_info --message="Validating restoration parameters..."
44 |
45 | ynh_webpath_available --domain=$domain --path_url=$path_url \
46 | || ynh_die --message="Path not available: ${domain}${path_url}"
47 | test ! -d $final_path \
48 | || ynh_die --message="There is already a directory: $final_path "
49 |
50 | #=================================================
51 | # STANDARD RESTORATION STEPS
52 | #=================================================
53 | # RESTORE THE NGINX CONFIGURATION
54 | #=================================================
55 |
56 | ynh_restore_file --origin_path="/etc/nginx/conf.d/$domain.d/$app.conf"
57 |
58 | #=================================================
59 | # RESTORE THE APP MAIN DIR
60 | #=================================================
61 | ynh_print_info --message="Restoring the app main directory..."
62 |
63 | ynh_restore_file --origin_path="$final_path"
64 |
65 | #=================================================
66 | # RECREATE THE DEDICATED USER
67 | #=================================================
68 | ynh_print_info --message="Recreating the dedicated system user..."
69 |
70 | # Create the dedicated user (if not existing)
71 | ynh_system_user_create --username=$app --home_dir="$final_path"
72 |
73 | #=================================================
74 | # RESTORE USER RIGHTS
75 | #=================================================
76 | ynh_print_info --message="Restoring user rights..."
77 |
78 | # Restore permissions on app files
79 | chown -R "$app": "$final_path"
80 |
81 | #=================================================
82 | # RECREATE THE DATA DIRECTORY
83 | #=================================================
84 | ynh_print_info --message="Recreate the data directory..."
85 |
86 | # Create app folders
87 | mkdir -p "$datadir"
88 | mkdir -p "$datadir/uploads/sounds"
89 | mkdir -p "$datadir/uploads/waveforms"
90 | mkdir -p "$datadir/uploads/artwork_albums"
91 | mkdir -p "$datadir/uploads/artwork_sounds"
92 | mkdir -p "$datadir/uploads/avatars"
93 |
94 | # Give permission to the datadir
95 | chown -R "$app": "$datadir"
96 |
97 | #=================================================
98 | # SPECIFIC RESTORATION
99 | #=================================================
100 | # ADD SWAP
101 | #=================================================
102 | ynh_print_info --message="Adding $swap_needed Mo to swap..."
103 |
104 | ynh_add_swap --size=$swap_needed
105 |
106 | #=================================================
107 | # REINSTALL DEPENDENCIES
108 | #=================================================
109 | ynh_print_info --message="Reinstalling dependencies..."
110 |
111 | # Define and install dependencies
112 | ynh_install_app_dependencies $pkg_dependencies
113 |
114 | #=================================================
115 | # RESTORE THE POSTGRESQL DATABASE
116 | #=================================================
117 | ynh_print_info --message="Restoring the PostgreSQL database..."
118 |
119 | ynh_psql_test_if_first_run
120 | ynh_psql_setup_db --db_user=$db_user --db_name=$db_name --db_pwd=$db_pwd
121 | ynh_psql_execute_as_root --sql="CREATE EXTENSION IF NOT EXISTS \"uuid-ossp\";" --database=$db_name
122 | ynh_psql_execute_file_as_root --file="./db.sql" --database="$db_name"
123 |
124 | #=================================================
125 | # RESTORE SYSTEMD
126 | #=================================================
127 | ynh_print_info --message="Restoring the systemd configuration..."
128 |
129 | ynh_restore_file --origin_path="/etc/systemd/system/$app-web.service"
130 | ynh_restore_file --origin_path="/etc/systemd/system/$app-worker.service"
131 | ynh_restore_file --origin_path="/etc/systemd/system/$app.target"
132 | systemctl enable $app-web.service
133 | systemctl enable $app-worker.service
134 | systemctl enable $app.target
135 |
136 | #=================================================
137 | # INTEGRATE SERVICE IN YUNOHOST
138 | #=================================================
139 | ynh_print_info --message="Integrating service in YunoHost..."
140 |
141 | yunohost service add "$app-web" --description "$app-web daemon for Reel2Bits"
142 | yunohost service add "$app-worker" --description "$app-worker daemon for Reel2Bits"
143 | yunohost service add "$app" --description "$app daemon for Reel2Bits"
144 |
145 | #=================================================
146 | # START SYSTEMD SERVICE
147 | #=================================================
148 | ynh_print_info --message="Starting a systemd service..."
149 |
150 | ynh_systemd_action --service_name=${app}-web --action="start" --log_path=systemd --line_match="Started ${app}-web"
151 | ynh_systemd_action --service_name=${app}-worker --action="start" --log_path=systemd --line_match="Started ${app}-worker"
152 | systemctl start $app.target
153 |
154 | #=================================================
155 | # GENERIC FINALIZATION
156 | #=================================================
157 | # RELOAD NGINX
158 | #=================================================
159 | ynh_print_info --message="Reloading nginx web server..."
160 |
161 | ynh_systemd_action --service_name=nginx --action=reload
162 |
163 | #=================================================
164 | # END OF SCRIPT
165 | #=================================================
166 |
167 | ynh_print_info --message="Restoration completed for $app"
168 |
--------------------------------------------------------------------------------
/scripts/upgrade:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | #=================================================
4 | # GENERIC START
5 | #=================================================
6 | # IMPORT GENERIC HELPERS
7 | #=================================================
8 |
9 | source _common.sh
10 | source ynh_add_swap
11 | source /usr/share/yunohost/helpers
12 |
13 | #=================================================
14 | # LOAD SETTINGS
15 | #=================================================
16 | ynh_print_info --message="Loading installation settings..."
17 |
18 | app=$YNH_APP_INSTANCE_NAME
19 |
20 | domain=$(ynh_app_setting_get --app=$app --key=domain)
21 | path_url=$(ynh_app_setting_get --app=$app --key=path)
22 | admin=$(ynh_app_setting_get --app=$app --key=admin)
23 | is_public=$(ynh_app_setting_get --app=$app --key=is_public)
24 | final_path=$(ynh_app_setting_get --app=$app --key=final_path)
25 | language=$(ynh_app_setting_get --app=$app --key=language)
26 | db_name=$(ynh_app_setting_get --app=$app --key=db_name)
27 | db_user=$db_name
28 | db_pwd=$(ynh_app_setting_get --app=$app --key=db_pwd)
29 | datadir=$(ynh_app_setting_get --app=$app --key=datadir)
30 | security_password_salt=$(ynh_app_setting_get --app=$app --key=security_password_salt)
31 | secret_key=$(ynh_app_setting_get --app=$app --key=secret_key)
32 | port=$(ynh_app_setting_get --app=$app --key=port)
33 |
34 | #=================================================
35 | # CHECK VERSION
36 | #=================================================
37 |
38 | upgrade_type=$(ynh_check_app_version_changed)
39 |
40 | #=================================================
41 | # ENSURE DOWNWARD COMPATIBILITY
42 | #=================================================
43 | ynh_print_info --message="Ensuring downward compatibility..."
44 |
45 | # Fix is_public as a boolean value
46 | if [ "$is_public" = "Yes" ]; then
47 | ynh_app_setting_set --app=$app --key=is_public --value=1
48 | is_public=1
49 | elif [ "$is_public" = "No" ]; then
50 | ynh_app_setting_set --app=$app --key=is_public --value=0
51 | is_public=0
52 | fi
53 |
54 | # If db_name doesn't exist, create it
55 | if [ -z "$db_name" ]; then
56 | db_name=$(ynh_sanitize_dbid --db_name=$app)
57 | ynh_app_setting_set --app=$app --key=db_name --value=$db_name
58 | fi
59 |
60 | # If final_path doesn't exist, create it
61 | if [ -z "$final_path" ]; then
62 | final_path=/var/www/$app
63 | ynh_app_setting_set --app=$app --key=final_path --value=$final_path
64 | fi
65 |
66 | #=================================================
67 | # BACKUP BEFORE UPGRADE THEN ACTIVE TRAP
68 | #=================================================
69 | ynh_print_info --message="Backing up the app before upgrading (may take a while)..."
70 |
71 | # Backup the current version of the app
72 | ynh_backup_before_upgrade
73 | ynh_clean_setup () {
74 | ynh_clean_check_starting
75 | # restore it if the upgrade fails
76 | ynh_restore_upgradebackup
77 | }
78 | # Exit if an error occurs during the execution of the script
79 | ynh_abort_if_errors
80 |
81 | #=================================================
82 | # STANDARD UPGRADE STEPS
83 | #=================================================
84 | # STOP SYSTEMD SERVICE
85 | #=================================================
86 | ynh_print_info --message="Stopping a systemd service..."
87 |
88 | ynh_systemd_action --service_name=${app}-web --action="stop" --log_path=systemd --line_match="Stopped ${app}-web"
89 | ynh_systemd_action --service_name=${app}-worker --action="stop" --log_path=systemd --line_match="Stopped ${app}-worker"
90 |
91 | #=================================================
92 | # DOWNLOAD, CHECK AND UNPACK SOURCE
93 | #=================================================
94 |
95 | if [ "$upgrade_type" == "UPGRADE_APP" ]
96 | then
97 | ynh_print_info --message="Upgrading source files..."
98 |
99 | # Download, check integrity, uncompress and patch the source from app.src
100 | ynh_setup_source --dest_dir="$final_path"
101 | ynh_replace_string --match_string="flasgger==0.9.3" --replace_string="flasgger==0.9.4" --target_file="$final_path/api/requirements.txt"
102 | ynh_replace_string --match_string="Flask_Babelex==0.9.3" --replace_string="Flask_Babelex>=0.9.4" --target_file="$final_path/api/requirements.txt"
103 | ynh_replace_string --match_string="flask_uploads==0.2.1" --replace_string="flask_uploads>=0.2.1" --target_file="$final_path/api/requirements.txt"
104 |
105 | ynh_setup_source --dest_dir="$final_path/front/dist" --source_id=front
106 | fi
107 |
108 | #=================================================
109 | # NGINX CONFIGURATION
110 | #=================================================
111 | ynh_print_info --message="Upgrading nginx web server configuration..."
112 |
113 | # Create a dedicated nginx config
114 | ynh_add_nginx_config "datadir"
115 |
116 | #=================================================
117 | # UPGRADE DEPENDENCIES
118 | #=================================================
119 | ynh_print_info --message="Upgrading dependencies..."
120 |
121 | ynh_install_app_dependencies $pkg_dependencies
122 |
123 | #=================================================
124 | # CREATE DEDICATED USER
125 | #=================================================
126 | ynh_print_info --message="Making sure dedicated system user exists..."
127 |
128 | # Create a dedicated user (if not existing)
129 | ynh_system_user_create --username=$app --home_dir="$final_path"
130 |
131 | #=================================================
132 | # SPECIFIC UPGRADE
133 | #=================================================
134 | # ADD SWAP
135 | #=================================================
136 | ynh_print_info --message="Adding $swap_needed Mo to swap..."
137 |
138 | ynh_add_swap --size=$swap_needed
139 |
140 | #=================================================
141 | # CREATE THE DATA DIRECTORY
142 | #=================================================
143 | ynh_print_info --message="Create the data directory..."
144 |
145 | # Create app folders
146 | mkdir -p "$datadir"
147 | mkdir -p "$datadir/uploads/sounds"
148 | mkdir -p "$datadir/uploads/waveforms"
149 | mkdir -p "$datadir/uploads/artwork_albums"
150 | mkdir -p "$datadir/uploads/artwork_sounds"
151 | mkdir -p "$datadir/uploads/avatars"
152 |
153 | # Give permission to the datadir
154 | chown -R "$app": "$datadir"
155 |
156 | #=================================================
157 | # MODIFY A CONFIG FILE
158 | #=================================================
159 | ynh_print_info --message="Modifying a config file..."
160 |
161 | api_config="$final_path/api/config/prod_secret.py"
162 | ynh_backup_if_checksum_is_different --file="$api_config"
163 | cp ../conf/prod_secret.py "$api_config"
164 |
165 | ynh_replace_string --match_string="__LANGUAGE__" --replace_string="$language" --target_file="$api_config"
166 | ynh_replace_string --match_string="__DATADIR__" --replace_string="$datadir" --target_file="$api_config"
167 | ynh_replace_string --match_string="__DOMAIN__" --replace_string="$domain" --target_file="$api_config"
168 | ynh_replace_string --match_string="__SECURITY_PASSWORD_SALT__" --replace_string="$security_password_salt" --target_file="$api_config"
169 | ynh_replace_string --match_string="__SECRET_KEY__" --replace_string="$secret_key" --target_file="$api_config"
170 | ynh_replace_string --match_string="__DB_USER__" --replace_string="$db_user" --target_file="$api_config"
171 | ynh_replace_string --match_string="__DB_PWD__" --replace_string="$db_pwd" --target_file="$api_config"
172 | ynh_replace_string --match_string="__DB_NAME__" --replace_string="$db_name" --target_file="$api_config"
173 | ynh_replace_string --match_string="__FINAL_PATH__" --replace_string="$final_path" --target_file="$api_config"
174 |
175 | front_config="$final_path/front/config/local.json"
176 | ynh_backup_if_checksum_is_different --file="$front_config"
177 | cp ../conf/local.example.json "$front_config"
178 | ynh_replace_string --match_string="__DOMAIN__" --replace_string="$domain" --target_file="$front_config"
179 |
180 | #=================================================
181 | # STORE THE CONFIG FILE CHECKSUM
182 | #=================================================
183 | ynh_print_info --message="Storing the config file checksum..."
184 |
185 | # Recalculate and store the checksum of the file for the next upgrade.
186 | ynh_store_file_checksum --file="$api_config"
187 |
188 | #=================================================
189 | # INSTALL PYTHONZ TO GET PYTHON
190 | #=================================================
191 | ynh_print_info --message="Installing Python..."
192 |
193 | # Get pythonz
194 | # curl -kL https://raw.githubusercontent.com/saghul/pythonz/master/pythonz-install
195 | # ./pythonz-install
196 | ynh_setup_source --dest_dir="$final_path/.pythonz" --source_id=pythonz
197 | export PYTHONZ_ROOT="$final_path/.pythonz"
198 | # Then install it
199 | python $final_path/.pythonz/pythonz_install.py
200 |
201 | # Install Python
202 | $final_path/.pythonz/bin/pythonz install $python_version
203 |
204 | #=================================================
205 | # INSTALL REEL2BITS
206 | #=================================================
207 | ynh_print_info --message="Installing Reel2Bits..."
208 |
209 | pushd $final_path/api
210 | virtualenv -p $($final_path/.pythonz/bin/pythonz locate $python_version) ve3
211 | ve3/bin/pip3 install wheel
212 | ve3/bin/pip3 install werkzeug==0.16.1
213 | ve3/bin/pip3 install --requirement requirements.txt
214 | #ve3/bin/python3 setup.py install
215 | export APP_SETTINGS='config.prod_secret.Config'
216 | ve3/bin/flask db upgrade
217 | ve3/bin/pip3 install waitress
218 | #ve3/bin/flask users create --password TEXT -a IDENTITY
219 | #ve3/bin/flask roles add yalh@yh.yalh.net admin
220 | popd
221 |
222 | #=================================================
223 | # SETUP SYSTEMD
224 | #=================================================
225 | ynh_print_info --message="Upgrading systemd configuration..."
226 |
227 | ynh_replace_string --match_string="__PORT__" --replace_string="$port" --target_file="../conf/reel2bits-web.service"
228 |
229 | # Create a dedicated systemd config
230 | cp ../conf/reel2bits.target /etc/systemd/system/reel2bits.target
231 | ynh_add_systemd_config --service="$app-web" --template="reel2bits-web.service"
232 | ynh_add_systemd_config --service="$app-worker" --template="reel2bits-worker.service"
233 |
234 | #=================================================
235 | # GENERIC FINALIZATION
236 | #=================================================
237 | # SECURE FILES AND DIRECTORIES
238 | #=================================================
239 | ynh_print_info --message="Securing files and directories..."
240 |
241 | # Set permissions on app files
242 | chown -R "$app": "$final_path"
243 |
244 | #=================================================
245 | # SETUP SSOWAT
246 | #=================================================
247 | ynh_print_info --message="Upgrading SSOwat configuration..."
248 |
249 | # Make app public if necessary
250 | if [ $is_public -eq 1 ]
251 | then
252 | # unprotected_uris allows SSO credentials to be passed anyway
253 | ynh_app_setting_set --app=$app --key=unprotected_uris --value="/"
254 | fi
255 |
256 | #=================================================
257 | # START SYSTEMD SERVICE
258 | #=================================================
259 | ynh_print_info --message="Starting a systemd service..."
260 |
261 | ynh_systemd_action --service_name=${app}-web --action="start" --log_path=systemd --line_match="Started ${app}-web"
262 | ynh_systemd_action --service_name=${app}-worker --action="start" --log_path=systemd --line_match="Started ${app}-worker"
263 | systemctl start $app.target
264 |
265 | #=================================================
266 | # RELOAD NGINX
267 | #=================================================
268 | ynh_print_info --message="Reloading nginx web server..."
269 |
270 | ynh_systemd_action --service_name=nginx --action=reload
271 |
272 | #=================================================
273 | # END OF SCRIPT
274 | #=================================================
275 |
276 | ynh_print_info --message="Upgrade of $app completed"
277 |
--------------------------------------------------------------------------------
/scripts/install:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | #=================================================
4 | # GENERIC START
5 | #=================================================
6 | # IMPORT GENERIC HELPERS
7 | #=================================================
8 |
9 | source _common.sh
10 | source ynh_add_swap
11 | source /usr/share/yunohost/helpers
12 |
13 | #=================================================
14 | # MANAGE SCRIPT FAILURE
15 | #=================================================
16 | ynh_print_info --message="Managing script failure..."
17 |
18 | ynh_clean_setup () {
19 | ynh_clean_check_starting
20 | }
21 | # Exit if an error occurs during the execution of the script
22 | ynh_abort_if_errors
23 |
24 | #=================================================
25 | # RETRIEVE ARGUMENTS FROM THE MANIFEST
26 | #=================================================
27 | ynh_print_info --message="Retrieving arguments from the manifest..."
28 |
29 | domain=$YNH_APP_ARG_DOMAIN
30 | path_url="/"
31 | admin=$YNH_APP_ARG_ADMIN
32 | is_public=$YNH_APP_ARG_IS_PUBLIC
33 | language=$YNH_APP_ARG_LANGUAGE
34 | password=$YNH_APP_ARG_PASSWORD
35 | security_password_salt=$(ynh_string_random 30)
36 | secret_key=$(ynh_string_random 30)
37 |
38 | app=$YNH_APP_INSTANCE_NAME
39 |
40 | # Define app's data directory
41 | datadir="/home/yunohost.app/${app}"
42 |
43 | #=================================================
44 | # CHECK IF THE APP CAN BE INSTALLED WITH THESE ARGS
45 | #=================================================
46 | ynh_print_info --message="Validating installation parameters..."
47 |
48 | final_path=/var/www/$app
49 | test ! -e "$final_path" || ynh_die --message="This path already contains a folder"
50 |
51 | # Register (book) web path
52 | ynh_webpath_register --app=$app --domain=$domain --path_url=$path_url
53 |
54 | #=================================================
55 | # STORE SETTINGS FROM MANIFEST
56 | #=================================================
57 | ynh_print_info --message="Storing installation settings..."
58 |
59 | ynh_app_setting_set --app=$app --key=domain --value=$domain
60 | ynh_app_setting_set --app=$app --key=path --value=$path_url
61 | ynh_app_setting_set --app=$app --key=admin --value=$admin
62 | ynh_app_setting_set --app=$app --key=is_public --value=$is_public
63 | ynh_app_setting_set --app=$app --key=language --value=$language
64 | ynh_app_setting_set --app=$app --key=security_password_salt --value=$security_password_salt
65 | ynh_app_setting_set --app=$app --key=secret_key --value=$secret_key
66 | ynh_app_setting_set --app=$app --key=datadir --value=$datadir
67 |
68 | #=================================================
69 | # STANDARD MODIFICATIONS
70 | #=================================================
71 | # FIND AND OPEN A PORT
72 | #=================================================
73 | ynh_print_info --message="Configuring firewall..."
74 |
75 | # Find an available port
76 | port=$(ynh_find_port --port=8095)
77 | ynh_app_setting_set --app=$app --key=port --value=$port
78 |
79 | #=================================================
80 | # ADD SWAP
81 | #=================================================
82 | ynh_print_info --message="Adding $swap_needed Mo to swap..."
83 |
84 | ynh_add_swap --size=$swap_needed
85 |
86 | #=================================================
87 | # INSTALL BUILD DEPENDENCIES
88 | #=================================================
89 | ynh_print_info --message="Installing build dependencies..."
90 |
91 | ynh_install_app_dependencies $build_dependencies
92 |
93 | #=================================================
94 | # BUILD AUDIOWAVEFORM
95 | #=================================================
96 | ynh_print_info --message="Building audiowaveform..."
97 |
98 | ynh_setup_source --dest_dir="$final_path/audiowaveform.d/audiowaveform" --source_id=audiowaveform
99 | ynh_setup_source --dest_dir="$final_path/audiowaveform.d/googletest" --source_id=googletest
100 |
101 | pushd "$final_path/audiowaveform.d/audiowaveform"
102 | ln -s $final_path/audiowaveform.d/googletest/googletest googletest
103 | ln -s $final_path/audiowaveform.d/googletest/googlemock googlemock
104 | mkdir build
105 | cd build
106 | cmake ..
107 | make
108 | cp $final_path/audiowaveform.d/audiowaveform/build/audiowaveform $final_path/.
109 | popd
110 |
111 | ynh_secure_remove --file="$final_path/audiowaveform.d"
112 |
113 | #=================================================
114 | # REMOVE BUILD DEPENDENCIES
115 | #=================================================
116 | ynh_print_info --message="Removing build dependencies"
117 |
118 | # Remove metapackage and its dependencies
119 | ynh_remove_app_dependencies
120 |
121 | #=================================================
122 | # INSTALL DEPENDENCIES
123 | #=================================================
124 | ynh_print_info --message="Installing dependencies..."
125 |
126 | ynh_install_app_dependencies $pkg_dependencies
127 |
128 | #=================================================
129 | # CREATE A POSTGRESQL DATABASE
130 | #=================================================
131 | ynh_print_info --message="Creating a PostgreSQL database..."
132 |
133 | db_name=$(ynh_sanitize_dbid --db_name=$app)
134 | db_user=$db_name
135 | db_pwd=$(ynh_string_random --length=30)
136 | ynh_app_setting_set --app=$app --key=db_name --value=$db_name
137 | ynh_app_setting_set --app=$app --key=db_pwd --value=$db_pwd
138 | ynh_psql_test_if_first_run
139 | ynh_psql_setup_db --db_user=$db_user --db_name=$db_name --db_pwd=$db_pwd
140 | ynh_psql_execute_as_root --sql="CREATE EXTENSION IF NOT EXISTS \"uuid-ossp\";" --database=$db_name
141 |
142 | #=================================================
143 | # DOWNLOAD, CHECK AND UNPACK SOURCE
144 | #=================================================
145 | ynh_print_info --message="Setting up source files..."
146 |
147 | ynh_app_setting_set --app=$app --key=final_path --value=$final_path
148 | # Download, check integrity, uncompress and patch the source from app.src
149 | ynh_setup_source --dest_dir="$final_path"
150 | ynh_replace_string --match_string="flasgger==0.9.3" --replace_string="flasgger==0.9.4" --target_file="$final_path/api/requirements.txt"
151 | ynh_replace_string --match_string="Flask_Babelex==0.9.3" --replace_string="Flask_Babelex>=0.9.4" --target_file="$final_path/api/requirements.txt"
152 | ynh_replace_string --match_string="flask_uploads==0.2.1" --replace_string="flask_uploads>=0.2.1" --target_file="$final_path/api/requirements.txt"
153 |
154 | ynh_setup_source --dest_dir="$final_path/front/dist" --source_id=front
155 |
156 | #=================================================
157 | # NGINX CONFIGURATION
158 | #=================================================
159 | ynh_print_info --message="Configuring nginx web server..."
160 |
161 | # Create a dedicated nginx config
162 | ynh_add_nginx_config "datadir"
163 |
164 | #=================================================
165 | # CREATE DEDICATED USER
166 | #=================================================
167 | ynh_print_info --message="Configuring system user..."
168 |
169 | # Create a system user
170 | ynh_system_user_create --username=$app --home_dir="$final_path"
171 |
172 | #=================================================
173 | # SPECIFIC SETUP
174 | #=================================================
175 | # CREATE THE DATA DIRECTORY
176 | #=================================================
177 | ynh_print_info --message="Create the data directory..."
178 |
179 | # Create app folders
180 | mkdir -p "$datadir"
181 | mkdir -p "$datadir/uploads/sounds"
182 | mkdir -p "$datadir/uploads/waveforms"
183 | mkdir -p "$datadir/uploads/artwork_albums"
184 | mkdir -p "$datadir/uploads/artwork_sounds"
185 | mkdir -p "$datadir/uploads/avatars"
186 |
187 | # Give permission to the datadir
188 | chown -R "$app": "$datadir"
189 |
190 | #=================================================
191 | # MODIFY A CONFIG FILE
192 | #=================================================
193 | ynh_print_info --message="Modifying a config file..."
194 |
195 | api_config="$final_path/api/config/prod_secret.py"
196 | cp ../conf/prod_secret.py "$api_config"
197 | ynh_replace_string --match_string="__LANGUAGE__" --replace_string="$language" --target_file="$api_config"
198 | ynh_replace_string --match_string="__DATADIR__" --replace_string="$datadir" --target_file="$api_config"
199 | ynh_replace_string --match_string="__DOMAIN__" --replace_string="$domain" --target_file="$api_config"
200 | ynh_replace_string --match_string="__SECURITY_PASSWORD_SALT__" --replace_string="$security_password_salt" --target_file="$api_config"
201 | ynh_replace_string --match_string="__SECRET_KEY__" --replace_string="$secret_key" --target_file="$api_config"
202 | ynh_replace_string --match_string="__DB_USER__" --replace_string="$db_user" --target_file="$api_config"
203 | ynh_replace_string --match_string="__DB_PWD__" --replace_string="$db_pwd" --target_file="$api_config"
204 | ynh_replace_string --match_string="__DB_NAME__" --replace_string="$db_name" --target_file="$api_config"
205 | ynh_replace_string --match_string="__FINAL_PATH__" --replace_string="$final_path" --target_file="$api_config"
206 |
207 | front_config="$final_path/front/config/local.json"
208 | cp ../conf/local.example.json "$front_config"
209 | ynh_replace_string --match_string="__DOMAIN__" --replace_string="$domain" --target_file="$front_config"
210 |
211 | #=================================================
212 | # INSTALL PYTHONZ TO GET PYTHON
213 | #=================================================
214 | ynh_print_info --message="Installing Python..."
215 |
216 | # Get pythonz
217 | # curl -kL https://raw.githubusercontent.com/saghul/pythonz/master/pythonz-install
218 | # ./pythonz-install
219 | ynh_setup_source --dest_dir="$final_path/.pythonz" --source_id=pythonz
220 | export PYTHONZ_ROOT="$final_path/.pythonz"
221 | # Then install it
222 | python $final_path/.pythonz/pythonz_install.py
223 |
224 | # Install Python
225 | $final_path/.pythonz/bin/pythonz install $python_version
226 |
227 | #=================================================
228 | # INSTALL REEL2BITS
229 | #=================================================
230 | ynh_print_info --message="Installing Reel2Bits..."
231 |
232 | # Set permissions to app files
233 | chown -R "$app": "$final_path"
234 |
235 | pushd $final_path/api
236 | virtualenv -p $($final_path/.pythonz/bin/pythonz locate $python_version) ve3
237 | ve3/bin/pip3 install wheel
238 | ve3/bin/pip3 install werkzeug==0.16.1
239 | ve3/bin/pip3 install --requirement requirements.txt
240 | #ve3/bin/python3 setup.py install
241 | export APP_SETTINGS=config.prod_secret.Config
242 | ve3/bin/flask db upgrade
243 | ve3/bin/flask db-datas 000-seeds
244 | #ve3/bin/flask seed
245 | ve3/bin/pip3 install waitress
246 | #ve3/bin/flask users create --password TEXT -a IDENTITY
247 | #ve3/bin/flask roles add yalh@yh.yalh.net admin
248 | popd
249 |
250 | #=================================================
251 | # SETUP SYSTEMD
252 | #=================================================
253 | ynh_print_info --message="Configuring a systemd service..."
254 |
255 | ynh_replace_string --match_string="__PORT__" --replace_string="$port" --target_file="../conf/reel2bits-web.service"
256 |
257 | # Create a dedicated systemd config
258 | cp ../conf/reel2bits.target /etc/systemd/system/$app.target
259 | ynh_add_systemd_config --service="$app-web" --template="reel2bits-web.service"
260 | ynh_add_systemd_config --service="$app-worker" --template="reel2bits-worker.service"
261 |
262 | #=================================================
263 | # STORE THE CONFIG FILE CHECKSUM
264 | #=================================================
265 | ynh_print_info --message="Storing the config file checksum..."
266 |
267 | # Calculate and store the config file checksum into the app settings
268 | ynh_store_file_checksum --file="$api_config"
269 | ynh_store_file_checksum --file="$front_config"
270 |
271 | #=================================================
272 | # GENERIC FINALIZATION
273 | #=================================================
274 | # SECURE FILES AND DIRECTORIES
275 | #=================================================
276 | ynh_print_info --message="Securing files and directories..."
277 |
278 | # Set permissions to app files
279 | chown -R "$app": "$final_path"
280 |
281 | #=================================================
282 | # INTEGRATE SERVICE IN YUNOHOST
283 | #=================================================
284 | ynh_print_info --message="Integrating service in YunoHost..."
285 |
286 | yunohost service add $app-web --description "$app-web daemon for Reel2Bits"
287 | yunohost service add $app-worker --description "$app-worker daemon for Reel2Bits"
288 | yunohost service add $app --description "$app daemon for Reel2Bits"
289 |
290 | #=================================================
291 | # START SYSTEMD SERVICE
292 | #=================================================
293 | ynh_print_info --message="Starting a systemd service..."
294 |
295 | # Start a systemd service
296 | ynh_systemd_action --service_name=${app}-web --action="start" --log_path=systemd --line_match="Started ${app}-web"
297 | ynh_systemd_action --service_name=${app}-worker --action="start" --log_path=systemd --line_match="Started ${app}-worker"
298 | systemctl start $app.target
299 |
300 | #=================================================
301 | # SETUP SSOWAT
302 | #=================================================
303 | ynh_print_info --message="Configuring SSOwat..."
304 |
305 | # Make app public if necessary
306 | if [ $is_public -eq 1 ]
307 | then
308 | # unprotected_uris allows SSO credentials to be passed anyway.
309 | ynh_app_setting_set --app=$app --key=unprotected_uris --value="/"
310 | fi
311 |
312 | #=================================================
313 | # RELOAD NGINX
314 | #=================================================
315 | ynh_print_info --message="Reloading nginx web server..."
316 |
317 | ynh_systemd_action --service_name=nginx --action=reload
318 |
319 | #=================================================
320 | # END OF SCRIPT
321 | #=================================================
322 |
323 | ynh_print_info --message="Installation of $app completed"
324 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | GNU AFFERO GENERAL PUBLIC LICENSE
2 | Version 3, 19 November 2007
3 |
4 | Copyright (C) 2007 Free Software Foundation, Inc.
5 | Everyone is permitted to copy and distribute verbatim copies
6 | of this license document, but changing it is not allowed.
7 |
8 | Preamble
9 |
10 | The GNU Affero General Public License is a free, copyleft license for
11 | software and other kinds of works, specifically designed to ensure
12 | cooperation with the community in the case of network server software.
13 |
14 | The licenses for most software and other practical works are designed
15 | to take away your freedom to share and change the works. By contrast,
16 | our General Public Licenses are intended to guarantee your freedom to
17 | share and change all versions of a program--to make sure it remains free
18 | software for all its users.
19 |
20 | When we speak of free software, we are referring to freedom, not
21 | price. Our General Public Licenses are designed to make sure that you
22 | have the freedom to distribute copies of free software (and charge for
23 | them if you wish), that you receive source code or can get it if you
24 | want it, that you can change the software or use pieces of it in new
25 | free programs, and that you know you can do these things.
26 |
27 | Developers that use our General Public Licenses protect your rights
28 | with two steps: (1) assert copyright on the software, and (2) offer
29 | you this License which gives you legal permission to copy, distribute
30 | and/or modify the software.
31 |
32 | A secondary benefit of defending all users' freedom is that
33 | improvements made in alternate versions of the program, if they
34 | receive widespread use, become available for other developers to
35 | incorporate. Many developers of free software are heartened and
36 | encouraged by the resulting cooperation. However, in the case of
37 | software used on network servers, this result may fail to come about.
38 | The GNU General Public License permits making a modified version and
39 | letting the public access it on a server without ever releasing its
40 | source code to the public.
41 |
42 | The GNU Affero General Public License is designed specifically to
43 | ensure that, in such cases, the modified source code becomes available
44 | to the community. It requires the operator of a network server to
45 | provide the source code of the modified version running there to the
46 | users of that server. Therefore, public use of a modified version, on
47 | a publicly accessible server, gives the public access to the source
48 | code of the modified version.
49 |
50 | An older license, called the Affero General Public License and
51 | published by Affero, was designed to accomplish similar goals. This is
52 | a different license, not a version of the Affero GPL, but Affero has
53 | released a new version of the Affero GPL which permits relicensing under
54 | this license.
55 |
56 | The precise terms and conditions for copying, distribution and
57 | modification follow.
58 |
59 | TERMS AND CONDITIONS
60 |
61 | 0. Definitions.
62 |
63 | "This License" refers to version 3 of the GNU Affero General Public License.
64 |
65 | "Copyright" also means copyright-like laws that apply to other kinds of
66 | works, such as semiconductor masks.
67 |
68 | "The Program" refers to any copyrightable work licensed under this
69 | License. Each licensee is addressed as "you". "Licensees" and
70 | "recipients" may be individuals or organizations.
71 |
72 | To "modify" a work means to copy from or adapt all or part of the work
73 | in a fashion requiring copyright permission, other than the making of an
74 | exact copy. The resulting work is called a "modified version" of the
75 | earlier work or a work "based on" the earlier work.
76 |
77 | A "covered work" means either the unmodified Program or a work based
78 | on the Program.
79 |
80 | To "propagate" a work means to do anything with it that, without
81 | permission, would make you directly or secondarily liable for
82 | infringement under applicable copyright law, except executing it on a
83 | computer or modifying a private copy. Propagation includes copying,
84 | distribution (with or without modification), making available to the
85 | public, and in some countries other activities as well.
86 |
87 | To "convey" a work means any kind of propagation that enables other
88 | parties to make or receive copies. Mere interaction with a user through
89 | a computer network, with no transfer of a copy, is not conveying.
90 |
91 | An interactive user interface displays "Appropriate Legal Notices"
92 | to the extent that it includes a convenient and prominently visible
93 | feature that (1) displays an appropriate copyright notice, and (2)
94 | tells the user that there is no warranty for the work (except to the
95 | extent that warranties are provided), that licensees may convey the
96 | work under this License, and how to view a copy of this License. If
97 | the interface presents a list of user commands or options, such as a
98 | menu, a prominent item in the list meets this criterion.
99 |
100 | 1. Source Code.
101 |
102 | The "source code" for a work means the preferred form of the work
103 | for making modifications to it. "Object code" means any non-source
104 | form of a work.
105 |
106 | A "Standard Interface" means an interface that either is an official
107 | standard defined by a recognized standards body, or, in the case of
108 | interfaces specified for a particular programming language, one that
109 | is widely used among developers working in that language.
110 |
111 | The "System Libraries" of an executable work include anything, other
112 | than the work as a whole, that (a) is included in the normal form of
113 | packaging a Major Component, but which is not part of that Major
114 | Component, and (b) serves only to enable use of the work with that
115 | Major Component, or to implement a Standard Interface for which an
116 | implementation is available to the public in source code form. A
117 | "Major Component", in this context, means a major essential component
118 | (kernel, window system, and so on) of the specific operating system
119 | (if any) on which the executable work runs, or a compiler used to
120 | produce the work, or an object code interpreter used to run it.
121 |
122 | The "Corresponding Source" for a work in object code form means all
123 | the source code needed to generate, install, and (for an executable
124 | work) run the object code and to modify the work, including scripts to
125 | control those activities. However, it does not include the work's
126 | System Libraries, or general-purpose tools or generally available free
127 | programs which are used unmodified in performing those activities but
128 | which are not part of the work. For example, Corresponding Source
129 | includes interface definition files associated with source files for
130 | the work, and the source code for shared libraries and dynamically
131 | linked subprograms that the work is specifically designed to require,
132 | such as by intimate data communication or control flow between those
133 | subprograms and other parts of the work.
134 |
135 | The Corresponding Source need not include anything that users
136 | can regenerate automatically from other parts of the Corresponding
137 | Source.
138 |
139 | The Corresponding Source for a work in source code form is that
140 | same work.
141 |
142 | 2. Basic Permissions.
143 |
144 | All rights granted under this License are granted for the term of
145 | copyright on the Program, and are irrevocable provided the stated
146 | conditions are met. This License explicitly affirms your unlimited
147 | permission to run the unmodified Program. The output from running a
148 | covered work is covered by this License only if the output, given its
149 | content, constitutes a covered work. This License acknowledges your
150 | rights of fair use or other equivalent, as provided by copyright law.
151 |
152 | You may make, run and propagate covered works that you do not
153 | convey, without conditions so long as your license otherwise remains
154 | in force. You may convey covered works to others for the sole purpose
155 | of having them make modifications exclusively for you, or provide you
156 | with facilities for running those works, provided that you comply with
157 | the terms of this License in conveying all material for which you do
158 | not control copyright. Those thus making or running the covered works
159 | for you must do so exclusively on your behalf, under your direction
160 | and control, on terms that prohibit them from making any copies of
161 | your copyrighted material outside their relationship with you.
162 |
163 | Conveying under any other circumstances is permitted solely under
164 | the conditions stated below. Sublicensing is not allowed; section 10
165 | makes it unnecessary.
166 |
167 | 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
168 |
169 | No covered work shall be deemed part of an effective technological
170 | measure under any applicable law fulfilling obligations under article
171 | 11 of the WIPO copyright treaty adopted on 20 December 1996, or
172 | similar laws prohibiting or restricting circumvention of such
173 | measures.
174 |
175 | When you convey a covered work, you waive any legal power to forbid
176 | circumvention of technological measures to the extent such circumvention
177 | is effected by exercising rights under this License with respect to
178 | the covered work, and you disclaim any intention to limit operation or
179 | modification of the work as a means of enforcing, against the work's
180 | users, your or third parties' legal rights to forbid circumvention of
181 | technological measures.
182 |
183 | 4. Conveying Verbatim Copies.
184 |
185 | You may convey verbatim copies of the Program's source code as you
186 | receive it, in any medium, provided that you conspicuously and
187 | appropriately publish on each copy an appropriate copyright notice;
188 | keep intact all notices stating that this License and any
189 | non-permissive terms added in accord with section 7 apply to the code;
190 | keep intact all notices of the absence of any warranty; and give all
191 | recipients a copy of this License along with the Program.
192 |
193 | You may charge any price or no price for each copy that you convey,
194 | and you may offer support or warranty protection for a fee.
195 |
196 | 5. Conveying Modified Source Versions.
197 |
198 | You may convey a work based on the Program, or the modifications to
199 | produce it from the Program, in the form of source code under the
200 | terms of section 4, provided that you also meet all of these conditions:
201 |
202 | a) The work must carry prominent notices stating that you modified
203 | it, and giving a relevant date.
204 |
205 | b) The work must carry prominent notices stating that it is
206 | released under this License and any conditions added under section
207 | 7. This requirement modifies the requirement in section 4 to
208 | "keep intact all notices".
209 |
210 | c) You must license the entire work, as a whole, under this
211 | License to anyone who comes into possession of a copy. This
212 | License will therefore apply, along with any applicable section 7
213 | additional terms, to the whole of the work, and all its parts,
214 | regardless of how they are packaged. This License gives no
215 | permission to license the work in any other way, but it does not
216 | invalidate such permission if you have separately received it.
217 |
218 | d) If the work has interactive user interfaces, each must display
219 | Appropriate Legal Notices; however, if the Program has interactive
220 | interfaces that do not display Appropriate Legal Notices, your
221 | work need not make them do so.
222 |
223 | A compilation of a covered work with other separate and independent
224 | works, which are not by their nature extensions of the covered work,
225 | and which are not combined with it such as to form a larger program,
226 | in or on a volume of a storage or distribution medium, is called an
227 | "aggregate" if the compilation and its resulting copyright are not
228 | used to limit the access or legal rights of the compilation's users
229 | beyond what the individual works permit. Inclusion of a covered work
230 | in an aggregate does not cause this License to apply to the other
231 | parts of the aggregate.
232 |
233 | 6. Conveying Non-Source Forms.
234 |
235 | You may convey a covered work in object code form under the terms
236 | of sections 4 and 5, provided that you also convey the
237 | machine-readable Corresponding Source under the terms of this License,
238 | in one of these ways:
239 |
240 | a) Convey the object code in, or embodied in, a physical product
241 | (including a physical distribution medium), accompanied by the
242 | Corresponding Source fixed on a durable physical medium
243 | customarily used for software interchange.
244 |
245 | b) Convey the object code in, or embodied in, a physical product
246 | (including a physical distribution medium), accompanied by a
247 | written offer, valid for at least three years and valid for as
248 | long as you offer spare parts or customer support for that product
249 | model, to give anyone who possesses the object code either (1) a
250 | copy of the Corresponding Source for all the software in the
251 | product that is covered by this License, on a durable physical
252 | medium customarily used for software interchange, for a price no
253 | more than your reasonable cost of physically performing this
254 | conveying of source, or (2) access to copy the
255 | Corresponding Source from a network server at no charge.
256 |
257 | c) Convey individual copies of the object code with a copy of the
258 | written offer to provide the Corresponding Source. This
259 | alternative is allowed only occasionally and noncommercially, and
260 | only if you received the object code with such an offer, in accord
261 | with subsection 6b.
262 |
263 | d) Convey the object code by offering access from a designated
264 | place (gratis or for a charge), and offer equivalent access to the
265 | Corresponding Source in the same way through the same place at no
266 | further charge. You need not require recipients to copy the
267 | Corresponding Source along with the object code. If the place to
268 | copy the object code is a network server, the Corresponding Source
269 | may be on a different server (operated by you or a third party)
270 | that supports equivalent copying facilities, provided you maintain
271 | clear directions next to the object code saying where to find the
272 | Corresponding Source. Regardless of what server hosts the
273 | Corresponding Source, you remain obligated to ensure that it is
274 | available for as long as needed to satisfy these requirements.
275 |
276 | e) Convey the object code using peer-to-peer transmission, provided
277 | you inform other peers where the object code and Corresponding
278 | Source of the work are being offered to the general public at no
279 | charge under subsection 6d.
280 |
281 | A separable portion of the object code, whose source code is excluded
282 | from the Corresponding Source as a System Library, need not be
283 | included in conveying the object code work.
284 |
285 | A "User Product" is either (1) a "consumer product", which means any
286 | tangible personal property which is normally used for personal, family,
287 | or household purposes, or (2) anything designed or sold for incorporation
288 | into a dwelling. In determining whether a product is a consumer product,
289 | doubtful cases shall be resolved in favor of coverage. For a particular
290 | product received by a particular user, "normally used" refers to a
291 | typical or common use of that class of product, regardless of the status
292 | of the particular user or of the way in which the particular user
293 | actually uses, or expects or is expected to use, the product. A product
294 | is a consumer product regardless of whether the product has substantial
295 | commercial, industrial or non-consumer uses, unless such uses represent
296 | the only significant mode of use of the product.
297 |
298 | "Installation Information" for a User Product means any methods,
299 | procedures, authorization keys, or other information required to install
300 | and execute modified versions of a covered work in that User Product from
301 | a modified version of its Corresponding Source. The information must
302 | suffice to ensure that the continued functioning of the modified object
303 | code is in no case prevented or interfered with solely because
304 | modification has been made.
305 |
306 | If you convey an object code work under this section in, or with, or
307 | specifically for use in, a User Product, and the conveying occurs as
308 | part of a transaction in which the right of possession and use of the
309 | User Product is transferred to the recipient in perpetuity or for a
310 | fixed term (regardless of how the transaction is characterized), the
311 | Corresponding Source conveyed under this section must be accompanied
312 | by the Installation Information. But this requirement does not apply
313 | if neither you nor any third party retains the ability to install
314 | modified object code on the User Product (for example, the work has
315 | been installed in ROM).
316 |
317 | The requirement to provide Installation Information does not include a
318 | requirement to continue to provide support service, warranty, or updates
319 | for a work that has been modified or installed by the recipient, or for
320 | the User Product in which it has been modified or installed. Access to a
321 | network may be denied when the modification itself materially and
322 | adversely affects the operation of the network or violates the rules and
323 | protocols for communication across the network.
324 |
325 | Corresponding Source conveyed, and Installation Information provided,
326 | in accord with this section must be in a format that is publicly
327 | documented (and with an implementation available to the public in
328 | source code form), and must require no special password or key for
329 | unpacking, reading or copying.
330 |
331 | 7. Additional Terms.
332 |
333 | "Additional permissions" are terms that supplement the terms of this
334 | License by making exceptions from one or more of its conditions.
335 | Additional permissions that are applicable to the entire Program shall
336 | be treated as though they were included in this License, to the extent
337 | that they are valid under applicable law. If additional permissions
338 | apply only to part of the Program, that part may be used separately
339 | under those permissions, but the entire Program remains governed by
340 | this License without regard to the additional permissions.
341 |
342 | When you convey a copy of a covered work, you may at your option
343 | remove any additional permissions from that copy, or from any part of
344 | it. (Additional permissions may be written to require their own
345 | removal in certain cases when you modify the work.) You may place
346 | additional permissions on material, added by you to a covered work,
347 | for which you have or can give appropriate copyright permission.
348 |
349 | Notwithstanding any other provision of this License, for material you
350 | add to a covered work, you may (if authorized by the copyright holders of
351 | that material) supplement the terms of this License with terms:
352 |
353 | a) Disclaiming warranty or limiting liability differently from the
354 | terms of sections 15 and 16 of this License; or
355 |
356 | b) Requiring preservation of specified reasonable legal notices or
357 | author attributions in that material or in the Appropriate Legal
358 | Notices displayed by works containing it; or
359 |
360 | c) Prohibiting misrepresentation of the origin of that material, or
361 | requiring that modified versions of such material be marked in
362 | reasonable ways as different from the original version; or
363 |
364 | d) Limiting the use for publicity purposes of names of licensors or
365 | authors of the material; or
366 |
367 | e) Declining to grant rights under trademark law for use of some
368 | trade names, trademarks, or service marks; or
369 |
370 | f) Requiring indemnification of licensors and authors of that
371 | material by anyone who conveys the material (or modified versions of
372 | it) with contractual assumptions of liability to the recipient, for
373 | any liability that these contractual assumptions directly impose on
374 | those licensors and authors.
375 |
376 | All other non-permissive additional terms are considered "further
377 | restrictions" within the meaning of section 10. If the Program as you
378 | received it, or any part of it, contains a notice stating that it is
379 | governed by this License along with a term that is a further
380 | restriction, you may remove that term. If a license document contains
381 | a further restriction but permits relicensing or conveying under this
382 | License, you may add to a covered work material governed by the terms
383 | of that license document, provided that the further restriction does
384 | not survive such relicensing or conveying.
385 |
386 | If you add terms to a covered work in accord with this section, you
387 | must place, in the relevant source files, a statement of the
388 | additional terms that apply to those files, or a notice indicating
389 | where to find the applicable terms.
390 |
391 | Additional terms, permissive or non-permissive, may be stated in the
392 | form of a separately written license, or stated as exceptions;
393 | the above requirements apply either way.
394 |
395 | 8. Termination.
396 |
397 | You may not propagate or modify a covered work except as expressly
398 | provided under this License. Any attempt otherwise to propagate or
399 | modify it is void, and will automatically terminate your rights under
400 | this License (including any patent licenses granted under the third
401 | paragraph of section 11).
402 |
403 | However, if you cease all violation of this License, then your
404 | license from a particular copyright holder is reinstated (a)
405 | provisionally, unless and until the copyright holder explicitly and
406 | finally terminates your license, and (b) permanently, if the copyright
407 | holder fails to notify you of the violation by some reasonable means
408 | prior to 60 days after the cessation.
409 |
410 | Moreover, your license from a particular copyright holder is
411 | reinstated permanently if the copyright holder notifies you of the
412 | violation by some reasonable means, this is the first time you have
413 | received notice of violation of this License (for any work) from that
414 | copyright holder, and you cure the violation prior to 30 days after
415 | your receipt of the notice.
416 |
417 | Termination of your rights under this section does not terminate the
418 | licenses of parties who have received copies or rights from you under
419 | this License. If your rights have been terminated and not permanently
420 | reinstated, you do not qualify to receive new licenses for the same
421 | material under section 10.
422 |
423 | 9. Acceptance Not Required for Having Copies.
424 |
425 | You are not required to accept this License in order to receive or
426 | run a copy of the Program. Ancillary propagation of a covered work
427 | occurring solely as a consequence of using peer-to-peer transmission
428 | to receive a copy likewise does not require acceptance. However,
429 | nothing other than this License grants you permission to propagate or
430 | modify any covered work. These actions infringe copyright if you do
431 | not accept this License. Therefore, by modifying or propagating a
432 | covered work, you indicate your acceptance of this License to do so.
433 |
434 | 10. Automatic Licensing of Downstream Recipients.
435 |
436 | Each time you convey a covered work, the recipient automatically
437 | receives a license from the original licensors, to run, modify and
438 | propagate that work, subject to this License. You are not responsible
439 | for enforcing compliance by third parties with this License.
440 |
441 | An "entity transaction" is a transaction transferring control of an
442 | organization, or substantially all assets of one, or subdividing an
443 | organization, or merging organizations. If propagation of a covered
444 | work results from an entity transaction, each party to that
445 | transaction who receives a copy of the work also receives whatever
446 | licenses to the work the party's predecessor in interest had or could
447 | give under the previous paragraph, plus a right to possession of the
448 | Corresponding Source of the work from the predecessor in interest, if
449 | the predecessor has it or can get it with reasonable efforts.
450 |
451 | You may not impose any further restrictions on the exercise of the
452 | rights granted or affirmed under this License. For example, you may
453 | not impose a license fee, royalty, or other charge for exercise of
454 | rights granted under this License, and you may not initiate litigation
455 | (including a cross-claim or counterclaim in a lawsuit) alleging that
456 | any patent claim is infringed by making, using, selling, offering for
457 | sale, or importing the Program or any portion of it.
458 |
459 | 11. Patents.
460 |
461 | A "contributor" is a copyright holder who authorizes use under this
462 | License of the Program or a work on which the Program is based. The
463 | work thus licensed is called the contributor's "contributor version".
464 |
465 | A contributor's "essential patent claims" are all patent claims
466 | owned or controlled by the contributor, whether already acquired or
467 | hereafter acquired, that would be infringed by some manner, permitted
468 | by this License, of making, using, or selling its contributor version,
469 | but do not include claims that would be infringed only as a
470 | consequence of further modification of the contributor version. For
471 | purposes of this definition, "control" includes the right to grant
472 | patent sublicenses in a manner consistent with the requirements of
473 | this License.
474 |
475 | Each contributor grants you a non-exclusive, worldwide, royalty-free
476 | patent license under the contributor's essential patent claims, to
477 | make, use, sell, offer for sale, import and otherwise run, modify and
478 | propagate the contents of its contributor version.
479 |
480 | In the following three paragraphs, a "patent license" is any express
481 | agreement or commitment, however denominated, not to enforce a patent
482 | (such as an express permission to practice a patent or covenant not to
483 | sue for patent infringement). To "grant" such a patent license to a
484 | party means to make such an agreement or commitment not to enforce a
485 | patent against the party.
486 |
487 | If you convey a covered work, knowingly relying on a patent license,
488 | and the Corresponding Source of the work is not available for anyone
489 | to copy, free of charge and under the terms of this License, through a
490 | publicly available network server or other readily accessible means,
491 | then you must either (1) cause the Corresponding Source to be so
492 | available, or (2) arrange to deprive yourself of the benefit of the
493 | patent license for this particular work, or (3) arrange, in a manner
494 | consistent with the requirements of this License, to extend the patent
495 | license to downstream recipients. "Knowingly relying" means you have
496 | actual knowledge that, but for the patent license, your conveying the
497 | covered work in a country, or your recipient's use of the covered work
498 | in a country, would infringe one or more identifiable patents in that
499 | country that you have reason to believe are valid.
500 |
501 | If, pursuant to or in connection with a single transaction or
502 | arrangement, you convey, or propagate by procuring conveyance of, a
503 | covered work, and grant a patent license to some of the parties
504 | receiving the covered work authorizing them to use, propagate, modify
505 | or convey a specific copy of the covered work, then the patent license
506 | you grant is automatically extended to all recipients of the covered
507 | work and works based on it.
508 |
509 | A patent license is "discriminatory" if it does not include within
510 | the scope of its coverage, prohibits the exercise of, or is
511 | conditioned on the non-exercise of one or more of the rights that are
512 | specifically granted under this License. You may not convey a covered
513 | work if you are a party to an arrangement with a third party that is
514 | in the business of distributing software, under which you make payment
515 | to the third party based on the extent of your activity of conveying
516 | the work, and under which the third party grants, to any of the
517 | parties who would receive the covered work from you, a discriminatory
518 | patent license (a) in connection with copies of the covered work
519 | conveyed by you (or copies made from those copies), or (b) primarily
520 | for and in connection with specific products or compilations that
521 | contain the covered work, unless you entered into that arrangement,
522 | or that patent license was granted, prior to 28 March 2007.
523 |
524 | Nothing in this License shall be construed as excluding or limiting
525 | any implied license or other defenses to infringement that may
526 | otherwise be available to you under applicable patent law.
527 |
528 | 12. No Surrender of Others' Freedom.
529 |
530 | If conditions are imposed on you (whether by court order, agreement or
531 | otherwise) that contradict the conditions of this License, they do not
532 | excuse you from the conditions of this License. If you cannot convey a
533 | covered work so as to satisfy simultaneously your obligations under this
534 | License and any other pertinent obligations, then as a consequence you may
535 | not convey it at all. For example, if you agree to terms that obligate you
536 | to collect a royalty for further conveying from those to whom you convey
537 | the Program, the only way you could satisfy both those terms and this
538 | License would be to refrain entirely from conveying the Program.
539 |
540 | 13. Remote Network Interaction; Use with the GNU General Public License.
541 |
542 | Notwithstanding any other provision of this License, if you modify the
543 | Program, your modified version must prominently offer all users
544 | interacting with it remotely through a computer network (if your version
545 | supports such interaction) an opportunity to receive the Corresponding
546 | Source of your version by providing access to the Corresponding Source
547 | from a network server at no charge, through some standard or customary
548 | means of facilitating copying of software. This Corresponding Source
549 | shall include the Corresponding Source for any work covered by version 3
550 | of the GNU General Public License that is incorporated pursuant to the
551 | following paragraph.
552 |
553 | Notwithstanding any other provision of this License, you have
554 | permission to link or combine any covered work with a work licensed
555 | under version 3 of the GNU General Public License into a single
556 | combined work, and to convey the resulting work. The terms of this
557 | License will continue to apply to the part which is the covered work,
558 | but the work with which it is combined will remain governed by version
559 | 3 of the GNU General Public License.
560 |
561 | 14. Revised Versions of this License.
562 |
563 | The Free Software Foundation may publish revised and/or new versions of
564 | the GNU Affero General Public License from time to time. Such new versions
565 | will be similar in spirit to the present version, but may differ in detail to
566 | address new problems or concerns.
567 |
568 | Each version is given a distinguishing version number. If the
569 | Program specifies that a certain numbered version of the GNU Affero General
570 | Public License "or any later version" applies to it, you have the
571 | option of following the terms and conditions either of that numbered
572 | version or of any later version published by the Free Software
573 | Foundation. If the Program does not specify a version number of the
574 | GNU Affero General Public License, you may choose any version ever published
575 | by the Free Software Foundation.
576 |
577 | If the Program specifies that a proxy can decide which future
578 | versions of the GNU Affero General Public License can be used, that proxy's
579 | public statement of acceptance of a version permanently authorizes you
580 | to choose that version for the Program.
581 |
582 | Later license versions may give you additional or different
583 | permissions. However, no additional obligations are imposed on any
584 | author or copyright holder as a result of your choosing to follow a
585 | later version.
586 |
587 | 15. Disclaimer of Warranty.
588 |
589 | THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
590 | APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
591 | HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
592 | OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
593 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
594 | PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
595 | IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
596 | ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
597 |
598 | 16. Limitation of Liability.
599 |
600 | IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
601 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
602 | THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
603 | GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
604 | USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
605 | DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
606 | PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
607 | EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
608 | SUCH DAMAGES.
609 |
610 | 17. Interpretation of Sections 15 and 16.
611 |
612 | If the disclaimer of warranty and limitation of liability provided
613 | above cannot be given local legal effect according to their terms,
614 | reviewing courts shall apply local law that most closely approximates
615 | an absolute waiver of all civil liability in connection with the
616 | Program, unless a warranty or assumption of liability accompanies a
617 | copy of the Program in return for a fee.
618 |
619 | END OF TERMS AND CONDITIONS
620 |
621 | How to Apply These Terms to Your New Programs
622 |
623 | If you develop a new program, and you want it to be of the greatest
624 | possible use to the public, the best way to achieve this is to make it
625 | free software which everyone can redistribute and change under these terms.
626 |
627 | To do so, attach the following notices to the program. It is safest
628 | to attach them to the start of each source file to most effectively
629 | state the exclusion of warranty; and each file should have at least
630 | the "copyright" line and a pointer to where the full notice is found.
631 |
632 | reel2bit - selfhosted federated audio publishing application
633 | Copyright (C) 2016-2019 dashie
634 |
635 | This program is free software: you can redistribute it and/or modify
636 | it under the terms of the GNU Affero General Public License as published by
637 | the Free Software Foundation, either version 3 of the License, or
638 | (at your option) any later version.
639 |
640 | This program is distributed in the hope that it will be useful,
641 | but WITHOUT ANY WARRANTY; without even the implied warranty of
642 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
643 | GNU Affero General Public License for more details.
644 |
645 | You should have received a copy of the GNU Affero General Public License
646 | along with this program. If not, see .
647 |
648 | Also add information on how to contact you by electronic and paper mail.
649 |
650 | If your software can interact with users remotely through a computer
651 | network, you should also make sure that it provides a way for users to
652 | get its source. For example, if your program is a web application, its
653 | interface could display a "Source" link that leads users to an archive
654 | of the code. There are many ways you could offer source, and different
655 | solutions will be better for different programs; see section 13 for the
656 | specific requirements.
657 |
658 | You should also get your employer (if you work as a programmer) or school,
659 | if any, to sign a "copyright disclaimer" for the program, if necessary.
660 | For more information on this, and how to apply and follow the GNU AGPL, see
661 | .
662 |
--------------------------------------------------------------------------------