Merge branch 'dev' of codeberg.org:streams/streams into dev

This commit is contained in:
Mike Macgirvin 2024-09-06 08:02:39 +10:00
commit 8befb91021
5 changed files with 818 additions and 47 deletions

View file

@ -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!

View file

@ -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

View file

@ -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

View file

@ -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 <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\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 "&#x1f4e2; Repeated %1$s's %2$s"
msgstr ""

View file

@ -1,2 +1,2 @@
<?php
define ('STD_VERSION', '24.08.22');
define ('STD_VERSION', '24.09.04');