diff --git a/contrib/debianinstall/README.md b/contrib/debianinstall/README.md new file mode 100644 index 000000000..1c7d10efc --- /dev/null +++ b/contrib/debianinstall/README.md @@ -0,0 +1,147 @@ +**This installation script was provided by the community and is officially unsupported. Use at your own risk. Only use with a fresh install of Debian stable. If you have a server that has Apache, PHP, MySQL, SSL, etc. already installed this will break your server.** + +-- + +# How to use + +### Keep it Simple and Stupid + +The script keeps everything as simple as possible (KISS): + +- Apache as webserver (there is no choice to use another webserver like nginx) +- default PHP version of Debian +- one single Streams intance only +- re-running the script does no harm + +### When to use other Scripts + +Use the scripts under [easyinstall](https://codeberg.org/streams/streams/src/branch/release/contrib/autoinstall) or [autoinstall](https://codeberg.org/streams/streams/src/branch/release/contrib/autoinstall) if you look for more choices. The main differences are: + +- Apache OR nginx as webserver +- install multiple instances (domains) that run side by side on the server +- adds apache vhosts (instead of using the standard doc root /var/www/streams) +- install PHP from https://packages.sury.org/php/ (instead of using the Debian repository) +- graphical installer whiptail +- The script stops (fails) if it finds results of a previous installation. +- If something fails the script tries to clean up everything that was installed up to the point of failure. (That might cause trouble if certbot registered a certificate already.) + +## Preconditions + +Hardware + ++ internet connection and router at home ++ computer connected to your router (a Raspberry 4 will do for very small instances) + +Software + ++ fresh installation of Debian 12 (bookworm) ++ router with open ports 80 and 443 for your web server + +You can of course run the script on a VPS or any distant server as long as the above sotfware requirements are satisfied. + +## How to run the script + ++ Register your own domain (for example at selfHOST) or a free subdomain (for example at freeDNS) ++ Log on to your fresh Debian + - apt-get install git + - mkdir -p /var/www + - cd /var/www + - git clone https://codeberg.org/streams/streams.git + - cd streams/contrib/debianinstall + - cp config.txt.template config.txt + - nano config.txt + - read the comments carefully + - enter your values: db pass, domain + - (optionally) Enter your values for dyn DNS + - ./debian-setup.sh as root + - ... wait, wait, wait until the script is finished ++ Open your domain with a browser and step through the initial configuration of your instance. + - default database name = streams + - default dababase user = streams + +## Optional - Switch verification of email on/off + +Do this just before you register the first user without email verification. + +In a terminal + + su - + cd /var/www/streams + +Check the current setting + + util/config system verify_email + +Switch the verification off + + util/config system verify_email 0 + +## What the script will do for you... + ++ install everything required by your streams instance, basically a web server (Apache), PHP, a database (MySQL/MariaDB), certbot,... ++ create a database ++ run certbot to have everything for a secure connection (httpS) ++ create a script for daily maintenance + - renew certfificate (letsencrypt) + - update of your instance for core and addons (git) + - update of Debian + - restart ++ create cron jobs for + - DynDNS (selfHOST.de or freedns.afraid.org) every 5 minutes + - Run.php for your instance every 10 minutes + - daily maintenance script every day at 05:30 + +The script is known to work without adjustments with + ++ Hardware + - standard PC with Debian 12 (bookworm) ++ DynDNS + - selfHOST.de + - freedns.afraid.org + +# Step-by-Step - some Details + +## Preparations + +## Configure your Router + +Your webserver has to be visible in the internet. + +Open the ports 80 and 443 on your router for your Debian. Make sure your web server is marked as "exposed host". + +## Preparations Dynamic IP Address + +Follow the instructions in contrib/debianinstall/config.txt. + +In short... + +Your streams server must be reachable by a domain that you can type in your browser + + cooldomain.org + +You can use subdomains as well + + my.cooldomain.org + +There are two ways to get a domain... + +### Method 1: Buy a Domain + +...for example buy at selfHOST.de + +The cost is 1,00 € per month (2024). + +### Method 2: Register a free subdomain + +...for example register at freedns.afraid.org + +## Note on Rasperry + +It is recommended to run the Raspi without graphical frontend (X-Server). Use... + + sudo raspi-config + +to boot the Rapsi to the client console. + +DO NOT FORGET TO CHANGE THE DEFAULT PASSWORD FOR USER PI! + diff --git a/contrib/debianinstall/config.txt.template b/contrib/debianinstall/config.txt.template new file mode 100644 index 000000000..869e0cfb9 --- /dev/null +++ b/contrib/debianinstall/config.txt.template @@ -0,0 +1,96 @@ + +############################################### +### MANDATORY - database password ############# +# +# Please give your database password +# It is better to not use blanks inside the password. +# Example: db_pass=pass_word_with_no_blanks_in_it +db_pass= + +############################################### +### MANDATORY - let's encrypt ################# +# +# The server software requires encrypted communication via secure HTTP (HTTPS). +# This script automates installation of an SSL certificate from +# Let's Encrypt (https://letsencrypt.org) +# +# Please give the domain name of your hub/instance +# +# Example: my.cooldomain.org +# Example: cooldomain.org +# +# +le_domain= +le_email= + + +############################################### +### OPTIONAL - selfHOST - dynamic IP address ## +# +# 1. Register a domain at selfhost.de +# - choose offer "DOMAIN dynamisch" 1,00€/mon at 08/2024 +# 2. Get your configuration for dynamic IP update +# - Log in at selfhost.de +# - go to "DynDNS Account" +# - klick "Details" of your (freshly) registered domain +# - You will find the configuration there +# - Benutzername (user name) > use this for "selfhost_user=" +# - Passwort (pass word) > use this for "selfhost_pass=" +# +# +selfhost_user= +selfhost_pass= + +############################################### +### OPTIONAL - FreeDNS - dynamic IP address ### +# +# Please give the alpha-numeric-key of freedns +# +# Get a free subdomain from freedns and use it for your dynamic ip address +# Documentation under http://www.techjawab.com/2013/06/setup-dynamic-dns-dyndns-for-free-on.html +# +# - Register for a Free domain at http://freedns.afraid.org/signup/ +# - WATCH THIS: Make sure you choose a domain with as less subdomains as +# possible. Why? Let's encrpyt issues a limited count of certificates each +# day. Possible other users of this domain will try to issue a certificate +# at the same day. +# - Logon to FreeDNS (where you just registered) +# - Goto http://freedns.afraid.org/dynamic/ +# - Right click on "Direct Link" and copy the URL and paste it somewhere. +# - You should notice a large and unique alpha-numeric key in the URL +# +# http://freedns.afraid.org/dynamic/update.php?alpha-numeric-key +# +# Provided your url from freedns is +# +# http://freedns.afraid.org/dynamic/update.php?U1Z6aGt2R0NzMFNPNWRjbWxxZGpsd093OjE1Mzg5NDE5 +# +# Then you have to provide +# +# freedns_key=U1Z6aGt2R0NzMFNPNWRjbWxxZGpsd093OjE1Mzg5NDE5 +# +# +freedns_key= + + +############################################### +### OPTIONAL - do not mess with things below ## +# (...if you are not certain) +# +# Usually you are done here +# Everything below is OPTIONAL +# +############################################### +# +# Database for your instance +# +db_name=streams +db_user=streams +# +# +# Password for package mysql-server +# Example: mysqlpass=aberhallo +# Example: mysqlpass="aber hallo has blanks in it" +# +mysqlpass=$db_pass + diff --git a/contrib/debianinstall/debian-setup.sh b/contrib/debianinstall/debian-setup.sh new file mode 100755 index 000000000..1bb72b5ae --- /dev/null +++ b/contrib/debianinstall/debian-setup.sh @@ -0,0 +1,528 @@ +#!/bin/bash +# +# How to use +# ---------- +# +# This file automates the installation of streams: https://codeberg.org/streams/streams.git +# under Debian Linux "bookworm" +# +# 1) Copy the file "config.txt.template" to "config.txt" +# Follow the instuctions there +# +# 2) Switch to user "root" by typing "su -" +# +# 3) Run with "./debian-setup.sh" +# If this fails check if you can execute the script. +# - To make it executable type "chmod +x debian-setup.sh" +# - or run "bash debian-setup.sh" +# +# +# What does this script do basically? +# ----------------------------------- +# +# This file automates the installation of a Hubzilla instance under Debian Linux +# - install +# * apache webserver, +# * php, +# * mariadb, +# * adminer, +# * addons +# - configure cron +# * "Run.php" for regular background processes of your instance +# * "apt-get update" and "apt-get dist-upgrade" and "apt-get autoremove" to keep linux up-to-date +# * run command to keep the IP up-to-date > DynDNS provided by selfHOST.de or freedns.afraid.org +# - run letsencrypt to create, register and use a certifacte for https +# +# +# Credits +# ------- +# +# The script is based on +# - Thomas Willinghams script "debian-setup.sh" which he used to install the red#matrix. + +function check_sanity { + # Do some sanity checking. + print_info "Sanity check..." + if [ $(/usr/bin/id -u) != "0" ] + then + die 'Must be run by root user' + fi + + if [ -f /etc/lsb-release ] + then + die "Distribution is not supported" + fi + if [ ! -f /etc/debian_version ] + then + die "Debian is supported only" + fi + if ! grep -q 'Linux 12' /etc/issue + then + die "Linux 12 (bookworm) is supported only"x + fi +} + +function check_config { + print_info "config check..." + # Check for required parameters + if [ -z "$db_pass" ] + then + die "db_pass not set in $configfile" + fi + if [ -z "$le_domain" ] + then + die "le_domain not set in $configfile" + fi + if [ -z "$le_email" ] + then + die "le_email not set in $configfile" + fi +} + +function die { + echo "ERROR: $1" > /dev/null 1>&2 + exit 1 +} + + +function update_upgrade { + print_info "updated and upgrade..." + # Run through the apt-get update/upgrade first. This should be done before + # we try to install any package + apt-get -q -y update && apt-get -q -y dist-upgrade && apt-get -q -y autoremove + print_info "updated and upgraded linux" +} + +function nocheck_install { + # export DEBIAN_FRONTEND=noninteractive ... answers from the package configuration database + # - q ... without progress information + # - y ... answer interactive questions with "yes" + # DEBIAN_FRONTEND=noninteractive apt-get --no-install-recommends -q -y install $2 + # DEBIAN_FRONTEND=noninteractive apt-get --install-suggests -q -y install $1 + DEBIAN_FRONTEND=noninteractive apt-get -q -y install $1 + print_info "installed $1" +} + + +function print_info { + echo -n -e '\e[1;34m' + echo -n $1 + echo -e '\e[0m' +} + +function print_warn { + echo -n -e '\e[1;31m' + echo -n $1 + echo -e '\e[0m' +} + +function stop_server { + print_info "stopping apache..." + systemctl stop apache2 + print_info "stopping mysql db..." + systemctl stop mariadb +} + +function install_apache { + print_info "installing apache..." + nocheck_install "apache2 apache2-utils" + a2enmod rewrite + systemctl restart apache2 +} + +function install_imagemagick { + print_info "installing imagemagick..." + nocheck_install "imagemagick" +} + +function install_curl { + print_info "installing curl..." + nocheck_install "curl" +} + +function install_wget { + print_info "installing wget..." + nocheck_install "wget" +} + +function install_sendmail { + print_info "installing sendmail..." + nocheck_install "sendmail sendmail-bin" +} + +function install_php { + # openssl and mbstring are included in libapache2-mod-php + print_info "installing php..." + nocheck_install "libapache2-mod-php php php-pear php-curl php-gd php-mbstring php-xml php-zip" + phpversion=$(php -v|grep --only-matching --perl-regexp "(PHP )\d+\.\\d+\.\\d+"|cut -c 5-7) + sed -i "s/^upload_max_filesize =.*/upload_max_filesize = 100M/g" /etc/php/$phpversion/apache2/php.ini + sed -i "s/^post_max_size =.*/post_max_size = 100M/g" /etc/php/$phpversion/apache2/php.ini + print_info "PHP version is ${phpversion}" +} + +function install_composer { + print_info "We check if Composer is already downloaded" + if [ ! -f /usr/local/bin/composer ] + then + EXPECTED_CHECKSUM="$(php -r 'copy("https://composer.github.io/installer.sig", "php://stdout");')" + php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');" + ACTUAL_CHECKSUM="$(php -r "echo hash_file('sha384', 'composer-setup.php');")" + if [ "$EXPECTED_CHECKSUM" != "$ACTUAL_CHECKSUM" ] + then + >&2 echo 'ERROR: Invalid installer checksum' + rm composer-setup.php + die 'ERROR: Invalid installer checksum' + fi + php composer-setup.php --quiet + RESULT=$? + rm composer-setup.php + # exit $RESULT + # We install Composer globally + mv composer.phar /usr/local/bin/composer + print_info "Composer was successfully downloaded." + cd $install_path + export COMPOSER_ALLOW_SUPERUSER=1; + /usr/local/bin/composer install --no-dev + /usr/local/bin/composer show + export COMPOSER_ALLOW_SUPERUSER=0; + else + print_info "Composer is already downloaded (and installed) on this system." + fi +} + +function install_mysql { + print_info "installing mysql..." + if [ -z "$mysqlpass" ] + then + die "mysqlpass not set in $configfile" + fi + if [ ! -z $(which mysql) ] + then + echo "mysql is already installed" + else + echo "we install mariadb-server" + nocheck_install "mariadb-server" + systemctl is-active --quiet mariadb && echo "MariaDB is running" + # We can probably find a more elegant solution like in create_website_db function + mysql -u root <<_EOF_ +ALTER USER 'root'@'localhost' IDENTIFIED BY '${mysqlpass}'; +DELETE FROM mysql.user WHERE User=''; +DROP DATABASE IF EXISTS test; +DELETE FROM mysql.db WHERE Db='test' OR Db='test\\_%'; +FLUSH PRIVILEGES; +_EOF_ + fi +} + +function install_adminer { + print_info "installing adminer..." + nocheck_install "adminer" + if [ ! -f /etc/adminer/adminer.conf ] + then + echo "Alias /adminer /usr/share/adminer/adminer" > /etc/adminer/adminer.conf + ln -s /etc/adminer/adminer.conf /etc/apache2/conf-available/adminer.conf + else + print_info "file /etc/adminer/adminer.conf exists already" + fi + + a2enmod rewrite + + if [ ! -f /etc/apache2/apache2.conf ] + then + die "could not find file /etc/apache2/apache2.conf" + fi + sed -i \ + "s/AllowOverride None/AllowOverride all/" \ + /etc/apache2/apache2.conf + + a2enconf adminer + systemctl restart mariadb + systemctl reload apache2 +} +function create_website_db { + print_info "creating website's database..." + if [ -z "$db_name" ] + then + db_name=$install_folder + fi + if [ -z "$db_user" ] + then + db_user=$install_folder + fi + if [ -z "$db_pass" ] + then + die "db_pass not set in $configfile" + fi + systemctl restart mariadb + # Make sure we don't write over an already existing database if we install more one website + if [ -z $(mysql -h localhost -u root -p$mysqlpass -e "SHOW DATABASES;" | grep $db_name) ] + then + Q1="CREATE DATABASE IF NOT EXISTS $db_name;" + Q2="GRANT USAGE ON *.* TO $db_user@localhost IDENTIFIED BY '$db_pass';" + Q3="GRANT ALL PRIVILEGES ON $db_name.* to $db_user@localhost identified by '$db_pass';" + Q4="FLUSH PRIVILEGES;" + SQL="${Q1}${Q2}${Q3}${Q4}" + mysql -uroot -p$mysqlpass -e "$SQL" + else + print_info "data base does exist already..." + fi +} + +function run_freedns { + print_info "run freedns (dynamic IP)..." + if [ -z "$freedns_key" ] + then + print_info "freedns was not started because 'freedns_key' is empty in $configfile" + else + if [ -n "$selfhost_user" ] + then + die "You can not use freeDNS AND selfHOST for dynamic IP updates ('freedns_key' AND 'selfhost_user' set in $configfile)" + fi + wget --no-check-certificate -O - http://freedns.afraid.org/dynamic/update.php?$freedns_key + fi +} + +function install_run_selfhost { + print_info "install and start selfhost (dynamic IP)..." + if [ -z "$selfhost_user" ] + then + print_info "selfHOST was not started because 'selfhost_user' is empty in $configfile" + else + if [ -n "$freedns_key" ] + then + die "You can not use freeDNS AND selfHOST for dynamic IP updates ('freedns_key' AND 'selfhost_user' set in $configfile)" + fi + if [ -z "$selfhost_pass" ] + then + die "selfHOST was not started because 'selfhost_pass' is empty in $configfile" + fi + if [ ! -d $selfhostdir ] + then + mkdir $selfhostdir + fi + # the old way + # https://carol.selfhost.de/update?username=123456&password=supersafe + # + # the prefered way + wget --output-document=$selfhostdir/$selfhostscript http://jonaspasche.de/selfhost-updater + echo "router" > $selfhostdir/device + echo "$selfhost_user" > $selfhostdir/user + echo "$selfhost_pass" > $selfhostdir/pass + bash $selfhostdir/$selfhostscript update + fi +} + +function ping_domain { + print_info "ping domain $domain..." + # Is the domain resolved? Try to ping 6 times à 10 seconds + COUNTER=0 + for i in {1..6} + do + print_info "loop $i for ping -c 1 $domain ..." + if ping -c 4 -W 1 $le_domain + then + print_info "$le_domain resolved" + break + else + if [ $i -gt 5 ] + then + die "Failed to: ping -c 1 $domain not resolved" + fi + fi + sleep 10 + done + sleep 5 +} + +function configure_cron_freedns { + print_info "configure cron for freedns..." + if [ -z "$freedns_key" ] + then + print_info "freedns is not configured because freedns_key is empty in $configfile" + else + # Use cron for dynamich ip update + # - at reboot + # - every 30 minutes + if [ -z "`grep 'freedns.afraid.org' /etc/crontab`" ] + then + echo "@reboot root http://freedns.afraid.org/dynamic/update.php?$freedns_key > /dev/null 2>&1" >> /etc/crontab + echo "*/30 * * * * root wget --no-check-certificate -O - http://freedns.afraid.org/dynamic/update.php?$freedns_key > /dev/null 2>&1" >> /etc/crontab + else + print_info "cron for freedns was configured already" + fi + fi +} + +function configure_cron_selfhost { + print_info "configure cron for selfhost..." + if [ -z "$selfhost_user" ] + then + print_info "selfhost is not configured because selfhost_key is empty in $configfile" + else + # Use cron for dynamich ip update + # - at reboot + # - every 5 minutes + if [ -z "`grep 'selfhost-updater.sh' /etc/crontab`" ] + then + echo "@reboot root bash /etc/selfhost/selfhost-updater.sh update > /dev/null 2>&1" >> /etc/crontab + echo "*/5 * * * * root /bin/bash /etc/selfhost/selfhost-updater.sh update > /dev/null 2>&1" >> /etc/crontab + else + print_info "cron for selfhost was configured already" + fi + fi +} + +function install_letsencrypt { + print_info "installing let's encrypt ..." + # check if user gave domain + if [ -z "$le_domain" ] + then + die "Failed to install let's encrypt: 'le_domain' is empty in $configfile" + fi + if [ -z "$le_email" ] + then + die "Failed to install let's encrypt: 'le_email' is empty in $configfile" + fi + nocheck_install "certbot python3-certbot-apache" + print_info "run certbot ..." + certbot --apache -w $install_path -d $le_domain -m $le_email --agree-tos --non-interactive --redirect --hsts --uir + systemctl restart apache2 +} + +function check_https { + print_info "checking httpS > testing ..." + url_https=https://$le_domain + wget_output=$(wget -nv --spider --max-redirect 0 $url_https) + if [ $? -ne 0 ] + then + print_warn "check not ok" + else + print_info "check ok" + fi +} + +function install_server { + print_info "installing addons..." + cd $install_path + util/add_addon_repo https://codeberg.org/streams/streams-addons.git zaddons + mkdir -p "store" + mkdir -p "cache/smarty3" + chmod -R 700 store cache + touch .htconfig.php + # The next run of $cron_job_file (daily-update script) will correct the permissions of the next line + chmod ou+w .htconfig.php + chown -R www-data:www-data $install_path + chown root:www-data $install_path/ + chown root:www-data $install_path/.htaccess + chmod 0644 $install_path/.htaccess + print_info "installed addons" +} + +function configure_cron_daily { print_info "configuring cron..." + # every 10 min for poller.php + if [ -z "`grep 'php src/Daemon/Run.php' /etc/crontab`" ] + then + echo "*/10 * * * * www-data cd $install_path; php src/Daemon/Run.php Cron >> /dev/null 2>&1" >> /etc/crontab + fi + + # Run external script daily at 05:30 + # - stop apache and mysql-server + # - renew the certificate of letsencrypt + # - show size of database files + # - update repository core and addon + # - update and upgrade linux + # - reboot is done by "shutdown -h now" because "reboot" hangs sometimes depending on the system + # - set permissions on some files + echo "#!/bin/sh" > $cron_job_file + echo "#" >> $cron_job_file + echo "echo \" \"" >> $cron_job_file + echo "echo \"+++ \$(date) +++\"" >> $cron_job_file + echo "echo \" \"" >> $cron_job_file + echo "echo \"\$(date) - stopping apache and mysql...\"" >> $cron_job_file + echo "systemctl stop apache2" >> $cron_job_file + echo "systemctl stop mariadb # to avoid inconsistencies" >> $cron_job_file + echo "#" >> $cron_job_file + echo "echo \"\$(date) - renew certificate...\"" >> $cron_job_file + echo "certbot renew --noninteractive" >> $cron_job_file + echo "#" >> $cron_job_file + echo "echo \"\$(date) - db size...\"" >> $cron_job_file + echo "du -h /var/lib/mysql/ | grep mysql/" >> $cron_job_file + echo "#" >> $cron_job_file + echo "# update of $le_domain instance" >> $cron_job_file + echo "echo \"\$(date) - updating core and addons...\"" >> $cron_job_file + echo "echo \"reaching git repository for $le_domain $server_name instance...\"" >> $cron_job_file + echo "(cd $install_path ; util/udall)" >> $cron_job_file + echo "chown -R www-data:www-data $install_path # make all accessible for the webserver" >> $cron_job_file + echo "chown root:www-data $install_path/.htaccess" >> $cron_job_file + echo "chmod 0644 $install_path/.htaccess # www-data can read but not write it" >> $cron_job_file + echo "echo \"\$(date) - updating linux...\"" >> $cron_job_file + echo "apt-get -q -y update && apt-get -q -y dist-upgrade && apt-get -q -y autoremove # update linux and upgrade" >> $cron_job_file + echo "echo \"\$(date) - Update finished. Rebooting...\"" >> $cron_job_file + echo "#" >> $cron_job_file + echo "shutdown -r now" >> $cron_job_file + + chmod a+x $cron_job_file + + # If global cron job does not exist we add it to /etc/crontab + if grep -q $cron_job_file /etc/crontab + then + echo "cron job already in /etc/crontab" + else + echo "30 05 * * * root /bin/bash $cron_job_file >> $cron_job_log_file 2>&1" >> /etc/crontab + echo "0 0 1 * * root rm $cron_job_log_file" >> /etc/crontab + fi + + # This is active after either "reboot" or cron reload" + systemctl restart cron + print_info "configured cron for updates/upgrades" +} + +######################################################################## +# START OF PROGRAM +######################################################################## +export PATH=/bin:/usr/bin:/sbin:/usr/sbin +check_sanity + +server_name=streams +install_path=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" & cd ../.. &> /dev/null && pwd ) +print_info "We're installing a $server_name instance into $install_path" + +# Read config file edited by user +configfile=config.txt +source $configfile + +selfhostdir=/etc/selfhost +selfhostscript=selfhost-updater.sh + +cron_job_dir=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" & cd ../../.. &> /dev/null && pwd ) +cron_job_file="$cron_job_dir/cron_job.sh" +print_info "The cron job script will be $cron_job_file" +cron_job_log_file="$cron_job_dir/daily-updates.log" +print_info "The cron job log file will be $cron_job_log_file" + +#set -x # activate debugging from here + +check_config +stop_server +update_upgrade +install_curl +install_wget +install_sendmail +install_apache +install_imagemagick +install_php +install_composer +install_mysql +install_adminer +create_website_db +run_freedns +install_run_selfhost +ping_domain +configure_cron_freedns +configure_cron_selfhost +install_letsencrypt +check_https +install_server +configure_cron_daily + +#set +x # stop debugging from here diff --git a/util/messages.po b/util/messages.po index 995b799f6..298b373b0 100644 --- a/util/messages.po +++ b/util/messages.po @@ -6,9 +6,9 @@ #, fuzzy msgid "" msgstr "" -"Project-Id-Version: 24.08.20\n" +"Project-Id-Version: 24.08.27\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2024-08-20 16:51+1000\n" +"POT-Creation-Date: 2024-08-27 06:59+1000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -42,7 +42,7 @@ msgstr "" msgid "Login" msgstr "" -#: boot.php:1128 src/Module/Rmagic.php:88 src/Lib/Channel.php:2205 +#: boot.php:1128 src/Module/Rmagic.php:88 src/Lib/Channel.php:2208 msgid "Remote Authentication" msgstr "" @@ -892,7 +892,7 @@ msgstr "" #: include/conversation.php:959 include/attach.php:1380 include/attach.php:1401 #: src/Module/Embedphotos.php:380 src/Module/Photos.php:856 #: src/Module/Photos.php:1324 src/Module/Cdav.php:877 src/Module/Cdav.php:878 -#: src/Module/Cdav.php:884 src/Lib/Activity.php:2459 src/Lib/Apps.php:1261 +#: src/Module/Cdav.php:884 src/Lib/Activity.php:2460 src/Lib/Apps.php:1261 #: src/Lib/Apps.php:1352 src/Widget/Portfolio.php:110 src/Widget/Album.php:100 #: src/Storage/Browser.php:183 msgid "Unknown" @@ -1418,8 +1418,8 @@ msgstr "" msgid "Visible to specific connections." msgstr "" -#: include/items.php:3093 include/misc.php:1720 include/misc.php:3217 -#: src/Lib/Activity.php:4067 +#: include/items.php:3093 include/misc.php:1720 include/misc.php:3193 +#: src/Lib/Activity.php:4068 #, php-format msgid "%1$s (%2$s)" msgstr "" @@ -1480,17 +1480,17 @@ msgstr "" msgid "profile photo" msgstr "" -#: include/items.php:4907 +#: include/items.php:4909 #, php-format msgid "[Edited %s]" msgstr "" -#: include/items.php:4907 +#: include/items.php:4909 msgctxt "edit_activity" msgid "Post" msgstr "" -#: include/items.php:4907 +#: include/items.php:4909 msgctxt "edit_activity" msgid "Comment" msgstr "" @@ -2341,97 +2341,97 @@ msgstr "" msgid "a-z, 0-9, -, and _ only" msgstr "" -#: include/misc.php:2911 +#: include/misc.php:2887 msgid "Design Tools" msgstr "" -#: include/misc.php:2914 src/Module/Blocks.php:167 +#: include/misc.php:2890 src/Module/Blocks.php:167 msgid "Blocks" msgstr "" -#: include/misc.php:2915 src/Module/Menu.php:177 +#: include/misc.php:2891 src/Module/Menu.php:177 msgid "Menus" msgstr "" -#: include/misc.php:2916 src/Module/Layouts.php:200 +#: include/misc.php:2892 src/Module/Layouts.php:200 msgid "Layouts" msgstr "" -#: include/misc.php:2917 +#: include/misc.php:2893 msgid "Pages" msgstr "" -#: include/misc.php:2939 src/Module/Cal.php:352 +#: include/misc.php:2915 src/Module/Cal.php:352 msgid "Import" msgstr "" -#: include/misc.php:2940 +#: include/misc.php:2916 msgid "Import website..." msgstr "" -#: include/misc.php:2941 +#: include/misc.php:2917 msgid "Select folder to import" msgstr "" -#: include/misc.php:2942 +#: include/misc.php:2918 msgid "Import from a zipped folder:" msgstr "" -#: include/misc.php:2943 +#: include/misc.php:2919 msgid "Import from cloud files:" msgstr "" -#: include/misc.php:2944 +#: include/misc.php:2920 msgid "/cloud/channel/path/to/folder" msgstr "" -#: include/misc.php:2945 +#: include/misc.php:2921 msgid "Enter path to website files" msgstr "" -#: include/misc.php:2946 +#: include/misc.php:2922 msgid "Select folder" msgstr "" -#: include/misc.php:2947 +#: include/misc.php:2923 msgid "Export website..." msgstr "" -#: include/misc.php:2948 +#: include/misc.php:2924 msgid "Export to a zip file" msgstr "" -#: include/misc.php:2949 +#: include/misc.php:2925 msgid "website.zip" msgstr "" -#: include/misc.php:2950 +#: include/misc.php:2926 msgid "Enter a name for the zip file." msgstr "" -#: include/misc.php:2951 +#: include/misc.php:2927 msgid "Export to cloud files" msgstr "" -#: include/misc.php:2952 +#: include/misc.php:2928 msgid "/path/to/export/folder" msgstr "" -#: include/misc.php:2953 +#: include/misc.php:2929 msgid "Enter a path to a cloud files destination." msgstr "" -#: include/misc.php:2954 +#: include/misc.php:2930 msgid "Specify folder" msgstr "" -#: include/misc.php:3360 src/Module/Directory.php:455 src/Module/Manage.php:85 +#: include/misc.php:3336 src/Module/Directory.php:455 src/Module/Manage.php:85 #: src/Module/Manage.php:198 src/Module/Manage.php:211 #: src/Storage/Browser.php:149 msgid "Collection" msgstr "" -#: include/misc.php:3673 src/Module/Admin/Site.php:204 +#: include/misc.php:3649 src/Module/Admin/Site.php:204 #: view/theme/fresh/php/config.php:22 view/theme/redbasic/php/config.php:22 msgid "Default" msgstr "" @@ -3350,7 +3350,7 @@ msgstr "" msgid "Restricted or Premium Channel" msgstr "" -#: src/Module/Follow.php:146 +#: src/Module/Follow.php:148 msgid "Connection added." msgstr "" @@ -3449,7 +3449,7 @@ msgstr "" msgid "Profile Visibility Editor" msgstr "" -#: src/Module/Profperm.php:131 src/Lib/Activity.php:3407 src/Lib/Apps.php:439 +#: src/Module/Profperm.php:131 src/Lib/Activity.php:3408 src/Lib/Apps.php:439 #: src/Lib/Libprofile.php:753 msgid "Profile" msgstr "" @@ -7470,11 +7470,11 @@ msgstr "" msgid "Authentication failed." msgstr "" -#: src/Module/Rmagic.php:89 src/Lib/Channel.php:2206 +#: src/Module/Rmagic.php:89 src/Lib/Channel.php:2209 msgid "Enter your channel address (e.g. channel@example.com)" msgstr "" -#: src/Module/Rmagic.php:92 src/Lib/Channel.php:2207 +#: src/Module/Rmagic.php:92 src/Lib/Channel.php:2210 msgid "Authenticate" msgstr "" @@ -9860,51 +9860,51 @@ msgstr "" msgid "Quoted post" msgstr "" -#: src/Lib/Activity.php:3405 +#: src/Lib/Activity.php:3406 msgid "Activity" msgstr "" -#: src/Lib/Activity.php:3413 +#: src/Lib/Activity.php:3414 #, php-format msgid "Likes %1$s's %2$s" msgstr "" -#: src/Lib/Activity.php:3416 +#: src/Lib/Activity.php:3417 #, php-format msgid "Doesn't like %1$s's %2$s" msgstr "" -#: src/Lib/Activity.php:3419 +#: src/Lib/Activity.php:3420 #, php-format msgid "Flagged %1$s's %2$s" msgstr "" -#: src/Lib/Activity.php:3422 +#: src/Lib/Activity.php:3423 #, php-format msgid "Blocked %1$s's %2$s" msgstr "" -#: src/Lib/Activity.php:3428 +#: src/Lib/Activity.php:3429 #, php-format msgid "Will attend %s's event" msgstr "" -#: src/Lib/Activity.php:3431 +#: src/Lib/Activity.php:3432 #, php-format msgid "Will not attend %s's event" msgstr "" -#: src/Lib/Activity.php:3434 +#: src/Lib/Activity.php:3435 #, php-format msgid "May attend %s's event" msgstr "" -#: src/Lib/Activity.php:3437 +#: src/Lib/Activity.php:3438 #, php-format msgid "May not attend %s's event" msgstr "" -#: src/Lib/Activity.php:3443 +#: src/Lib/Activity.php:3444 #, php-format msgid "📢 Repeated %1$s's %2$s" msgstr "" diff --git a/version.php b/version.php index a0a1533db..e2f4fd87c 100644 --- a/version.php +++ b/version.php @@ -1,2 +1,2 @@