From f82a69a65b7b213742a6a70b1c6554680318dde1 Mon Sep 17 00:00:00 2001 From: ericgaspar Date: Tue, 15 Mar 2022 08:41:58 +0100 Subject: [PATCH 01/10] Fix --- conf/app.src | 7 + conf/nginx.conf | 28 ++-- conf/systemd.service | 13 ++ manifest.json | 143 +++++++------------- scripts/install | 309 +++++++++++++++++++++++-------------------- scripts/remove | 132 ++++++++++++------ 6 files changed, 334 insertions(+), 298 deletions(-) create mode 100644 conf/app.src create mode 100644 conf/systemd.service diff --git a/conf/app.src b/conf/app.src new file mode 100644 index 0000000..c7e3da7 --- /dev/null +++ b/conf/app.src @@ -0,0 +1,7 @@ +SOURCE_URL=https://github.com/rembo10/headphones/archive/refs/tags/v0.6.0-beta.5.tar.gz +SOURCE_SUM=b96c09fc7c384affa8beab0995447d54ed2d5bd4022278068e5ee93b71e07be8 +SOURCE_SUM_PRG=sha256sum +SOURCE_FORMAT=tar.gz +SOURCE_IN_SUBDIR=true +SOURCE_FILENAME= +SOURCE_EXTRACT=true diff --git a/conf/nginx.conf b/conf/nginx.conf index 2898fa8..a03bd49 100644 --- a/conf/nginx.conf +++ b/conf/nginx.conf @@ -1,15 +1,15 @@ -location PATHTOCHANGE { - proxy_http_version 1.1; - proxy_pass_header Server; - proxy_pass HOSTTOCHANGE; - proxy_redirect off; - proxy_set_header Host $http_host; - proxy_set_header X-Real-IP $remote_addr; - proxy_set_header X-Scheme $scheme; - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection "upgrade"; - - # Include SSOWAT user panel. - include conf.d/yunohost_panel.conf.inc; - more_clear_input_headers 'Accept-Encoding'; +#sub_path_only rewrite ^__PATH__$ __PATH__/ permanent; +location __PATH__/ { + + proxy_pass https://127.0.0.1:__PORT__; + proxy_redirect off; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Host $server_name; + + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; } diff --git a/conf/systemd.service b/conf/systemd.service new file mode 100644 index 0000000..6ae7420 --- /dev/null +++ b/conf/systemd.service @@ -0,0 +1,13 @@ +[Unit] +Description=Headphones +Wants=network.target network-online.target +After=network.target network-online.target + +[Service] +Type=forking +User=__APP__ +Group=__APP__ +ExecStart=/usr/bin/python3 __FINALPATH__/Headphones.py -d --datadir __DATADIR__ --nolaunch --config /etc/headphones/headphones.ini --port __PORT__ + +[Install] +WantedBy=multi-user.target \ No newline at end of file diff --git a/manifest.json b/manifest.json index 62b9aa3..73acda7 100644 --- a/manifest.json +++ b/manifest.json @@ -1,101 +1,48 @@ { - "name": "Headphones", - "id": "headphones", - "description": { - "en": "Automatic music downloader", - "fr": "Téléchargement automatisé de musique" - }, - "license": "GPL-3", - "maintainer": { - "name": "Snipees", - "email": "snipees@wareziens.net", - "url": "https://github.com/Snipees" - }, - "multi_instance": "false", - "arguments": { - "install": [ - { - "name": "domain", - "ask": { - "en": "Choose a domain for Headphones", - "fr": "Choisissez un domaine pour Headphones" - }, - "example": "mydomain.org" - }, - { - "name": "path", - "ask": { - "en": "Choose a path for Headphones", - "fr": "Choisissez un chemin pour Headphones" - }, - "example": "/headphones", - "default": "/headphones" - }, - { - "name": "public", - "ask": { - "en": "Is it a public application ?", - "fr": "Est-ce une application publique ?" - }, - "choices": ["Yes", "No"], - "default": "No" - }, - { - "name": "method", - "ask": { - "en": "Choose installation method", - "fr": "Choisissez le type d'installation" - }, - "choices": ["LOCAL", "REMOTE"], - "default": "LOCAL" - }, - { - "name": "port", - "ask": { - "en": "LOCAL: Choose the listening port of the app", - "fr": "LOCAL: Choisissez le port d'écoute de l'application" - }, - "example": "8181", - "default": "8181" - }, - { - "name": "fork", - "ask": { - "en": "LOCAL: Source URL of GIT to use", - "fr": "LOCAL: URL du GIT source à utiliser" - }, - "example": "https://github.com/Snipees/headphones", - "default": "https://github.com/rembo10/headphones" - }, - { - "name": "options", - "ask": { - "en": "LOCAL: Choose a downloader to configure", - "fr": "LOCAL: Choisissez un client de téléchargement" - }, - "choices": ["None", "Transmission"], - "default": "None" - }, - { - "name": "host", - "ask": { - "en": "REMOTE: Specify URL for the host", - "fr": "REMOTE: Indiquez l'URL de l'hôte" - }, - "example": "http://192.168.1.100:8888/myapp", - "default": "http://" - } + "name": "Headphones", + "id": "headphones", + "packaging_format": 1, + "description": { + "en": "Automated music downloader for NZB and Torrent", + "fr": "Automated music downloader for NZB and Torrent" + }, + "version": "0.6.0~ynh1", + "url": "https://github.com/rembo10/headphones", + "upstream": { + "license": "free", + "website": "https://github.com/rembo10/headphones", + "userdoc": "https://github.com/rembo10/headphones/wiki/Usage-guide", + "code": "https://github.com/rembo10/headphones" + }, + "license": "free", + "maintainer": { + "name": "John doe", + "email": "john.doe@example.com" + }, + "requirements": { + "yunohost": ">= 4.3.0" + }, + "multi_instance": true, + "services": [ + "nginx" ], - "remove": [ - { - "name": "data", - "ask": { - "en": "Would you like to keep data files ?", - "fr": "Souhaitez-vous conserver les données ?" - }, - "choices": ["Yes", "No"], - "default": "Yes" - } - ] - } + "arguments": { + "install" : [ + { + "name": "domain", + "type": "domain" + }, + { + "name": "path", + "type": "path", + "example": "/headphones", + "default": "/headphones" + }, + { + "name": "is_public", + "type": "boolean", + "default": true + } + ] + } } diff --git a/scripts/install b/scripts/install index ac71795..95c7ca0 100644 --- a/scripts/install +++ b/scripts/install @@ -1,155 +1,178 @@ #!/bin/bash -#debug commands -#exec > >(tee /tmp/debug-install.log) -#exec 2>&1 +#================================================= +# GENERIC START +#================================================= +# IMPORT GENERIC HELPERS +#================================================= -# Retrieve arguments -app_domain=$1 -app_path=$2 -app_public=$3 -app_method=$4 -app_port=$5 -app_fork=$6 -app_opts=$7 -app_host=$8 +source _common.sh +source /usr/share/yunohost/helpers -# Basic variable declaration -BASEDIR="$(dirname "$(pwd)")" +#================================================= +# MANAGE SCRIPT FAILURE +#================================================= -# Common variable declaration -app_id=headphones -app_user=headphones -app_local_host="127.0.0.1" -app_python_bin="/usr/bin/python" -## Destinations definitions -app_install_dir="/opt/yunohost/${app_id}" -app_data_dir="/home/yunohost.app/${app_id}" -app_logs_dir="/var/log/${app_id}" -app_config_file="${app_data_dir}/config.ini" -app_pid_file="/var/run/${app_id}/${app_id}.pid" -## Sources definitions -app_src_conf="$BASEDIR/conf/${app_id}.conf" -app_src_dfts="$BASEDIR/conf/${app_id}.defaults" -app_src_init="$BASEDIR/conf/${app_id}.init" -app_src_nginx_conf="$BASEDIR/conf/nginx.conf" +ynh_clean_setup () { + ### Remove this function if there's nothing to clean before calling the remove script. + true +} +# Exit if an error occurs during the execution of the script +ynh_abort_if_errors +#================================================= +# RETRIEVE ARGUMENTS FROM THE MANIFEST +#================================================= -# Check domain/path availability -sudo yunohost app checkurl $app_domain$app_path -a $app_id -if [[ ! $? -eq 0 ]]; then - exit 1 +domain=$YNH_APP_ARG_DOMAIN +path_url=$YNH_APP_ARG_PATH +is_public=$YNH_APP_ARG_IS_PUBLIC + +app=$YNH_APP_INSTANCE_NAME + +#================================================= +# CHECK IF THE APP CAN BE INSTALLED WITH THESE ARGS +#================================================= +ynh_script_progression --message="Validating installation parameters..." --time --weight=1 + +final_path=/var/www/$app +test ! -e "$final_path" || ynh_die --message="This path already contains a folder" + +# Register (book) web path +ynh_webpath_register --app=$app --domain=$domain --path_url=$path_url + +#================================================= +# STORE SETTINGS FROM MANIFEST +#================================================= +ynh_script_progression --message="Storing installation settings..." --time --weight=1 + +ynh_app_setting_set --app=$app --key=domain --value=$domain +ynh_app_setting_set --app=$app --key=path --value=$path_url + +#================================================= +# STANDARD MODIFICATIONS +#================================================= +# FIND AND OPEN A PORT +#================================================= +ynh_script_progression --message="Finding an available port..." --time --weight=1 + +# Find an available port +port=$(ynh_find_port --port=8181) +ynh_app_setting_set --app=$app --key=port --value=$port + +#================================================= +# INSTALL DEPENDENCIES +#================================================= +# ynh_script_progression --message="Installing dependencies..." --time --weight=1 + +# ynh_install_app_dependencies $pkg_dependencies + +#================================================= +# CREATE DEDICATED USER +#================================================= +ynh_script_progression --message="Configuring system user..." --time --weight=1 + +# Create a system user +ynh_system_user_create --username=$app --home_dir="$final_path" + +#================================================= +# DOWNLOAD, CHECK AND UNPACK SOURCE +#================================================= +ynh_script_progression --message="Setting up source files..." --time --weight=1 + +ynh_app_setting_set --app=$app --key=final_path --value=$final_path +# Download, check integrity, uncompress and patch the source from app.src +ynh_setup_source --dest_dir="$final_path" + +chmod 750 "$final_path" +chmod -R o-rwx "$final_path" +chown -R $app:www-data "$final_path" + +#================================================= +# NGINX CONFIGURATION +#================================================= +ynh_script_progression --message="Configuring NGINX web server..." --time --weight=1 + +# Create a dedicated NGINX config +ynh_add_nginx_config + +#================================================= +# CREATE DATA DIRECTORY +#================================================= +ynh_script_progression --message="Creating a data directory..." --time --weight=1 + +datadir=/home/yunohost.app/$app +ynh_app_setting_set --app=$app --key=datadir --value=$datadir + +mkdir -p $datadir + +chmod 750 "$datadir" +chmod -R o-rwx "$datadir" +chown -R $app:www-data "$datadir" + +#================================================= +# ADD A CONFIGURATION +#================================================= +ynh_script_progression --message="Adding a configuration file..." --time --weight=1 + +ynh_add_config --template="some_config_file" --destination="$final_path/some_config_file" + +chmod 400 "$final_path/some_config_file" +chown $app:$app "$final_path/some_config_file" + +#================================================= +# SETUP SYSTEMD +#================================================= +ynh_script_progression --message="Configuring a systemd service..." --time --weight=1 + +# Create a dedicated systemd config +ynh_add_systemd_config + +#================================================= +# GENERIC FINALIZATION +#================================================= +# SETUP LOGROTATE +#================================================= +ynh_script_progression --message="Configuring log rotation..." --time --weight=1 + +# Use logrotate to manage application logfile(s) +ynh_use_logrotate + +#================================================= +# INTEGRATE SERVICE IN YUNOHOST +#================================================= +ynh_script_progression --message="Integrating service in YunoHost..." --time --weight=1 + +yunohost service add $app --description="A short description of the app" --log="/var/log/$app/$app.log" + +#================================================= +# START SYSTEMD SERVICE +#================================================= +ynh_script_progression --message="Starting a systemd service..." --time --weight=1 + +# Start a systemd service +ynh_systemd_action --service_name=$app --action="start" --log_path="/var/log/$app/$app.log" + +#================================================= +# SETUP SSOWAT +#================================================= +ynh_script_progression --message="Configuring permissions..." --time --weight=1 + +# Make app public if necessary +if [ $is_public -eq 1 ] +then + ynh_permission_update --permission="main" --add="visitors" fi +#================================================= +# RELOAD NGINX +#================================================= +ynh_script_progression --message="Reloading NGINX web server..." --time --weight=1 -# Make install if localhost installation -if [[ $app_method == "LOCAL"* ]]; then +ynh_systemd_action --service_name=nginx --action=reload - # Check port availability - sudo yunohost app checkport $app_port - if [[ ! $? -eq 0 ]]; then - exit 1 - fi - - # Make directories - sudo mkdir -p $app_logs_dir - sudo mkdir -p $app_data_dir - sudo mkdir -p $app_install_dir - - # Install latest version of app using the fork - sudo apt-get install -y git-core - sudo git clone $app_fork $app_install_dir - - # Install dependencies (using virtualenv) - if [[ $(python --version 2>&1) != Python\ 2* ]]; then - app_python_bin=$app_install_dir/bin/python - sudo apt-get install -y python-pip python-virtualenv python-dev uwsgi uwsgi-plugin-python - sudo virtualenv $app_install_dir - sudo bash -c "source $app_install_dir/bin/activate && pip install cheetah" - fi - - # Create app user - id -u $app_user &>/dev/null || sudo useradd --home-dir $app_data_dir --shell /bin/false $app_user - - # Configure daemon - sudo sed -i "s@USERTOCHANGE@$app_user@g" $app_src_dfts - sudo sed -i "s@APPDIRTOCHANGE@$app_install_dir@g" $app_src_dfts - sudo sed -i "s@DATADIRTOCHANGE@$app_data_dir@g" $app_src_dfts - sudo sed -i "s@PIDFILETOCHANGE@$app_pid_file@g" $app_src_dfts - sudo sed -i "s@PYTBINTOCHANGE@$app_python_bin@g" $app_src_dfts - sudo sed -i "s@OPTSTOCHANGE@$app_config_file@g" $app_src_dfts - sudo sed -i "s@PORTTOCHANGE@$app_port@g" $app_src_dfts - sudo cp -a $app_src_dfts /etc/default/$app_id - sudo cp -a $app_src_init /etc/init.d/$app_id - - # Configure app - sudo sed -i "s@PATHTOCHANGE@$app_path@g" $app_src_conf - sudo sed -i "s@PORTTOCHANGE@$app_port@g" $app_src_conf - sudo sed -i "s@APPDIRTOCHANGE@$app_install_dir@g" $app_src_conf - sudo sed -i "s@LOGSDIRTOCHANGE@$app_logs_dir@g" $app_src_conf - sudo cp -a $app_src_conf $app_config_file - - # Configure specifics options - case "$app_opts" in - *"Transmission"*) - ref_file=$(sudo sed -n -e '/^CONFIG_DIR/ s/.*\= *//p' $(find /etc/default -name '*transmission*') | sed 's/["* ]//g')/settings.json - ref_field=(download-dir rpc-bind-address rpc-port rpc-url rpc-username rpc-password) - for i in ${ref_field[*]}; do ref_value+=$(sudo sed -n -e "/$i/ s/.*\: *//p" $ref_file | sed 's/["*,]//g'); done - ref_value=($ref_value) - sudo sed -i "s@download_torrent_dir =.*@download_torrent_dir = ${ref_value[0]}@g" $app_src_conf - sudo sed -i "s@transmission_host =.*@transmission_host = http://${ref_value[1]}:${ref_value[2]}${ref_value[3]}@g" $app_src_conf - sudo sed -i "s@transmission_username =.*@transmission_username = ${ref_value[4]}@g" $app_src_conf - sudo sed -i "s@transmission_password =.*@transmission_password = ${ref_value[5]}@g" $app_src_conf - sudo sed -i "s@torrent_downloader =.*@torrent_downloader = 1@g" $app_src_conf - sudo sed -i "s@keep_torrent_files =.*@keep_torrent_files = 1@g" $app_src_conf - sudo sed -i "s@prefer_torrents =.*@prefer_torrents = 1@g" $app_src_conf - sudo cp -a $app_src_conf $app_config_file - ;; - esac - - # Set rights - sudo chown -R $app_user $app_install_dir - sudo chown -R $app_user $app_data_dir - sudo chown -R $app_user $app_logs_dir - sudo chmod +x /etc/init.d/$app_id - sudo chmod +x -R $app_install_dir - sudo chmod +x -R $app_data_dir - sudo chmod +x -R $app_logs_dir - - # Add service to YunoHost's monitoring - sudo yunohost service add $app_id --log $app_logs_dir --status "ps aux | grep $app_id | grep -v grep" - - # Start daemon at boot - sudo update-rc.d $app_id defaults - - # Start service - sudo service $app_id start - - # Set proxy host variable - app_host="http://${app_local_host}:${app_port}${app_path%/}" - -fi +#================================================= +# END OF SCRIPT +#================================================= - -# Remove trailing "/" for next commands -app_path=${app_path%/} - -# Configure Nginx -sudo sed -i "s@PATHTOCHANGE@$app_path@g" $app_src_nginx_conf -sudo sed -i "s@HOSTTOCHANGE@$app_host@g" $app_src_nginx_conf -sudo cp $app_src_nginx_conf /etc/nginx/conf.d/$app_domain.d/$app_id.conf - -# If app is public, add url to SSOWat conf as skipped_uris -if [[ $app_public == "Yes" ]]; then - # unprotected_uris allows SSO credentials to be passed anyway. - sudo yunohost app setting $app_id unprotected_uris -v "/" -fi - -# Save app settings -sudo yunohost app setting $app_id public -v "$app_public" -sudo yunohost app setting $app_id method -v "$app_method" -sudo yunohost app setting $app_id host -v "$app_host" - -# Reload Nginx and regenerate SSOwat conf -sudo service nginx reload -sudo yunohost app ssowatconf +ynh_script_progression --message="Installation of $app completed" --time --last diff --git a/scripts/remove b/scripts/remove index 9d8485f..491796a 100644 --- a/scripts/remove +++ b/scripts/remove @@ -1,56 +1,102 @@ #!/bin/bash -# Common variable declaration -app_id=headphones -app_user=headphones -app_install_dir="/opt/yunohost/${app_id}" -app_data_dir="/home/yunohost.app/${app_id}" -app_logs_dir="/var/log/${app_id}" +#================================================= +# GENERIC START +#================================================= +# IMPORT GENERIC HELPERS +#================================================= -# Retrieve arguments -app_method="$(sudo yunohost app setting ${app_id} method)" -app_domain="$(sudo yunohost app setting ${app_id} domain)" -keep_data=$1 +source _common.sh +source /usr/share/yunohost/helpers +#================================================= +# LOAD SETTINGS +#================================================= +ynh_script_progression --message="Loading installation settings..." --time --weight=1 -# Remove files if localhost installation -if [[ $app_method == "LOCAL"* ]]; then +app=$YNH_APP_INSTANCE_NAME - # Kill app and remove from boot - sudo service $app_id stop - sudo killall $app_id - sudo update-rc.d $app_id remove - - # Delete app user - sudo deluser $app_user - - # Remove sources - sudo rm -rf $app_install_dir +domain=$(ynh_app_setting_get --app=$app --key=domain) +port=$(ynh_app_setting_get --app=$app --key=port) +final_path=$(ynh_app_setting_get --app=$app --key=final_path) +datadir=$(ynh_app_setting_get --app=$app --key=datadir) - # Remove logs - if [[ $app_logs_dir != "$app_data_dir"* ]]; then - sudo rm -rf $app_logs_dir - fi - - # Remove data - if [[ $keep_data == "No" ]]; then - sudo rm -rf $app_data_dir - fi - - # Remove daemon config - sudo rm -f /etc/init.d/$app_id - sudo rm -f /etc/default/$app_id - sudo rm -rf /var/run/$app_id +#================================================= +# STANDARD REMOVE +#================================================= +# REMOVE SERVICE INTEGRATION IN YUNOHOST +#================================================= +# Remove the service from the list of services known by YunoHost (added from `yunohost service add`) +if ynh_exec_warn_less yunohost service status $app >/dev/null +then + ynh_script_progression --message="Removing $app service integration..." --time --weight=1 + yunohost service remove $app fi +#================================================= +# STOP AND REMOVE SERVICE +#================================================= +ynh_script_progression --message="Stopping and removing the systemd service..." --time --weight=1 -# Remove Nginx parameters -sudo rm -f /etc/nginx/conf.d/$app_domain.d/$app_id.conf +# Remove the dedicated systemd config +ynh_remove_systemd_config -# Remove Yunohost service -sudo yunohost service remove $app_id +#================================================= +# REMOVE LOGROTATE CONFIGURATION +#================================================= +ynh_script_progression --message="Removing logrotate configuration..." --time --weight=1 -# Reload Nginx and update Yunohost -sudo service nginx reload -sudo yunohost app ssowatconf \ No newline at end of file +# Remove the app-specific logrotate config +ynh_remove_logrotate + +#================================================= +# REMOVE APP MAIN DIR +#================================================= +ynh_script_progression --message="Removing app main directory..." --time --weight=1 + +# Remove the app directory securely +ynh_secure_remove --file="$final_path" + +#================================================= +# REMOVE DATA DIR +#================================================= + +# Remove the data directory if --purge option is used +if [ "${YNH_APP_PURGE:-0}" -eq 1 ] +then + ynh_script_progression --message="Removing app data directory..." --time --weight=1 + ynh_secure_remove --file="$datadir" +fi + +#================================================= +# REMOVE NGINX CONFIGURATION +#================================================= +ynh_script_progression --message="Removing NGINX web server configuration..." --time --weight=1 + +# Remove the dedicated NGINX config +ynh_remove_nginx_config + +#================================================= +# REMOVE DEPENDENCIES +#================================================= +# ynh_script_progression --message="Removing dependencies..." --time --weight=1 + +# # Remove metapackage and its dependencies +# ynh_remove_app_dependencies + +#================================================= +# GENERIC FINALIZATION +#================================================= +# REMOVE DEDICATED USER +#================================================= +ynh_script_progression --message="Removing the dedicated system user..." --time --weight=1 + +# Delete a system user +ynh_system_user_delete --username=$app + +#================================================= +# END OF SCRIPT +#================================================= + +ynh_script_progression --message="Removal of $app completed" --time --last From e4fa0c217ab40352251aa13fa57f6fff5a030c08 Mon Sep 17 00:00:00 2001 From: yunohost-bot Date: Tue, 15 Mar 2022 07:42:04 +0000 Subject: [PATCH 02/10] Auto-update README --- README.md | 76 +++++++++++++++++++++++++--------------------------- README_fr.md | 39 +++++++++++++++++++++++++++ 2 files changed, 75 insertions(+), 40 deletions(-) create mode 100644 README_fr.md diff --git a/README.md b/README.md index 98fdb9e..59f9430 100644 --- a/README.md +++ b/README.md @@ -1,47 +1,43 @@ -## headphones_ynh + -[![Latest Version](https://img.shields.io/badge/version-_--_-green.svg?style=flat)](https://github.com/Snipees/headphones_ynh/releases) -[![Status](https://img.shields.io/badge/status-in_progress-yellow.svg?style=flat)](https://github.com/Snipees/headphones_ynh/milestones) -[![Dependencies](https://img.shields.io/badge/dependencies-includes-lightgrey.svg?style=flat)](https://github.com/Snipees/headphones_ynh#dependencies) -[![GitHub license](https://img.shields.io/badge/license-GPLv3-blue.svg?style=flat)](https://raw.githubusercontent.com/Snipees/headphones_ynh/master/LICENSE) -[![Yunohost version](https://img.shields.io/badge/yunohost-2.2.0_tested-orange.svg?style=flat)](https://github.com/YunoHost/yunohost) -[![GitHub issues](https://img.shields.io/github/issues/Snipees/headphones_ynh.svg?style=flat)](https://github.com/Snipees/headphones_ynh/issues) - -[ **Headphones Integration for Yunohost** ] -This install script uses a Git-fork as sources for a local installation. -Otherwise the script sets a reverse-proxy to a remote instance. +# Headphones for YunoHost + +[![Integration level](https://dash.yunohost.org/integration/headphones.svg)](https://dash.yunohost.org/appci/app/headphones) ![](https://ci-apps.yunohost.org/ci/badges/headphones.status.svg) ![](https://ci-apps.yunohost.org/ci/badges/headphones.maintain.svg) +[![Install Headphones with YunoHost](https://install-app.yunohost.org/install-with-yunohost.svg)](https://install-app.yunohost.org/?app=headphones) + +*[Lire ce readme en français.](./README_fr.md)* + +> *This package allows you to install Headphones quickly and simply on a YunoHost server. +If you don't have YunoHost, please consult [the guide](https://yunohost.org/#/install) to learn how to install it.* + +## Overview + +Automated music downloader for NZB and Torrent + +**Shipped version:** 0.6.0~ynh1 -### How to install: -- Use **Install software** option from Yunohost admin panel -- Find textbox tagged as **Install custom App from github** -- Copy and paste: https://github.com/YunoHost-Apps/headphones_ynh -- Choose the method installation: *local* or *remote* (as described above) -- Answer the required questions to the selected method +## Documentation and resources -### More information about: -- Headphones : https://github.com/rembo10/headphones -- Yunohost : https://yunohost.org +* Official app website: https://github.com/rembo10/headphones +* Official user documentation: https://github.com/rembo10/headphones/wiki/Usage-guide +* Upstream app code repository: https://github.com/rembo10/headphones +* YunoHost documentation for this app: https://yunohost.org/app_headphones +* Report a bug: https://github.com/YunoHost-Apps/headphones_ynh/issues +## Developer info -#### Special Thanks to the Yunohost Community: -[anaqreon](https://github.com/anaqreon), -[aymhce](https://github.com/aymhce), -[beudbeud](https://github.com/abeudin), -[Chao-Man](https://github.com/Chao-Man), -[chtixof](https://github.com/chtixof), -[CotzaDev](https://github.com/CotzaDev), -[courgette](https://github.com/courgette), -[Jérôme](https://github.com/jeromelebleu), -[JocelynD](https://github.com/JocelynDelalande), -[Ju](https://github.com/julienmalik), -[Le Kload](https://github.com/Kloadut), -[lunarok](https://github.com/lunarok), -[maniackcrudelis](https://github.com/maniackcrudelis), -[Matlink](https://github.com/matlink), -[Moul](https://github.com/M5oul), -[polytan02](https://github.com/polytan02), -[scith](https://github.com/scith), -[tifred](https://github.com/drfred1981), -... :dizzy: +Please send your pull request to the [testing branch](https://github.com/YunoHost-Apps/headphones_ynh/tree/testing). + +To try the testing branch, please proceed like that. +``` +sudo yunohost app install https://github.com/YunoHost-Apps/headphones_ynh/tree/testing --debug +or +sudo yunohost app upgrade headphones -u https://github.com/YunoHost-Apps/headphones_ynh/tree/testing --debug +``` + +**More info regarding app packaging:** https://yunohost.org/packaging_apps \ No newline at end of file diff --git a/README_fr.md b/README_fr.md new file mode 100644 index 0000000..9d1f70b --- /dev/null +++ b/README_fr.md @@ -0,0 +1,39 @@ +# Headphones pour YunoHost + +[![Niveau d'intégration](https://dash.yunohost.org/integration/headphones.svg)](https://dash.yunohost.org/appci/app/headphones) ![](https://ci-apps.yunohost.org/ci/badges/headphones.status.svg) ![](https://ci-apps.yunohost.org/ci/badges/headphones.maintain.svg) +[![Installer Headphones avec YunoHost](https://install-app.yunohost.org/install-with-yunohost.svg)](https://install-app.yunohost.org/?app=headphones) + +*[Read this readme in english.](./README.md)* +*[Lire ce readme en français.](./README_fr.md)* + +> *Ce package vous permet d'installer Headphones rapidement et simplement sur un serveur YunoHost. +Si vous n'avez pas YunoHost, regardez [ici](https://yunohost.org/#/install) pour savoir comment l'installer et en profiter.* + +## Vue d'ensemble + +Automated music downloader for NZB and Torrent + +**Version incluse :** 0.6.0~ynh1 + + + +## Documentations et ressources + +* Site officiel de l'app : https://github.com/rembo10/headphones +* Documentation officielle utilisateur : https://github.com/rembo10/headphones/wiki/Usage-guide +* Dépôt de code officiel de l'app : https://github.com/rembo10/headphones +* Documentation YunoHost pour cette app : https://yunohost.org/app_headphones +* Signaler un bug : https://github.com/YunoHost-Apps/headphones_ynh/issues + +## Informations pour les développeurs + +Merci de faire vos pull request sur la [branche testing](https://github.com/YunoHost-Apps/headphones_ynh/tree/testing). + +Pour essayer la branche testing, procédez comme suit. +``` +sudo yunohost app install https://github.com/YunoHost-Apps/headphones_ynh/tree/testing --debug +ou +sudo yunohost app upgrade headphones -u https://github.com/YunoHost-Apps/headphones_ynh/tree/testing --debug +``` + +**Plus d'infos sur le packaging d'applications :** https://yunohost.org/packaging_apps \ No newline at end of file From 0f2b06b5d65563fceaa0cb2e6b6556fcee0c5ce5 Mon Sep 17 00:00:00 2001 From: ericgaspar Date: Tue, 15 Mar 2022 08:43:43 +0100 Subject: [PATCH 03/10] fix --- scripts/_common.sh | 20 ++++++++++++++++++++ scripts/install | 8 ++++---- 2 files changed, 24 insertions(+), 4 deletions(-) create mode 100644 scripts/_common.sh diff --git a/scripts/_common.sh b/scripts/_common.sh new file mode 100644 index 0000000..7e55ac0 --- /dev/null +++ b/scripts/_common.sh @@ -0,0 +1,20 @@ +#!/bin/bash + +#================================================= +# COMMON VARIABLES +#================================================= + +# dependencies used by the app +pkg_dependencies="deb1 deb2 php$YNH_DEFAULT_PHP_VERSION-deb1 php$YNH_DEFAULT_PHP_VERSION-deb2" + +#================================================= +# PERSONAL HELPERS +#================================================= + +#================================================= +# EXPERIMENTAL HELPERS +#================================================= + +#================================================= +# FUTURE OFFICIAL HELPERS +#================================================= diff --git a/scripts/install b/scripts/install index 95c7ca0..c3843e2 100644 --- a/scripts/install +++ b/scripts/install @@ -113,12 +113,12 @@ chown -R $app:www-data "$datadir" #================================================= # ADD A CONFIGURATION #================================================= -ynh_script_progression --message="Adding a configuration file..." --time --weight=1 +# ynh_script_progression --message="Adding a configuration file..." --time --weight=1 -ynh_add_config --template="some_config_file" --destination="$final_path/some_config_file" +# ynh_add_config --template="some_config_file" --destination="$final_path/some_config_file" -chmod 400 "$final_path/some_config_file" -chown $app:$app "$final_path/some_config_file" +# chmod 400 "$final_path/some_config_file" +# chown $app:$app "$final_path/some_config_file" #================================================= # SETUP SYSTEMD From ce0b130b136808919d093e99906a158f658eabe8 Mon Sep 17 00:00:00 2001 From: ericgaspar Date: Tue, 15 Mar 2022 08:59:42 +0100 Subject: [PATCH 04/10] Fix --- conf/headphones.defaults | 16 ++++++++-------- scripts/install | 9 +++++---- 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/conf/headphones.defaults b/conf/headphones.defaults index 585501d..cc7df5e 100644 --- a/conf/headphones.defaults +++ b/conf/headphones.defaults @@ -5,11 +5,11 @@ ## add HP_USER=username to /etc/default/headphones ## otherwise default headphones is used -HP_USER=USERTOCHANGE #$RUN_AS, username to run headphones under, the default is headphones -HP_HOME=APPDIRTOCHANGE #$APP_PATH, the location of Headphones.py, the default is /opt/headphones -HP_DATA=DATADIRTOCHANGE #$DATA_DIR, the location of headphones.db, cache, logs, the default is /opt/headphones -HP_PIDFILE=PIDFILETOCHANGE #$PID_FILE, the location of headphones.pid, the default is /var/run/headphones/headphones.pid -PYTHON_BIN=PYTBINTOCHANGE #$DAEMON, the location of the python binary, the default is /usr/bin/python -HP_OPTS=" --config=OPTSTOCHANGE" #$EXTRA_DAEMON_OPTS, extra cli option for headphones, i.e. " --config=/home/headphones/config.ini" -#SSD_OPTS=SSDTOCHANGE #$EXTRA_SSD_OPTS, extra start-stop-daemon option like " --group=users" -HP_PORT=PORTTOCHANGE #$PORT_OPTS, hardcoded port for the webserver, overrides value in config.ini +HP_USER=__APP__ #$RUN_AS, username to run headphones under, the default is headphones +HP_HOME=__FINALPATH__ #$APP_PATH, the location of Headphones.py, the default is /opt/headphones +HP_DATA=__DATADIR__ #$DATA_DIR, the location of headphones.db, cache, logs, the default is /opt/headphones +#HP_PIDFILE=PIDFILETOCHANGE #$PID_FILE, the location of headphones.pid, the default is /var/run/headphones/headphones.pid +#PYTHON_BIN=/usr/bin/python3 #$DAEMON, the location of the python binary, the default is /usr/bin/python +#HP_OPTS=" --config=OPTSTOCHANGE" #$EXTRA_DAEMON_OPTS, extra cli option for headphones, i.e. " --config=/home/headphones/config.ini" +#SSD_OPTS=SSDTOCHANGE #$EXTRA_SSD_OPTS, extra start-stop-daemon option like " --group=users" +HP_PORT=__PORT__ #$PORT_OPTS, hardcoded port for the webserver, overrides value in config.ini diff --git a/scripts/install b/scripts/install index c3843e2..f682b45 100644 --- a/scripts/install +++ b/scripts/install @@ -87,6 +87,7 @@ ynh_setup_source --dest_dir="$final_path" chmod 750 "$final_path" chmod -R o-rwx "$final_path" chown -R $app:www-data "$final_path" +chmod +x "$final_path/Headphones.py" #================================================= # NGINX CONFIGURATION @@ -113,12 +114,12 @@ chown -R $app:www-data "$datadir" #================================================= # ADD A CONFIGURATION #================================================= -# ynh_script_progression --message="Adding a configuration file..." --time --weight=1 +ynh_script_progression --message="Adding a configuration file..." --time --weight=1 -# ynh_add_config --template="some_config_file" --destination="$final_path/some_config_file" +ynh_add_config --template="../conf/headphones.defaults" --destination="/etc/default/headphones" -# chmod 400 "$final_path/some_config_file" -# chown $app:$app "$final_path/some_config_file" +#chmod 400 "$final_path/some_config_file" +#chown $app:$app "$final_path/some_config_file" #================================================= # SETUP SYSTEMD From 478404afc5e527a21bb3c9cbb4780fbe9c107d78 Mon Sep 17 00:00:00 2001 From: ericgaspar Date: Tue, 15 Mar 2022 09:23:11 +0100 Subject: [PATCH 05/10] Update install --- scripts/install | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/install b/scripts/install index f682b45..b96c10b 100644 --- a/scripts/install +++ b/scripts/install @@ -118,8 +118,8 @@ ynh_script_progression --message="Adding a configuration file..." --time --weigh ynh_add_config --template="../conf/headphones.defaults" --destination="/etc/default/headphones" -#chmod 400 "$final_path/some_config_file" -#chown $app:$app "$final_path/some_config_file" +#chmod 400 "/etc/default/headphones" +#chown $app:$app "/etc/default/headphones" #================================================= # SETUP SYSTEMD From 11bcf20f19b2cc8730c33a75a1dabf06450f998a Mon Sep 17 00:00:00 2001 From: yalh76 Date: Thu, 24 Mar 2022 00:32:11 +0100 Subject: [PATCH 06/10] Apply last example_ynh --- .github/ISSUE_TEMPLATE.md | 55 +++++ .github/PULL_REQUEST_TEMPLATE.md | 16 ++ LICENSE | 8 +- README_fr.md | 39 ---- check_process | 21 ++ conf/headphones.conf | 233 -------------------- conf/headphones.defaults | 15 -- conf/headphones.ini | 360 +++++++++++++++++++++++++++++++ conf/headphones.init | 209 ------------------ conf/nginx.conf | 16 +- conf/systemd.service | 9 +- doc/.gitkeep | 0 doc/DESCRIPTION.md | 1 + doc/DISCLAIMER.md | 0 doc/screenshots/.gitkeep | 0 doc/screenshots/screenshot01.png | Bin 0 -> 144288 bytes manifest.json | 11 +- scripts/_common.sh | 2 +- scripts/backup | 98 ++++++--- scripts/change_url | 143 ++++++++++++ scripts/install | 67 +++--- scripts/remove | 38 ++-- scripts/restore | 181 ++++++++++++---- scripts/upgrade | 208 +++++++++++++----- 24 files changed, 1042 insertions(+), 688 deletions(-) create mode 100644 .github/ISSUE_TEMPLATE.md create mode 100644 .github/PULL_REQUEST_TEMPLATE.md delete mode 100644 README_fr.md create mode 100644 check_process delete mode 100644 conf/headphones.conf delete mode 100644 conf/headphones.defaults create mode 100644 conf/headphones.ini delete mode 100644 conf/headphones.init create mode 100644 doc/.gitkeep create mode 100644 doc/DESCRIPTION.md create mode 100644 doc/DISCLAIMER.md create mode 100644 doc/screenshots/.gitkeep create mode 100644 doc/screenshots/screenshot01.png create mode 100644 scripts/change_url diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md new file mode 100644 index 0000000..2729a6b --- /dev/null +++ b/.github/ISSUE_TEMPLATE.md @@ -0,0 +1,55 @@ +--- +name: Bug report +about: When creating a bug report, please use the following template to provide all the relevant information and help debugging efficiently. + +--- + +**How to post a meaningful bug report** +1. *Read this whole template first.* +2. *Determine if you are on the right place:* + - *If you were performing an action on the app from the webadmin or the CLI (install, update, backup, restore, change_url...), you are on the right place!* + - *Otherwise, the issue may be due to the app itself. Refer to its documentation or repository for help.* + - *When in doubt, post here and we will figure it out together.* +3. *Delete the italic comments as you write over them below, and remove this guide.* +--- + +### Describe the bug + +*A clear and concise description of what the bug is.* + +### Context + +- Hardware: *VPS bought online / Old laptop or computer / Raspberry Pi at home / Internet Cube with VPN / Other ARM board / ...* +- YunoHost version: x.x.x +- I have access to my server: *Through SSH | through the webadmin | direct access via keyboard / screen | ...* +- Are you in a special context or did you perform some particular tweaking on your YunoHost instance?: *no / yes* + - If yes, please explain: +- Using, or trying to install package version/branch: +- If upgrading, current package version: *can be found in the admin, or with `yunohost app info $app_id`* + +### Steps to reproduce + +- *If you performed a command from the CLI, the command itself is enough. For example:* + ```sh + sudo yunohost app install the_app + ``` +- *If you used the webadmin, please perform the equivalent command from the CLI first.* +- *If the error occurs in your browser, explain what you did:* + 1. *Go to '...'* + 2. *Click on '...'* + 3. *Scroll down to '...'* + 4. *See error* + +### Expected behavior + +*A clear and concise description of what you expected to happen. You can remove this section if the command above is enough to understand your intent.* + +### Logs + +*When an operation fails, YunoHost provides a simple way to share the logs.* +- *In the webadmin, the error message contains a link to the relevant log page. On that page, you will be able to 'Share with Yunopaste'. If you missed it, the logs of previous operations are also available under Tools > Logs.* +- *In command line, the command to share the logs is displayed at the end of the operation and looks like `yunohost log display [log name] --share`. If you missed it, you can find the log ID of a previous operation using `yunohost log list`.* + +*After sharing the log, please copypaste directly the link provided by YunoHost (to help readability, no need to copypaste the entire content of the log here, just the link is enough...)* + +*If applicable and useful, add screenshots to help explain your problem.* diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 0000000..ef70e18 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,16 @@ +## Problem + +- *Description of why you made this PR* + +## Solution + +- *And how do you fix that problem* + +## PR Status + +- [ ] Code finished and ready to be reviewed/tested +- [ ] The fix/enhancement were manually tested (if applicable) + +## Automatic tests + +Automatic tests can be triggered on https://ci-apps-dev.yunohost.org/ *after creating the PR*, by commenting "!testme", "!gogogadgetoci" or "By the power of systemd, I invoke The Great App CI to test this Pull Request!". (N.B. : for this to work you need to be a member of the Yunohost-Apps organization) diff --git a/LICENSE b/LICENSE index 55b5b7e..94a9ed0 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,4 @@ - GNU GENERAL PUBLIC LICENSE + GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (C) 2007 Free Software Foundation, Inc. @@ -631,8 +631,8 @@ to attach them to the start of each source file to most effectively state the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. - {one line to give the program's name and a brief idea of what it does.} - Copyright (C) {year} {name of author} + + Copyright (C) This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -652,7 +652,7 @@ Also add information on how to contact you by electronic and paper mail. If the program does terminal interaction, make it output a short notice like this when it starts in an interactive mode: - {project} Copyright (C) {year} {fullname} + Copyright (C) This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. diff --git a/README_fr.md b/README_fr.md deleted file mode 100644 index 9d1f70b..0000000 --- a/README_fr.md +++ /dev/null @@ -1,39 +0,0 @@ -# Headphones pour YunoHost - -[![Niveau d'intégration](https://dash.yunohost.org/integration/headphones.svg)](https://dash.yunohost.org/appci/app/headphones) ![](https://ci-apps.yunohost.org/ci/badges/headphones.status.svg) ![](https://ci-apps.yunohost.org/ci/badges/headphones.maintain.svg) -[![Installer Headphones avec YunoHost](https://install-app.yunohost.org/install-with-yunohost.svg)](https://install-app.yunohost.org/?app=headphones) - -*[Read this readme in english.](./README.md)* -*[Lire ce readme en français.](./README_fr.md)* - -> *Ce package vous permet d'installer Headphones rapidement et simplement sur un serveur YunoHost. -Si vous n'avez pas YunoHost, regardez [ici](https://yunohost.org/#/install) pour savoir comment l'installer et en profiter.* - -## Vue d'ensemble - -Automated music downloader for NZB and Torrent - -**Version incluse :** 0.6.0~ynh1 - - - -## Documentations et ressources - -* Site officiel de l'app : https://github.com/rembo10/headphones -* Documentation officielle utilisateur : https://github.com/rembo10/headphones/wiki/Usage-guide -* Dépôt de code officiel de l'app : https://github.com/rembo10/headphones -* Documentation YunoHost pour cette app : https://yunohost.org/app_headphones -* Signaler un bug : https://github.com/YunoHost-Apps/headphones_ynh/issues - -## Informations pour les développeurs - -Merci de faire vos pull request sur la [branche testing](https://github.com/YunoHost-Apps/headphones_ynh/tree/testing). - -Pour essayer la branche testing, procédez comme suit. -``` -sudo yunohost app install https://github.com/YunoHost-Apps/headphones_ynh/tree/testing --debug -ou -sudo yunohost app upgrade headphones -u https://github.com/YunoHost-Apps/headphones_ynh/tree/testing --debug -``` - -**Plus d'infos sur le packaging d'applications :** https://yunohost.org/packaging_apps \ No newline at end of file diff --git a/check_process b/check_process new file mode 100644 index 0000000..56a84c7 --- /dev/null +++ b/check_process @@ -0,0 +1,21 @@ +;; Test complet + ; Manifest + domain="domain.tld" + path="/path" + is_public=1 + ; Checks + pkg_linter=1 + setup_sub_dir=1 + setup_root=1 + setup_nourl=0 + setup_private=1 + setup_public=1 + upgrade=1 + upgrade=1 from_commit=CommitHash + backup_restore=1 + multi_instance=1 + port_already_use=0 + change_url=1 +;;; Options +Email= +Notification=none diff --git a/conf/headphones.conf b/conf/headphones.conf deleted file mode 100644 index e1bdf71..0000000 --- a/conf/headphones.conf +++ /dev/null @@ -1,233 +0,0 @@ -[General] -config_version = 5 -http_port = PORTTOCHANGE -http_host = 0.0.0.0 -http_username = "" -http_password = "" -http_root = PATHTOCHANGE -http_proxy = 0 -enable_https = 0 -https_cert = "" -https_key = "" -launch_browser = 1 -api_enabled = 0 -api_key = "" -log_dir = LOGSDIRTOCHANGE -cache_dir = APPDIRTOCHANGE/cache -git_path = "" -git_user = rembo10 -git_branch = master -do_not_override_git_branch = 0 -check_github = 1 -check_github_on_startup = 1 -check_github_interval = 360 -music_dir = "" -destination_dir = "" -lossless_destination_dir = "" -preferred_quality = 0 -preferred_bitrate = "" -preferred_bitrate_high_buffer = "" -preferred_bitrate_low_buffer = "" -preferred_bitrate_allow_lossless = 0 -detect_bitrate = 0 -lossless_bitrate_from = "" -lossless_bitrate_to = "" -auto_add_artists = 1 -correct_metadata = 0 -move_files = 0 -rename_files = 0 -folder_format = $Artist/$Album [$Year] -file_format = $Track $Artist - $Album [$Year] - $Title -file_underscores = 0 -cleanup_files = 0 -keep_nfo = 0 -add_album_art = 0 -album_art_format = folder -embed_album_art = 0 -embed_lyrics = 0 -replace_existing_folders = 0 -nzb_downloader = 0 -torrent_downloader = 0 -download_dir = "" -blackhole_dir = "" -usenet_retention = 1500 -include_extras = 0 -extras = "" -autowant_upcoming = 1 -autowant_all = 0 -keep_torrent_files = 0 -prefer_torrents = 0 -open_magnet_links = False -numberofseeders = 10 -torrentblackhole_dir = "" -download_torrent_dir = "" -search_interval = 1440 -libraryscan = 1 -libraryscan_interval = 300 -download_scan_interval = 5 -update_db_interval = 24 -mb_ignore_age = 365 -preferred_words = "" -ignored_words = "" -required_words = "" -lastfm_username = "" -interface = default -folder_permissions = 0755 -file_permissions = 0644 -music_encoder = 0 -encoder = ffmpeg -xldprofile = "" -bitrate = 192 -samplingfrequency = 44100 -encoder_path = "" -advancedencoder = "" -encoderoutputformat = mp3 -encoderquality = 2 -encodervbrcbr = cbr -encoderlossless = 1 -encoder_multicore = 0 -encoder_multicore_count = 0 -delete_lossless_files = 1 -mirror = musicbrainz.org -customhost = localhost -customport = 5000 -customsleep = 1 -hpuser = "" -hppass = "" -[Kat] -kat = 0 -kat_proxy_url = "" -kat_ratio = "" -[Mininova] -mininova = 0 -mininova_ratio = "" -[Piratebay] -piratebay = 0 -piratebay_proxy_url = "" -piratebay_ratio = "" -[Waffles] -waffles = 0 -waffles_uid = "" -waffles_passkey = "" -waffles_ratio = "" -[Rutracker] -rutracker = 0 -rutracker_user = "" -rutracker_password = "" -rutracker_ratio = "" -[What.cd] -whatcd = 0 -whatcd_username = "" -whatcd_password = "" -whatcd_ratio = "" -[SABnzbd] -sab_host = "" -sab_username = "" -sab_password = "" -sab_apikey = "" -sab_category = "" -[NZBget] -nzbget_username = nzbget -nzbget_password = "" -nzbget_category = "" -nzbget_host = "" -nzbget_priority = 0 -[Headphones] -headphones_indexer = 0 -[Transmission] -transmission_host = "" -transmission_username = "" -transmission_password = "" -[uTorrent] -utorrent_host = "" -utorrent_username = "" -utorrent_password = "" -utorrent_label = "" -[Newznab] -newznab = 0 -newznab_host = "" -newznab_apikey = "" -newznab_enabled = 1 -extra_newznabs = , -[NZBsorg] -nzbsorg = 0 -nzbsorg_uid = "" -nzbsorg_hash = "" -[omgwtfnzbs] -omgwtfnzbs = 0 -omgwtfnzbs_uid = "" -omgwtfnzbs_apikey = "" -[Growl] -growl_enabled = 0 -growl_host = "" -growl_password = "" -growl_onsnatch = 0 -[Prowl] -prowl_enabled = 0 -prowl_keys = "" -prowl_onsnatch = 0 -prowl_priority = 0 -[XBMC] -xbmc_enabled = 0 -xbmc_host = "" -xbmc_username = "" -xbmc_password = "" -xbmc_update = 0 -xbmc_notify = 0 -[LMS] -lms_enabled = 0 -lms_host = "" -[Plex] -plex_enabled = 0 -plex_server_host = "" -plex_client_host = "" -plex_username = "" -plex_password = "" -plex_update = 0 -plex_notify = 0 -[NMA] -nma_enabled = 0 -nma_apikey = "" -nma_priority = 0 -nma_onsnatch = 0 -[Pushalot] -pushalot_enabled = 0 -pushalot_apikey = "" -pushalot_onsnatch = 0 -[Pushover] -pushover_enabled = 0 -pushover_keys = "" -pushover_onsnatch = 0 -pushover_priority = 0 -pushover_apitoken = "" -[PushBullet] -pushbullet_enabled = 0 -pushbullet_apikey = "" -pushbullet_deviceid = "" -pushbullet_onsnatch = 0 -[Twitter] -twitter_enabled = 0 -twitter_onsnatch = 0 -twitter_username = "" -twitter_password = "" -twitter_prefix = Headphones -[OSX_Notify] -osx_notify_enabled = 0 -osx_notify_onsnatch = 0 -osx_notify_app = /Applications/Headphones -[Boxcar] -boxcar_enabled = 0 -boxcar_onsnatch = 0 -boxcar_token = "" -[Songkick] -songkick_enabled = 1 -songkick_apikey = nd1We7dFW2RqxPw8 -songkick_location = "" -songkick_filter_enabled = 0 -[Synoindex] -synoindex_enabled = 0 -[Advanced] -album_completion_pct = 80 -cache_sizemb = 32 -journal_mode = wal -verify_ssl_cert = 1 diff --git a/conf/headphones.defaults b/conf/headphones.defaults deleted file mode 100644 index cc7df5e..0000000 --- a/conf/headphones.defaults +++ /dev/null @@ -1,15 +0,0 @@ -# COPY THIS FILE TO /etc/default/headphones -# OPTIONS: HP_HOME, HP_USER, HP_DATA, HP_PIDFILE, PYTHON_BIN, HP_OPTS, SSD_OPTS, HP_PORT - -## EXAMPLE if want to run as different user -## add HP_USER=username to /etc/default/headphones -## otherwise default headphones is used - -HP_USER=__APP__ #$RUN_AS, username to run headphones under, the default is headphones -HP_HOME=__FINALPATH__ #$APP_PATH, the location of Headphones.py, the default is /opt/headphones -HP_DATA=__DATADIR__ #$DATA_DIR, the location of headphones.db, cache, logs, the default is /opt/headphones -#HP_PIDFILE=PIDFILETOCHANGE #$PID_FILE, the location of headphones.pid, the default is /var/run/headphones/headphones.pid -#PYTHON_BIN=/usr/bin/python3 #$DAEMON, the location of the python binary, the default is /usr/bin/python -#HP_OPTS=" --config=OPTSTOCHANGE" #$EXTRA_DAEMON_OPTS, extra cli option for headphones, i.e. " --config=/home/headphones/config.ini" -#SSD_OPTS=SSDTOCHANGE #$EXTRA_SSD_OPTS, extra start-stop-daemon option like " --group=users" -HP_PORT=__PORT__ #$PORT_OPTS, hardcoded port for the webserver, overrides value in config.ini diff --git a/conf/headphones.ini b/conf/headphones.ini new file mode 100644 index 0000000..88db4cc --- /dev/null +++ b/conf/headphones.ini @@ -0,0 +1,360 @@ +[General] +add_album_art = 0 +advancedencoder = +album_art_format = folder +album_art_min_width = +album_art_max_width = +api_enabled = 0 +api_key = +autowant_all = 0 +autowant_manually_added = 1 +autowant_upcoming = 1 +auto_add_artists = 1 +bitrate = 192 +blackhole = 0 +blackhole_dir = +cache_dir = __DATADIR__/cache +check_github = 0 +check_github_interval = 360 +check_github_on_startup = 0 +cleanup_files = 0 +config_version = 6 +correct_metadata = 0 +cue_split = 1 +cue_split_flac_path = +cue_split_shntool_path = +customauth = 0 +customhost = localhost +custompass = +customport = 5000 +customsleep = 1 +customuser = +delete_lossless_files = 1 +destination_dir = +detect_bitrate = 0 +do_not_process_unmatched = 0 +download_dir = +download_scan_interval = 5 +download_torrent_dir = +do_not_override_git_branch = 0 +embed_album_art = 0 +embed_lyrics = 0 +enable_https = 0 +encoder = ffmpeg +encoderfolder = +encoderlossless = 1 +encoderoutputformat = mp3 +encoderquality = 2 +encodervbrcbr = cbr +encoder_multicore = 0 +encoder_multicore_count = 0 +encoder_path = +extras = +file_format = $Track $Artist - $Album [$Year] - $Title +file_permissions = 0644 +file_permissions_enabled = True +file_underscores = 0 +folder_format = $Artist/$Album [$Year] +folder_permissions_enabled = True +folder_permissions = 0755 +freeze_db = 0 +git_branch = master +git_path = +git_user = rembo10 +headphones_indexer = 0 +hppass = +hpuser = +https_cert = +https_key = +http_host = localhost +http_password = +http_port = __PORT__ +http_proxy = 0 +http_root = __PATH_URL__ +http_username = +ignore_clean_releases = 0 +ignored_words = +include_extras = 0 +interface = default +keep_nfo = 0 +keep_torrent_files = 0 +keep_torrent_files_dir = +lastfm_username = +launch_browser = 1 +libraryscan = 1 +libraryscan_interval = 24 +log_dir = /var/log/__APP__ +lossless_bitrate_from = 0 +lossless_bitrate_to = 0 +lossless_destination_dir = +mb_ignore_age = 365 +mb_ignore_age_missing = 0 +mirror = musicbrainz.org +move_files = 0 +music_dir = +music_encoder = 0 +numberofseeders = 10 +nzb_downloader = 0 +official_releases_only = 0 +open_magnet_links = 0 +magnet_links = 0 +preferred_bitrate = +preferred_bitrate_allow_lossless = 0 +preferred_bitrate_high_buffer = 0 +preferred_bitrate_low_buffer = 0 +preferred_quality = 0 +preferred_words = +prefer_torrents = 0 +rename_files = 0 +rename_single_disc_ignore = 0 +rename_unprocessed = 1 +rename_frozen = 1 +replace_existing_folders = 0 +keep_original_folder = 0 +required_words = +samplingfrequency = 44100 +search_interval = 1440 +soft_chroot = +torrentblackhole_dir = +torrent_downloader = 0 +torrent_removal_interval = 720 +update_db_interval = 24 +usenet_retention = 1500 +wait_until_release_date = 0 +xldprofile = + +[Advanced] +album_completion_pct = 80 +cache_sizemb = 32 +ignored_folders = [] +ignored_files = [] +journal_mode = wal +verify_ssl_cert = 1 + +[Orpheus.network] +orpheus = 0 +orpheus_password = +orpheus_ratio = +orpheus_username = +orpheus_url = https://orpheus.network + +[Boxcar] +boxcar_enabled = 0 +boxcar_onsnatch = 0 +boxcar_token = + +[Deluge] +deluge_host = +deluge_cert = +deluge_password = +deluge_label = +deluge_done_directory = +deluge_paused = 0 + +[Email] +email_enabled = 0 +email_from = +email_to = +email_smtp_server = localhost +email_smtp_user = +email_smtp_password = +email_smtp_port = 25 +email_ssl = 0 +email_tls = 0 +email_onsnatch = 0 + +[Newznab] +extra_newznabs = [] +newznab = 0 +newznab_apikey = +newznab_enabled = 1 +newznab_host = + +[Torznab] +extra_torznabs = [] +torznab = 0 +torznab_apikey = +torznab_enabled = 1 +torznab_host = +torznab_ratio = + +[Growl] +growl_enabled = 0 +growl_host = +growl_onsnatch = 0 +growl_password = + +[Beets] +idtag = 0 + +[Join] +join_apikey = +join_deviceid = +join_enabled = 0 +join_onsnatch = 0 + +[LMS] +lms_enabled = 0 +lms_host = + +[MPC] +mpc_enabled = 0 + +[NMA] +nma_apikey = +nma_enabled = 0 +nma_onsnatch = 0 +nma_priority = 0 + +[NZBget] +nzbget_category = +nzbget_host = +nzbget_password = +nzbget_priority = 0 +nzbget_username = nzbget + +[NZBsorg] +nzbsorg = 0 +nzbsorg_hash = +nzbsorg_uid = + +[omgwtfnzbs] +omgwtfnzbs = 0 +omgwtfnzbs_apikey = +omgwtfnzbs_uid = + +[OSX_Notify] +osx_notify_app = /Applications/Headphones +osx_notify_enabled = 0 +osx_notify_onsnatch = 0 + +[Piratebay] +piratebay = 0 +piratebay_proxy_url = +piratebay_ratio = + +[Old Piratebay] +oldpiratebay = 0 +oldpiratebay_url = +oldpiratebay_ratio = + +[Plex] +plex_client_host = +plex_enabled = 0 +plex_notify = 0 +plex_password = +plex_server_host = +plex_update = 0 +plex_username = +plex_token = + +[Prowl] +prowl_enabled = 0 +prowl_keys = +prowl_onsnatch = 0 +prowl_priority = 0 + +[Pushalot] +pushalot_apikey = +pushalot_enabled = 0 +pushalot_onsnatch = 0 + +[PushBullet] +pushbullet_apikey = +pushbullet_deviceid = +pushbullet_enabled = 0 +pushbullet_onsnatch = 0 + +[Pushover] +pushover_apitoken = +pushover_enabled = 0 +pushover_keys = +pushover_onsnatch = 0 +pushover_priority = 0 + +[QBitTorrent] +qbittorrent_host = +qbittorrent_label = +qbittorrent_password = +qbittorrent_username = + +[Rutracker] +rutracker = 0 +rutracker_password = +rutracker_ratio = +rutracker_user = +rutracker_cookie = + +[SABnzbd] +sab_apikey = +sab_category = +sab_host = +sab_password = +sab_username = + +[Slack] +slack_enabled = 0 +slack_url = +slack_channel = +slack_emoji = +slack_onsnatch = 0 + +[Songkick] +songkick_apikey = nd1We7dFW2RqxPw8 +songkick_enabled = 1 +songkick_filter_enabled = 0 +songkick_location = + +[Subsonic] +subsonic_enabled = 0 +subsonic_host = +subsonic_password = +subsonic_username = + +[Synoindex] +synoindex_enabled = 0 + +[Telegram] +telegram_token = +telegram_userid = +telegram_enabled = 0 +telegram_onsnatch = 0 + +[Transmission] +transmission_host = +transmission_password = +transmission_username = + +[Twitter] +twitter_enabled = 0 +twitter_onsnatch = 0 +twitter_password = +twitter_prefix = Headphones +twitter_username = + +[uTorrent] +utorrent_host = +utorrent_label = +utorrent_password = +utorrent_username = + +[Waffles] +waffles = 0 +waffles_passkey = +waffles_ratio = +waffles_uid = + +[Redacted] +redacted = 0 +redacted_username = +redacted_password = +redacted_ratio = +redacted_use_fltoken = 0 + +[XBMC] +xbmc_enabled = 0 +xbmc_host = +xbmc_notify = 0 +xbmc_password = +xbmc_update = 0 +xbmc_username = diff --git a/conf/headphones.init b/conf/headphones.init deleted file mode 100644 index 6820fc5..0000000 --- a/conf/headphones.init +++ /dev/null @@ -1,209 +0,0 @@ -#!/bin/sh -# -## Don't edit this file -## Edit user configuation in /etc/default/headphones to change -## -## Make sure init script is executable -## sudo chmod +x /path/to/init.ubuntu -## -## Install the init script -## sudo ln -s /path/to/init.ubuntu /etc/init.d/headphones -## -## Create the headphones daemon user: -## sudo adduser --system --no-create-home headphones -## -## Make sure /opt/headphones is owned by the headphones user -## sudo chown headphones:nogroup -R /opt/headphones -## -## Touch the default file to stop the warning message when starting -## sudo touch /etc/default/headphones -## -## To start Headphones automatically -## sudo update-rc.d headphones defaults -## -## To start/stop/restart Headphones -## sudo service headphones start -## sudo service headphones stop -## sudo service headphones restart -## -## HP_USER= #$RUN_AS, username to run headphones under, the default is headphones -## HP_HOME= #$APP_PATH, the location of Headphones.py, the default is /opt/headphones -## HP_DATA= #$DATA_DIR, the location of headphones.db, cache, logs, the default is /opt/headphones -## HP_PIDFILE= #$PID_FILE, the location of headphones.pid, the default is /var/run/headphones/headphones.pid -## PYTHON_BIN= #$DAEMON, the location of the python binary, the default is /usr/bin/python -## HP_OPTS= #$EXTRA_DAEMON_OPTS, extra cli option for headphones, i.e. " --config=/home/headphones/config.ini" -## SSD_OPTS= #$EXTRA_SSD_OPTS, extra start-stop-daemon option like " --group=users" -## HP_PORT= #$PORT_OPTS, hardcoded port for the webserver, overrides value in config.ini -## -## EXAMPLE if want to run as different user -## add HP_USER=username to /etc/default/headphones -## otherwise default headphones is used -# -### BEGIN INIT INFO -# Provides: headphones -# Required-Start: $local_fs $network $remote_fs -# Required-Stop: $local_fs $network $remote_fs -# Should-Start: $NetworkManager -# Should-Stop: $NetworkManager -# Default-Start: 2 3 4 5 -# Default-Stop: 0 1 6 -# Short-Description: starts instance of Headphones -# Description: starts instance of Headphones using start-stop-daemon -### END INIT INFO - -# Script name -NAME=headphones - -# App name -DESC=Headphones - -SETTINGS_LOADED=FALSE - -. /lib/lsb/init-functions - -# Source Headphones configuration -if [ -f /etc/default/headphones ]; then - SETTINGS=/etc/default/headphones -else - log_warning_msg "/etc/default/headphones not found using default settings."; -fi - -check_retval() { - if [ $? -eq 0 ]; then - log_end_msg 0 - return 0 - else - log_end_msg 1 - exit 1 - fi -} - -load_settings() { - if [ $SETTINGS_LOADED != "TRUE" ]; then - . $SETTINGS - - ## The defaults - # Run as username - RUN_AS=${HP_USER-headphones} - - # Path to app HP_HOME=path_to_app_Headphones.py - APP_PATH=${HP_HOME-/opt/headphones} - - # Data directory where headphones.db, cache and logs are stored - DATA_DIR=${HP_DATA-/opt/headphones} - - # Path to store PID file - PID_FILE=${HP_PIDFILE-/var/run/headphones/headphones.pid} - - # Path to python bin - DAEMON=${PYTHON_BIN-/usr/bin/python} - - # Extra daemon option like: HP_OPTS=" --config=/home/headphones/config.ini" - EXTRA_DAEMON_OPTS=${HP_OPTS-} - - # Extra start-stop-daemon option like START_OPTS=" --group=users" - EXTRA_SSD_OPTS=${SSD_OPTS-} - - # Hardcoded port to run on, overrides config.ini settings - [ -n "$HP_PORT" ] && { - PORT_OPTS=" --port=${HP_PORT} " - } - - DAEMON_OPTS=" Headphones.py --quiet --daemon --nolaunch --pidfile=${PID_FILE} --datadir=${DATA_DIR} ${PORT_OPTS}${EXTRA_DAEMON_OPTS}" - - SETTINGS_LOADED=TRUE - fi - - [ -x $DAEMON ] || { - log_warning_msg "$DESC: Can't execute daemon, aborting. See $DAEMON"; - return 1;} - - return 0 -} - -load_settings || exit 0 - -is_running () { - # returns 1 when running, else 0. - if [ -e $PID_FILE ]; then - PID=`cat $PID_FILE` - - RET=$? - [ $RET -gt 1 ] && exit 1 || return $RET - else - return 1 - fi -} - -handle_pid () { - PID_PATH=`dirname $PID_FILE` - [ -d $PID_PATH ] || mkdir -p $PID_PATH && chown -R $RUN_AS $PID_PATH > /dev/null || { - log_warning_msg "$DESC: Could not create $PID_FILE, See $SETTINGS, aborting."; - return 1;} - - if [ -e $PID_FILE ]; then - PID=`cat $PID_FILE` - if ! kill -0 $PID > /dev/null 2>&1; then - log_warning_msg "Removing stale $PID_FILE" - rm $PID_FILE - fi - fi -} - -handle_datadir () { - [ -d $DATA_DIR ] || mkdir -p $DATA_DIR && chown -R $RUN_AS $DATA_DIR > /dev/null || { - log_warning_msg "$DESC: Could not create $DATA_DIR, See $SETTINGS, aborting."; - return 1;} -} - -handle_updates () { - chown -R $RUN_AS $APP_PATH > /dev/null || { - log_warning_msg "$DESC: $APP_PATH not writable by $RUN_AS for web-updates"; - return 0; } -} - -start_headphones () { - handle_pid - handle_datadir - handle_updates - if ! is_running; then - log_daemon_msg "Starting $DESC" - start-stop-daemon -o -d $APP_PATH -c $RUN_AS --start $EXTRA_SSD_OPTS --pidfile $PID_FILE --exec $DAEMON -- $DAEMON_OPTS - check_retval - else - log_success_msg "$DESC: already running (pid $PID)" - fi -} - -stop_headphones () { - if is_running; then - log_daemon_msg "Stopping $DESC" - start-stop-daemon -o --stop --pidfile $PID_FILE --retry 15 - check_retval - else - log_success_msg "$DESC: not running" - fi -} - -case "$1" in - start) - start_headphones - ;; - stop) - stop_headphones - ;; - restart|force-reload) - stop_headphones - start_headphones - ;; - status) - status_of_proc -p "$PID_FILE" "$DAEMON" "$DESC" - ;; - *) - N=/etc/init.d/$NAME - echo "Usage: $N {start|stop|restart|force-reload|status}" >&2 - exit 1 - ;; -esac - -exit 0 \ No newline at end of file diff --git a/conf/nginx.conf b/conf/nginx.conf index a03bd49..e2eed91 100644 --- a/conf/nginx.conf +++ b/conf/nginx.conf @@ -1,15 +1,9 @@ #sub_path_only rewrite ^__PATH__$ __PATH__/ permanent; location __PATH__/ { - proxy_pass https://127.0.0.1:__PORT__; - proxy_redirect off; - proxy_set_header Host $host; - proxy_set_header X-Real-IP $remote_addr; - proxy_set_header X-Forwarded-Proto $scheme; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - proxy_set_header X-Forwarded-Host $server_name; - - proxy_http_version 1.1; - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection "upgrade"; + proxy_pass http://localhost:__PORT__; + proxy_set_header Host $host; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Scheme $scheme; + proxy_set_header X-Script-Name __PATH__/; } diff --git a/conf/systemd.service b/conf/systemd.service index 6ae7420..98af8ae 100644 --- a/conf/systemd.service +++ b/conf/systemd.service @@ -1,13 +1,12 @@ [Unit] Description=Headphones -Wants=network.target network-online.target -After=network.target network-online.target [Service] -Type=forking +Type=simple User=__APP__ Group=__APP__ -ExecStart=/usr/bin/python3 __FINALPATH__/Headphones.py -d --datadir __DATADIR__ --nolaunch --config /etc/headphones/headphones.ini --port __PORT__ +WorkingDirectory=__FINALPATH__/ +ExecStart=__FINALPATH__/venv/bin/python3 __FINALPATH__/Headphones.py --config /etc/__APP__/__APP__.ini --datadir __DATADIR__ --nolaunch [Install] -WantedBy=multi-user.target \ No newline at end of file +WantedBy=multi-user.target diff --git a/doc/.gitkeep b/doc/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/doc/DESCRIPTION.md b/doc/DESCRIPTION.md new file mode 100644 index 0000000..88c63d6 --- /dev/null +++ b/doc/DESCRIPTION.md @@ -0,0 +1 @@ +Headphones is an automated music downloader for NZB and Torrent, written in Python. It supports SABnzbd, NZBget, Transmission, µTorrent, Deluge and Blackhole. diff --git a/doc/DISCLAIMER.md b/doc/DISCLAIMER.md new file mode 100644 index 0000000..e69de29 diff --git a/doc/screenshots/.gitkeep b/doc/screenshots/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/doc/screenshots/screenshot01.png b/doc/screenshots/screenshot01.png new file mode 100644 index 0000000000000000000000000000000000000000..8a85f5eb84a2560f59a7d57b9c73003515b06964 GIT binary patch literal 144288 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 z%0A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 z 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 literal 0 HcmV?d00001 diff --git a/manifest.json b/manifest.json index 73acda7..e5b616f 100644 --- a/manifest.json +++ b/manifest.json @@ -3,18 +3,17 @@ "id": "headphones", "packaging_format": 1, "description": { - "en": "Automated music downloader for NZB and Torrent", - "fr": "Automated music downloader for NZB and Torrent" + "en": "Automated music downloader for NZB and Torrent" }, "version": "0.6.0~ynh1", "url": "https://github.com/rembo10/headphones", "upstream": { - "license": "free", + "license": "GPL-3.0-or-later", "website": "https://github.com/rembo10/headphones", "userdoc": "https://github.com/rembo10/headphones/wiki/Usage-guide", "code": "https://github.com/rembo10/headphones" }, - "license": "free", + "license": "GPL-3.0-or-later", "maintainer": { "name": "John doe", "email": "john.doe@example.com" @@ -27,7 +26,7 @@ "nginx" ], "arguments": { - "install" : [ + "install": [ { "name": "domain", "type": "domain" @@ -41,7 +40,7 @@ { "name": "is_public", "type": "boolean", - "default": true + "default": false } ] } diff --git a/scripts/_common.sh b/scripts/_common.sh index 7e55ac0..7c12937 100644 --- a/scripts/_common.sh +++ b/scripts/_common.sh @@ -5,7 +5,7 @@ #================================================= # dependencies used by the app -pkg_dependencies="deb1 deb2 php$YNH_DEFAULT_PHP_VERSION-deb1 php$YNH_DEFAULT_PHP_VERSION-deb2" +pkg_dependencies="python3 python3-venv" #================================================= # PERSONAL HELPERS diff --git a/scripts/backup b/scripts/backup index d5c2c89..1252248 100644 --- a/scripts/backup +++ b/scripts/backup @@ -1,37 +1,81 @@ #!/bin/bash -# Common variable declaration -app_id=headphones -app_user=headphones -app_install_dir="/opt/yunohost/${app_id}" -app_data_dir="/home/yunohost.app/${app_id}" +#================================================= +# GENERIC START +#================================================= +# IMPORT GENERIC HELPERS +#================================================= -# Retrieve arguments -app_method="$(sudo yunohost app setting ${app_id} method)" -app_domain="$(sudo yunohost app setting ${app_id} domain)" +# Keep this path for calling _common.sh inside the execution's context of backup and restore scripts +source ../settings/scripts/_common.sh +source /usr/share/yunohost/helpers -# The parameter $1 is the backup directory location -# which will be compressed afterward -app_backup_dir="$1/apps/${app_id}" -sudo mkdir -p $app_backup_dir +#================================================= +# MANAGE SCRIPT FAILURE +#================================================= +ynh_clean_setup () { + true +} +# Exit if an error occurs during the execution of the script +ynh_abort_if_errors -# Backup files if localhost installation -if [[ $app_method == "LOCAL"* ]]; then +#================================================= +# LOAD SETTINGS +#================================================= +ynh_print_info --message="Loading installation settings..." - # Backup sources - sudo cp -a $app_install_dir/. $app_backup_dir/sources +app=$YNH_APP_INSTANCE_NAME - # Backup data - sudo cp -a $app_data_dir/. $app_backup_dir/data - - # Backup daemon config - sudo cp -a /etc/default/$app_id $app_backup_dir/conf/$app_id.default - sudo cp -a /etc/init.d/$app_id $app_backup_dir/conf/$app_id.init - -fi +final_path=$(ynh_app_setting_get --app=$app --key=final_path) +domain=$(ynh_app_setting_get --app=$app --key=domain) +datadir=$(ynh_app_setting_get --app=$app --key=datadir) +#================================================= +# DECLARE DATA AND CONF FILES TO BACKUP +#================================================= +ynh_print_info --message="Declaring files to be backed up..." -# Copy Nginx and YunoHost parameters to make the script "standalone" -sudo cp -a /etc/yunohost/apps/$app_id/. $app_backup_dir/yunohost -sudo cp -a /etc/nginx/conf.d/$app_domain.d/$app_id.conf $app_backup_dir/nginx.conf \ No newline at end of file +#================================================= +# BACKUP THE APP MAIN DIR +#================================================= + +ynh_backup --src_path="$final_path" + +#================================================= +# BACKUP THE DATA DIR +#================================================= + +ynh_backup --src_path="$datadir" --is_big + +#================================================= +# BACKUP THE NGINX CONFIGURATION +#================================================= + +ynh_backup --src_path="/etc/nginx/conf.d/$domain.d/$app.conf" + +#================================================= +# SPECIFIC BACKUP +#================================================= +# BACKUP LOGROTATE +#================================================= + +ynh_backup --src_path="/etc/logrotate.d/$app" + +#================================================= +# BACKUP SYSTEMD +#================================================= + +ynh_backup --src_path="/etc/systemd/system/$app.service" + +#================================================= +# BACKUP VARIOUS FILES +#================================================= + +ynh_backup --src_path="/etc/$app/" + +#================================================= +# END OF SCRIPT +#================================================= + +ynh_print_info --message="Backup script completed for $app. (YunoHost will then actually copy those files to the archive)." diff --git a/scripts/change_url b/scripts/change_url new file mode 100644 index 0000000..cea5987 --- /dev/null +++ b/scripts/change_url @@ -0,0 +1,143 @@ +#!/bin/bash + +#================================================= +# GENERIC STARTING +#================================================= +# IMPORT GENERIC HELPERS +#================================================= + +source _common.sh +source /usr/share/yunohost/helpers + +#================================================= +# RETRIEVE ARGUMENTS +#================================================= + +old_domain=$YNH_APP_OLD_DOMAIN +old_path=$YNH_APP_OLD_PATH + +new_domain=$YNH_APP_NEW_DOMAIN +new_path=$YNH_APP_NEW_PATH + +app=$YNH_APP_INSTANCE_NAME + +#================================================= +# LOAD SETTINGS +#================================================= +ynh_script_progression --message="Loading installation settings..." + +# Needed for helper "ynh_add_nginx_config" +final_path=$(ynh_app_setting_get --app=$app --key=final_path) + +# Add settings here as needed by your application +datadir=$(ynh_app_setting_get --app=$app --key=datadir) +port=$(ynh_app_setting_get --app=$app --key=port) +final_path=$(ynh_app_setting_get --app=$app --key=final_path) +#================================================= +# BACKUP BEFORE CHANGE URL THEN ACTIVE TRAP +#================================================= +ynh_script_progression --message="Backing up the app before changing its URL (may take a while)..." + +# Backup the current version of the app +ynh_backup_before_upgrade +ynh_clean_setup () { + ynh_clean_check_starting + # Remove the new domain config file, the remove script won't do it as it doesn't know yet its location. + ynh_secure_remove --file="/etc/nginx/conf.d/$new_domain.d/$app.conf" + + # Restore it if the upgrade fails + ynh_restore_upgradebackup +} +# Exit if an error occurs during the execution of the script +ynh_abort_if_errors + +#================================================= +# CHECK WHICH PARTS SHOULD BE CHANGED +#================================================= + +change_domain=0 +if [ "$old_domain" != "$new_domain" ] +then + change_domain=1 +fi + +change_path=0 +if [ "$old_path" != "$new_path" ] +then + change_path=1 +fi + +#================================================= +# STANDARD MODIFICATIONS +#================================================= +# STOP SYSTEMD SERVICE +#================================================= +ynh_script_progression --message="Stopping a systemd service..." + +ynh_systemd_action --service_name=$app --action="stop" --log_path="/var/log/$app/$app.log" --line_match="Headphones is shutting down" + +#================================================= +# MODIFY URL IN NGINX CONF +#================================================= +ynh_script_progression --message="Updating NGINX web server configuration..." + +nginx_conf_path=/etc/nginx/conf.d/$old_domain.d/$app.conf + +# Change the path in the NGINX config file +if [ $change_path -eq 1 ] +then + # Make a backup of the original NGINX config file if modified + ynh_backup_if_checksum_is_different --file="$nginx_conf_path" + # Set global variables for NGINX helper + domain="$old_domain" + path_url="$new_path" + # Create a dedicated NGINX config + ynh_add_nginx_config +fi + +# Change the domain for NGINX +if [ $change_domain -eq 1 ] +then + # Delete file checksum for the old conf file location + ynh_delete_file_checksum --file="$nginx_conf_path" + mv $nginx_conf_path /etc/nginx/conf.d/$new_domain.d/$app.conf + # Store file checksum for the new config file location + ynh_store_file_checksum --file="/etc/nginx/conf.d/$new_domain.d/$app.conf" +fi + +#================================================= +# SPECIFIC MODIFICATIONS +#================================================= +# UPDATE A CONFIG FILE +#================================================= +ynh_script_progression --message="Updating a configuration file..." + +path_url=$new_path +domain=$new_domain +ynh_add_config --template="../conf/headphones.ini" --destination="/etc/$app/$app.ini" + +chmod 600 "/etc/$app/$app.ini" +chown $app:$app "/etc/$app/$app.ini" + +#================================================= +# GENERIC FINALISATION +#================================================= +# START SYSTEMD SERVICE +#================================================= +ynh_script_progression --message="Starting a systemd service..." + +# Start a systemd service +ynh_systemd_action --service_name=$app --action="start" --log_path="/var/log/$app/$app.log" --line_match="Starting Headphones web server" + +#================================================= +# RELOAD NGINX +#================================================= +ynh_script_progression --message="Reloading NGINX web server..." + +ynh_systemd_action --service_name=nginx --action=reload + +#================================================= +# END OF SCRIPT +#================================================= + +ynh_script_progression --message="Change of URL completed for $app" diff --git a/scripts/install b/scripts/install index b96c10b..18c2c36 100644 --- a/scripts/install +++ b/scripts/install @@ -14,8 +14,7 @@ source /usr/share/yunohost/helpers #================================================= ynh_clean_setup () { - ### Remove this function if there's nothing to clean before calling the remove script. - true + ynh_clean_check_starting } # Exit if an error occurs during the execution of the script ynh_abort_if_errors @@ -33,7 +32,7 @@ app=$YNH_APP_INSTANCE_NAME #================================================= # CHECK IF THE APP CAN BE INSTALLED WITH THESE ARGS #================================================= -ynh_script_progression --message="Validating installation parameters..." --time --weight=1 +ynh_script_progression --message="Validating installation parameters..." final_path=/var/www/$app test ! -e "$final_path" || ynh_die --message="This path already contains a folder" @@ -44,7 +43,7 @@ ynh_webpath_register --app=$app --domain=$domain --path_url=$path_url #================================================= # STORE SETTINGS FROM MANIFEST #================================================= -ynh_script_progression --message="Storing installation settings..." --time --weight=1 +ynh_script_progression --message="Storing installation settings..." ynh_app_setting_set --app=$app --key=domain --value=$domain ynh_app_setting_set --app=$app --key=path --value=$path_url @@ -54,23 +53,23 @@ ynh_app_setting_set --app=$app --key=path --value=$path_url #================================================= # FIND AND OPEN A PORT #================================================= -ynh_script_progression --message="Finding an available port..." --time --weight=1 +ynh_script_progression --message="Finding an available port..." # Find an available port -port=$(ynh_find_port --port=8181) +port=$(ynh_find_port --port=8095) ynh_app_setting_set --app=$app --key=port --value=$port #================================================= # INSTALL DEPENDENCIES #================================================= -# ynh_script_progression --message="Installing dependencies..." --time --weight=1 +ynh_script_progression --message="Installing dependencies..." -# ynh_install_app_dependencies $pkg_dependencies +ynh_install_app_dependencies $pkg_dependencies #================================================= # CREATE DEDICATED USER #================================================= -ynh_script_progression --message="Configuring system user..." --time --weight=1 +ynh_script_progression --message="Configuring system user..." # Create a system user ynh_system_user_create --username=$app --home_dir="$final_path" @@ -78,7 +77,7 @@ ynh_system_user_create --username=$app --home_dir="$final_path" #================================================= # DOWNLOAD, CHECK AND UNPACK SOURCE #================================================= -ynh_script_progression --message="Setting up source files..." --time --weight=1 +ynh_script_progression --message="Setting up source files..." ynh_app_setting_set --app=$app --key=final_path --value=$final_path # Download, check integrity, uncompress and patch the source from app.src @@ -86,21 +85,30 @@ ynh_setup_source --dest_dir="$final_path" chmod 750 "$final_path" chmod -R o-rwx "$final_path" -chown -R $app:www-data "$final_path" +chown -R $app:$app "$final_path" chmod +x "$final_path/Headphones.py" #================================================= # NGINX CONFIGURATION #================================================= -ynh_script_progression --message="Configuring NGINX web server..." --time --weight=1 +ynh_script_progression --message="Configuring NGINX web server..." # Create a dedicated NGINX config ynh_add_nginx_config +#================================================= +# SPECIFIC SETUP +#================================================= +# INSTALL PYTHON DEPENDENCIES +#================================================= +ynh_script_progression --message="Installing Python dependencies..." + +python3 -m venv $final_path/venv + #================================================= # CREATE DATA DIRECTORY #================================================= -ynh_script_progression --message="Creating a data directory..." --time --weight=1 +ynh_script_progression --message="Creating a data directory..." datadir=/home/yunohost.app/$app ynh_app_setting_set --app=$app --key=datadir --value=$datadir @@ -109,22 +117,23 @@ mkdir -p $datadir chmod 750 "$datadir" chmod -R o-rwx "$datadir" -chown -R $app:www-data "$datadir" +chown -R $app:$app "$datadir" #================================================= # ADD A CONFIGURATION #================================================= -ynh_script_progression --message="Adding a configuration file..." --time --weight=1 +ynh_script_progression --message="Adding a configuration file..." -ynh_add_config --template="../conf/headphones.defaults" --destination="/etc/default/headphones" +mkdir -p "/etc/$app" +ynh_add_config --template="../conf/headphones.ini" --destination="/etc/$app/$app.ini" -#chmod 400 "/etc/default/headphones" -#chown $app:$app "/etc/default/headphones" +chmod 600 "/etc/$app/$app.ini" +chown $app:$app "/etc/$app/$app.ini" #================================================= # SETUP SYSTEMD #================================================= -ynh_script_progression --message="Configuring a systemd service..." --time --weight=1 +ynh_script_progression --message="Configuring a systemd service..." # Create a dedicated systemd config ynh_add_systemd_config @@ -134,41 +143,45 @@ ynh_add_systemd_config #================================================= # SETUP LOGROTATE #================================================= -ynh_script_progression --message="Configuring log rotation..." --time --weight=1 +ynh_script_progression --message="Configuring log rotation..." +mkdir -p "/var/log/$app" +chown -R $app:$app "/var/log/$app" # Use logrotate to manage application logfile(s) ynh_use_logrotate #================================================= # INTEGRATE SERVICE IN YUNOHOST #================================================= -ynh_script_progression --message="Integrating service in YunoHost..." --time --weight=1 +ynh_script_progression --message="Integrating service in YunoHost..." -yunohost service add $app --description="A short description of the app" --log="/var/log/$app/$app.log" +yunohost service add $app --log="/var/log/$app/$app.log" #================================================= # START SYSTEMD SERVICE #================================================= -ynh_script_progression --message="Starting a systemd service..." --time --weight=1 +ynh_script_progression --message="Starting a systemd service..." # Start a systemd service -ynh_systemd_action --service_name=$app --action="start" --log_path="/var/log/$app/$app.log" +ynh_systemd_action --service_name=$app --action="start" --log_path="/var/log/$app/$app.log" --line_match="Starting Headphones web server" #================================================= # SETUP SSOWAT #================================================= -ynh_script_progression --message="Configuring permissions..." --time --weight=1 +ynh_script_progression --message="Configuring permissions..." # Make app public if necessary if [ $is_public -eq 1 ] then + # Everyone can access the app. + # The "main" permission is automatically created before the install script. ynh_permission_update --permission="main" --add="visitors" fi #================================================= # RELOAD NGINX #================================================= -ynh_script_progression --message="Reloading NGINX web server..." --time --weight=1 +ynh_script_progression --message="Reloading NGINX web server..." ynh_systemd_action --service_name=nginx --action=reload @@ -176,4 +189,4 @@ ynh_systemd_action --service_name=nginx --action=reload # END OF SCRIPT #================================================= -ynh_script_progression --message="Installation of $app completed" --time --last +ynh_script_progression --message="Installation of $app completed" diff --git a/scripts/remove b/scripts/remove index 491796a..aaa5219 100644 --- a/scripts/remove +++ b/scripts/remove @@ -12,12 +12,11 @@ source /usr/share/yunohost/helpers #================================================= # LOAD SETTINGS #================================================= -ynh_script_progression --message="Loading installation settings..." --time --weight=1 +ynh_script_progression --message="Loading installation settings..." app=$YNH_APP_INSTANCE_NAME domain=$(ynh_app_setting_get --app=$app --key=domain) -port=$(ynh_app_setting_get --app=$app --key=port) final_path=$(ynh_app_setting_get --app=$app --key=final_path) datadir=$(ynh_app_setting_get --app=$app --key=datadir) @@ -30,14 +29,14 @@ datadir=$(ynh_app_setting_get --app=$app --key=datadir) # Remove the service from the list of services known by YunoHost (added from `yunohost service add`) if ynh_exec_warn_less yunohost service status $app >/dev/null then - ynh_script_progression --message="Removing $app service integration..." --time --weight=1 + ynh_script_progression --message="Removing $app service integration..." yunohost service remove $app fi #================================================= # STOP AND REMOVE SERVICE #================================================= -ynh_script_progression --message="Stopping and removing the systemd service..." --time --weight=1 +ynh_script_progression --message="Stopping and removing the systemd service..." # Remove the dedicated systemd config ynh_remove_systemd_config @@ -45,7 +44,7 @@ ynh_remove_systemd_config #================================================= # REMOVE LOGROTATE CONFIGURATION #================================================= -ynh_script_progression --message="Removing logrotate configuration..." --time --weight=1 +ynh_script_progression --message="Removing logrotate configuration..." # Remove the app-specific logrotate config ynh_remove_logrotate @@ -53,7 +52,7 @@ ynh_remove_logrotate #================================================= # REMOVE APP MAIN DIR #================================================= -ynh_script_progression --message="Removing app main directory..." --time --weight=1 +ynh_script_progression --message="Removing app main directory..." # Remove the app directory securely ynh_secure_remove --file="$final_path" @@ -65,14 +64,14 @@ ynh_secure_remove --file="$final_path" # Remove the data directory if --purge option is used if [ "${YNH_APP_PURGE:-0}" -eq 1 ] then - ynh_script_progression --message="Removing app data directory..." --time --weight=1 + ynh_script_progression --message="Removing app data directory..." ynh_secure_remove --file="$datadir" fi #================================================= # REMOVE NGINX CONFIGURATION #================================================= -ynh_script_progression --message="Removing NGINX web server configuration..." --time --weight=1 +ynh_script_progression --message="Removing NGINX web server configuration..." # Remove the dedicated NGINX config ynh_remove_nginx_config @@ -80,17 +79,30 @@ ynh_remove_nginx_config #================================================= # REMOVE DEPENDENCIES #================================================= -# ynh_script_progression --message="Removing dependencies..." --time --weight=1 +ynh_script_progression --message="Removing dependencies..." -# # Remove metapackage and its dependencies -# ynh_remove_app_dependencies +# Remove metapackage and its dependencies +ynh_remove_app_dependencies + +#================================================= +# SPECIFIC REMOVE +#================================================= +# REMOVE VARIOUS FILES +#================================================= +ynh_script_progression --message="Removing various files..." + +# Remove a directory securely +ynh_secure_remove --file="/etc/$app" + +# Remove the log files +ynh_secure_remove --file="/var/log/$app" #================================================= # GENERIC FINALIZATION #================================================= # REMOVE DEDICATED USER #================================================= -ynh_script_progression --message="Removing the dedicated system user..." --time --weight=1 +ynh_script_progression --message="Removing the dedicated system user..." # Delete a system user ynh_system_user_delete --username=$app @@ -99,4 +111,4 @@ ynh_system_user_delete --username=$app # END OF SCRIPT #================================================= -ynh_script_progression --message="Removal of $app completed" --time --last +ynh_script_progression --message="Removal of $app completed" diff --git a/scripts/restore b/scripts/restore index 53e69bd..9ae75f7 100644 --- a/scripts/restore +++ b/scripts/restore @@ -1,56 +1,149 @@ #!/bin/bash -# Common variable declaration -app_id=headphones -app_user=headphones -app_install_dir="/opt/yunohost/${app_id}" -app_data_dir="/home/yunohost.app/${app_id}" +#================================================= +# GENERIC START +#================================================= +# IMPORT GENERIC HELPERS +#================================================= -# Retrieve arguments -app_method="$(sudo yunohost app setting ${app_id} method)" -app_domain="$(sudo yunohost app setting ${app_id} domain)" +# Keep this path for calling _common.sh inside the execution's context of backup and restore scripts +source ../settings/scripts/_common.sh +source /usr/share/yunohost/helpers -# The parameter $1 is the uncompressed restore directory location -app_backup_dir="$1/apps/${app_id}" +#================================================= +# MANAGE SCRIPT FAILURE +#================================================= +ynh_clean_setup () { + ynh_clean_check_starting +} +# Exit if an error occurs during the execution of the script +ynh_abort_if_errors -# Restore files if localhost installation -if [[ $app_method == "LOCAL"* ]]; then +#================================================= +# LOAD SETTINGS +#================================================= +ynh_script_progression --message="Loading installation settings..." - # Kill app - sudo service $app_id stop - sudo killall $app_id +app=$YNH_APP_INSTANCE_NAME - # Restore sources - sudo cp -a $app_backup_dir/sources/. $app_install_dir +domain=$(ynh_app_setting_get --app=$app --key=domain) +path_url=$(ynh_app_setting_get --app=$app --key=path) +final_path=$(ynh_app_setting_get --app=$app --key=final_path) +datadir=$(ynh_app_setting_get --app=$app --key=datadir) - # Restore data - sudo cp -a $app_backup_dir/data/. $app_data_dir - - # Restore daemon config - sudo cp -a $app_backup_dir/conf/$app_id.default /etc/default/$app_id - sudo cp -a $app_backup_dir/conf/$app_id.init /etc/init.d/$app_id - - # Set rights - sudo chown -R $app_user $app_install_dir - sudo chown -R $app_user $app_data_dir - sudo chmod +x /etc/init.d/$app_id - sudo chmod +x -R $app_install_dir - sudo chmod +x -R $app_data_dir - - # Start daemon at boot - sudo update-rc.d $app_id defaults - - # Reload daemon - sudo service $app_id restart - -fi +#================================================= +# CHECK IF THE APP CAN BE RESTORED +#================================================= +ynh_script_progression --message="Validating restoration parameters..." +test ! -d $final_path \ + || ynh_die --message="There is already a directory: $final_path " -# Restore Nginx and YunoHost parameters -sudo cp -a $app_backup_dir/yunohost/. /etc/yunohost/apps/$app_id -sudo cp -a $app_backup_dir/nginx.conf /etc/nginx/conf.d/$app_domain.d/$app_id.conf +#================================================= +# STANDARD RESTORATION STEPS +#================================================= +# RESTORE THE NGINX CONFIGURATION +#================================================= +ynh_script_progression --message="Restoring the NGINX web server configuration..." -# Reload Nginx and regenerate SSOwat conf -sudo service nginx reload -sudo yunohost app ssowatconf \ No newline at end of file +ynh_restore_file --origin_path="/etc/nginx/conf.d/$domain.d/$app.conf" + +#================================================= +# RECREATE THE DEDICATED USER +#================================================= +ynh_script_progression --message="Recreating the dedicated system user..." + +# Create the dedicated user (if not existing) +ynh_system_user_create --username=$app --home_dir="$final_path" + +#================================================= +# RESTORE THE APP MAIN DIR +#================================================= +ynh_script_progression --message="Restoring the app main directory..." + +ynh_restore_file --origin_path="$final_path" + +chmod 750 "$final_path" +chmod -R o-rwx "$final_path" +chown -R $app:$app "$final_path" +chmod +x "$final_path/Headphones.py" + +#================================================= +# RESTORE THE DATA DIRECTORY +#================================================= +ynh_script_progression --message="Restoring the data directory..." + +ynh_restore_file --origin_path="$datadir" --not_mandatory + +mkdir -p $datadir + +chmod 750 "$datadir" +chmod -R o-rwx "$datadir" +chown -R $app:$app "$datadir" + +#================================================= +# SPECIFIC RESTORATION +#================================================= +# REINSTALL DEPENDENCIES +#================================================= +ynh_script_progression --message="Reinstalling dependencies..." + +# Define and install dependencies +ynh_install_app_dependencies $pkg_dependencies + +#================================================= +# RESTORE VARIOUS FILES +#================================================= +ynh_script_progression --message="Restoring various files..." + +ynh_restore_file --origin_path="/etc/$app/" + +chmod 600 "/etc/$app/$app.ini" +chown $app:$app "/etc/$app/$app.ini" + +#================================================= +# RESTORE SYSTEMD +#================================================= +ynh_script_progression --message="Restoring the systemd configuration..." + +ynh_restore_file --origin_path="/etc/systemd/system/$app.service" +systemctl enable $app.service --quiet + +#================================================= +# RESTORE THE LOGROTATE CONFIGURATION +#================================================= +ynh_script_progression --message="Restoring the logrotate configuration..." + +mkdir -p "/var/log/$app" +chown -R $app:$app "/var/log/$app" +ynh_restore_file --origin_path="/etc/logrotate.d/$app" + +#================================================= +# INTEGRATE SERVICE IN YUNOHOST +#================================================= +ynh_script_progression --message="Integrating service in YunoHost..." + +yunohost service add $app --log="/var/log/$app/$app.log" + +#================================================= +# START SYSTEMD SERVICE +#================================================= +ynh_script_progression --message="Starting a systemd service..." + +ynh_systemd_action --service_name=$app --action="start" --log_path="/var/log/$app/$app.log" --line_match="Starting Headphones web server" + +#================================================= +# GENERIC FINALIZATION +#================================================= +# RELOAD NGINX +#================================================= +ynh_script_progression --message="Reloading NGINX web server..." + +ynh_systemd_action --service_name=nginx --action=reload + +#================================================= +# END OF SCRIPT +#================================================= + +ynh_script_progression --message="Restoration completed for $app" diff --git a/scripts/upgrade b/scripts/upgrade index 950c87b..2173573 100644 --- a/scripts/upgrade +++ b/scripts/upgrade @@ -1,70 +1,170 @@ #!/bin/bash -# Basic variable declaration -BASEDIR="$(dirname "$(pwd)")" +#================================================= +# GENERIC START +#================================================= +# IMPORT GENERIC HELPERS +#================================================= -# Common variable declaration -app_id=headphones -app_user=headphones -app_install_dir="/opt/yunohost/${app_id}" -app_data_dir="/home/yunohost.app/${app_id}" -app_logs_dir="/var/log/${app_id}" -## Sources definitions -app_src_init="$BASEDIR/conf/${app_id}.init" -app_src_nginx_conf="$BASEDIR/conf/nginx.conf" +source _common.sh +source /usr/share/yunohost/helpers -# Retrieve arguments -app_public="$(sudo yunohost app setting ${app_id} public)" -app_method="$(sudo yunohost app setting ${app_id} method)" -app_domain="$(sudo yunohost app setting ${app_id} domain)" -app_path="$(sudo yunohost app setting ${app_id} path)" -app_host="$(sudo yunohost app setting ${app_id} host)" +#================================================= +# LOAD SETTINGS +#================================================= +ynh_script_progression --message="Loading installation settings..." +app=$YNH_APP_INSTANCE_NAME -# Make upgrade if localhost installation -if [[ $app_method == "LOCAL"* ]]; then +domain=$(ynh_app_setting_get --app=$app --key=domain) +path_url=$(ynh_app_setting_get --app=$app --key=path) +final_path=$(ynh_app_setting_get --app=$app --key=final_path) - # Kill app - sudo service $app_id stop - sudo killall $app_id - - # Upgrade to the latest version of app using the fork - cd $app_install_dir && sudo git pull - cd - +#================================================= +# CHECK VERSION +#================================================= +ynh_script_progression --message="Checking version..." - # Upgrade dependencies - - # Update init file - sudo cp -a $app_src_init /etc/init.d/$app_id - - # Set rights - sudo chown -R $app_user $app_install_dir - sudo chmod +x /etc/init.d/$app_id - sudo chmod +x -R $app_install_dir - - # Start service - sudo service $app_id start - +upgrade_type=$(ynh_check_app_version_changed) + +#================================================= +# BACKUP BEFORE UPGRADE THEN ACTIVE TRAP +#================================================= +ynh_script_progression --message="Backing up the app before upgrading (may take a while)..." + +# Backup the current version of the app +ynh_backup_before_upgrade +ynh_clean_setup () { + ynh_clean_check_starting + # Restore it if the upgrade fails + ynh_restore_upgradebackup +} +# Exit if an error occurs during the execution of the script +ynh_abort_if_errors + +#================================================= +# STANDARD UPGRADE STEPS +#================================================= +# STOP SYSTEMD SERVICE +#================================================= +ynh_script_progression --message="Stopping a systemd service..." + +ynh_systemd_action --service_name=$app --action="stop" --log_path="/var/log/$app/$app.log" --line_match="Headphones is shutting down" + +#================================================= +# ENSURE DOWNWARD COMPATIBILITY +#================================================= +ynh_script_progression --message="Ensuring downward compatibility..." + +# Cleaning legacy permissions +if ynh_legacy_permissions_exists; then + ynh_legacy_permissions_delete_all + + ynh_app_setting_delete --app=$app --key=is_public fi +#================================================= +# CREATE DEDICATED USER +#================================================= +ynh_script_progression --message="Making sure dedicated system user exists..." -# Remove trailing "/" for next commands -app_path=${app_path%/} +# Create a dedicated user (if not existing) +ynh_system_user_create --username=$app --home_dir="$final_path" -# Configure Nginx -sudo sed -i "s@PATHTOCHANGE@$app_path@g" $app_src_nginx_conf -sudo sed -i "s@HOSTTOCHANGE@$app_host@g" $app_src_nginx_conf -sudo cp $app_src_nginx_conf /etc/nginx/conf.d/$app_domain.d/$app_id.conf +#================================================= +# DOWNLOAD, CHECK AND UNPACK SOURCE +#================================================= -# If app is public, add url to SSOWat conf as skipped_uris -if [[ $app_public = "Yes" ]]; +if [ "$upgrade_type" == "UPGRADE_APP" ] then - # See install script - sudo yunohost app setting $app_id unprotected_uris -v "/" - # Remove old settings - sudo yunohost app setting $app_id skipped_uris -d + ynh_script_progression --message="Upgrading source files..." + + # Download, check integrity, uncompress and patch the source from app.src + ynh_setup_source --dest_dir="$final_path" fi -# Reload Nginx and regenerate SSOwat conf -sudo service nginx reload -sudo yunohost app ssowatconf +chmod 750 "$final_path" +chmod -R o-rwx "$final_path" +chown -R $app:$app "$final_path" +chmod +x "$final_path/Headphones.py" + +#================================================= +# NGINX CONFIGURATION +#================================================= +ynh_script_progression --message="Upgrading NGINX web server configuration..." + +# Create a dedicated NGINX config +ynh_add_nginx_config + +#================================================= +# UPGRADE DEPENDENCIES +#================================================= +ynh_script_progression --message="Upgrading dependencies..." + +ynh_install_app_dependencies $pkg_dependencies + +#================================================= +# SPECIFIC UPGRADE +#================================================= +# INSTALL PYTHON DEPENDENCIES +#================================================= +ynh_script_progression --message="Installing Python dependencies..." + +ynh_secure_remove --file="$final_path/venv" +python3 -m venv $final_path/venv + +#================================================= +# UPDATE A CONFIG FILE +#================================================= +ynh_script_progression --message="Updating a configuration file..." + +mkdir -p "/etc/$app" +ynh_add_config --template="../conf/headphones.ini" --destination="/etc/$app/$app.ini" + +chmod 600 "/etc/$app/$app.ini" +chown $app:$app "/etc/$app/$app.ini" + +#================================================= +# SETUP SYSTEMD +#================================================= +ynh_script_progression --message="Upgrading systemd configuration..." + +# Create a dedicated systemd config +ynh_add_systemd_config + +#================================================= +# GENERIC FINALIZATION +#================================================= +# SETUP LOGROTATE +#================================================= +ynh_script_progression --message="Upgrading logrotate configuration..." + +# Use logrotate to manage app-specific logfile(s) +ynh_use_logrotate --non-append + +#================================================= +# INTEGRATE SERVICE IN YUNOHOST +#================================================= +ynh_script_progression --message="Integrating service in YunoHost..." + +yunohost service add $app --log="/var/log/$app/$app.log" + +#================================================= +# START SYSTEMD SERVICE +#================================================= +ynh_script_progression --message="Starting a systemd service..." + +ynh_systemd_action --service_name=$app --action="start" --log_path="/var/log/$app/$app.log" --line_match="Starting Headphones web server" + +#================================================= +# RELOAD NGINX +#================================================= +ynh_script_progression --message="Reloading NGINX web server..." + +ynh_systemd_action --service_name=nginx --action=reload + +#================================================= +# END OF SCRIPT +#================================================= + +ynh_script_progression --message="Upgrade of $app completed" From 06b077ade045a0edbb42d3dc388a9de34298bbd4 Mon Sep 17 00:00:00 2001 From: yalh76 Date: Thu, 24 Mar 2022 00:49:41 +0100 Subject: [PATCH 07/10] charset --- doc/DESCRIPTION.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/DESCRIPTION.md b/doc/DESCRIPTION.md index 88c63d6..7ec0b6a 100644 --- a/doc/DESCRIPTION.md +++ b/doc/DESCRIPTION.md @@ -1 +1 @@ -Headphones is an automated music downloader for NZB and Torrent, written in Python. It supports SABnzbd, NZBget, Transmission, µTorrent, Deluge and Blackhole. +Headphones is an automated music downloader for NZB and Torrent, written in Python. It supports SABnzbd, NZBget, Transmission, µTorrent, Deluge and Blackhole. From 98e1cd20c60539650f0b19a9cdd89b1796bf1c8f Mon Sep 17 00:00:00 2001 From: yunohost-bot Date: Wed, 23 Mar 2022 23:49:46 +0000 Subject: [PATCH 08/10] Auto-update README --- README.md | 7 ++++++- README_fr.md | 44 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+), 1 deletion(-) create mode 100644 README_fr.md diff --git a/README.md b/README.md index 59f9430..dfb8409 100644 --- a/README.md +++ b/README.md @@ -15,12 +15,17 @@ If you don't have YunoHost, please consult [the guide](https://yunohost.org/#/in ## Overview -Automated music downloader for NZB and Torrent +Headphones is an automated music downloader for NZB and Torrent, written in Python. It supports SABnzbd, NZBget, Transmission, µTorrent, Deluge and Blackhole. + **Shipped version:** 0.6.0~ynh1 +## Screenshots + +![](./doc/screenshots/screenshot01.png) + ## Documentation and resources * Official app website: https://github.com/rembo10/headphones diff --git a/README_fr.md b/README_fr.md new file mode 100644 index 0000000..5937881 --- /dev/null +++ b/README_fr.md @@ -0,0 +1,44 @@ +# Headphones pour YunoHost + +[![Niveau d'intégration](https://dash.yunohost.org/integration/headphones.svg)](https://dash.yunohost.org/appci/app/headphones) ![](https://ci-apps.yunohost.org/ci/badges/headphones.status.svg) ![](https://ci-apps.yunohost.org/ci/badges/headphones.maintain.svg) +[![Installer Headphones avec YunoHost](https://install-app.yunohost.org/install-with-yunohost.svg)](https://install-app.yunohost.org/?app=headphones) + +*[Read this readme in english.](./README.md)* +*[Lire ce readme en français.](./README_fr.md)* + +> *Ce package vous permet d'installer Headphones rapidement et simplement sur un serveur YunoHost. +Si vous n'avez pas YunoHost, regardez [ici](https://yunohost.org/#/install) pour savoir comment l'installer et en profiter.* + +## Vue d'ensemble + +Headphones is an automated music downloader for NZB and Torrent, written in Python. It supports SABnzbd, NZBget, Transmission, µTorrent, Deluge and Blackhole. + + +**Version incluse :** 0.6.0~ynh1 + + + +## Captures d'écran + +![](./doc/screenshots/screenshot01.png) + +## Documentations et ressources + +* Site officiel de l'app : https://github.com/rembo10/headphones +* Documentation officielle utilisateur : https://github.com/rembo10/headphones/wiki/Usage-guide +* Dépôt de code officiel de l'app : https://github.com/rembo10/headphones +* Documentation YunoHost pour cette app : https://yunohost.org/app_headphones +* Signaler un bug : https://github.com/YunoHost-Apps/headphones_ynh/issues + +## Informations pour les développeurs + +Merci de faire vos pull request sur la [branche testing](https://github.com/YunoHost-Apps/headphones_ynh/tree/testing). + +Pour essayer la branche testing, procédez comme suit. +``` +sudo yunohost app install https://github.com/YunoHost-Apps/headphones_ynh/tree/testing --debug +ou +sudo yunohost app upgrade headphones -u https://github.com/YunoHost-Apps/headphones_ynh/tree/testing --debug +``` + +**Plus d'infos sur le packaging d'applications :** https://yunohost.org/packaging_apps \ No newline at end of file From b697a10261e47130d075be2fbeea7b215987d873 Mon Sep 17 00:00:00 2001 From: yalh76 Date: Thu, 24 Mar 2022 08:28:27 +0100 Subject: [PATCH 09/10] missing port --- scripts/upgrade | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/upgrade b/scripts/upgrade index 2173573..88acc35 100644 --- a/scripts/upgrade +++ b/scripts/upgrade @@ -19,6 +19,7 @@ app=$YNH_APP_INSTANCE_NAME domain=$(ynh_app_setting_get --app=$app --key=domain) path_url=$(ynh_app_setting_get --app=$app --key=path) final_path=$(ynh_app_setting_get --app=$app --key=final_path) +port=$(ynh_app_setting_get --app=$app --key=port) #================================================= # CHECK VERSION From a9b10e50b37abc8ae3bcf9e80c3ba227330a6334 Mon Sep 17 00:00:00 2001 From: yalh76 Date: Thu, 24 Mar 2022 21:23:41 +0100 Subject: [PATCH 10/10] Missing datadir --- scripts/upgrade | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/upgrade b/scripts/upgrade index 88acc35..188872e 100644 --- a/scripts/upgrade +++ b/scripts/upgrade @@ -20,6 +20,7 @@ domain=$(ynh_app_setting_get --app=$app --key=domain) path_url=$(ynh_app_setting_get --app=$app --key=path) final_path=$(ynh_app_setting_get --app=$app --key=final_path) port=$(ynh_app_setting_get --app=$app --key=port) +datadir=$(ynh_app_setting_get --app=$app --key=datadir) #================================================= # CHECK VERSION